1/** 2 * browser-deeplink v0.1 3 * 4 * Author: Hampus Ohlsson, Nov 2014 5 * GitHub: http://github.com/hampusohlsson/browser-deeplink 6 * 7 * MIT License 8 */ 9 10//!function(n,e){"function"==typeof define&&define.amd?define("deeplink",e(n)):"object"==typeof exports?module.exports=e(n):n.deeplink=e(n)}(window||this,function(n){"use strict";if(n.document&&n.navigator){var e,t={},a={iOS:{},android:{},androidDisabled:!1,fallback:!0,fallbackToWeb:!0,delay:1e3,delta:500},r=function(n,e){var t={};for(var a in n)t[a]=n[a];for(var a in e)t[a]=e[a];return t},o=function(){var n="itms-apps://itunes.apple.com/app/",e=t.iOS.appName,a=t.iOS.appId;return a&&e?n+e+"/id"+a+"?mt=8":null},i=function(){var n="market://details?id=",e=t.android.appId;return e?n+e:null},d=function(){var n={ios:t.iOS.storeUrl||o(),android:t.android.storeUrl||i()};return n[t.platform]},l=function(){var n={ios:t.iOS.fallbackWebUrl||location.href,android:t.android.fallbackWebUrl||location.href};return n[t.platform]},f=function(){return navigator.userAgent.match("Android")},u=function(){return navigator.userAgent.match("iPad")||navigator.userAgent.match("iPhone")||navigator.userAgent.match("iPod")},c=function(){return f()||u()},p=function(n){return function(){var e=t.fallbackToWeb?l():d(),a=t.delay+t.delta;"string"==typeof e&&Date.now()-n<a&&(window.location.href=e)}},s=function(n){t=r(a,n),f()&&(t.platform="android"),u()&&(t.platform="ios")},m=function(n){if(!c())return!1;if(!f()||!t.androidDisabled){if(f()&&!navigator.userAgent.match(/Firefox/)){var a=n.match(/([^:]+):\/\/(.+)$/i);n="intent://"+a[2]+"#Intent;scheme="+a[1],n+=";package="+t.android.appId+";end"}(t.fallback||t.fallbackToWeb)&&(e=setTimeout(p(Date.now()),t.delay));var r=document.createElement("iframe");return r.onload=function(){clearTimeout(e),r.parentNode.removeChild(r),window.location.href=n},r.src=n,r.setAttribute("style","display:none;"),document.body.appendChild(r),!0}};return{setup:s,open:m}}}); 11 12(function (root, factory) { 13 if ( typeof define === 'function' && define.amd ) { 14 define("deeplink", factory(root)); 15 } else if ( typeof exports === 'object' ) { 16 module.exports = factory(root); 17 } else { 18 root["deeplink"] = factory(root); 19 } 20})(window || this, function(root) { 21 22 "use strict" 23 24 /** 25 * Cannot run without DOM or user-agent 26 */ 27 if (!root.document || !root.navigator) { 28 return; 29 } 30 31 /** 32 * Set up scope variables and settings 33 */ 34 var timeout; 35 var settings = {}; 36 var defaults = { 37 iOS: {}, 38 android: {}, 39 androidDisabled: false, 40 fallback: true, 41 fallbackToWeb: true, 42 delay: 2000, 43 delta: 500 44 } 45 46 /** 47 * Merge defaults with user options 48 * @private 49 * @param {Object} defaults Default settings 50 * @param {Object} options User options 51 * @returns {Object} Merged values of defaults and options 52 */ 53 var extend = function(defaults, options) { 54 var extended = {}; 55 for(var key in defaults) { 56 extended[key] = defaults[key]; 57 }; 58 for(var key in options) { 59 extended[key] = options[key]; 60 }; 61 return extended; 62 }; 63 64 /** 65 * Generate the app store link for iOS / Apple app store 66 * 67 * @private 68 * @returns {String} App store itms-apps:// link 69 */ 70 var getStoreURLiOS = function() { 71 var baseurl = "itms-apps://itunes.apple.com/us/app/"; 72 var name = settings.iOS.appName; 73 var id = settings.iOS.appId; 74 return (id && name) ? (baseurl + name + "/id" + id + "?mt=8") : null; 75 } 76 77 /** 78 * Generate the app store link for Google Play 79 * 80 * @private 81 * @returns {String} Play store https:// link 82 */ 83 var getStoreURLAndroid = function() { 84 var baseurl = "market://details?id="; 85 var id = settings.android.appId; 86 return id ? (baseurl + id) : null; 87 } 88 89 /** 90 * Get app store link, depending on the current platform 91 * 92 * @private 93 * @returns {String} url 94 */ 95 var getStoreLink = function() { 96 var linkmap = { 97 "ios": settings.iOS.storeUrl || getStoreURLiOS(), 98 "android": settings.android.storeUrl || getStoreURLAndroid() 99 } 100 101 return linkmap[settings.platform]; 102 } 103 104 /** 105 * Get web fallback link, depending on the current platform 106 * If none is set, default to current url 107 * 108 * @private 109 * @returns {String} url 110 */ 111 var getWebLink = function() { 112 var linkmap = { 113 "ios": settings.iOS.fallbackWebUrl || location.href, 114 "android": settings.android.fallbackWebUrl || location.href 115 } 116 117 return linkmap[settings.platform]; 118 } 119 120 /** 121 * Check if the user-agent is Android 122 * 123 * @private 124 * @returns {Boolean} true/false 125 */ 126 var isAndroid = function() { 127 return navigator.userAgent.match('Android'); 128 } 129 130 /** 131 * Check if the user-agent is iPad/iPhone/iPod 132 * 133 * @private 134 * @returns {Boolean} true/false 135 */ 136 var isIOS = function() { 137 return navigator.userAgent.match('iPad') || 138 navigator.userAgent.match('iPhone') || 139 navigator.userAgent.match('iPod'); 140 } 141 142 /** 143 * Check if the user is on mobile 144 * 145 * @private 146 * @returns {Boolean} true/false 147 */ 148 var isMobile = function() { 149 return isAndroid() || isIOS(); 150 } 151 152 /** 153 * Timeout function that tries to open the fallback link. 154 * The fallback link is either the storeUrl for the platofrm 155 * or the fallbackWebUrl for the current platform. 156 * The time delta comparision is to prevent the app store
157 * link from opening at a later point in time. E.g. if the 158 * user has your app installed, opens it, and then returns 159 * to their browser later on. 160 * 161 * @private 162 * @param {Integer} Timestamp when trying to open deeplink 163 * @returns {Function} Function to be executed by setTimeout 164 */ 165 var openFallback = function(ts) { 166 return function() { 167 var link = (settings.fallbackToWeb) ? getWebLink() : getStoreLink(); 168 var wait = settings.delay + settings.delta; 169 if (typeof link === "string" && (Date.now() - ts) < wait) { 170 window.location.href = link; 171 } 172 } 173 } 174 175 /** 176 * The setup() function needs to be run before deeplinking can work, 177 * as you have to provide the iOS and/or Android settings for your app. 178 * 179 * @public 180 * @param {object} setup options 181 */ 182 var setup = function(options) { 183 settings = extend(defaults, options); 184 if (isAndroid()) settings.platform = "android"; 185 if (isIOS()) settings.platform = "ios"; 186 } 187 188 /** 189 * Tries to open your app URI through a hidden iframe. 190 * 191 * @public 192 * @param {String} Deeplink URI 193 * @return {Boolean} true, if you're on a mobile device and the link was opened 194 */ 195 var deeplinkOpen = function(uri) { 196 if (!isMobile()) { 197 return false; 198 } 199 200 if (isAndroid() && settings.androidDisabled) { 201 return; 202 } 203 204 if (settings.fallback|| settings.fallbackToWeb) { 205 timeout = setTimeout(openFallback(Date.now()), settings.delay); 206 } 207 208 if (isAndroid()) { 209 var matches = uri.match(/([^:]+):\/\/(.+)$/i); 210 uri = "intent://" + matches[2] + "#Intent;scheme=" + matches[1]; 211 uri += ";package=" + settings.android.appId; 212 uri += ";S.browser_fallback_url=" + getWebLink() + ";end" 213 var iframe = document.createElement("iframe"); 214 iframe.onload = function () { 215 clearTimeout(timeout); 216 iframe.parentNode.removeChild(iframe); 217 window.location.href = uri; 218 }; 219 iframe.src = uri; 220 iframe.setAttribute("style", "display:none;"); 221 document.body.appendChild(iframe); 222 } else { //is IOS 223 var link = getStoreURLiOS(); 224 window.location.href = link; 225 } 226 return true; 227 } 228 229 // Public API 230 return { 231 setup: setup, 232 open: deeplinkOpen 233 }; 234 235});
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.