1cordova.define("ionic-plugin-deeplinks.deeplink", function(require, exports, module) { var argscheck = require('cordova/argscheck'), 2 utils = require('cordova/utils'), 3 exec = require('cordova/exec'); 4 5var PLUGIN_NAME = 'IonicDeeplinkPlugin'; 6 7var extend = function (out) { 8 out = out || {}; 9 10 for (var i = 1; i < arguments.length; i++) { 11 if (!arguments[i]) { 12 continue; 13 } 14 for (var key in arguments[i]) { 15 if (arguments[i].hasOwnProperty(key)) { 16 out[key] = arguments[i][key]; 17 } 18 } 19 } 20 return out; 21}; 22 23 24var IonicDeeplink = { 25 26 /** 27 * How long to wait after a deeplink match before navigating. 28 * Default is 800ms which gives the app time to get back and then 29 * smoothly animate. 30 */ 31 NAVIGATION_DELAY: 800, 32 33 canOpenApp: function (app, cb) { 34 exec(cb, null, PLUGIN_NAME, 'canOpenApp', []); 35 }, 36 37 route: function (paths, success, error) { 38 var self = this; 39 this.paths = paths; 40 41 this.onDeepLink(function (data) { 42 var realPath = self._getRealPath(data); 43 44 var args = self._queryToObject(data.queryString); 45 46 var matched = false; 47 var finalArgs; 48 var pathData; 49 50 for (var targetPath in paths) { 51 pathData = paths[targetPath]; 52 53 var matchedParams = self.routeMatch(targetPath, realPath); 54 55 if (matchedParams !== false) { 56 matched = true; 57 finalArgs = extend({}, matchedParams, args); 58 59 break; 60 } 61 } 62 63 if (matched === true) { 64 console.log('Match found', realPath); 65 66 if (typeof (success) === 'function') { 67 success({ 68 $route: pathData, 69 $args: finalArgs, 70 $link: data, 71 }); 72 } 73 74 return; 75 } 76 77 if (typeof (error) === 'function') { 78 console.log('No Match found'); 79 error({ $link: data }); 80 } 81 }) 82 }, 83 84 routeWithNavController: function (navController, paths, options, success, error) { 85 var self = this; 86 87 var defaultOptions = { 88 root: false, 89 }; 90 91 if (typeof options !== 'function') { 92 options = extend(defaultOptions, options); 93 } else { 94 success = options; 95 error = success; 96 options = defaultOptions; 97 } 98 99 this.route(paths, function (match) { 100 // Defer this to ensure animations run 101 setTimeout(function () { 102 if (options.root === true) { 103 navController.setRoot(match.$route, match.$args); 104 } else { 105 navController.push(match.$route, match.$args); 106 } 107 }, self.NAVIGATION_DELAY); 108 109 if (typeof (success) === 'function') { 110 success(match); 111 } 112 }, function (nomatch) { 113 if (typeof (error) === 'function') { 114 error(nomatch); 115 } 116 }); 117 }, 118 119 /** 120 * Check if the path matches the route. 121 */ 122 routeMatch: function (route, path) { 123 if (route === path) { 124 return {}; 125 } 126 127 var parts = path.split('/'); 128 var routeParts = route.split('/'); 129 130 // Our aggregated route params that matched our route path. 131 // This is used for things like /post/:id 132 var routeParams = {}; 133 134 if (parts.length !== routeParts.length) { 135 // Can't possibly match if the lengths are different 136 return false; 137 } 138 139 // Otherwise, we need to check each part 140 141 var rp, 142 pp; 143 144 for (var i = 0; i < parts.length; i++) {
145 pp = parts[i]; 146 rp = routeParts[i]; 147 148 if (rp[0] == ':') { 149 // We have a route param, store it in our 150 // route params without the colon 151 routeParams[rp.slice(1)] = pp; 152 } else if (pp !== rp) { 153 return false; 154 } 155 } 156 return routeParams; 157 }, 158 159 _queryToObject: function (q) { 160 if (!q) return {}; 161 162 var qIndex = q.indexOf('?'); 163 164 if (qIndex > -1) { 165 q = q.slice(qIndex + 1); 166 } 167 168 var i = 0, 169 retObj = {}, 170 pair = null, 171 qArr = q.split('&'); 172 173 for (; i < qArr.length; i++) { 174 if (!qArr[i]) { 175 continue; 176 } 177 178 pair = qArr[i].split('='); 179 retObj[pair[0]] = pair[1]; 180 } 181 182 return retObj; 183 }, 184 185 _stripFragmentLeadingHash: function (fragment) { 186 var hs = fragment.indexOf('#'); 187 188 if (hs > -1) { 189 fragment.slice(0, hs); 190 } 191 192 return fragment; 193 }, 194 195 /** 196 * We're fairly flexible when it comes to matching a URL. We support 197 * host-less custom URL scheme matches like ionic://camera?blah but also support 198 * and match against fragments. 199 * 200 * This method tries to infer what the proper "path" is from the URL 201 */ 202 _getRealPath: function (data) { 203 204 // 1. Let's just do the obvious and return the parsed 'path' first, if available. 205 if (!!data.path && data.path !== "") { 206 return data.path; 207 } 208 209 // 2. Now, are we using a non-standard scheme? 210 var isCustomScheme = data.scheme.indexOf('http') === -1; 211 212 // 3. Nope so we'll go fragment first if available as that should be what comes after 213 if (!isCustomScheme) { 214 if (!!data.fragment) { 215 return this._stripFragmentLeadingHash(data.fragment); 216 } 217 } 218 219 // 4. Now fall back to host / authority 220 if (!!data.host) { 221 if (data.host.charAt(0) != '/') { 222 data.host = '/' + data.host; 223 } 224 225 return data.host; 226 } 227 228 // 5. We'll use fragment next if we're in a custom scheme, though this might need a little more thought 229 if (isCustomScheme && !!data.fragment) { 230 return this._stripFragmentLeadingHash(data.fragment); 231 } 232 233 // 6. Last resort - no obvious path, fragment or host, so we 234 // slice out the scheme and any query string or fragment from the full url. 235 var restOfUrl = data.url; 236 var separator = data.url.indexOf('://'); 237 238 if (separator !== -1) { 239 restOfUrl = data.url.slice(separator + 3); 240 } else { 241 separator = data.url.indexOf(':/'); 242 if (separator !== -1) { 243 restOfUrl = data.url.slice(separator + 2); 244 } 245 } 246 247 var qs = restOfUrl.indexOf('?'); 248 if (qs > -1) { 249 restOfUrl = restOfUrl.slice(0, qs); 250 } 251 252 var hs = restOfUrl.indexOf('#'); 253 if (hs > -1) { 254 restOfUrl = restOfUrl.slice(0, hs); 255 } 256 257 return restOfUrl; 258 }, 259 260 onDeepLink: function (callback) { 261 var innerCB = function (data) { 262 callback(data); 263 }; 264 exec(innerCB, null, PLUGIN_NAME, 'onDeepLink', []); 265 }, 266 267 getHardwareInfo: function (callback) { 268 exec(callback, null, PLUGIN_NAME, 'getHardwareInfo', []); 269 }, 270}; 271 272module.exports = IonicDeeplink; 273 274});
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.