summaryrefslogtreecommitdiffstats
path: root/devtools/client/netmonitor/custom-request-view.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/netmonitor/custom-request-view.js')
-rw-r--r--devtools/client/netmonitor/custom-request-view.js216
1 files changed, 216 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/custom-request-view.js b/devtools/client/netmonitor/custom-request-view.js
new file mode 100644
index 000000000..3159ffcc7
--- /dev/null
+++ b/devtools/client/netmonitor/custom-request-view.js
@@ -0,0 +1,216 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* globals window, dumpn, gNetwork, $, EVENTS, NetMonitorView */
+"use strict";
+
+const {Task} = require("devtools/shared/task");
+const {writeHeaderText, getKeyWithEvent} = require("./request-utils");
+
+loader.lazyRequireGetter(this, "NetworkHelper",
+ "devtools/shared/webconsole/network-helper");
+
+/**
+ * Functions handling the custom request view.
+ */
+function CustomRequestView() {
+ dumpn("CustomRequestView was instantiated");
+}
+
+CustomRequestView.prototype = {
+ /**
+ * Initialization function, called when the network monitor is started.
+ */
+ initialize: function () {
+ dumpn("Initializing the CustomRequestView");
+
+ this.updateCustomRequestEvent = getKeyWithEvent(this.onUpdate.bind(this));
+ $("#custom-pane").addEventListener("input",
+ this.updateCustomRequestEvent, false);
+ },
+
+ /**
+ * Destruction function, called when the network monitor is closed.
+ */
+ destroy: function () {
+ dumpn("Destroying the CustomRequestView");
+
+ $("#custom-pane").removeEventListener("input",
+ this.updateCustomRequestEvent, false);
+ },
+
+ /**
+ * Populates this view with the specified data.
+ *
+ * @param object data
+ * The data source (this should be the attachment of a request item).
+ * @return object
+ * Returns a promise that resolves upon population the view.
+ */
+ populate: Task.async(function* (data) {
+ $("#custom-url-value").value = data.url;
+ $("#custom-method-value").value = data.method;
+ this.updateCustomQuery(data.url);
+
+ if (data.requestHeaders) {
+ let headers = data.requestHeaders.headers;
+ $("#custom-headers-value").value = writeHeaderText(headers);
+ }
+ if (data.requestPostData) {
+ let postData = data.requestPostData.postData.text;
+ $("#custom-postdata-value").value = yield gNetwork.getString(postData);
+ }
+
+ window.emit(EVENTS.CUSTOMREQUESTVIEW_POPULATED);
+ }),
+
+ /**
+ * Handle user input in the custom request form.
+ *
+ * @param object field
+ * the field that the user updated.
+ */
+ onUpdate: function (field) {
+ let selectedItem = NetMonitorView.RequestsMenu.selectedItem;
+ let value;
+
+ switch (field) {
+ case "method":
+ value = $("#custom-method-value").value.trim();
+ selectedItem.attachment.method = value;
+ break;
+ case "url":
+ value = $("#custom-url-value").value;
+ this.updateCustomQuery(value);
+ selectedItem.attachment.url = value;
+ break;
+ case "query":
+ let query = $("#custom-query-value").value;
+ this.updateCustomUrl(query);
+ field = "url";
+ value = $("#custom-url-value").value;
+ selectedItem.attachment.url = value;
+ break;
+ case "body":
+ value = $("#custom-postdata-value").value;
+ selectedItem.attachment.requestPostData = { postData: { text: value } };
+ break;
+ case "headers":
+ let headersText = $("#custom-headers-value").value;
+ value = parseHeadersText(headersText);
+ selectedItem.attachment.requestHeaders = { headers: value };
+ break;
+ }
+
+ NetMonitorView.RequestsMenu.updateMenuView(selectedItem, field, value);
+ },
+
+ /**
+ * Update the query string field based on the url.
+ *
+ * @param object url
+ * The URL to extract query string from.
+ */
+ updateCustomQuery: function (url) {
+ let paramsArray = NetworkHelper.parseQueryString(
+ NetworkHelper.nsIURL(url).query);
+
+ if (!paramsArray) {
+ $("#custom-query").hidden = true;
+ return;
+ }
+
+ $("#custom-query").hidden = false;
+ $("#custom-query-value").value = writeQueryText(paramsArray);
+ },
+
+ /**
+ * Update the url based on the query string field.
+ *
+ * @param object queryText
+ * The contents of the query string field.
+ */
+ updateCustomUrl: function (queryText) {
+ let params = parseQueryText(queryText);
+ let queryString = writeQueryString(params);
+
+ let url = $("#custom-url-value").value;
+ let oldQuery = NetworkHelper.nsIURL(url).query;
+ let path = url.replace(oldQuery, queryString);
+
+ $("#custom-url-value").value = path;
+ }
+};
+
+/**
+ * Parse text representation of multiple HTTP headers.
+ *
+ * @param string text
+ * Text of headers
+ * @return array
+ * Array of headers info {name, value}
+ */
+function parseHeadersText(text) {
+ return parseRequestText(text, "\\S+?", ":");
+}
+
+/**
+ * Parse readable text list of a query string.
+ *
+ * @param string text
+ * Text of query string represetation
+ * @return array
+ * Array of query params {name, value}
+ */
+function parseQueryText(text) {
+ return parseRequestText(text, ".+?", "=");
+}
+
+/**
+ * Parse a text representation of a name[divider]value list with
+ * the given name regex and divider character.
+ *
+ * @param string text
+ * Text of list
+ * @return array
+ * Array of headers info {name, value}
+ */
+function parseRequestText(text, namereg, divider) {
+ let regex = new RegExp("(" + namereg + ")\\" + divider + "\\s*(.+)");
+ let pairs = [];
+
+ for (let line of text.split("\n")) {
+ let matches;
+ if (matches = regex.exec(line)) { // eslint-disable-line
+ let [, name, value] = matches;
+ pairs.push({name: name, value: value});
+ }
+ }
+ return pairs;
+}
+
+/**
+ * Write out a list of query params into a chunk of text
+ *
+ * @param array params
+ * Array of query params {name, value}
+ * @return string
+ * List of query params in text format
+ */
+function writeQueryText(params) {
+ return params.map(({name, value}) => name + "=" + value).join("\n");
+}
+
+/**
+ * Write out a list of query params into a query string
+ *
+ * @param array params
+ * Array of query params {name, value}
+ * @return string
+ * Query string that can be appended to a url.
+ */
+function writeQueryString(params) {
+ return params.map(({name, value}) => name + "=" + value).join("&");
+}
+
+exports.CustomRequestView = CustomRequestView;