⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 248753 in webkit


Ignore:
Timestamp:
Aug 15, 2019, 5:43:11 PM (7 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Sources: provide a way to create an arbitrary Inspector Style Sheet
https://bugs.webkit.org/show_bug.cgi?id=200425

Reviewed by Joseph Pecoraro.

Source/WebInspectorUI:

Right now, the only way to create an Inspector Style Sheet is by creating a new rule in the
Styles sidebar of the Elements Tab. This is unnecessarily restrictive, especially for those
who don't use the Elements tab.

Add a + button after the filter bar in the Navigation sidebar. Clicking on the + button will
show a menu with the following (more likely to be added later):

  • Inspector Style Sheet
  • Frames (if there are subframes)
    • (name of subframe)
      • Inspector Style Sheet
  • UserInterface/Views/SourcesNavigationSidebarPanel.js:

(WI.SourcesNavigationSidebarPanel):
(WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject): Added.
(WI.SourcesNavigationSidebarPanel.prototype._filterByResourcesWithIssues): Added.
(WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
(WI.SourcesNavigationSidebarPanel.prototype._updateMainFrameTreeElement):
(WI.SourcesNavigationSidebarPanel.prototype._addResource):
(WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
(WI.SourcesNavigationSidebarPanel.prototype._populateCreateResourceContextMenu): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeChanged):
(WI.SourcesNavigationSidebarPanel.prototype._handleFrameWasAdded): Added.
(WI.SourcesNavigationSidebarPanel.prototype._handleMainFrameDidChange): Deleted.

  • UserInterface/Views/GeneralTreeElement.js:

(WI.GeneralTreeElement.prototype.createFoldersAsNeededForSubpath):
Drive-by: sort WI.ResourceTreeElements alongside WI.FolderTreeElements for easier readability.

  • UserInterface/Views/FrameTreeElement.js:

(WI.FrameTreeElement.prototype.onpopulate):
Add all inspectorStyleSheetsForFrame instead of just the preferred one so that they all
are visible/selectable for editing.

  • UserInterface/Views/FilterBar.js:

(WI.FilterBar):

  • UserInterface/Views/FilterBar.css:

(.filter-bar > .navigation-bar > .item):
(.filter-bar > input[type="search"]):
(.filter-bar > .navigation-bar + input[type="search"]): Added.
(.filter-bar > input[type="search"] + .navigation-bar:empty): Added.
Move the position of the filter bar buttons to be after the filter bar itself, so that other
parents can add action items before the filter bar to keep a consistent positioning.

  • to the left of the filter bar are action items (e.g. "+")
  • the filter bar itself
  • to the right of the filter bar are filter buttons (e.g. "filter by resoure with issue")
  • UserInterface/Controllers/NetworkManager.js:

(WI.NetworkManager.prototype.get frames):
Drive-by: use Array.from, instead of [...map.values()].

  • UserInterface/Models/Frame.js:

(WI.Frame.prototype.get url):
(WI.Frame.prototype.get urlComponents): Added.

  • UserInterface/Base/URLUtilities.js.js:

(parseURL):
Calculate and include the origin string with the output.

  • UserInterface/Controllers/CSSManager.js:

(WI.CSSManager.prototype.preferredInspectorStyleSheetForFrame):
Remove doNotCreateIfMissing now that the last caller has been removed.

  • Localizations/en.lproj/localizedStrings.js:

LayoutTests:

  • inspector/unit-tests/url-utilities.html:
  • inspector/unit-tests/url-utilities-expected.txt:
Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r248752 r248753  
     12019-08-15  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Sources: provide a way to create an arbitrary Inspector Style Sheet
     4        https://bugs.webkit.org/show_bug.cgi?id=200425
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        * inspector/unit-tests/url-utilities.html:
     9        * inspector/unit-tests/url-utilities-expected.txt:
     10
    1112019-08-15  Wenson Hsieh  <wenson_hsieh@apple.com>
    212
  • trunk/LayoutTests/inspector/unit-tests/url-utilities-expected.txt

    r246559 r248753  
    1616PASS: host should be: 'example.com'
    1717PASS: port should be: 'null'
     18PASS: origin should be: 'http://example.com'
    1819PASS: path should be: 'null'
    1920PASS: queryString should be: 'null'
     
    2627PASS: host should be: 'example.com'
    2728PASS: port should be: 'null'
     29PASS: origin should be: 'http://example.com'
    2830PASS: path should be: '/'
    2931PASS: queryString should be: 'null'
     
    3638PASS: host should be: 'example.com'
    3739PASS: port should be: '80'
     40PASS: origin should be: 'http://example.com:80'
    3841PASS: path should be: '/'
    3942PASS: queryString should be: 'null'
     
    4649PASS: host should be: 'example.com'
    4750PASS: port should be: 'null'
     51PASS: origin should be: 'http://example.com'
    4852PASS: path should be: '/path/to/page.html'
    4953PASS: queryString should be: 'null'
     
    5660PASS: host should be: 'example.com'
    5761PASS: port should be: 'null'
     62PASS: origin should be: 'http://example.com'
    5863PASS: path should be: '/path/to/page.html'
    5964PASS: queryString should be: ''
     
    6671PASS: host should be: 'example.com'
    6772PASS: port should be: 'null'
     73PASS: origin should be: 'http://example.com'
    6874PASS: path should be: '/path/to/page.html'
    6975PASS: queryString should be: 'a=1'
     
    7682PASS: host should be: 'example.com'
    7783PASS: port should be: 'null'
     84PASS: origin should be: 'http://example.com'
    7885PASS: path should be: '/path/to/page.html'
    7986PASS: queryString should be: 'a=1&b=2'
     
    8693PASS: host should be: 'example.com'
    8794PASS: port should be: 'null'
     95PASS: origin should be: 'http://example.com'
    8896PASS: path should be: '/path/to/page.html'
    8997PASS: queryString should be: 'a=1&b=2'
     
    96104PASS: host should be: 'example.com'
    97105PASS: port should be: '123'
     106PASS: origin should be: 'http://example.com:123'
    98107PASS: path should be: '/path/to/page.html'
    99108PASS: queryString should be: 'a=1&b=2'
     
    106115PASS: host should be: 'example.com'
    107116PASS: port should be: 'null'
     117PASS: origin should be: 'http://example.com'
    108118PASS: path should be: '/path/to/page.html'
    109119PASS: queryString should be: 'null'
     
    116126PASS: host should be: 'example.com'
    117127PASS: port should be: 'null'
     128PASS: origin should be: 'http://example.com'
    118129PASS: path should be: 'null'
    119130PASS: queryString should be: 'null'
     
    126137PASS: host should be: 'example.com'
    127138PASS: port should be: 'null'
     139PASS: origin should be: 'app-specific://example.com'
    128140PASS: path should be: 'null'
    129141PASS: queryString should be: 'null'
     
    136148PASS: host should be: 'example'
    137149PASS: port should be: 'null'
     150PASS: origin should be: 'http://example'
    138151PASS: path should be: 'null'
    139152PASS: queryString should be: 'null'
     
    146159PASS: host should be: 'my.example.com'
    147160PASS: port should be: 'null'
     161PASS: origin should be: 'http://my.example.com'
    148162PASS: path should be: 'null'
    149163PASS: queryString should be: 'null'
     
    156170PASS: host should be: 'null'
    157171PASS: port should be: 'null'
     172PASS: origin should be: 'null'
    158173PASS: path should be: 'null'
    159174PASS: queryString should be: 'null'
     
    184199    Actual: null
    185200PASS: port should be: 'null'
     201FAIL: origin should be: 'http://example.com'
     202    Expected: "http://example.com"
     203    Actual: null
    186204FAIL: path should be: '/'
    187205    Expected: "/"
     
    200218    Actual: null
    201219PASS: port should be: 'null'
     220FAIL: origin should be: 'http://example.com'
     221    Expected: "http://example.com"
     222    Actual: null
    202223FAIL: path should be: '/'
    203224    Expected: "/"
     
    212233PASS: host should be: 'example.com'
    213234PASS: port should be: 'null'
     235PASS: origin should be: 'http://example.com'
    214236PASS: path should be: '/'
    215237PASS: queryString should be: 'null'
     
    226248    Actual: null
    227249PASS: port should be: 'null'
     250FAIL: origin should be: 'http://example.com'
     251    Expected: "http://example.com"
     252    Actual: null
    228253FAIL: path should be: '/'
    229254    Expected: "/"
     
    240265    Actual: "example.com?key=alpha"
    241266PASS: port should be: 'null'
     267FAIL: origin should be: 'http://example.com'
     268    Expected: "http://example.com"
     269    Actual: "http://example.com?key=alpha"
    242270FAIL: path should be: 'null'
    243271    Expected: null
     
    351379PASS: The query 'a&b=1&c==2=&d&e=3&f==4=' was parsed successfully.
    352380PASS: The query 'a=foo%20bar&b=123%3A456' was parsed successfully.
     381
     382-- Running test case: WI.displayNameForURL
     383PASS: Display name of 'a' should be 'a'.
     384PASS: Display name of 'http://' should be 'http://'.
     385PASS: Display name of 'http://example' should be 'example'.
     386PASS: Display name of 'http://example.com' should be 'example.com'.
     387PASS: Display name of 'http://example.com/' should be 'example.com'.
     388PASS: Display name of 'http://example.com:999999999' should be 'example.com'.
     389PASS: Display name of 'http://example.com:80/' should be 'example.com'.
     390PASS: Display name of 'http://example.com/path' should be 'path'.
     391PASS: Display name of 'http://example.com/path/' should be 'path'.
     392PASS: Display name of 'http://example.com/path/to' should be 'to'.
     393PASS: Display name of 'http://example.com/path/to/' should be 'to'.
     394PASS: Display name of 'http://example.com/path/to/page.html' should be 'page.html'.
     395PASS: Display name of 'http://example.com/path/to/page.html?' should be 'page.html'.
     396PASS: Display name of 'http://example.com/path/to/page.html?a=1' should be 'page.html'.
     397PASS: Display name of 'http://example.com/path/to/page.html?a=1&b=2' should be 'page.html'.
     398PASS: Display name of 'http://example.com/path/to/page.html?a=1&b=2#test' should be 'page.html'.
     399PASS: Display name of 'http://example.com:123/path/to/page.html?a=1&b=2#test' should be 'page.html'.
     400PASS: Display name of 'http://example.com/path/to/page.html#test' should be 'page.html'.
     401PASS: Display name of 'http://example.com#alpha/beta' should be 'example.com'.
     402PASS: Display name of 'http://example.com?key=alpha/beta' should be 'beta'.
     403PASS: Display name of 'http://user:pass@example.com/' should be 'example.com'.
     404PASS: Display name of 'http://my.example.com' should be 'my.example.com'.
     405PASS: Display name of 'file://foo/bar' should be 'bar'.
     406PASS: Display name of 'data:text/plain,test' should be 'data:text/plain,test'.
     407PASS: Display name of 'about:blank' should be 'about:blank'.
     408PASS: Display name of 'about:srcdoc' should be 'about:srcdoc'.
     409PASS: Display name of 'app-specific://example.com' should be 'example.com'.
     410
     411Allowing directory as name...
     412PASS: Display name of 'a' should be 'a'.
     413PASS: Display name of 'http://' should be 'http://'.
     414PASS: Display name of 'http://example' should be 'example'.
     415PASS: Display name of 'http://example.com' should be 'example.com'.
     416PASS: Display name of 'http://example.com/' should be '/'.
     417PASS: Display name of 'http://example.com:999999999' should be 'example.com'.
     418PASS: Display name of 'http://example.com:80/' should be '/'.
     419PASS: Display name of 'http://example.com/path' should be 'path'.
     420PASS: Display name of 'http://example.com/path/' should be '/'.
     421PASS: Display name of 'http://example.com/path/to' should be 'to'.
     422PASS: Display name of 'http://example.com/path/to/' should be '/'.
     423PASS: Display name of 'http://example.com/path/to/page.html' should be 'page.html'.
     424PASS: Display name of 'http://example.com/path/to/page.html?' should be 'page.html'.
     425PASS: Display name of 'http://example.com/path/to/page.html?a=1' should be 'page.html'.
     426PASS: Display name of 'http://example.com/path/to/page.html?a=1&b=2' should be 'page.html'.
     427PASS: Display name of 'http://example.com/path/to/page.html?a=1&b=2#test' should be 'page.html'.
     428PASS: Display name of 'http://example.com:123/path/to/page.html?a=1&b=2#test' should be 'page.html'.
     429PASS: Display name of 'http://example.com/path/to/page.html#test' should be 'page.html'.
     430PASS: Display name of 'http://example.com#alpha/beta' should be 'example.com'.
     431PASS: Display name of 'http://example.com?key=alpha/beta' should be 'beta'.
     432PASS: Display name of 'http://user:pass@example.com/' should be '/'.
     433PASS: Display name of 'http://my.example.com' should be 'my.example.com'.
     434PASS: Display name of 'file://foo/bar' should be 'bar'.
     435PASS: Display name of 'data:text/plain,test' should be 'data:text/plain,test'.
     436PASS: Display name of 'about:blank' should be 'about:blank'.
     437PASS: Display name of 'about:srcdoc' should be 'about:srcdoc'.
     438PASS: Display name of 'app-specific://example.com' should be 'example.com'.
    353439
    354440-- Running test case: WI.h2Authority
  • trunk/LayoutTests/inspector/unit-tests/url-utilities.html

    r246559 r248753  
    2828                InspectorTest.log("Test Valid: " + url);
    2929
    30                 let {scheme: expectedScheme, userinfo: expectedUserInfo, host: expectedHost, port: expectedPort, path: expectedPath, queryString: expectedQueryString, fragment: expectedFragment, lastPathComponent: expectedLastPathComponent} = expected;
    31                 let {scheme: actualScheme, userinfo: actualUserInfo, host: actualHost, port: actualPort, path: actualPath, queryString: actualQueryString, fragment: actualFragment, lastPathComponent: actualLastPathComponent} = parseURL(url);
     30                let {scheme: expectedScheme, userinfo: expectedUserInfo, host: expectedHost, port: expectedPort, origin: expectedOrigin, path: expectedPath, queryString: expectedQueryString, fragment: expectedFragment, lastPathComponent: expectedLastPathComponent} = expected;
     31                let {scheme: actualScheme, userinfo: actualUserInfo, host: actualHost, port: actualPort, origin: actualOrigin, path: actualPath, queryString: actualQueryString, fragment: actualFragment, lastPathComponent: actualLastPathComponent} = parseURL(url);
    3232
    3333                InspectorTest.expectEqual(actualScheme, expectedScheme, `scheme should be: '${expectedScheme}'`);
     
    3535                InspectorTest.expectEqual(actualHost, expectedHost, `host should be: '${expectedHost}'`);
    3636                InspectorTest.expectEqual(actualPort, expectedPort, `port should be: '${expectedPort}'`);
     37                InspectorTest.expectEqual(actualOrigin, expectedOrigin, `origin should be: '${expectedOrigin}'`);
    3738                InspectorTest.expectEqual(actualPath, expectedPath, `path should be: '${expectedPath}'`);
    3839                InspectorTest.expectEqual(actualQueryString, expectedQueryString, `queryString should be: '${expectedQueryString}'`);
     
    4950                host: "example.com",
    5051                port: null,
     52                origin: "http://example.com",
    5153                path: null,
    5254                queryString: null,
     
    6062                host: "example.com",
    6163                port: null,
     64                origin: "http://example.com",
    6265                path: "/",
    6366                queryString: null,
     
    7174                host: "example.com",
    7275                port: 80,
     76                origin: "http://example.com:80",
    7377                path: "/",
    7478                queryString: null,
     
    8286                host: "example.com",
    8387                port: null,
     88                origin: "http://example.com",
    8489                path: "/path/to/page.html",
    8590                queryString: null,
     
    9398                host: "example.com",
    9499                port: null,
     100                origin: "http://example.com",
    95101                path: "/path/to/page.html",
    96102                queryString: "",
     
    104110                host: "example.com",
    105111                port: null,
     112                origin: "http://example.com",
    106113                path: "/path/to/page.html",
    107114                queryString: "a=1",
     
    115122                host: "example.com",
    116123                port: null,
     124                origin: "http://example.com",
    117125                path: "/path/to/page.html",
    118126                queryString: "a=1&b=2",
     
    126134                host: "example.com",
    127135                port: null,
     136                origin: "http://example.com",
    128137                path: "/path/to/page.html",
    129138                queryString: "a=1&b=2",
     
    137146                host: "example.com",
    138147                port: 123,
     148                origin: "http://example.com:123",
    139149                path: "/path/to/page.html",
    140150                queryString: "a=1&b=2",
     
    148158                host: "example.com",
    149159                port: null,
     160                origin: "http://example.com",
    150161                path: "/path/to/page.html",
    151162                queryString: null,
     
    159170                host: "example.com",
    160171                port: null,
     172                origin: "http://example.com",
    161173                path: null,
    162174                queryString: null,
     
    170182                host: "example.com",
    171183                port: null,
     184                origin: "app-specific://example.com",
    172185                path: null,
    173186                queryString: null,
     
    181194                host: "example",
    182195                port: null,
     196                origin: "http://example",
    183197                path: null,
    184198                queryString: null,
     
    192206                host: "my.example.com",
    193207                port: null,
     208                origin: "http://my.example.com",
    194209                path: null,
    195210                queryString: null,
     
    204219                host: null,
    205220                port: null,
     221                origin: null,
    206222                path: null,
    207223                queryString: null,
     
    222238                host: "example.com",
    223239                port: null,
     240                origin: "http://example.com",
    224241                path: "/",
    225242                queryString: null,
     
    233250                host: "example.com",
    234251                port: null,
     252                origin: "http://example.com",
    235253                path: "/",
    236254                queryString: null,
     
    244262                host: "example.com",
    245263                port: null,
     264                origin: "http://example.com",
    246265                path: "/",
    247266                queryString: null,
     
    255274                host: "example.com",
    256275                port: null,
     276                origin: "http://example.com",
    257277                path: "/",
    258278                queryString: null,
     
    266286                host: "example.com",
    267287                port: null,
     288                origin: "http://example.com",
    268289                path: null,
    269290                queryString: "key=alpha/beta",
     
    420441
    421442    suite.addTestCase({
     443        name: "WI.displayNameForURL",
     444        test() {
     445            const tests = [
     446                {url: "a", expected: "a"},
     447                {url: "http://", expected: "http://"},
     448                {url: "http://example", expected: "example"},
     449                {url: "http://example.com", expected: "example.com"},
     450                {url: "http://example.com/", expected: "example.com", directory: "/"},
     451                {url: "http://example.com:999999999", expected: "example.com"},
     452                {url: "http://example.com:80/", expected: "example.com", directory: "/"},
     453                {url: "http://example.com/path", expected: "path"},
     454                {url: "http://example.com/path/", expected: "path", directory: "/"},
     455                {url: "http://example.com/path/to", expected: "to"},
     456                {url: "http://example.com/path/to/", expected: "to", directory: "/"},
     457                {url: "http://example.com/path/to/page.html", expected: "page.html"},
     458                {url: "http://example.com/path/to/page.html?", expected: "page.html"},
     459                {url: "http://example.com/path/to/page.html?a=1", expected: "page.html"},
     460                {url: "http://example.com/path/to/page.html?a=1&b=2", expected: "page.html"},
     461                {url: "http://example.com/path/to/page.html?a=1&b=2#test", expected: "page.html"},
     462                {url: "http://example.com:123/path/to/page.html?a=1&b=2#test", expected: "page.html"},
     463                {url: "http://example.com/path/to/page.html#test", expected: "page.html"},
     464                {url: "http://example.com#alpha/beta", expected: "example.com"},
     465                {url: "http://example.com?key=alpha/beta", expected: "beta"},
     466                {url: "http://user:pass@example.com/", expected: "example.com", directory: "/"},
     467                {url: "http://my.example.com", expected: "my.example.com"},
     468                {url: "file://foo/bar", expected: "bar"},
     469                {url: "data:text/plain,test", expected: "data:text/plain,test"},
     470                {url: "about:blank", expected: "about:blank"},
     471                {url: "about:srcdoc", expected: "about:srcdoc"},
     472                {url: "app-specific://example.com", expected: "example.com"},
     473            ];
     474
     475            for (let {url, expected} of tests)
     476                InspectorTest.expectEqual(WI.displayNameForURL(url), expected, `Display name of '${url}' should be '${expected}'.`);
     477
     478            InspectorTest.newline();
     479
     480            InspectorTest.log("Allowing directory as name...");
     481            for (let {url, expected, directory} of tests)
     482                InspectorTest.expectEqual(WI.displayNameForURL(url, null, {allowDirectoryAsName: true}), directory || expected, `Display name of '${url}' should be '${directory || expected}'.`);
     483        },
     484    });
     485
     486    suite.addTestCase({
    422487        name: "WI.h2Authority",
    423488        test() {
  • trunk/Source/WebInspectorUI/ChangeLog

    r248739 r248753  
     12019-08-15  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Sources: provide a way to create an arbitrary Inspector Style Sheet
     4        https://bugs.webkit.org/show_bug.cgi?id=200425
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Right now, the only way to create an Inspector Style Sheet is by creating a new rule in the
     9        Styles sidebar of the Elements Tab. This is unnecessarily restrictive, especially for those
     10        who don't use the Elements tab.
     11
     12        Add a + button after the filter bar in the Navigation sidebar. Clicking on the + button will
     13        show a menu with the following (more likely to be added later):
     14         - Inspector Style Sheet
     15         - Frames (if there are subframes)
     16           - (name of subframe)
     17              - Inspector Style Sheet
     18
     19        * UserInterface/Views/SourcesNavigationSidebarPanel.js:
     20        (WI.SourcesNavigationSidebarPanel):
     21        (WI.SourcesNavigationSidebarPanel.prototype.treeElementForRepresentedObject): Added.
     22        (WI.SourcesNavigationSidebarPanel.prototype._filterByResourcesWithIssues): Added.
     23        (WI.SourcesNavigationSidebarPanel.prototype._compareTreeElements):
     24        (WI.SourcesNavigationSidebarPanel.prototype._updateMainFrameTreeElement):
     25        (WI.SourcesNavigationSidebarPanel.prototype._addResource):
     26        (WI.SourcesNavigationSidebarPanel.prototype._handleTreeSelectionDidChange):
     27        (WI.SourcesNavigationSidebarPanel.prototype._populateCreateResourceContextMenu): Added.
     28        (WI.SourcesNavigationSidebarPanel.prototype._handleResourceGroupingModeChanged):
     29        (WI.SourcesNavigationSidebarPanel.prototype._handleFrameWasAdded): Added.
     30        (WI.SourcesNavigationSidebarPanel.prototype._handleMainFrameDidChange): Deleted.
     31        * UserInterface/Views/GeneralTreeElement.js:
     32        (WI.GeneralTreeElement.prototype.createFoldersAsNeededForSubpath):
     33        Drive-by: sort `WI.ResourceTreeElement`s alongside `WI.FolderTreeElement`s for easier readability.
     34
     35        * UserInterface/Views/FrameTreeElement.js:
     36        (WI.FrameTreeElement.prototype.onpopulate):
     37        Add all `inspectorStyleSheetsForFrame` instead of just the preferred one so that they all
     38        are visible/selectable for editing.
     39
     40        * UserInterface/Views/FilterBar.js:
     41        (WI.FilterBar):
     42        * UserInterface/Views/FilterBar.css:
     43        (.filter-bar > .navigation-bar > .item):
     44        (.filter-bar > input[type="search"]):
     45        (.filter-bar > .navigation-bar + input[type="search"]): Added.
     46        (.filter-bar > input[type="search"] + .navigation-bar:empty): Added.
     47        Move the position of the filter bar buttons to be after the filter bar itself, so that other
     48        parents can add action items before the filter bar to keep a consistent positioning.
     49         - to the left of the filter bar are action items (e.g. "+")
     50         - the filter bar itself
     51         - to the right of the filter bar are filter buttons (e.g. "filter by resoure with issue")
     52
     53        * UserInterface/Controllers/NetworkManager.js:
     54        (WI.NetworkManager.prototype.get frames):
     55        Drive-by: use `Array.from`, instead of `[...map.values()]`.
     56
     57        * UserInterface/Models/Frame.js:
     58        (WI.Frame.prototype.get url):
     59        (WI.Frame.prototype.get urlComponents): Added.
     60
     61        * UserInterface/Base/URLUtilities.js.js:
     62        (parseURL):
     63        Calculate and include the `origin` string with the output.
     64
     65        * UserInterface/Controllers/CSSManager.js:
     66        (WI.CSSManager.prototype.preferredInspectorStyleSheetForFrame):
     67        Remove `doNotCreateIfMissing` now that the last caller has been removed.
     68
     69        * Localizations/en.lproj/localizedStrings.js:
     70
    1712019-08-15  Devin Rousso  <drousso@apple.com>
    272
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r248485 r248753  
    301301localizedStrings["Create %s Rule"] = "Create %s Rule";
    302302localizedStrings["Create Breakpoint"] = "Create Breakpoint";
     303localizedStrings["Create Resource"] = "Create Resource";
    303304localizedStrings["Create a new tab"] = "Create a new tab";
    304305localizedStrings["Cross-Origin Restrictions"] = "Cross-Origin Restrictions";
  • trunk/Source/WebInspectorUI/UserInterface/Base/URLUtilities.js

    r246559 r248753  
    9797
    9898    if (url.startsWith("data:"))
    99         return {scheme: "data", userinfo: null, host: null, port: null, path: null, queryString: null, fragment: null, lastPathComponent: null};
     99        return {scheme: "data", userinfo: null, host: null, port: null, origin: null, path: null, queryString: null, fragment: null, lastPathComponent: null};
    100100
    101101    let match = url.match(/^(?<scheme>[^\/:]+):\/\/(?:(?<userinfo>[^#@\/]+)@)?(?<host>[^\/#:]*)(?::(?<port>[\d]+))?(?:(?<path>\/[^#]*)?(?:#(?<fragment>.*))?)?$/i);
    102102    if (!match)
    103         return {scheme: null, userinfo: null, host: null, port: null, path: null, queryString: null, fragment: null, lastPathComponent: null};
     103        return {scheme: null, userinfo: null, host: null, port: null, origin: null, path: null, queryString: null, fragment: null, lastPathComponent: null};
    104104
    105105    let scheme = match.groups.scheme.toLowerCase();
     
    132132    }
    133133
    134     return {scheme, userinfo, host, port, path, queryString, fragment, lastPathComponent};
     134    let origin = null;
     135    if (scheme && host) {
     136        origin = scheme + "://" + host;
     137        if (port)
     138            origin += ":" + port;
     139    }
     140
     141    return {scheme, userinfo, host, port, origin, path, queryString, fragment, lastPathComponent};
    135142}
    136143
     
    235242    }
    236243
    237     if (options.allowDirectoryAsName && (!displayName || urlComponents.path.endsWith(displayName + "/")))
     244    if (options.allowDirectoryAsName && (urlComponents.path === "/" || (displayName && urlComponents.path.endsWith(displayName + "/"))))
    238245        displayName = "/";
    239246
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js

    r248602 r248753  
    306306    }
    307307
    308     preferredInspectorStyleSheetForFrame(frame, callback, doNotCreateIfMissing)
     308    preferredInspectorStyleSheetForFrame(frame, callback)
    309309    {
    310310        var inspectorStyleSheets = this.inspectorStyleSheetsForFrame(frame);
     
    315315            }
    316316        }
    317 
    318         if (doNotCreateIfMissing)
    319             return;
    320317
    321318        if (CSSAgent.createStyleSheet) {
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js

    r248536 r248753  
    114114    get frames()
    115115    {
    116         return [...this._frameIdentifierMap.values()];
     116        return Array.from(this._frameIdentifierMap.values());
    117117    }
    118118
  • trunk/Source/WebInspectorUI/UserInterface/Models/Frame.js

    r248497 r248753  
    188188    get url()
    189189    {
    190         return this._mainResource._url;
     190        return this._mainResource.url;
     191    }
     192
     193    get urlComponents()
     194    {
     195        return this._mainResource.urlComponents;
    191196    }
    192197
  • trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.css

    r242768 r248753  
    4141.filter-bar > .navigation-bar > .item {
    4242    padding: 0 0 3px;
    43     -webkit-padding-start: 8px;
    4443}
    4544
     
    4948    min-width: 0;
    5049
    51     margin: 3px 6px 4px;
     50    margin: 3px 0 4px;
     51    -webkit-margin-start: 6px;
    5252    padding-top: 0;
    5353
     
    6262
    6363    height: 22px;
     64}
     65
     66.filter-bar > .navigation-bar + input[type="search"] {
     67    -webkit-margin-start: 0;
    6468}
    6569
     
    97101    animation-timing-function: step-start;
    98102}
     103
     104.filter-bar > input[type="search"] + .navigation-bar:empty {
     105    -webkit-margin-start: 6px;
     106}
  • trunk/Source/WebInspectorUI/UserInterface/Views/FilterBar.js

    r248198 r248753  
    3333        this._element.classList.add("filter-bar");
    3434
    35         this._filtersNavigationBar = new WI.NavigationBar;
    36         this._element.appendChild(this._filtersNavigationBar.element);
    37 
    3835        this._filterFunctionsMap = new Map;
    3936
     
    4744        this._element.appendChild(this._inputField);
    4845
     46        this._filtersNavigationBar = new WI.NavigationBar;
     47        this._element.appendChild(this._filtersNavigationBar.element);
     48
    4949        this._lastFilterValue = this.filters;
    5050    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js

    r236885 r248753  
    179179        }
    180180
    181         const doNotCreateIfMissing = true;
    182         WI.cssManager.preferredInspectorStyleSheetForFrame(this._frame, this.addRepresentedObjectToNewChildQueue.bind(this), doNotCreateIfMissing);
     181        for (let styleSheet of WI.cssManager.inspectorStyleSheetsForFrame(this._frame))
     182            this.addChildForRepresentedObject(styleSheet);
    183183    }
    184184
  • trunk/Source/WebInspectorUI/UserInterface/Views/GeneralTreeElement.js

    r243300 r248753  
    192192    }
    193193
    194     createFoldersAsNeededForSubpath(subpath)
     194    createFoldersAsNeededForSubpath(subpath, comparator)
    195195    {
    196196        if (!subpath)
     
    224224            this._subpathFolderTreeElementMap.set(currentPath, newFolder);
    225225
    226             let index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
     226            let index = insertionIndexForObjectInListSortedByFunction(newFolder, currentFolderTreeElement.children, comparator || WI.ResourceTreeElement.compareFolderAndResourceTreeElements);
    227227            currentFolderTreeElement.insertChild(newFolder, index);
    228228            currentFolderTreeElement = newFolder;
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourcesNavigationSidebarPanel.js

    r248737 r248753  
    243243        resourcesContainer.appendChild(this._resourcesTreeOutline.element);
    244244
    245         let onlyShowResourcesWithIssuesFilterFunction = (treeElement) => {
    246             if (treeElement.treeOutline !== this._resourcesTreeOutline)
    247                 return true;
    248 
    249             if (treeElement instanceof WI.IssueTreeElement)
    250                 return true;
    251 
    252             if (treeElement.hasChildren) {
    253                 for (let child of treeElement.children) {
    254                     if (child instanceof WI.IssueTreeElement)
    255                         return true;
    256                 }
    257             }
    258             return false;
    259         };
     245        if (InspectorBackend.domains.CSS) {
     246            let createResourceNavigationBar = new WI.NavigationBar;
     247
     248            let createResourceButtonNavigationItem = new WI.ButtonNavigationItem("create-resource", WI.UIString("Create Resource"), "Images/Plus15.svg", 15, 15);
     249            WI.addMouseDownContextMenuHandlers(createResourceButtonNavigationItem.element, this._populateCreateResourceContextMenu.bind(this));
     250            createResourceNavigationBar.addNavigationItem(createResourceButtonNavigationItem);
     251
     252            this.filterBar.element.insertBefore(createResourceNavigationBar.element, this.filterBar.element.firstChild);
     253        }
     254
    260255        const activatedByDefault = false;
    261         this.filterBar.addFilterBarButton("sources-only-show-resources-with-issues", onlyShowResourcesWithIssuesFilterFunction, activatedByDefault, WI.UIString("Only show resources with issues"), WI.UIString("Show all resources"), "Images/Errors.svg", 15, 15);
     256        this.filterBar.addFilterBarButton("sources-only-show-resources-with-issues", this._filterByResourcesWithIssues.bind(this), activatedByDefault, WI.UIString("Only show resources with issues"), WI.UIString("Show all resources"), "Images/Errors.svg", 15, 15);
    262257
    263258        WI.settings.resourceGroupingMode.addEventListener(WI.Setting.Event.Changed, this._handleResourceGroupingModeChanged, this);
     
    267262        WI.Target.addEventListener(WI.Target.Event.ResourceAdded, this._handleResourceAdded, this);
    268263
    269         WI.networkManager.addEventListener(WI.NetworkManager.Event.MainFrameDidChange, this._handleMainFrameDidChange, this);
     264        WI.networkManager.addEventListener(WI.NetworkManager.Event.FrameWasAdded, this._handleFrameWasAdded, this);
    270265
    271266        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.BreakpointAdded, this._handleDebuggerBreakpointAdded, this);
     
    430425        }
    431426
    432         if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
    433             representedObject = representedObject.parentFrame;
     427        switch (WI.settings.resourceGroupingMode.value) {
     428        case WI.Resource.GroupingMode.Path:
     429            if (representedObject instanceof WI.Frame)
     430                representedObject = representedObject.mainResource;
     431            break;
     432
     433        default:
     434            WI.reportInternalError("Unknown resource grouping mode", {"Resource Grouping Mode": WI.settings.resourceGroupingMode.value});
     435            // Fallthrough for default value.
     436
     437        case WI.Resource.GroupingMode.Type:
     438            if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
     439                representedObject = representedObject.parentFrame;
     440            break;
     441        }
    434442
    435443        function isAncestor(ancestor, resourceOrFrame) {
     
    598606    // Private
    599607
     608    _filterByResourcesWithIssues(treeElement)
     609    {
     610        if (treeElement.treeOutline !== this._resourcesTreeOutline)
     611            return true;
     612
     613        if (treeElement instanceof WI.IssueTreeElement)
     614            return true;
     615
     616        if (treeElement.hasChildren) {
     617            for (let child of treeElement.children) {
     618                if (child instanceof WI.IssueTreeElement)
     619                    return true;
     620            }
     621        }
     622        return false;
     623    }
     624
    600625    _compareTreeElements(a, b)
    601626    {
     
    605630            (treeElement) => treeElement instanceof WI.FrameTreeElement,
    606631            (treeElement) => {
    607                 return treeElement instanceof WI.FolderTreeElement
    608                     && treeElement !== this._extensionScriptsFolderTreeElement
     632                return treeElement !== this._extensionScriptsFolderTreeElement
    609633                    && treeElement !== this._extraScriptsFolderTreeElement
    610634                    && treeElement !== this._anonymousScriptsFolderTreeElement;
     
    639663            return;
    640664
    641         let resourceGroupingMode = WI.settings.resourceGroupingMode.value;
    642         switch (resourceGroupingMode) {
    643         case WI.Resource.GroupingMode.Path:
     665        switch (WI.settings.resourceGroupingMode.value) {
     666        case WI.Resource.GroupingMode.Path: {
    644667            for (let treeElement of this._originTreeElementMap.values()) {
    645668                if (treeElement !== oldMainFrameTreeElement)
     
    648671            this._originTreeElementMap.clear();
    649672
    650             this._mainFrameTreeElement = new WI.FolderTreeElement(mainFrame.securityOrigin, mainFrame);
    651             this._originTreeElementMap.set(mainFrame.securityOrigin, this._mainFrameTreeElement);
     673            let origin = mainFrame.urlComponents.origin;
     674            this._mainFrameTreeElement = new WI.FolderTreeElement(origin);
     675            this._originTreeElementMap.set(origin, this._mainFrameTreeElement);
    652676            break;
     677        }
    653678
    654679        default:
     
    712737                return;
    713738
    714             let origin = null;
    715             if (resource.urlComponents.scheme && resource.urlComponents.host) {
    716                 origin = resource.urlComponents.scheme + "://" + resource.urlComponents.host;
    717                 if (resource.urlComponents.port)
    718                     origin += ":" + resource.urlComponents.port;
    719             } else if (resource.parentFrame)
    720                 origin = resource.parentFrame.securityOrigin;
    721 
    722739            let parentTreeElement = null;
    723             if (origin) {
    724                 let frameTreeElement = this._originTreeElementMap.get(origin);
    725                 if (!frameTreeElement) {
    726                     frameTreeElement = new WI.FolderTreeElement(origin, origin === resource.parentFrame.securityOrigin ? resource.parentFrame : null);
    727                     this._originTreeElementMap.set(origin, frameTreeElement);
    728 
    729                     let index = insertionIndexForObjectInListSortedByFunction(frameTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
    730                     this._resourcesTreeOutline.insertChild(frameTreeElement, index);
    731                 }
    732 
    733                 let subpath = resource.urlComponents.path;
    734                 if (subpath && subpath[0] === "/")
    735                     subpath = subpath.substring(1);
    736 
    737                 parentTreeElement = frameTreeElement.createFoldersAsNeededForSubpath(subpath);
    738             } else {
    739                 parentTreeElement = this._resourcesTreeOutline;
     740
     741            if (resource instanceof WI.CSSStyleSheet && resource.isInspectorStyleSheet())
     742                parentTreeElement = this._resourcesTreeOutline.findTreeElement(resource.parentFrame.mainResource);
     743
     744            if (!parentTreeElement) {
     745                let origin = resource.urlComponents.origin;
     746                if (origin) {
     747                    let frameTreeElement = this._originTreeElementMap.get(origin);
     748                    if (!frameTreeElement) {
     749                        frameTreeElement = new WI.FolderTreeElement(origin);
     750                        this._originTreeElementMap.set(origin, frameTreeElement);
     751
     752                        let index = insertionIndexForObjectInListSortedByFunction(frameTreeElement, this._resourcesTreeOutline.children, this._boundCompareTreeElements);
     753                        this._resourcesTreeOutline.insertChild(frameTreeElement, index);
     754                    }
     755
     756                    let subpath = resource.urlComponents.path;
     757                    if (subpath && subpath[0] === "/")
     758                        subpath = subpath.substring(1);
     759
     760                    parentTreeElement = frameTreeElement.createFoldersAsNeededForSubpath(subpath, this._boundCompareTreeElements);
     761                } else
     762                    parentTreeElement = this._resourcesTreeOutline;
    740763            }
    741764
     
    15061529            || treeElement instanceof WI.CSSStyleSheetTreeElement) {
    15071530            let representedObject = treeElement.representedObject;
    1508             if (representedObject instanceof WI.Collection || representedObject instanceof WI.SourceCode)
     1531            if (representedObject instanceof WI.Collection || representedObject instanceof WI.SourceCode || representedObject instanceof WI.Frame)
    15091532                WI.showRepresentedObject(representedObject);
    15101533            return;
     
    16471670    }
    16481671
     1672    _populateCreateResourceContextMenu(contextMenu)
     1673    {
     1674        if (InspectorBackend.domains.CSS) {
     1675            let addInspectorStyleSheetItem = (menu, frame) => {
     1676                menu.appendItem(WI.UIString("Inspector Style Sheet"), () => {
     1677                    if (WI.settings.resourceGroupingMode.value === WI.Resource.GroupingMode.Path) {
     1678                        // Force the parent to populate.
     1679                        let parentFrameTreeElement = this._resourcesTreeOutline.findTreeElement(frame.mainResource);
     1680                        parentFrameTreeElement.reveal();
     1681                        parentFrameTreeElement.expand();
     1682                    }
     1683
     1684                    WI.cssManager.preferredInspectorStyleSheetForFrame(frame, (styleSheet) => {
     1685                        WI.showRepresentedObject(styleSheet);
     1686                    });
     1687                });
     1688            };
     1689
     1690            addInspectorStyleSheetItem(contextMenu, WI.networkManager.mainFrame);
     1691
     1692            let frames = WI.networkManager.frames;
     1693            if (frames.length > 2) {
     1694                let framesSubMenu = contextMenu.appendSubMenuItem(WI.UIString("Frames"));
     1695
     1696                for (let frame of frames) {
     1697                    if (frame === WI.networkManager.mainFrame || frame.mainResource.type !== WI.Resource.Type.Document)
     1698                        continue;
     1699
     1700                    let frameSubMenuItem = framesSubMenu.appendSubMenuItem(frame.name ? WI.UIString("%s (%s)").format(frame.name, frame.mainResource.displayName) : frame.mainResource.displayName);
     1701
     1702                    addInspectorStyleSheetItem(frameSubMenuItem, frame);
     1703                }
     1704            }
     1705        }
     1706    }
     1707
    16491708    _handleResourceGroupingModeChanged(event)
    16501709    {
     
    16631722            this._updateMainFrameTreeElement(mainFrame);
    16641723            this._addResourcesRecursivelyForFrame(mainFrame);
     1724
     1725            for (let frame of WI.networkManager.frames) {
     1726                if (frame !== mainFrame)
     1727                    this._addResourcesRecursivelyForFrame(frame);
     1728            }
    16651729        }
    16661730
     
    16961760    }
    16971761
    1698     _handleMainFrameDidChange(event)
    1699     {
    1700         let mainFrame = WI.networkManager.mainFrame;
    1701         this._updateMainFrameTreeElement(mainFrame);
    1702         this._addResourcesRecursivelyForFrame(mainFrame);
     1762    _handleFrameWasAdded(event)
     1763    {
     1764        let {frame} = event.data;
     1765
     1766        if (frame.isMainFrame())
     1767            this._updateMainFrameTreeElement(frame);
     1768
     1769        this._addResourcesRecursivelyForFrame(frame);
    17031770    }
    17041771
Note: See TracChangeset for help on using the changeset viewer.