Created
August 4, 2017 15:33
-
-
Save korc/eb78250797bbb9391805fbbd2cefcff8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Control Remote Web</title> | |
| <script> | |
| "use strict"; | |
| var targets = []; | |
| var messageQueue = {}; | |
| function Target(url) { | |
| this.url = url; | |
| } | |
| Target.prototype.open = function (url) { | |
| if (url) this.url = url; | |
| else url = this.url; | |
| console.log("opening", url); | |
| this.window = window.open(url); | |
| function keepPinging() { | |
| console.log("Pinging", url); | |
| this.sendReceiveMessage({ cmd: "PING", value: "Hi there!" }, function (msg) { | |
| console.log("Ping answered: " + msg.value, url); | |
| }, keepPinging, 3000); | |
| } | |
| keepPinging.call(this); | |
| return this; | |
| } | |
| Target.prototype.eval = function (code, cb, errorCallback) { | |
| if (typeof (code) === "function") { | |
| var args = Array.prototype.splice.call(arguments, 3); | |
| code = "(" + code.toString() + ").apply(this, JSON.parse('" + JSON.stringify(args).replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'))"; | |
| } | |
| return this.sendReceiveMessage({ cmd: "EVAL", value: code }, function (data) { | |
| if (data.cmd === "RETURN") { | |
| if (cb) cb.call(this, data.value); | |
| } else if (data.cmd === "ERROR") | |
| if (errorCallback) errorCallback.call(this, data.value); | |
| }) | |
| } | |
| Target.prototype.queryAttributeOf = function (selector, attribute, cb) { | |
| this.eval(function (sel, attr) { | |
| var elems = document.querySelectorAll(sel); | |
| var ret = []; | |
| for (var i = 0; i < elems.length; i++) { | |
| var val = elems[i][attr]; | |
| if(typeof(val)==="object" && ("length" in val)) | |
| val = Array.prototype.slice.call(val, 0); | |
| ret.push(val); | |
| } | |
| return ret; | |
| }, cb, null, selector, attribute); | |
| } | |
| Target.prototype.sendReceiveMessage = function (message, successCallback, failCallback, failTimeout) { | |
| if (this.window.closed) throw ("Error: target window closed"); | |
| if (failCallback && !failTimeout) failTimeout = 300; | |
| var messageId = message._id = (new Date()).getTime(); | |
| var queueObject = messageQueue[message._id] = { | |
| target: this, | |
| successCallback: successCallback, | |
| failCallback: failCallback, | |
| message: message | |
| } | |
| if (failTimeout) | |
| queueObject.failTimer = window.setTimeout(function () { | |
| delete messageQueue[messageId]; | |
| if (failCallback) failCallback.call(queueObject.target); | |
| }, failTimeout); | |
| this.window.postMessage(message, "*"); | |
| return this; | |
| } | |
| window.addEventListener("message", function (ev) { | |
| var replyTo = messageQueue[ev.data._id]; | |
| console.log("Received message from:", ev.origin, "data:", ev.data, "reply to:", replyTo); | |
| if (!replyTo) return; | |
| delete messageQueue[ev.data._id]; | |
| if (replyTo.failTimer) window.clearTimeout(replyTo.failTimer); | |
| if (replyTo.successCallback) replyTo.successCallback.call(replyTo.target, ev.data); | |
| }, false); | |
| window.addEventListener('load', function () { | |
| var bmlet = document.getElementById('allow-bmlet') | |
| bmlet.href = "javascript:(" + escape((function (allowOrigin) { | |
| window.addEventListener("message", function (ev) { | |
| if (ev.origin !== allowOrigin) return; | |
| switch (ev.data.cmd) { | |
| case "PING": | |
| ev.source.postMessage({ cmd: "PONG", _id: ev.data._id, value: ev.data.value }, allowOrigin) | |
| break; | |
| case "EVAL": | |
| try { ev.source.postMessage({ cmd: 'RETURN', _id: ev.data._id, value: eval(ev.data.value) }, allowOrigin); } | |
| catch (e) { ev.source.postMessage({ cmd: 'ERROR', _id: ev.data._id, value: e.toString() }, allowOrigin); } | |
| break; | |
| default: | |
| console.log("Bad message: ", ev) | |
| } | |
| }, false); | |
| }).toString()) + ")('" + escape(document.origin) + "')" | |
| bmlet.innerText = "CTRL|" + document.origin; | |
| }, false); | |
| </script> | |
| </head> | |
| <body> | |
| <ol> | |
| <li>Show your bookmark bar with CTRL+SHIFT+B</li> | |
| <li>Drag <a id='allow-bmlet' href="#">*INCOMPLETE*</a> bookmarklet to your bookmarks</li> | |
| <li>Write target URL here: <input size="80" onfocus="this.select()" id="target-url" value="https://google.com/search?q=test"></li> | |
| <li>Click on <button onclick="targets.push((new Target(document.getElementById('target-url').value)).open())">open</button> button</li> | |
| <li>Click on "CTRL|*" bookmark when page has loaded</li> | |
| </ol> | |
| Current scrape targets: | |
| <ul id="targets"> | |
| </ul> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment