Bug 127613 - Web Inspector: In a DataGrid, store value of columnIdentifier to DOM node representing a cell
Summary: Web Inspector: In a DataGrid, store value of columnIdentifier to DOM node rep...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Enhancement
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2014-01-25 00:39 PST by Diego Pino
Modified: 2014-01-28 07:35 PST (History)
5 users (show)

See Also:


Attachments
Patch (4.25 KB, patch)
2014-01-25 00:48 PST, Diego Pino
no flags Details | Formatted Diff | Diff
Patch (3.64 KB, patch)
2014-01-25 14:38 PST, Diego Pino
no flags Details | Formatted Diff | Diff
Patch (3.63 KB, patch)
2014-01-27 16:22 PST, Diego Pino
no flags Details | Formatted Diff | Diff
Patch (4.44 KB, patch)
2014-01-28 04:56 PST, Diego Pino
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Diego Pino 2014-01-25 00:39:46 PST
Currently, cell DOM nodes of a DataGrid store the value of a 'columnIdentifier' in the 'class' attribute. This requires later parsing of attribute 'class' to know the value of 'columnIdentifier'. HTML5 provides a proper way to store custom attributes to a DOM node, which is by using the 'dataset' attribute. 

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset

Storing 'columnIdentifier' as a dataset attribute won't require later parsing.
Comment 1 Radar WebKit Bug Importer 2014-01-25 00:40:04 PST
<rdar://problem/15908787>
Comment 2 Diego Pino 2014-01-25 00:48:07 PST
Created attachment 222197 [details]
Patch
Comment 3 Joseph Pecoraro 2014-01-25 09:31:28 PST
Comment on attachment 222197 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222197&action=review

r- because I think it breaks styles. But make it so you set classname and dataset attribute, and it is good!

> Source/WebInspectorUI/UserInterface/DataGrid.js:88
> -        cell.className = columnIdentifier + "-column";
> +        cell.dataset["columnIdentifier"] = columnIdentifier;

