diff options
Diffstat (limited to 'devtools/client/netmonitor/custom-request-view.js')
-rw-r--r-- | devtools/client/netmonitor/custom-request-view.js | 216 |
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; |