Skip to content

Instantly share code, notes, and snippets.

@korc
Created August 4, 2017 15:33
Show Gist options
  • Select an option

  • Save korc/eb78250797bbb9391805fbbd2cefcff8 to your computer and use it in GitHub Desktop.

Select an option

Save korc/eb78250797bbb9391805fbbd2cefcff8 to your computer and use it in GitHub Desktop.
<!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