I think we will need to set the class name for styles. There are a lot of CSS instances of "<foo>-column":

    shell> ack "\-column" *.css
    DOMTreeDataGrid.css
    62:.dom-tree-data-grid .data-container .name-column {
    66:.dom-tree-data-grid .data-container .name-column .icon {
    74:.dom-tree-data-grid .data-container .name-column .label {
    83:.dom-tree-data-grid .data-container tr:hover .name-column .label {

    DetailsSection.css
    251:.details-section > .content .data-grid td.value-column {
    257:.details-section > .content .data-grid td.value-column > div {
    ...

> Source/WebInspectorUI/UserInterface/DataGrid.js:155
> -        td.className = columnIdentifier + "-column";
> +        td.dataset["columnIdentifier"] = columnIdentifier;

Same here.

> Source/WebInspectorUI/UserInterface/DataGrid.js:346
> -        // FIXME: Better way to do this than regular expressions?
> -        var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);
> +        var columnIdentifier = element.dataset["columnIdentifier"];

This looks great though!
Comment 4 Timothy Hatcher 2014-01-25 09:36:38 PST
Comment on attachment 222197 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222197&action=review

I agree with Joe. We need the className for style reasons. I am also not a fan of dataset. There is no reason to use a DOM attribute for internal logic. I would just set cell.__columnIdentifier and use it later.

> Source/WebInspectorUI/UserInterface/DataGrid.js:903
> -                // The first child of the selected element is the <td class="0-column">,
> +                // The first child of the selected element is the <td data-columnIdentifier="0">,

The original comment is not correct, the column identifier is not usually a number, it is a arbitrary string. Just remove this comment.
Comment 5 Timothy Hatcher 2014-01-25 09:39:43 PST
Lets not use dataset. Using the DOM for this is expensive. A private property on the DOM element is good.
Comment 6 Diego Pino 2014-01-25 14:38:06 PST
Created attachment 222234 [details]
Patch
Comment 7 Joseph Pecoraro 2014-01-25 16:49:59 PST
Comment on attachment 222234 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222234&action=review

r=me

> Source/WebInspectorUI/UserInterface/DataGrid.js:156
> +        td.columnIdentifier = columnIdentifier;

As Tim suggested, we should use "__columnIdentifier".

We typically use "__foo" syntax for property names when one class is storing properties on another object, and that other object has no knowledge of the existence of that property. Though ".columnIdentifier" works, it is not immediately clear if you're debugging this element that the property is something we injected onto the element. And having it show up as obvious in the debugger can sometimes be helpful! Also, if in the further that object wanted to add a "columnIdentifier" property then the double underscore would avoid a naming conflict.
Comment 8 Diego Pino 2014-01-27 16:22:51 PST
Created attachment 222378 [details]
Patch
Comment 9 Joseph Pecoraro 2014-01-27 16:38:33 PST
Comment on attachment 222378 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222378&action=review

> Source/WebInspectorUI/UserInterface/DataGrid.js:156
> +        td.__columnIdentifier = parseInt(columnIdentifier);

Whoa, there is a parseInt now? Can't columnIdentifier be a string like "name"?
Comment 10 Timothy Hatcher 2014-01-27 18:11:09 PST
Comment on attachment 222378 [details]
Patch

Yeah, parseInt is not correct. The old code had it in a different spot and it was wrong.
Comment 11 Diego Pino 2014-01-28 00:11:32 PST
Comment on attachment 222378 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222378&action=review

>> Source/WebInspectorUI/UserInterface/DataGrid.js:156
>> +        td.__columnIdentifier = parseInt(columnIdentifier);
> 
> Whoa, there is a parseInt now? Can't columnIdentifier be a string like "name"?

I noticed that __columnIdentifier has to be "numeric". If __columnIdentifier is a "string", there's a regression. When I try the following:

   * double-click on a "Key" column 
   * Insert a value, for instance "Key1"
   * Press return

The result is stored in the key column as "Key1" but it's also stored in the value column as "Key1". This is not correct.

In the original code, parseInt was used in "_editingCommited" and "_contextMenuInDataTable" for casting the value of columnIdentifier after retrieving that value from a regular expression.

var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);

Since there is going to be a field for storing columnIdentifier I thought it was better to store that field as numeric, instead of casting it everytime "_editingCommited" and "_contextMenuInDataTable" were called.

Still, why columnIdentifier has to be numeric? If __columnIdentifier is a string, function "_contextMenuInDataTable" works well. The problem is in function "_editingCommited". _editingCommited calls this._editCallback. _editCallback (DOMStorageContentView.js:215) does a strict comparison of the value of columnIdentifier.

_editingCallback: function(editingNode, columnIdentifier, oldText, newText)
{
    var domStorage = this.representedObject;
    if (columnIdentifier === 0) {
        if (oldText)
            domStorage.removeItem(oldText);

        domStorage.setItem(newText, editingNode.data[1]);
    } else
        domStorage.setItem(editingNode.data[0], newText);

    this.update();
}

If columnIdentifier is a "string" the else branch is always executed (it updates the value of the value column). That's why in the use-case explained above, when updating a key the key column gets updated (visually) and the value column gets updated too.
Comment 12 Timothy Hatcher 2014-01-28 00:29:15 PST
Comment on attachment 222378 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=222378&action=review

>>> Source/WebInspectorUI/UserInterface/DataGrid.js:156
>>> +        td.__columnIdentifier = parseInt(columnIdentifier);
>> 
>> Whoa, there is a parseInt now? Can't columnIdentifier be a string like "name"?
> 
> I noticed that __columnIdentifier has to be "numeric". If __columnIdentifier is a "string", there's a regression. When I try the following:
> 
>    * double-click on a "Key" column 
>    * Insert a value, for instance "Key1"
>    * Press return
> 
> The result is stored in the key column as "Key1" but it's also stored in the value column as "Key1". This is not correct.
> 
> In the original code, parseInt was used in "_editingCommited" and "_contextMenuInDataTable" for casting the value of columnIdentifier after retrieving that value from a regular expression.
> 
> var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);
> 
> Since there is going to be a field for storing columnIdentifier I thought it was better to store that field as numeric, instead of casting it everytime "_editingCommited" and "_contextMenuInDataTable" were called.
> 
> Still, why columnIdentifier has to be numeric? If __columnIdentifier is a string, function "_contextMenuInDataTable" works well. The problem is in function "_editingCommited". _editingCommited calls this._editCallback. _editCallback (DOMStorageContentView.js:215) does a strict comparison of the value of columnIdentifier.
> 
> _editingCallback: function(editingNode, columnIdentifier, oldText, newText)
> {
>     var domStorage = this.representedObject;
>     if (columnIdentifier === 0) {
>         if (oldText)
>             domStorage.removeItem(oldText);
> 
>         domStorage.setItem(newText, editingNode.data[1]);
>     } else
>         domStorage.setItem(editingNode.data[0], newText);
> 
>     this.update();
> }
> 
> If columnIdentifier is a "string" the else branch is always executed (it updates the value of the value column). That's why in the use-case explained above, when updating a key the key column gets updated (visually) and the value column gets updated too.

Good catch! But DOMStorageContentView.js is the one that should change. Making the 0s and 1s be "0" and "1" would be fine to fix in this patch. Ideally, DOMStorageContentView.js would use identifiers like "key" and "value" instead of numbers.
Comment 13 Diego Pino 2014-01-28 04:56:51 PST
Created attachment 222430 [details]
Patch
Comment 14 WebKit Commit Bot 2014-01-28 07:35:53 PST
Comment on attachment 222430 [details]
Patch

Clearing flags on attachment: 222430

Committed r162931: <http://trac.webkit.org/changeset/162931>
Comment 15 WebKit Commit Bot 2014-01-28 07:35:56 PST
All reviewed patches have been landed.  Closing bug.