PageSourceSearch

https://livesexprofiler.com/inapp-escape.js

js livesexprofiler.com collected 2026-10-06 13:03:08 UTC 5,067 bytes, 161 lines download raw bytes

1(function (root, factory) {
2  if (typeof module === 'object' && module.exports) module.exports = factory();
3  else root.InAppEscape = factory();
4})(typeof self !== 'undefined' ? self : this, function () {
5  'use strict';
6
7  // Webview signatures. FBAN/FBAV = Facebook iOS/Android, GSA = Google
8  // Search app (Google app / Discover feed in-app browser), "wv" = Android
9  // WebView.
10  var IN_APP = /(Instagram|FBAN|FBAV|FB_IAB|Messenger|Line|Snapchat|TikTok|musical_ly|Pinterest|WeChat|MicroMessenger|LinkedInApp|Twitter|GSA|GoogleSearch|InApp|WebView|; wv)/i;
11  var INSTAGRAM = /instagram/i;
12  var IOS = /(iPhone|iPod|iPad)/i;
13  var ANDROID = /Android/i;
14
15  var STORAGE_KEY = 'inapp-escape:attempted';
16
17  function ua() {
18    return (navigator && navigator.userAgent) || '';
19  }
20
21  function isInApp() {
22    return IN_APP.test(ua());
23  }
24
25  function isIOS() {
26    // iPadOS 13+ reports a desktop UA, so fall back to the touch-point check.
27    return IOS.test(ua()) ||
28      (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
29  }
30
31  function isAndroid() {
32    return ANDROID.test(ua());
33  }
34
35  function isInstagram() {
36    return INSTAGRAM.test(ua());
37  }
38
39  /**
40   * Build the platform-specific URL that asks the OS to hand off to the
41   * native browser. Returns null when there is no known handoff for this
42   * platform (desktop, or an OS we have no scheme for).
43   *
44   * None of these are documented, supported APIs — they are observed app
45   * behaviour and can stop working after any OS or app update. Always keep a
46   * fallback path for users
47   */
48  function nativeUrlFor(target) {
49    var bare = target.replace(/^https?:\/\//, '');
50
51    if (isIOS()) {
52      // Instagram's app-specific handoff. Everything else gets Safari's
53      // private scheme, which more in-app browsers honour than you'd expect.
54      return isInstagram()
55        ? 'instagram://extbrowser/?url=' + encodeURIComponent(target)
56        : 'x-safari-https://' + bare;
57    }
58
59    if (isAndroid()) {
60      // Documented Android mechanism: hand the URL to the default browser.
61      return 'intent://' + bare + '#Intent;scheme=https;end';
62    }
63
64    return null;
65  }
66
67  function sameAsCurrentPage(target) {
68    try {
69      return new URL(target, location.href).href === location.href;
70    } catch (e) {
71      return target === location.href;
72    }
73  }
74
75  // sessionStorage throws in some webviews (private mode, blocked storage),
76  // so every access is guarded and failure degrades to "not yet attempted".
77  function alreadyAttempted() {
78    try {
79      return sessionStorage.getItem(STORAGE_KEY) === '1';
80    } catch (e) {
81      return false;
82    }
83  }
84
85  function markAttempted() {
86    try {
87      sessionStorage.setItem(STORAGE_KEY, '1');
88    } catch (e) {}
89  }
90
91  /**
92   * Attempt the escape.
93   *
94   * @param {Object}  [opts]
95   * @param {string}  [opts.url]      Where to send them. Default: current URL.
96   * @param {boolean} [opts.fallback] If the handoff fails, navigate to url
97   *                                  anyway inside the webview. Ignored when
98   *                                  url is the current page (that would just
99   *                                  reload and re-trigger). Default true.
100   * @param {number}  [opts.timeout]  ms to wait before deciding it failed.
101   * @param {boolean} [opts.once]     Only ever attempt once per tab. Default true.
102   * @returns {boolean} whether a handoff was attempted.
103   */
104  function escape(opts) {
105    opts = opts || {};
106
107    var target = opts.url || location.href;
108    var useFallback = opts.fallback !== false;
109    var timeout = typeof opts.timeout === 'number' ? opts.timeout : 500;
110    var once = opts.once !== false;
111
112    if (!isInApp()) return false;
113    if (once && alreadyAttempted()) return false;
114
115    var nativeUrl = nativeUrlFor(target);
116    if (!nativeUrl) return false;
117
118    if (once) markAttempted();
119
120    // Redirecting to the page we're already on would reload the webview and
121    // run this script again — so only ever fall back to a *different* URL.
122    if (useFallback) {
123      var timer = setTimeout(function () {
124        location.href = target;
125      }, timeout);
126
127      // If the native browser really opened, this tab gets backgrounded.
128      // That's our signal the handoff worked, so cancel the fallback.
129      var cancel = function () {
130        clearTimeout(timer);
131      };
132      document.addEventListener('visibilitychange', function () {
133        if (document.hidden) cancel();
134      });
135      window.addEventListener('pagehide', cancel);
136      window.addEventListener('blur', cancel);
137    }
138
139    location.href = nativeUrl;
140    return true;
141  }
142
143  var api = {
144    escape: escape,
145    isInApp: isInApp,
146    isIOS: isIOS,
147    isAndroid: isAndroid,
148    isInstagram: isInstagram,
149    nativeUrlFor: nativeUrlFor,
150  };
151
152  // Auto-run unless the tag opts out with data-auto="false".
153  if (typeof document !== 'undefined') {
154    var self = document.currentScript;
155    if (!self || self.getAttribute('data-auto') !== 'false') {
156      escape();
157    }
158  }
159
160  return api;
161});

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.