-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbookmarklet.js
More file actions
111 lines (105 loc) · 5.33 KB
/
Copy pathbookmarklet.js
File metadata and controls
111 lines (105 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
javascript:(function(){
window.logs = [];
var btn = document.createElement('div');
btn.style = "position:fixed;top:0;left:0;width:30px;height:30px;background:#ddd;z-index:999999;opacity:0.2;cursor:pointer;border-radius:0 0 5px 0;";
document.body.appendChild(btn);
var overlay = document.createElement('div');
overlay.style = "display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(255,255,255,0.1);z-index:999997;";
document.body.appendChild(overlay);
var container = document.createElement('div');
container.style = "display:none;position:fixed;top:10%;left:5%;width:90%;height:50%;z-index:999998;background:#fff;border:1px solid #004b9b;border-radius:8px;box-shadow:0 4px 15px rgba(0,0,0,0.1);overflow:hidden;flex-direction:column;";
document.body.appendChild(container);
var display = document.createElement('textarea');
display.style = "width:100%;height:100%;background:#fff;color:#333;font-size:10px;font-family:monospace;padding:15px;border:none;outline:none;resize:none;white-space:pre;";
container.appendChild(display);
var scrollBtn = document.createElement('div');
scrollBtn.style = "position:absolute;bottom:10px;right:10px;width:30px;height:30px;background:#004b9b;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:18px;cursor:pointer;opacity:0.8;";
scrollBtn.innerText = "↓";
container.appendChild(scrollBtn);
var toast = document.createElement('div');
toast.style = "display:none;position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:rgba(0,75,155,0.7);color:#fff;padding:5px 15px;border-radius:20px;font-size:10px;z-index:1000000;font-family:sans-serif;";
document.body.appendChild(toast);
function showToast(m) { toast.innerText = m; toast.style.display = 'block'; setTimeout(() => { toast.style.display = 'none'; }, 1000); }
function formatLog(entry) {
return `=== [${entry.type}] ${entry.method} ${entry.url} ===\n` +
`TIME: ${new Date().toLocaleTimeString()}\n` +
`-- REQUEST --\n` +
`Headers: ${JSON.stringify(entry.reqHeaders, null, 2)}\n` +
`Cookies: ${document.cookie || 'None'}\n` +
`Body: ${entry.reqBody || 'Empty'}\n` +
`-- RESPONSE --\n` +
`Status: ${entry.status}\n` +
`Headers: ${JSON.stringify(entry.resHeaders, null, 2)}\n` +
`Data: ${entry.resBody}\n\n` +
"-".repeat(50) + "\n\n";
}
scrollBtn.onclick = (e) => { e.stopPropagation(); display.scrollTop = display.scrollHeight; };
overlay.onclick = () => { overlay.style.display = 'none'; container.style.display = 'none'; };
var clickCount = 0, clickTimer = null;
btn.onclick = (e) => {
e.stopPropagation(); clickCount++;
if (clickTimer) clearTimeout(clickTimer);
clickTimer = setTimeout(() => {
var content = window.logs.map(formatLog).join('');
if (clickCount === 1) {
var blob = new Blob([content], {type: "text/plain"});
var a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "export.txt"; a.click();
showToast("Exported to export.txt");
} else if (clickCount === 2) {
display.value = content;
container.style.display = container.style.display === 'flex' ? 'none' : 'flex';
overlay.style.display = container.style.display === 'flex' ? 'block' : 'none';
} else if (clickCount === 3) {
var t = document.createElement('textarea'); document.body.appendChild(t); t.value = content; t.select(); document.execCommand('copy'); document.body.removeChild(t);
showToast("Copied in clipboard");
}
clickCount = 0; clickTimer = null;
}, 400);
};
const origFetch = window.fetch;
window.fetch = async (...args) => {
const reqUrl = args[0];
const reqOptions = args[1] || {};
const res = await origFetch(...args);
const clone = res.clone();
let resHeaders = {};
clone.headers.forEach((v, k) => { resHeaders[k] = v; });
clone.text().then(t => {
window.logs.push({
type: 'FETCH',
method: reqOptions.method || 'GET',
url: reqUrl,
reqHeaders: reqOptions.headers || {},
reqBody: reqOptions.body || null,
status: res.status,
resHeaders: resHeaders,
resBody: t
});
});
return res;
};
(function(open, send, setHeader) {
window.XMLHttpRequest.prototype.open = function(method, url) {
this.data = { type: 'XHR', method: method, url: url, reqHeaders: {}, resHeaders: {} };
open.apply(this, arguments);
};
window.XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
this.data.reqHeaders[header] = value;
setHeader.apply(this, arguments);
};
window.XMLHttpRequest.prototype.send = function(body) {
this.data.reqBody = body;
this.addEventListener("load", function() {
this.data.status = this.status;
let hString = this.getAllResponseHeaders();
hString.split('\r\n').forEach(line => {
let parts = line.split(': ');
if(parts[0]) this.data.resHeaders[parts[0]] = parts[1];
});
this.data.resBody = this.responseText;
window.logs.push(this.data);
});
send.apply(this, arguments);
};
})(window.XMLHttpRequest.prototype.open, window.XMLHttpRequest.prototype.send, window.XMLHttpRequest.prototype.setRequestHeader);
})();