Bug 93444 - Web Inspector: SourceFrame shouldn't be a View
Summary: Web Inspector: SourceFrame shouldn't be a View
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Inspector (Deprecated) (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Jan Keromnes
URL:
Keywords:
Depends on: 94347
Blocks: 94325
  Show dependency treegraph
 
Reported: 2012-08-08 00:11 PDT by Jan Keromnes
Modified: 2014-01-13 08:33 PST (History)
14 users (show)

See Also:


Attachments
Patch (6.07 KB, patch)
2012-08-08 00:22 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from gce-cr-linux-02 (313.60 KB, application/zip)
2012-08-08 01:00 PDT, WebKit Review Bot
no flags Details
Patch (8.23 KB, patch)
2012-08-08 14:08 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff
Patch (9.80 KB, patch)
2012-08-13 17:13 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff
Patch (11.75 KB, patch)
2012-08-14 16:49 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff
Patch (11.45 KB, patch)
2012-08-14 18:15 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff
Patch (11.09 KB, patch)
2012-08-17 00:04 PDT, Jan Keromnes
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Keromnes 2012-08-08 00:11:00 PDT
Currently, SourceFrame is a View, and 100% of its screen space is filled by its TextEditor, which is also a View. Aside from being unnecessary, this will be problematic if we want future ExtensionTextEditors to create only one iframe ExtensionView for all the SourceFrames.
Comment 1 Jan Keromnes 2012-08-08 00:22:19 PDT
Created attachment 157138 [details]
Patch
Comment 2 Jan Keromnes 2012-08-08 00:28:07 PDT
Uploaded patch makes the following test fail:

inspector/styles/edit-inspector-stylesheet.html

It looks like it is flaky and I don't understand why it worked before.
Comment 3 WebKit Review Bot 2012-08-08 01:00:46 PDT
Comment on attachment 157138 [details]
Patch

Attachment 157138 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/13460079

New failing tests:
inspector/styles/edit-inspector-stylesheet.html
Comment 4 WebKit Review Bot 2012-08-08 01:00:51 PDT
Created attachment 157144 [details]
Archive of layout-test-results from gce-cr-linux-02

The attached test failures were seen while running run-webkit-tests on the chromium-ews.
Bot: gce-cr-linux-02  Port: <class 'webkitpy.common.config.ports.ChromiumXVFBPort'>  Platform: Linux-2.6.39-gcg-201203291735-x86_64-with-Ubuntu-10.04-lucid
Comment 5 Pavel Feldman 2012-08-08 10:38:53 PDT
Comment on attachment 157138 [details]
Patch

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

> Source/WebCore/inspector/front-end/SourceFrame.js:88
> +    show: function(parent)

The change in the behavior here is that wasShown was called every time the view was shown (every time it got on screen be it switching on the container panel or switching to the tab that contains it). Now it happens only upon explicit show call.

> Source/WebCore/inspector/front-end/SourceFrame.js:97
> +        //WebInspector.View.prototype.willHide.call(this);

Same is true for detach. So I think that might be the source of the flakiness you were seeing. The right way of addressing it would be to add a listener for WasShown / WasHidden on the view object. Then SourceFrame would receive it exactly when it used to and no changes to the behavior would happen. And your show and detach would delegate to the corresponsing show and detach of the textEditor inside.
Comment 6 Jan Keromnes 2012-08-08 14:08:37 PDT
Created attachment 157288 [details]
Patch
Comment 7 Jan Keromnes 2012-08-08 14:13:49 PDT
(In reply to comment #5)
> The change in the behavior here is that wasShown was called every time the view was shown (every time it got on screen be it switching on the container panel or switching to the tab that contains it). Now it happens only upon explicit show call.
>
> Same is true for detach. So I think that might be the source of the flakiness you were seeing. The right way of addressing it would be to add a listener for WasShown / WasHidden on the view object. Then SourceFrame would receive it exactly when it used to and no changes to the behavior would happen. And your show and detach would delegate to the corresponsing show and detach of the textEditor inside.

Thanks for the advice, I made SourceFrame listen for WasShown and WillHide on its TextEditor and it works like a charm! On to #92769...
Comment 8 Pavel Feldman 2012-08-08 22:40:04 PDT
Comment on attachment 157288 [details]
Patch

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

Looks like it is almost ready.

> Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js:66
> +    show: function(parent)

Just nuke the entire method.

> Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js:74
>          this._popoverHelper.hidePopover();

This should go into the willHide listener (and be done every time we hide)

> Source/WebCore/inspector/front-end/SourceFrame.js:112
> +        //WebInspector.View.prototype.willHide.call(this);

nuke this line
Comment 9 Jan Keromnes 2012-08-13 17:13:05 PDT
Created attachment 158151 [details]
Patch
Comment 10 Jan Keromnes 2012-08-13 17:18:56 PDT
Should be ready now. Thanks for the feedback!
Comment 11 Pavel Feldman 2012-08-14 04:13:38 PDT
Comment on attachment 158151 [details]
Patch

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

> Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js:66
> +    _onTextEditorWillHide: function()

You can't override private methods in a different file. _bar are only used within single file.

> Source/WebCore/inspector/front-end/SourceFrame.js:-98
> -        this._textEditor.show(this.element);

This still changes the behavior. We used to append the text editor upon showing it in the screen, i.e. lazily. Now it is appended right away. Why did you change this?
Comment 12 Jan Keromnes 2012-08-14 16:49:44 PDT
Created attachment 158447 [details]
Patch
Comment 13 Jan Keromnes 2012-08-14 16:59:47 PDT
(In reply to comment #11)
> > Source/WebCore/inspector/front-end/JavaScriptSourceFrame.js:66
> > +    _onTextEditorWillHide: function()
> 
> You can't override private methods in a different file. _bar are only used within single file.

Fixed by attaching a second listener to TextEditor.Events.WillHide instead of overriding a private method.

> > Source/WebCore/inspector/front-end/SourceFrame.js:-98
> > -        this._textEditor.show(this.element);
> 
> This still changes the behavior. We used to append the text editor upon showing it in the screen, i.e. lazily. Now it is appended right away. Why did you change this?

The only problem was TabbedEditorContainer calling show() on its tabs (i.e. sourceFrames, i.e. textEditors) even when itself wasn't showing. I fixed this by making TabbedPane lazy with its Views: Now, nobody calls sourceFrame.show() or textEditor.show() in an "unlazy fashion". Does that solve the problem?
Comment 14 Jan Keromnes 2012-08-14 17:32:35 PDT
Comment on attachment 158447 [details]
Patch

The TabbedPane change doesn't work.
Comment 15 Jan Keromnes 2012-08-14 18:15:40 PDT
Created attachment 158469 [details]
Patch
Comment 16 Pavel Feldman 2012-08-14 23:45:00 PDT
Comment on attachment 158469 [details]
Patch

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

> Source/WebCore/inspector/front-end/SourceFrame.js:-39
> -    this.element.addStyleClass("script-view");

You should remove the corresponding css definition.

> Source/WebCore/inspector/front-end/SourceFrame.js:-98
> -        this._textEditor.show(this.element);

I guess you should either refactor View.js (see below) or preserve the original behavior (store parent from show and use it in here).

> Source/WebCore/inspector/front-end/TabbedPane.js:461
> +        if (this.isShowing())

This kind of change should be done in the View.js once for all view containers, no need to specifically fix it for TabbedPane.
Comment 17 Pavel Feldman 2012-08-16 23:09:19 PDT
Comment on attachment 158469 [details]
Patch

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

>> Source/WebCore/inspector/front-end/TabbedPane.js:461
>> +        if (this.isShowing())
> 
> This kind of change should be done in the View.js once for all view containers, no need to specifically fix it for TabbedPane.

i did not realize that the laziness that was there was already mitigated by the view subsystem
earlier in the day, everything was in the dom at all times
so that laziness made sense. Then i added this view subsystem and it saved us a lot of time. I did not realize it was covering this case as well, sorry.

I think this part can be simply reverted.
Comment 18 Jan Keromnes 2012-08-17 00:04:38 PDT
Created attachment 159016 [details]
Patch
Comment 19 WebKit Review Bot 2012-08-17 04:42:24 PDT
Comment on attachment 159016 [details]
Patch

Clearing flags on attachment: 159016

Committed r125880: <http://trac.webkit.org/changeset/125880>
Comment 20 WebKit Review Bot 2012-08-17 04:42:30 PDT
All reviewed patches have been landed.  Closing bug.
Comment 21 WebKit Review Bot 2012-08-17 07:18:29 PDT
Re-opened since this is blocked by 94347
Comment 22 johnjbarton 2012-08-20 16:43:29 PDT
Jan has returned to his studies.

This change was reverted because the compile fails:
-------------
Source/WebCore/inspector/front-end/TabbedEditorContainer.js:279: WARNING - actual parameter 3 of WebInspector.TabbedPane.prototype.appendTab does not match formal parameter
found   : (WebInspector.SourceFrame|null)
required: (WebInspector.View|null)
        this._tabbedPane.appendTab(tabId, title, view, tooltip, userGesture);
                                                 ^

Source/WebCore/inspector/front-end/TabbedEditorContainer.js:338: WARNING - actual parameter 2 of WebInspector.TabbedPane.prototype.changeTabView does not match formal parameter
found   : (WebInspector.SourceFrame|null)
required: (WebInspector.View|null)
        this._tabbedPane.changeTabView(tabId, this._delegate.viewForFile(uiSourceCode));
-------------

However all of the tests pass. This means that SourceFrame is adequate for the Tab 'view' API.

In particular TabbedPaneTab, a private class of TabbedPane, has a 'view' property that needs to support methods:
  .detach(), .show(), SourceFrame delegates to TextEditor
  .highlightLine(), .canHighlightLine() SourceFrame implements

The tab.view is also is exported by two events, TabClosed and TabSelected. However if that field is removed from the event.data all tests pass.

Finally TabbedPane has a .visibleView which exports the TabbedPaneTab.view. In TabbedEditorContainer it is called:
   .defaultFocusedElement(), SourceFrame delegates to TextEditor

But .visibleView is called by many other places. I guess that clients of .visibleView either rely on only the methods listed above, or they rely on knowing that they alone supply the .view value and thus can operate on it correctly. (ie, the 'view' objects are not mixed across containers so code that inserts knows the contained object type).

The correct solution to the compile failures depends upon the plan for SourceFrame. Is it still in flux? Suggestions?
Comment 23 Pavel Feldman 2012-08-21 00:00:46 PDT
> 
> However all of the tests pass. This means that SourceFrame is adequate for the Tab 'view' API.
> 

When compilation fails and the tests pass that rather means that we have poor test coverage.

> In particular TabbedPaneTab, a private class of TabbedPane, has a 'view' property that needs to support methods:
>   .detach(), .show(), SourceFrame delegates to TextEditor
>   .highlightLine(), .canHighlightLine() SourceFrame implements
>

It is a 'view' property that is annotate with the type WebInspector.View.

> The correct solution to the compile failures depends upon the plan for SourceFrame. Is it still in flux? Suggestions?

Well, no matter what the plans for SourceFrame are, this patch is wrong. Instead of passing SourceFrame into all of these TabbedPane methods, Jan should have passed SourceFrame's view explicitly. I.e. instead of wrapping View's methods and faking a view, we should introduce view: function() {} in SourceFrame and use it where appropriate.
Comment 24 johnjbarton 2012-08-21 09:24:51 PDT
(In reply to comment #23)
> > 
> > However all of the tests pass. This means that SourceFrame is adequate for the Tab 'view' API.
> > 
> 
> When compilation fails and the tests pass that rather means that we have poor test coverage.

Isn't it also possible that the annotations are incomplete?

> 
> > In particular TabbedPaneTab, a private class of TabbedPane, has a 'view' property that needs to support methods:
> >   .detach(), .show(), SourceFrame delegates to TextEditor
> >   .highlightLine(), .canHighlightLine() SourceFrame implements
> >
> 
> It is a 'view' property that is annotate with the type WebInspector.View.

Yes, but the annotation is not completely correct. TabbedPaneTab will 
work with a View but it will also work with an object with a subset of the
View API. In particular the client of TabbedPaneTab need not have an element even though View does have an element.

> 
> > The correct solution to the compile failures depends upon the plan for SourceFrame. Is it still in flux? Suggestions?
> 
> Well, no matter what the plans for SourceFrame are, this patch is wrong. Instead of passing SourceFrame into all of these TabbedPane methods, Jan should have passed SourceFrame's view explicitly. I.e. instead of wrapping View's methods and faking a view, we should introduce view: function() {} in SourceFrame and use it where appropriate.

But what object will this function return? It can't be the underlying TextEditor (which is a View) because that object does not currently implement all of the View methods as required by SourceFrame.

If further changes to SourceFrame will cause TextEditor to absorb the SourceFrame's View implementations, then we can make those changes and solve this bug. 

If further changes to SourceFrame aren't planned, then we could create a new API object, eg TabbedPaneTabDelegate, to allow an object like SourceFrame to be placed in the TabbedPane.

These are quite different directions and perhaps not the only two.