Changeset 252652 in webkit


Ignore:
Timestamp:
Nov 19, 2019 2:55:04 PM (4 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Local Overrides: the placeholder for the MIME type, status code, and status text is the same as the placeholder URL
https://bugs.webkit.org/show_bug.cgi?id=204330

Reviewed by Joseph Pecoraro.

  • UserInterface/Views/LocalResourceOverridePopover.js:

(WI.LocalResourceOverridePopover.prototype.get serializedData):
(WI.LocalResourceOverridePopover.prototype.show):
(WI.LocalResourceOverridePopover.prototype._createEditor):

  • UserInterface/Views/LocalResourceOverridePopover.css:

(.popover .local-resource-override-popover-content .data-grid tr.header-content-type > :matches(.name-column, .value-column)): Added.
Replace the hardcoded placeholder with an optional options object that can include a
placeholder value, allowing each caller to customize what is shown. Disallow selecting the
"Content-Type" header since it's automatically populated, even if there is no set value for
the MIME type or URL (e.g. inferred from placeholders).
Drive-by: if a CodeMirror has no value, attempt to use it's placeholder instead.
Drive-by: replace generic dataGrid with more specific this._headersDataGrid, which is

more clear given how many WI.DataGrid are created by this class.

  • UserInterface/Views/DataGridNode.js:

(WI.DataGridNode.prototype.get selectable):
(WI.PlaceholderDataGridNode):

  • UserInterface/Views/DataGrid.js:

(WI.DataGrid.createSortableDataGrid):

  • UserInterface/Views/DOMStorageContentView.js:

(WI.DOMStorageContentView.prototype.itemAdded):
(WI.DOMStorageContentView.prototype._populate):

  • UserInterface/Views/EditableDataGridNode.js:

(WI.EditableDataGridNode): Deleted.

  • UserInterface/Views/HeapSnapshotClassDataGridNode.js:

(WI.HeapSnapshotClassDataGridNode):

  • UserInterface/Views/HeapSnapshotInstanceDataGridNode.js:

(WI.HeapSnapshotInstanceDataGridNode):

  • UserInterface/Views/HeapSnapshotInstanceFetchMoreDataGridNode.js:

(WI.HeapSnapshotInstanceFetchMoreDataGridNode):

  • UserInterface/Views/ProfileDataGridNode.js:

(WI.ProfileDataGridNode):

  • UserInterface/Views/RecordingStateDetailsSidebarPanel.js:

(WI.RecordingStateDetailsSidebarPanel.prototype._generateDetailsCanvas2D):
(WI.RecordingStateDetailsSidebarPanel):

  • UserInterface/Views/ResourceDetailsSidebarPanel.js:

(WI.ResourceDetailsSidebarPanel.prototype._createNameValueDataGrid.addDataGridNode):

  • UserInterface/Views/TimelineDataGridNode.js:

(WI.TimelineDataGridNode):
Rework constructor of WI.DataGridNode to accept an options-style object as its second
parameter, instead of separate parameters for each configurable property. Now that this is
able to be done via a single parameter, add support for marking a WI.DataGridNode as not
being selectable.

Location:
trunk/Source/WebInspectorUI
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r252637 r252652  
     12019-11-19  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Local Overrides: the placeholder for the MIME type, status code, and status text is the same as the placeholder URL
     4        https://bugs.webkit.org/show_bug.cgi?id=204330
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        * UserInterface/Views/LocalResourceOverridePopover.js:
     9        (WI.LocalResourceOverridePopover.prototype.get serializedData):
     10        (WI.LocalResourceOverridePopover.prototype.show):
     11        (WI.LocalResourceOverridePopover.prototype._createEditor):
     12        * UserInterface/Views/LocalResourceOverridePopover.css:
     13        (.popover .local-resource-override-popover-content .data-grid tr.header-content-type > :matches(.name-column, .value-column)): Added.
     14        Replace the hardcoded `placeholder` with an optional `options` object that can include a
     15        `placeholder` value, allowing each caller to customize what is shown. Disallow selecting the
     16        "Content-Type" header since it's automatically populated, even if there is no set value for
     17        the MIME type or URL (e.g. inferred from placeholders).
     18        Drive-by: if a `CodeMirror` has no value, attempt to use it's placeholder instead.
     19        Drive-by: replace generic `dataGrid` with more specific `this._headersDataGrid`, which is
     20                  more clear given how many `WI.DataGrid` are created by this class.
     21
     22        * UserInterface/Views/DataGridNode.js:
     23        (WI.DataGridNode.prototype.get selectable):
     24        (WI.PlaceholderDataGridNode):
     25        * UserInterface/Views/DataGrid.js:
     26        (WI.DataGrid.createSortableDataGrid):
     27        * UserInterface/Views/DOMStorageContentView.js:
     28        (WI.DOMStorageContentView.prototype.itemAdded):
     29        (WI.DOMStorageContentView.prototype._populate):
     30        * UserInterface/Views/EditableDataGridNode.js:
     31        (WI.EditableDataGridNode): Deleted.
     32        * UserInterface/Views/HeapSnapshotClassDataGridNode.js:
     33        (WI.HeapSnapshotClassDataGridNode):
     34        * UserInterface/Views/HeapSnapshotInstanceDataGridNode.js:
     35        (WI.HeapSnapshotInstanceDataGridNode):
     36        * UserInterface/Views/HeapSnapshotInstanceFetchMoreDataGridNode.js:
     37        (WI.HeapSnapshotInstanceFetchMoreDataGridNode):
     38        * UserInterface/Views/ProfileDataGridNode.js:
     39        (WI.ProfileDataGridNode):
     40        * UserInterface/Views/RecordingStateDetailsSidebarPanel.js:
     41        (WI.RecordingStateDetailsSidebarPanel.prototype._generateDetailsCanvas2D):
     42        (WI.RecordingStateDetailsSidebarPanel):
     43        * UserInterface/Views/ResourceDetailsSidebarPanel.js:
     44        (WI.ResourceDetailsSidebarPanel.prototype._createNameValueDataGrid.addDataGridNode):
     45        * UserInterface/Views/TimelineDataGridNode.js:
     46        (WI.TimelineDataGridNode):
     47        Rework constructor of `WI.DataGridNode` to accept an `options`-style object as its second
     48        parameter, instead of separate parameters for each configurable property. Now that this is
     49        able to be done via a single parameter, add support for marking a `WI.DataGridNode` as not
     50        being selectable.
     51
    1522019-11-19  Brian Burg  <bburg@apple.com>
    253
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMStorageContentView.js

    r245486 r252652  
    9999        }
    100100
    101         this._dataGrid.appendChild(new WI.DataGridNode({key, value, originalValue}, false));
     101        this._dataGrid.appendChild(new WI.DataGridNode({key, value, originalValue}));
    102102        this._sortDataGrid();
    103103    }
     
    146146                let originalValue = value;
    147147                value = this._truncateValue(value);
    148                 let node = new WI.DataGridNode({key, value, originalValue}, false);
     148                let node = new WI.DataGridNode({key, value, originalValue});
    149149                this._dataGrid.appendChild(node);
    150150            }
  • trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js

    r249655 r252652  
    178178                data[columnNames[j]] = values[numColumns * i + j];
    179179
    180             var node = new WI.DataGridNode(data, false);
     180            var node = new WI.DataGridNode(data);
    181181            dataGrid.appendChild(node);
    182182        }
  • trunk/Source/WebInspectorUI/UserInterface/Views/DataGridNode.js

    r249504 r252652  
    2626WI.DataGridNode = class DataGridNode extends WI.Object
    2727{
    28     constructor(data, hasChildren, classNames)
     28    constructor(data, {selectable, copyable, editable, hasChildren, classNames} = {})
    2929    {
    3030        super();
     
    3333        this._hidden = false;
    3434        this._selected = false;
    35         this._copyable = true;
    36         this._editable = true;
     35        this._selectable = selectable !== undefined ? selectable : true;
     36        this._copyable = copyable !== undefined ? copyable : true;
     37        this._editable = editable !== undefined ? editable : true;
    3738        this._shouldRefreshChildren = true;
    3839        this._data = data || {};
     
    6970    get selectable()
    7071    {
    71         return this._element && !this._hidden;
     72        return this._element && !this._hidden && this._selectable;
    7273    }
    7374
     
    771772    constructor(data)
    772773    {
    773         super(data, false);
     774        super(data);
    774775        this.isPlaceholderNode = true;
    775776    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/EditableDataGridNode.js

    r220119 r252652  
    2626WI.EditableDataGridNode = class EditableDataGridNode extends WI.DataGridNode
    2727{
    28     constructor(data)
    29     {
    30         const hasChildren = false;
    31         super(data, hasChildren);
    32     }
    33 
    3428    // Public
    3529
  • trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotClassDataGridNode.js

    r241787 r252652  
    2828    constructor(data, tree)
    2929    {
    30         super(data, true);
     30        super(data, {hasChildren: true});
    3131
    3232        this._data = data;
  • trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceDataGridNode.js

    r248898 r252652  
    3131        let hasChildren = node.hasChildren && node.className !== "string";
    3232
    33         super(node, hasChildren);
     33        // FIXME: Make instance grid nodes copyable.
     34        super(node, {hasChildren, copyable: false});
    3435
    3536        console.assert(node instanceof WI.HeapSnapshotNodeProxy);
     
    4142        this._edge = edge || null;
    4243        this._base = base || null;
    43 
    44         // FIXME: Make instance grid nodes copyable.
    45         this.copyable = false;
    4644
    4745        if (hasChildren)
  • trunk/Source/WebInspectorUI/UserInterface/Views/HeapSnapshotInstanceFetchMoreDataGridNode.js

    r220119 r252652  
    2828    constructor(tree, batchCount, remainingCount, fetchCallback)
    2929    {
    30         super({}, false);
     30        super();
    3131
    3232        console.assert(typeof batchCount === "number");
  • trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.css

    r252614 r252652  
    9191}
    9292
     93.popover .local-resource-override-popover-content .data-grid tr.header-content-type > :matches(.name-column, .value-column) {
     94    opacity: 0.5;
     95}
     96
    9397.popover .local-resource-override-popover-content .add-header {
    9498    margin-top: 8px;
  • trunk/Source/WebInspectorUI/UserInterface/Views/LocalResourceOverridePopover.js

    r252614 r252652  
    6565        // the popover doesn't have to have an additional state for "pass through".
    6666
    67         let mimeType = this._mimeTypeCodeMirror.getValue();
     67        let mimeType = this._mimeTypeCodeMirror.getValue() || this._mimeTypeCodeMirror.getOption("placeholder");
    6868        if (!mimeType)
    6969            return null;
    7070
    7171        let statusCode = parseInt(this._statusCodeCodeMirror.getValue());
     72        if (isNaN(statusCode))
     73            statusCode = parseInt(this._statusCodeCodeMirror.getOption("placeholder"));
    7274        if (isNaN(statusCode) || statusCode < 0)
    7375            return null;
    7476
    75         let statusText = this._statusTextCodeMirror.getValue();
     77        let statusText = this._statusTextCodeMirror.getValue() || this._statusTextCodeMirror.getOption("placeholder");
    7678        if (!statusText)
    7779            return null;
     
    119121        let localResource = localResourceOverride ? localResourceOverride.localResource : null;
    120122
    121         let url = localResource ? localResource.url : "";
    122         let mimeType = localResource ? localResource.mimeType : "";
    123         let statusCode = localResource ? String(localResource.statusCode) : "";
    124         let statusText = localResource ? localResource.statusText : "";
     123        let data = {};
     124        let resourceData = {};
     125        if (localResource) {
     126            data.url = resourceData.url = localResource.url;
     127            data.mimeType = resourceData.mimeType = localResource.mimeType;
     128            data.statusCode = resourceData.statusCode = String(localResource.statusCode);
     129            data.statusText = resourceData.statusText = localResource.statusText;
     130        }
     131
     132        if (!data.url)
     133            data.url = this._defaultURL();
     134        if (!data.mimeType)
     135            data.mimeType = "text/javascript";
     136        if (!data.statusCode || data.statusCode === "NaN")
     137            data.statusCode = "200";
     138        if (!data.statusText)
     139            data.statusText = WI.HTTPUtilities.statusTextForStatusCode(parseInt(data.statusCode));
     140
    125141        let responseHeaders = localResource ? localResource.responseHeaders : {};
    126 
    127         if (!url)
    128             url = this._defaultURL();
    129         if (!mimeType)
    130             mimeType = "text/javascript";
    131         if (!statusCode || statusCode === "NaN")
    132             statusCode = "200";
    133         if (!statusText)
    134             statusText = WI.HTTPUtilities.statusTextForStatusCode(parseInt(statusCode));
    135142
    136143        let popoverContentElement = document.createElement("div");
     
    139146        let table = popoverContentElement.appendChild(document.createElement("table"));
    140147
    141         let createRow = (label, id, text, placeholder) => {
     148        let createRow = (label, id, value, placeholder) => {
    142149            let row = table.appendChild(document.createElement("tr"));
    143150            let headerElement = row.appendChild(document.createElement("th"));
     
    150157            editorElement.classList.add("editor", id);
    151158
    152             let codeMirror = this._createEditor(editorElement, text, placeholder);
     159            let codeMirror = this._createEditor(editorElement, {value, placeholder});
    153160            let inputField = codeMirror.getInputField();
    154161            inputField.id = `local-resource-override-popover-${id}-input-field`;
     
    158165        };
    159166
    160         let urlRow = createRow(WI.UIString("URL"), "url", url, url || "http://example.com/index.html");
     167        let urlRow = createRow(WI.UIString("URL"), "url", resourceData.url || "", data.url);
    161168        this._urlCodeMirror = urlRow.codeMirror;
    162169
     
    168175            if (!isRegex) {
    169176                let url = this._urlCodeMirror.getValue();
    170                 const schemes = ["http:", "https:", "file:"];
    171                 if (!schemes.some((scheme) => url.toLowerCase().startsWith(scheme)))
    172                     this._urlCodeMirror.setValue("http://" + url);
     177                if (url) {
     178                    const schemes = ["http:", "https:", "file:"];
     179                    if (!schemes.some((scheme) => url.toLowerCase().startsWith(scheme)))
     180                        this._urlCodeMirror.setValue("http://" + url);
     181                }
    173182            }
    174183        };
     
    199208        }
    200209
    201         let mimeTypeRow = createRow(WI.UIString("MIME Type"), "mime", mimeType, mimeType || "text/html");
     210        let mimeTypeRow = createRow(WI.UIString("MIME Type"), "mime", resourceData.mimeType || "", data.mimeType);
    202211        this._mimeTypeCodeMirror = mimeTypeRow.codeMirror;
    203212
    204         let statusCodeRow = createRow(WI.UIString("Status"), "status", statusCode, statusCode || "200");
     213        let statusCodeRow = createRow(WI.UIString("Status"), "status", resourceData.statusCode || "", data.statusCode);
    205214        this._statusCodeCodeMirror = statusCodeRow.codeMirror;
    206215
    207216        let statusTextEditorElement = statusCodeRow.dataElement.appendChild(document.createElement("div"));
    208217        statusTextEditorElement.className = "editor status-text";
    209         this._statusTextCodeMirror = this._createEditor(statusTextEditorElement, statusText, statusText || "OK");
     218        this._statusTextCodeMirror = this._createEditor(statusTextEditorElement, {value: resourceData.statusText || "", placeholder: data.statusText});
    210219
    211220        let editCallback = () => {};
     
    215224
    216225            let siblingToSelect = node.nextSibling || node.previousSibling;
    217             dataGrid.removeChild(node);
     226            this._headersDataGrid.removeChild(node);
    218227            if (siblingToSelect)
    219228                siblingToSelect.select();
    220229
    221             dataGrid.updateLayoutIfNeeded();
     230            this._headersDataGrid.updateLayoutIfNeeded();
    222231            this.update();
    223232        };
     
    233242        };
    234243
    235         let dataGrid = this._headersDataGrid = new WI.DataGrid(columns, {editCallback, deleteCallback});
    236         dataGrid.inline = true;
    237         dataGrid.variableHeightRows = true;
    238         dataGrid.copyTextDelimiter = ": ";
    239 
    240         function addDataGridNodeForHeader(name, value) {
    241             let node = new WI.DataGridNode({name, value});
    242             dataGrid.appendChild(node);
     244        this._headersDataGrid = new WI.DataGrid(columns, {editCallback, deleteCallback});
     245        this._headersDataGrid.inline = true;
     246        this._headersDataGrid.variableHeightRows = true;
     247        this._headersDataGrid.copyTextDelimiter = ": ";
     248
     249        let addDataGridNodeForHeader = (name, value, options = {}) => {
     250            let node = new WI.DataGridNode({name, value}, options);
     251            this._headersDataGrid.appendChild(node);
    243252            return node;
    244         }
    245 
    246         let contentTypeDataGridNode = addDataGridNodeForHeader("Content-Type", mimeType);
    247         contentTypeDataGridNode.editable = false;
     253        };
     254
     255        let contentTypeDataGridNode = addDataGridNodeForHeader("Content-Type", data.mimeType, {selectable: false, editable: false, classNames: ["header-content-type"]});
    248256
    249257        for (let name in responseHeaders) {
     
    260268        let headersLabel = headersHeader.appendChild(document.createElement("label"));
    261269        headersLabel.textContent = WI.UIString("Headers");
    262         headersData.appendChild(dataGrid.element);
    263         dataGrid.updateLayoutIfNeeded();
     270        headersData.appendChild(this._headersDataGrid.element);
     271        this._headersDataGrid.updateLayoutIfNeeded();
    264272
    265273        let addHeaderButton = headersData.appendChild(document.createElement("button"));
     
    268276        addHeaderButton.addEventListener("click", (event) => {
    269277            let newNode = new WI.DataGridNode({name: "Header", value: "value"});
    270             dataGrid.appendChild(newNode);
    271             dataGrid.updateLayoutIfNeeded();
     278            this._headersDataGrid.appendChild(newNode);
     279            this._headersDataGrid.updateLayoutIfNeeded();
    272280            this.update();
    273             dataGrid.startEditingNode(newNode);
     281            this._headersDataGrid.startEditingNode(newNode);
    274282        });
    275283
    276284        let incrementStatusCode = () => {
    277285            let x = parseInt(this._statusCodeCodeMirror.getValue());
     286            if (isNaN(x))
     287                x = parseInt(this._statusCodeCodeMirror.getOption("placeholder"));
    278288            if (isNaN(x) || x >= 999)
    279289                return;
     
    294304        let decrementStatusCode = () => {
    295305            let x = parseInt(this._statusCodeCodeMirror.getValue());
     306            if (isNaN(x))
     307                x = parseInt(this._statusCodeCodeMirror.getOption("placeholder"));
    296308            if (isNaN(x) || x <= 0)
    297309                return;
     
    323335        this._statusCodeCodeMirror.on("change", (cm) => {
    324336            let statusCode = parseInt(cm.getValue());
     337            if (isNaN(statusCode)) {
     338                this._statusTextCodeMirror.setValue("");
     339                return;
     340            }
     341
    325342            let statusText = WI.HTTPUtilities.statusTextForStatusCode(statusCode);
    326343            this._statusTextCodeMirror.setValue(statusText);
     
    346363        // Update Content-Type header when mimeType changes.
    347364        this._mimeTypeCodeMirror.on("change", (cm) => {
    348             let mimeType = cm.getValue();
     365            let mimeType = cm.getValue() || cm.getOption("placeholder");
    349366            contentTypeDataGridNode.data = {name: "Content-Type", value: mimeType};
    350367        });
     
    371388    // Private
    372389
    373     _createEditor(element, value, placeholder)
     390    _createEditor(element, options = {})
    374391    {
    375392        let codeMirror = WI.CodeMirrorEditor.create(element, {
     
    378395            mode: "text/plain",
    379396            matchBrackets: true,
    380             placeholder,
    381397            scrollbarStyle: null,
    382             value,
     398            ...options,
    383399        });
    384400
  • trunk/Source/WebInspectorUI/UserInterface/Views/ProfileDataGridNode.js

    r238743 r252652  
    2828    constructor(callingContextTreeNode, tree)
    2929    {
    30         super(callingContextTreeNode, false);
     30        // FIXME: Make profile data grid nodes copyable.
     31        super(callingContextTreeNode, {copyable: false});
    3132
    3233        this._node = callingContextTreeNode;
     
    3536        this._childrenToChargeToSelf = new Set;
    3637        this._extraSelfTimeFromChargedChildren = 0;
    37 
    38         // FIXME: Make profile data grid nodes copyable.
    39         this.copyable = false;
    4038
    4139        this.addEventListener("populate", this._populate, this);
  • trunk/Source/WebInspectorUI/UserInterface/Views/RecordingStateDetailsSidebarPanel.js

    r241875 r252652  
    169169                    classNames.push("non-standard");
    170170
    171                 const hasChildren = false;
    172                 dataGrid.appendChild(new WI.DataGridNode({name, value}, hasChildren, classNames));
     171                dataGrid.appendChild(new WI.DataGridNode({name, value}, {classNames}));
    173172            }
    174173
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js

    r251227 r252652  
    451451            console.assert(!nodeValue.value || typeof nodeValue.value === "string");
    452452
    453             var node = new WI.DataGridNode({name: nodeValue.name, value: nodeValue.value || ""}, false);
     453            var node = new WI.DataGridNode({name: nodeValue.name, value: nodeValue.value || ""});
    454454            dataGrid.appendChild(node);
    455455        }
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js

    r251959 r252652  
    2626WI.TimelineDataGridNode = class TimelineDataGridNode extends WI.DataGridNode
    2727{
    28     constructor(records, options = {})
    29     {
    30         super({}, options.hasChildren);
    31 
    32         this.copyable = false;
     28    constructor(records, {hasChildren, includesGraph, graphDataSource} = {})
     29    {
     30        super({}, {hasChildren, copyable: false});
    3331
    3432        this._records = records;
    35         this._includesGraph = options.includesGraph || false;
    36         this._graphDataSource = options.graphDataSource || null;
     33        this._includesGraph = includesGraph || false;
     34        this._graphDataSource = graphDataSource || null;
    3735        this._cachedData = null;
    3836
Note: See TracChangeset for help on using the changeset viewer.