function Console() {}
|
|
|
|
Console.Type = {
|
|
LOG: "log",
|
|
DEBUG: "debug",
|
|
INFO: "info",
|
|
WARN: "warn",
|
|
ERROR: "error",
|
|
GROUP: "group",
|
|
GROUP_COLLAPSED: "groupCollapsed",
|
|
GROUP_END: "groupEnd"
|
|
};
|
|
|
|
Console.addMessage = function (type, format, args) {
|
|
chrome.runtime.sendMessage({
|
|
command: "sendToConsole",
|
|
tabId: chrome.devtools.inspectedWindow.tabId,
|
|
args: escape(JSON.stringify(Array.prototype.slice.call(arguments, 0)))
|
|
});
|
|
};
|
|
|
|
// Generate Console output methods, i.e. Console.log(), Console.debug() etc.
|
|
(function () {
|
|
var console_types = Object.getOwnPropertyNames(Console.Type);
|
|
for (var type = 0; type < console_types.length; ++type) {
|
|
var method_name = Console.Type[console_types[type]];
|
|
Console[method_name] = Console.addMessage.bind(Console, method_name);
|
|
}
|
|
})();
|
|
|
|
BNPChrome.controller("PanelController", function PanelController($scope, toolbar, parse, $timeout) {
|
|
|
|
const LOCALSTORAGE = window.localStorage;
|
|
const MAXBODYSIZE = 20000;
|
|
const HOST = "https://leviolson.com" // "http://localhost:3000"
|
|
const CHANGELOG = {
|
|
"What's New": {
|
|
"v1.0.0:": {
|
|
"Improved Search": HOST + "/posts/bnp-changelog#improved-search",
|
|
"JSON Editor BUILT IN": HOST + "/posts/bnp-changelog#json-editor-built-in",
|
|
"Vertical Chrome Panel": HOST + "/posts/bnp-changelog#vertical-chrome-panel",
|
|
"Download JSON": HOST + "/posts/bnp-changelog#download-json"
|
|
}
|
|
}
|
|
}
|
|
|
|
$scope.search = "";
|
|
$scope.searchTerms = [];
|
|
$scope.oldSearchTerms = [];
|
|
$scope.andFilter = true;
|
|
$scope.uniqueId = 100000;
|
|
$scope.activeId = null;
|
|
$scope.requests = {};
|
|
$scope.masterRequests = [];
|
|
$scope.filteredRequests = [];
|
|
$scope.showAll = true;
|
|
$scope.limitNetworkRequests = false;
|
|
$scope.showOriginal = false;
|
|
$scope.currentDetailTab = "tab-response";
|
|
$scope.showIncomingRequests = true;
|
|
$scope.myResponseCodeMirror = null;
|
|
$scope.filter = "";
|
|
$scope.editor = null;
|
|
|
|
$scope.activeCookies = [];
|
|
$scope.activeHeaders = [];
|
|
$scope.activePostData = [];
|
|
$scope.activeRequest = [];
|
|
$scope.activeResponseData = [];
|
|
$scope.activeResponseCookies = [];
|
|
$scope.activeResponseHeaders = [];
|
|
$scope.activeCode = null;
|
|
|
|
$scope.init = function (type) {
|
|
$("#tabs").tabs();
|
|
|
|
$scope.initChrome();
|
|
|
|
$scope.createToolbar();
|
|
|
|
const options = {
|
|
mode: 'view',
|
|
modes: ['code', 'view'],
|
|
onEditable: function (node) {
|
|
if (!node.path) {
|
|
// In modes code and text, node is empty: no path, field, or value
|
|
// returning false makes the text area read-only
|
|
return false;
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
const response = document.getElementById('response-jsoneditor')
|
|
const request = document.getElementById('request-jsoneditor')
|
|
$scope.responseJsonEditor = new JSONEditor(response, options)
|
|
$scope.requestJsonEditor = new JSONEditor(request, options)
|
|
|
|
$timeout(() => {
|
|
$scope.responseJsonEditor.set(CHANGELOG);
|
|
$scope.responseJsonEditor.expandAll();
|
|
})
|
|
};
|
|
|
|
$scope.initChrome = function () {
|
|
try {
|
|
let oldSearchTerms = JSON.parse(LOCALSTORAGE.getItem('bnp-oldsearchterms'));
|
|
$scope.oldSearchTerms = oldSearchTerms || [];
|
|
} catch (e) {
|
|
$scope.oldSearchTerms = [];
|
|
}
|
|
|
|
try {
|
|
let searchTerms = JSON.parse(LOCALSTORAGE.getItem('bnp-searchterms'));
|
|
$scope.searchTerms = searchTerms || [];
|
|
} catch (e) {
|
|
$scope.searchTerms = [];
|
|
}
|
|
|
|
try {
|
|
let andFilter = JSON.parse(LOCALSTORAGE.getItem('bnp-andfilter'));
|
|
$scope.andFilter = andFilter || false;
|
|
} catch (e) {
|
|
$scope.andFilter = false;
|
|
}
|
|
|
|
console.debug('Retrieving', $scope.andFilter, $scope.searchTerms, $scope.oldSearchTerms);
|
|
|
|
chrome.devtools.network.onRequestFinished.addListener(function (request) {
|
|
// do not show requests to chrome extension resources
|
|
if (request.request.url.startsWith("chrome-extension://")) {
|
|
return;
|
|
}
|
|
$scope.handleRequest(request);
|
|
});
|
|
|
|
chrome.devtools.network.onNavigated.addListener(function (event) {
|
|
console.log("Event", event);
|
|
$scope.masterRequests.push({
|
|
id: $scope.uniqueId,
|
|
separator: true,
|
|
event: event
|
|
});
|
|
$scope.uniqueId++;
|
|
$scope.cleanRequests();
|
|
});
|
|
};
|
|
|
|
$scope.filterRequests = function () {
|
|
if (!$scope.searchTerms || $scope.searchTerms.length === 0) {
|
|
$scope.filteredRequests = $scope.masterRequests;
|
|
return;
|
|
}
|
|
// console.log("Filtering for: ", $scope.searchTerms);
|
|
|
|
let negTerms = [];
|
|
let posTerms = [];
|
|
for (let term of $scope.searchTerms) {
|
|
term = term.toLowerCase();
|
|
if (term && term[0] === '-') negTerms.push(term.substring(1));
|
|
else posTerms.push(term);
|
|
}
|
|
|
|
$scope.filteredRequests = $scope.masterRequests.filter(function (x) {
|
|
if (x.separator) return true;
|
|
for (let term of negTerms) {
|
|
// if neg
|
|
if (x && x.searchIndex && x.searchIndex.includes(term)) return false;
|
|
}
|
|
|
|
if ($scope.andFilter) {
|
|
// AND condition
|
|
for (let term of posTerms) {
|
|
// if pos
|
|
if (x && x.searchIndex && !x.searchIndex.includes(term)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
// OR condition
|
|
for (let term of posTerms) {
|
|
// if pos
|
|
if (x && x.searchIndex && x.searchIndex.includes(term)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
};
|
|
|
|
$scope.toggleSearchType = function() {
|
|
$scope.andFilter = !$scope.andFilter;
|
|
_setLocalStorage();
|
|
$scope.filterRequests();
|
|
};
|
|
|
|
$scope.customSearch = function() {
|
|
if (!$scope.searchTerms.includes($scope.search)) {
|
|
$scope.searchTerms.push($scope.search);
|
|
$scope.search = "";
|
|
_setLocalStorage();
|
|
$scope.filterRequests()
|
|
}
|
|
};
|
|
|
|
_setLocalStorage = function() {
|
|
// do some sort of comparison to searchTerms and oldSearchTerms to make sure there is only one.
|
|
// although, now that I think about it... this comparison shouldn't be necessary... /shrug
|
|
LOCALSTORAGE.setItem('bnp-andfilter', JSON.stringify($scope.andFilter));
|
|
LOCALSTORAGE.setItem('bnp-searchterms', JSON.stringify($scope.searchTerms));
|
|
LOCALSTORAGE.setItem('bnp-oldsearchterms', JSON.stringify($scope.oldSearchTerms));
|
|
console.debug('Saving', $scope.andFilter, $scope.searchTerms, $scope.oldSearchTerms);
|
|
}
|
|
|
|
$scope.addSearchTerm = function(index) {
|
|
$scope.searchTerms.push($scope.oldSearchTerms.splice(index, 1)[0]);
|
|
_setLocalStorage();
|
|
$scope.filterRequests();
|
|
};
|
|
|
|
$scope.removeSearchTerm = function(index) {
|
|
$scope.oldSearchTerms.push($scope.searchTerms.splice(index, 1)[0]);
|
|
_setLocalStorage();
|
|
$scope.filterRequests();
|
|
};
|
|
|
|
$scope.deleteSearchTerm = function(index) {
|
|
$scope.oldSearchTerms.splice(index, 1);
|
|
_setLocalStorage();
|
|
};
|
|
|
|
$scope.handleRequest = function (har_entry) {
|
|
$scope.addRequest(har_entry, har_entry.request.method, har_entry.request.url, har_entry.response.status, null);
|
|
};
|
|
|
|
$scope.createToolbar = function () {
|
|
toolbar.createToggleButton(
|
|
"embed",
|
|
"JSON Parsing",
|
|
false,
|
|
function () {
|
|
// ga('send', 'event', 'button', 'click', 'Toggle JSON Parsing');
|
|
$scope.$apply(function () {
|
|
$scope.showOriginal = !$scope.showOriginal;
|
|
$scope.selectDetailTab($scope.currentDetailTab);
|
|
// $scope.displayCode();
|
|
});
|
|
},
|
|
true
|
|
);
|
|
toolbar.createButton("download3", "Download", false, function () {
|
|
// ga('send', 'event', 'button', 'click', 'Download');
|
|
$scope.$apply(function () {
|
|
const panel = $scope.currentDetailTab;
|
|
if (panel === "tab-response") {
|
|
var blob = new Blob([JSON.parse(JSON.stringify($scope.activeCode, null, 4))], { type: "application/json;charset=utf-8" });
|
|
saveAs(blob, "export_response.json");
|
|
} else {
|
|
try {
|
|
var blob = new Blob([JSON.stringify($scope.activePostData)], { type: "application/json;charset=utf-8" });
|
|
saveAs(blob, "export_request.json");
|
|
} catch (e) {
|
|
console.log(e)
|
|
}
|
|
|
|
}
|
|
});
|
|
});
|
|
toolbar.createButton("blocked", "Clear", false, function () {
|
|
// ga('send', 'event', 'button', 'click', 'Clear');
|
|
$scope.$apply(function () {
|
|
$scope.clear();
|
|
});
|
|
});
|
|
|
|
$(".toolbar").replaceWith(toolbar.render());
|
|
};
|
|
|
|
$scope.addRequest = function (data, request_method, request_url, response_status) {
|
|
$scope.$apply(function () {
|
|
const requestId = data.id || $scope.uniqueId;
|
|
$scope.uniqueId++
|
|
|
|
if (data.request != null) {
|
|
data["request_data"] = $scope.createKeypairs(data.request);
|
|
if (data.request.cookies != null) {
|
|
data.cookies = $scope.createKeypairsDeep(data.request.cookies);
|
|
}
|
|
if (data.request.headers != null) {
|
|
data.headers = $scope.createKeypairsDeep(data.request.headers);
|
|
}
|
|
if (data.request.postData != null) {
|
|
data.postData = $scope.createKeypairs(data.request.postData);
|
|
}
|
|
}
|
|
if (data.response != null) {
|
|
data["response_data"] = $scope.createKeypairs(data.response);
|
|
data.response_data.response_body = "Loading " + requestId;
|
|
if (data.response.cookies != null) {
|
|
data["response_cookies"] = $scope.createKeypairsDeep(data.response.cookies);
|
|
}
|
|
if (data.response.headers != null) {
|
|
data["response_headers"] = $scope.createKeypairsDeep(data.response.headers);
|
|
}
|
|
}
|
|
|
|
data["request_method"] = request_method;
|
|
if (request_url.includes("apexremote")) {
|
|
try {
|
|
let text = data && data.request && data.request.postData && data.request.postData.text ? JSON.parse(data.request.postData.text) : "";
|
|
data["request_apex_type"] = text.data && typeof text.data[1] === "string" ? text.data[1] : JSON.stringify(text.data);
|
|
data["request_apex_method"] = text.method || "";
|
|
} catch (e) {
|
|
console.debug("Error", e);
|
|
}
|
|
}
|
|
data.request_url = request_url;
|
|
data.response_status = response_status;
|
|
data['id'] = requestId;
|
|
let ctObj = data.response_headers.find(x => x.name == "Content-Type")
|
|
data.content_type = ctObj && ctObj.value || null;
|
|
|
|
$scope.requests[requestId] = data; // master
|
|
data.searchIndex = JSON.stringify(data.request).toLowerCase();
|
|
$scope.masterRequests.push(data);
|
|
|
|
data.getContent(function (content, encoding) {
|
|
$scope.requests[requestId].response_data.response_body = content;
|
|
});
|
|
|
|
$scope.cleanRequests();
|
|
});
|
|
};
|
|
|
|
$scope.cleanRequests = function () {
|
|
if ($scope.limitNetworkRequests === true) {
|
|
if ($scope.masterRequests.length >= 500) $scope.masterRequests.shift();
|
|
const keys = Object.keys($scope.requests).reverse().slice(500);
|
|
keys.forEach(function (key) {
|
|
if ($scope.requests[key]) {
|
|
delete $scope.requests[key];
|
|
}
|
|
});
|
|
}
|
|
$scope.filterRequests();
|
|
};
|
|
|
|
$scope.clear = function () {
|
|
$scope.requests = {};
|
|
$scope.activeId = null;
|
|
$scope.masterRequests = [];
|
|
$scope.filteredRequests = [];
|
|
|
|
$scope.activeCookies = [];
|
|
$scope.activeHeaders = [];
|
|
$scope.activePostData = [];
|
|
$scope.activeRequest = [];
|
|
$scope.activeResponseData = [];
|
|
$scope.activeResponseDataPreview = "";
|
|
$scope.activeResponseCookies = [];
|
|
$scope.activeResponseHeaders = [];
|
|
$scope.activeCode = null;
|
|
|
|
$scope.showIncomingRequests = true;
|
|
};
|
|
|
|
$scope.setActive = function (requestId) {
|
|
if (!$scope.requests[requestId]) {
|
|
return;
|
|
}
|
|
$scope.activeId = requestId;
|
|
|
|
$scope.activeCookies = $scope.requests[requestId].cookies;
|
|
$scope.activeHeaders = $scope.requests[requestId].headers;
|
|
$scope.activePostData = $scope.requests[requestId].postData;
|
|
$scope.activeRequest = $scope.requests[requestId].request_data;
|
|
$scope.activeResponseData = $scope.requests[requestId].response_data;
|
|
$scope.activeResponseDataPreview = $scope.requests[requestId].response_data.response_body;
|
|
$scope.activeResponseCookies = $scope.requests[requestId].response_cookies;
|
|
$scope.activeResponseHeaders = $scope.requests[requestId].response_headers;
|
|
$scope.activeCode = $scope.requests[requestId].response_data.response_body;
|
|
};
|
|
|
|
$scope.getClass = function (requestId, separator) {
|
|
if (separator) return "separator"
|
|
if (requestId === $scope.activeId) {
|
|
return "selected";
|
|
} else {
|
|
return "";
|
|
}
|
|
};
|
|
$scope.titleIfSeparator = function(separator) {
|
|
if (separator)
|
|
return "Page reloaded here"
|
|
return ""
|
|
};
|
|
|
|
$scope.createKeypairs = function (data) {
|
|
let keypairs = [];
|
|
if (!(data instanceof Object)) {
|
|
return keypairs;
|
|
}
|
|
|
|
$.each(data, function (key, value) {
|
|
if (!(value instanceof Object)) {
|
|
keypairs.push({
|
|
name: key,
|
|
value: value
|
|
});
|
|
}
|
|
});
|
|
|
|
return keypairs;
|
|
};
|
|
|
|
$scope.createKeypairsDeep = function (data) {
|
|
let keypairs = [];
|
|
|
|
if (!(data instanceof Object)) {
|
|
return keypairs;
|
|
}
|
|
|
|
$.each(data, function (key, value) {
|
|
keypairs.push({
|
|
name: value.name,
|
|
value: value.value
|
|
});
|
|
});
|
|
|
|
return keypairs;
|
|
};
|
|
|
|
$scope.$watch("activeCode", function (newVal, oldVal) {
|
|
if (newVal === null) {
|
|
$scope.responseJsonEditor.set(null)
|
|
$scope.requestJsonEditor.set(null)
|
|
}
|
|
$scope.displayCode("responseJsonEditor", $scope.activeCode, 3);
|
|
$scope.displayCode("requestJsonEditor", $scope.activePostData, 6);
|
|
});
|
|
|
|
$scope.selectDetailTab = function (tabId, external) {
|
|
$scope.currentDetailTab = tabId;
|
|
if (external) {
|
|
$("#tabs a[href='#" + tabId + "']").trigger("click");
|
|
}
|
|
if (tabId === "tab-response") {
|
|
$scope.displayCode("responseJsonEditor", $scope.activeCode, 3);
|
|
}
|
|
if (tabId === "tab-request") {
|
|
$scope.displayCode("requestJsonEditor", $scope.activePostData, 6);
|
|
}
|
|
};
|
|
|
|
$scope.displayCode = function (elementId, input, depth) {
|
|
if (input) {
|
|
let content;
|
|
if ($scope.showOriginal) {
|
|
content = parse(input, 0, 1);
|
|
} else {
|
|
content = parse(input, 0, depth);
|
|
}
|
|
|
|
if (typeof input === 'object' || Array.isArray(input)) {
|
|
// JSON
|
|
$scope[elementId].setMode("view");
|
|
$scope[elementId].set(content);
|
|
} else {
|
|
// Something else
|
|
try {
|
|
let json = JSON.parse(input)
|
|
$scope[elementId].setMode("view");
|
|
$scope[elementId].set(content);
|
|
} catch (e) {
|
|
$scope[elementId].setMode("code");
|
|
$scope[elementId].set(content);
|
|
}
|
|
}
|
|
|
|
if (elementId === "responseJsonEditor") {
|
|
var bodySize = $scope.activeResponseData.find(x => x.name === "bodySize");
|
|
if (bodySize && bodySize.value < MAXBODYSIZE) { // an arbitrary number that I picked so there is HUGE lag
|
|
if ($scope[elementId].getMode() === 'tree' || $scope[elementId].getMode() === 'view')
|
|
$scope[elementId].expandAll();
|
|
}
|
|
} else if (elementId === "requestJsonEditor") {
|
|
var bodySize = $scope.activeRequest.find(x => x.name === "bodySize");
|
|
if (bodySize && bodySize.value < MAXBODYSIZE) {
|
|
if ($scope[elementId].getMode() === 'tree' || $scope[elementId].getMode() === 'view')
|
|
$scope[elementId].expandAll();
|
|
}
|
|
}
|
|
} else {
|
|
$scope[elementId].set(null);
|
|
$scope[elementId].expandAll();
|
|
}
|
|
};
|
|
});
|