Advertisement
Calculus

Untitled

Aug 25th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.49 KB | None | 0 0
  1. function inject() {
  2.  
  3. var originalOpenWndFnKey = "originalOpenFunction";
  4.  
  5. var originalWindowOpenFn = window.open,
  6. originalCreateElementFn = document.createElement,
  7. originalAppendChildFn = HTMLElement.prototype.appendChild;
  8. originalCreateEventFn = document.createEvent,
  9. windowsWithNames = {};
  10. var timeSinceCreateAElement = 0;
  11. var lastCreatedAElement = null;
  12. var fullScreenOpenTime;
  13. var winWidth = window.innerWidth;
  14. var winHeight = window.innerHeight;
  15. var parentRef = window.parent;
  16. var parentOrigin = (window.location != window.parent.location) ? document.referrer: document.location;
  17.  
  18. Object.defineProperty(window, 'BetterJsPop', {
  19. value: undefined,
  20. writable: false
  21. });
  22.  
  23. window[originalOpenWndFnKey] = window.open; // save the original open window as global param
  24.  
  25. function newWindowOpenFn() {
  26.  
  27. var openWndArguments = arguments,
  28. useOriginalOpenWnd = true,
  29. generatedWindow = null;
  30.  
  31. function blockedWndNotification(openWndArguments) {
  32. parentRef.postMessage({ type: "blockedWindow", args: JSON.stringify(openWndArguments) }, parentOrigin);
  33. }
  34.  
  35. function getWindowName(openWndArguments) {
  36. var windowName = openWndArguments[1];
  37. if ((windowName != null) && (["_blank", "_parent", "_self", "_top"].indexOf(windowName) < 0)) {
  38. return windowName;
  39. }
  40.  
  41. return null;
  42. }
  43.  
  44. function copyMissingProperties(src, dest) {
  45. var prop;
  46. for(prop in src) {
  47. try {
  48. if (dest[prop] === undefined) {
  49. dest[prop] = src[prop];
  50. }
  51. } catch (e) {}
  52. }
  53. return dest;
  54. }
  55.  
  56. function isParentWindow() {
  57. try {
  58. return !!(parent.Window && capturingElement instanceof parent.Window);
  59. } catch (e) {
  60. return false;
  61. }
  62. }
  63.  
  64. function isOverlayish(el) {
  65. var style = el && el.style;
  66.  
  67. if (style && /fixed|absolute/.test(style.position) && el.offsetWidth >= winWidth * 0.6 && el.offsetHeight >= winHeight * 0.75) {
  68. return true;
  69. }
  70.  
  71. return false;
  72. }
  73.  
  74. var capturingElement = null; // the element who registered to the event
  75. var srcElement = null; // the clicked on element
  76. var closestParentLink = null;
  77.  
  78. if (window.event != null) {
  79. capturingElement = window.event.currentTarget;
  80. srcElement = window.event.srcElement;
  81. }
  82.  
  83. if (srcElement != null && srcElement instanceof HTMLElement) {
  84. closestParentLink = srcElement.closest('a');
  85.  
  86. if (closestParentLink && closestParentLink.href) {
  87. openWndArguments[3] = closestParentLink.href;
  88. }
  89. }
  90.  
  91. //callee will not work in ES6 or stict mode
  92. try {
  93. if (capturingElement == null) {
  94. var caller = openWndArguments.callee;
  95. while (caller.arguments != null && caller.arguments.callee.caller != null) {
  96. caller = caller.arguments.callee.caller;
  97. }
  98. if (caller.arguments != null && caller.arguments.length > 0 && caller.arguments[0].currentTarget != null) {
  99. capturingElement = caller.arguments[0].currentTarget;
  100. }
  101. }
  102. } catch (e) {}
  103.  
  104.  
  105.  
  106. /////////////////////////////////////////////////////////////////////////////////
  107. // Blocked if a click on background element occurred (<body> or document)
  108. /////////////////////////////////////////////////////////////////////////////////
  109. if (capturingElement == null) {
  110. window.pbreason = 'Blocked a new window opened without any user interaction';
  111. useOriginalOpenWnd = false;
  112. } else if (capturingElement != null && (capturingElement instanceof Window || isParentWindow(capturingElement) || capturingElement === document || capturingElement.URL != null && capturingElement.body != null || capturingElement.nodeName != null && (capturingElement.nodeName.toLowerCase() == "body" || capturingElement.nodeName.toLowerCase() == "document"))) {
  113. window.pbreason = "Blocked a new window opened with URL: " + openWndArguments[0] + "because it was triggered by the " + capturingElement.nodeName + " element";
  114. useOriginalOpenWnd = false;
  115. } else if (isOverlayish(capturingElement)) {
  116. window.pbreason = 'Blocked a new window opened when clicking on an element that seems to be an overlay';
  117. useOriginalOpenWnd = false;
  118. } else {
  119. useOriginalOpenWnd = true;
  120. }
  121. /////////////////////////////////////////////////////////////////////////////////
  122.  
  123.  
  124.  
  125. /////////////////////////////////////////////////////////////////////////////////
  126. // Block if a full screen was just initiated while opening this url.
  127. /////////////////////////////////////////////////////////////////////////////////
  128. var fullScreenElement = document.webkitFullscreenElement || document.mozFullscreenElement || document.fullscreenElement;
  129. if (new Date().getTime() - fullScreenOpenTime < 1000 || isNaN(fullScreenOpenTime) && isDocumentInFullScreenMode()) {
  130.  
  131. window.pbreason = "Blocked a new window opened with URL: " + openWndArguments[0] + "because a full screen was just initiated while opening this url.";
  132.  
  133. /* JRA REMOVED
  134. if (window[script_params.fullScreenFnKey]) {
  135. window.clearTimeout(window[script_params.fullScreenFnKey]);
  136. }
  137. */
  138.  
  139. if (document.exitFullscreen) {
  140. document.exitFullscreen();
  141. } else if (document.mozCancelFullScreen) {
  142. document.mozCancelFullScreen();
  143. } else if (document.webkitCancelFullScreen) {
  144. document.webkitCancelFullScreen();
  145. }
  146.  
  147. useOriginalOpenWnd = false;
  148. }
  149. /////////////////////////////////////////////////////////////////////////////////
  150.  
  151. if (useOriginalOpenWnd == true) {
  152. generatedWindow = originalWindowOpenFn.apply(this, openWndArguments);
  153. // save the window by name, for latter use.
  154. var windowName = getWindowName(openWndArguments);
  155. if (windowName != null) {
  156. windowsWithNames[windowName] = generatedWindow;
  157. }
  158.  
  159. // 2nd line of defence: allow window to open but monitor carefully...
  160.  
  161. /////////////////////////////////////////////////////////////////////////////////
  162. // Kill window if a blur (remove focus) is called to that window
  163. /////////////////////////////////////////////////////////////////////////////////
  164. if (generatedWindow !== window) {
  165. var openTime = new Date().getTime();
  166. var originalWndBlurFn = generatedWindow.blur;
  167. generatedWindow.blur = () => {
  168. if (new Date().getTime() - openTime < 1000 /* one second */) {
  169. window.pbreason = "Blocked a new window opened with URL: " + openWndArguments[0] + "because a it was blured";
  170. generatedWindow.close();
  171. blockedWndNotification(openWndArguments);
  172. } else {
  173. originalWndBlurFn();
  174. }
  175. };
  176. }
  177. /////////////////////////////////////////////////////////////////////////////////
  178. } else { // (useOriginalOpenWnd == false)
  179.  
  180. var location = {
  181. href: openWndArguments[0]
  182. };
  183. location.replace = function(url) {
  184. location.href = url;
  185. };
  186.  
  187. generatedWindow = {
  188. close: function() {return true;},
  189. test: function() {return true;},
  190. blur: function() {return true;},
  191. focus: function() {return true;},
  192. showModelessDialog: function() {return true;},
  193. showModalDialog: function() {return true;},
  194. prompt: function() {return true;},
  195. confirm: function() {return true;},
  196. alert: function() {return true;},
  197. moveTo: function() {return true;},
  198. moveBy: function() {return true;},
  199. resizeTo: function() {return true;},
  200. resizeBy: function() {return true;},
  201. scrollBy: function() {return true;},
  202. scrollTo: function() {return true;},
  203. getSelection: function() {return true;},
  204. onunload: function() {return true;},
  205. print: function() {return true;},
  206. open: function() {return this;},
  207. opener: window,
  208. closed: false,
  209. innerHeight: 480,
  210. innerWidth: 640,
  211. name: openWndArguments[1],
  212. location: location,
  213. document: {location: location}
  214. };
  215.  
  216. copyMissingProperties(window, generatedWindow);
  217.  
  218. generatedWindow.window = generatedWindow;
  219.  
  220. var windowName = getWindowName(openWndArguments);
  221. if (windowName != null) {
  222. try {
  223. // originalWindowOpenFn("", windowName).close();
  224. windowsWithNames[windowName].close();
  225. } catch (err) {
  226. }
  227. }
  228.  
  229. var fnGetUrl = function () {
  230. var url;
  231. if (!(generatedWindow.location instanceof Object)) {
  232. url = generatedWindow.location;
  233. } else if (!(generatedWindow.document.location instanceof Object)) {
  234. url = generatedWindow.document.location;
  235. } else if (location.href != null) {
  236. url = location.href;
  237. } else {
  238. url = openWndArguments[0];
  239. }
  240. openWndArguments[0] = url;
  241.  
  242. blockedWndNotification(openWndArguments);
  243. };
  244.  
  245. if (top == self) {
  246. setTimeout(fnGetUrl, 100);
  247. } else {
  248. fnGetUrl();
  249. }
  250. }
  251.  
  252. return generatedWindow;
  253. }
  254.  
  255.  
  256. /////////////////////////////////////////////////////////////////////////////////
  257. // Replace the window open method with Poper Blocker's
  258. /////////////////////////////////////////////////////////////////////////////////
  259. window.open = function() {
  260. try {
  261. return newWindowOpenFn.apply(this, arguments);
  262. } catch(err) {
  263. return null;
  264. }
  265. };
  266. /////////////////////////////////////////////////////////////////////////////////
  267.  
  268.  
  269.  
  270. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  271. // Monitor dynamic html element creation to prevent generating <a> elements with click dispatching event
  272. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  273. HTMLElement.prototype.appendChild = function () {
  274. var newElement = originalAppendChildFn.apply(this, arguments);
  275.  
  276. if (newElement.nodeName == 'IFRAME' && newElement.contentWindow) {
  277. try {
  278. var code = "(function () {"+ inject.toString() + "inject()})();";
  279.  
  280. var s = document.createElement('script');
  281. s.textContent = code;
  282. var doc = newElement.contentWindow.document;
  283.  
  284. (doc.head || doc.body).appendChild(s);
  285. } catch (e) {
  286.  
  287. }
  288. }
  289.  
  290. return newElement;
  291. };
  292.  
  293. document.createElement = function (tagName) {
  294. var newElement = originalCreateElementFn.apply(document, arguments);
  295.  
  296. if (tagName.toLowerCase() == 'a') {
  297.  
  298. timeSinceCreateAElement = new Date().getTime();
  299.  
  300. var originalDispatchEventFn = newElement.dispatchEvent;
  301.  
  302. newElement.dispatchEvent = function (event) {
  303. if (event.type != null && (("" + event.type).toLocaleLowerCase() == "click")) {
  304.  
  305. window.pbreason = "blocked due to an explicit dispatchEvent event with type 'click' on an 'a' tag";
  306. parentRef.postMessage({type:"blockedWindow", args: JSON.stringify({"0": newElement.href}) }, parentOrigin);
  307. return true;
  308.  
  309. }
  310.  
  311. return originalDispatchEventFn(event);
  312. };
  313.  
  314. lastCreatedAElement = newElement;
  315. }
  316.  
  317. return newElement;
  318. };
  319. /////////////////////////////////////////////////////////////////////////////////
  320.  
  321.  
  322.  
  323.  
  324. /////////////////////////////////////////////////////////////////////////////////
  325. // Block artificial mouse click on frashly created <a> elements
  326. /////////////////////////////////////////////////////////////////////////////////
  327. document.createEvent = function () {
  328. try {
  329. if (arguments[0].toLowerCase().includes("mouse") && new Date().getTime() - timeSinceCreateAElement <= 50) {
  330. var openUrlDomain, topUrl, topDomain;
  331.  
  332. try {
  333. openUrlDomain = new URL(lastCreatedAElement.href).hostname;
  334. } catch (e) {}
  335.  
  336. try {
  337. topUrl = window.location != window.parent.location ? document.referrer : document.location.href;
  338. } catch (e) {}
  339.  
  340. try {
  341. topDomain = new URL(topUrl).hostname;
  342. } catch (e) {}
  343.  
  344. //block if the origin is not same
  345. var isSelfDomain = openUrlDomain == topDomain;
  346.  
  347. if (lastCreatedAElement.href.trim() && !isSelfDomain) {
  348. //this makes too much false positive so we do not display the toast message
  349. window.pbreason = "Blocked because 'a' element was recently created and " + arguments[0] + "event was created shortly after";
  350. arguments[0] = lastCreatedAElement.href;
  351.  
  352. parentRef.postMessage({ type: "blockedWindow", args: JSON.stringify({"0": lastCreatedAElement.href}) }, parentOrigin);
  353.  
  354. return {
  355. type: 'click',
  356. initMouseEvent: function () {}
  357. };
  358. }
  359. }
  360.  
  361. return originalCreateEventFn.apply(document, arguments);
  362. } catch (err) {}
  363. };
  364. /////////////////////////////////////////////////////////////////////////////////
  365.  
  366.  
  367.  
  368.  
  369.  
  370. /////////////////////////////////////////////////////////////////////////////////
  371. // Monitor full screen requests
  372. /////////////////////////////////////////////////////////////////////////////////
  373. function onFullScreen(isInFullScreenMode) {
  374. if (isInFullScreenMode) {
  375. fullScreenOpenTime = (new Date()).getTime();
  376. // console.info("fullScreenOpenTime = " + fullScreenOpenTime);
  377. } else {
  378. fullScreenOpenTime = NaN;
  379. }
  380. };
  381. /////////////////////////////////////////////////////////////////////////////////
  382.  
  383. function isDocumentInFullScreenMode() {
  384. // Note that the browser fullscreen (triggered by short keys) might
  385. // be considered different from content fullscreen when expecting a boolean
  386. return ((document.fullScreenElement && document.fullScreenElement !== null) || // alternative standard methods
  387. ((document.mozFullscreenElement != null) || (document.webkitFullscreenElement != null))); // current working methods
  388. }
  389.  
  390.  
  391. document.addEventListener("fullscreenchange", function () {
  392. onFullScreen(document.fullscreen);
  393. }, false);
  394.  
  395. document.addEventListener("mozfullscreenchange", function () {
  396. onFullScreen(document.mozFullScreen);
  397. }, false);
  398.  
  399. document.addEventListener("webkitfullscreenchange", function () {
  400. onFullScreen(document.webkitIsFullScreen);
  401. }, false);
  402.  
  403.  
  404. } inject()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement