Changeset 208091 in webkit


Ignore:
Timestamp:
Oct 28, 2016, 6:17:43 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: Preferences for Text Editor behavior
https://bugs.webkit.org/show_bug.cgi?id=149120

Patch by Devin Rousso <Devin Rousso> on 2016-10-28
Reviewed by Timothy Hatcher.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/Base/Main.js:

(WebInspector.loaded):
(WebInspector.contentLoaded):
(WebInspector.contentLoaded.setTabSize):
(WebInspector.contentLoaded.setInvalidCharacterClassName):
(WebInspector.contentLoaded.setWhitespaceCharacterClassName):
(WebInspector._tryToRestorePendingTabs):
(WebInspector.indentString):
(WebInspector._updateNewTabButtonState): Deleted.
(WebInspector._newTabItemClicked): Deleted.
Removed calls to the New Tab tab bar item on the Tab Bar instance.
Added listener to the indentUnit setting to change the tab-size value on <body>.
Created helper function to generate the indentString value from settings.

  • UserInterface/Base/Test.js:

(WebInspector.indentString):
Assume indent string is " " for tests.

  • UserInterface/Base/Setting.js:

Added global WebInspector.settings dictionary for holding settings with UI editors.

  • UserInterface/Main.html:

Added GeneralTabBarItem, PinnedTabBarItem, and SettingsTabContentView.

  • UserInterface/Models/CSSStyleDeclaration.js:

(WebInspector.CSSStyleDeclaration.prototype.generateCSSRuleString):

  • UserInterface/Views/CSSStyleDeclarationTextEditor.js:

(WebInspector.CSSStyleDeclarationTextEditor.prototype._formattedContentFromEditor):
(WebInspector.CSSStyleDeclarationTextEditor.prototype._resetContent.update):

  • UserInterface/Views/VisualStylePropertyEditor.js:

(WebInspector.VisualStylePropertyEditor.generateFormattedTextForNewProperty):

  • UserInterface/Views/SourceCodeTextEditor.js:

(WebInspector.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
Now uses WebInspector.indentUnit for indentation values

  • UserInterface/Views/CodeMirrorAdditions.js:

Added "showWhitespaceCharacter" option to CodeMirror. When enabled, it adds an overlay to
the editor that will use pseudo-elements to display whitespace characters (unicode 00B7).

  • UserInterface/Views/CodeMirrorOverrides.css:

(.CodeMirror .cm-tab):
(.show-whitespace-characters .CodeMirror .cm-tab::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-1::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-2::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-3::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-4::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-5::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-6::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-7::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-8::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-9::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-10::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-11::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-12::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-13::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-14::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-15::before):
(.show-whitespace-characters .CodeMirror .cm-whitespace-16::before):
(.show-invalid-characters .CodeMirror .cm-invalidchar):
(.CodeMirror .cm-invalidchar): Deleted.
Use unicode character 00B7 (middle dot) to display a space. Also uses a grey border for
visualizing tab characters.

  • UserInterface/Views/ApplicationCacheFrameContentView.js:
  • UserInterface/Views/CSSStyleDeclarationTextEditor.js:
  • UserInterface/Views/ClusterContentView.js:
  • UserInterface/Views/DOMTreeContentView.js:
  • UserInterface/Views/DatabaseContentView.js:
  • UserInterface/Views/IndexedDatabaseObjectStoreContentView.js:
  • UserInterface/Views/NetworkGridContentView.js:
  • UserInterface/Views/ResourceContentView.js:
  • UserInterface/Views/ScriptContentView.js:
  • UserInterface/Views/TabContentView.js:
  • UserInterface/Views/TimelineRecordingContentView.js:

Add calls to super.shown(), super.hidden(), and super.closed().

  • UserInterface/Views/ConsoleTabContentView.js:
  • UserInterface/Views/DebuggerTabContentView.js:
  • UserInterface/Views/ElementsTabContentView.js:
  • UserInterface/Views/NetworkTabContentView.js:
  • UserInterface/Views/NewTabContentView.js:
  • UserInterface/Views/ResourcesTabContentView.js:
  • UserInterface/Views/SearchTabContentView.js:
  • UserInterface/Views/StorageTabContentView.js:
  • UserInterface/Views/TimelineTabContentView.js:

Now uses WebInspector.GeneralTabBarItem.

  • UserInterface/Views/GeneralTabBarItem.js: Added.

(WebInspector.GeneralTabBarItem):
(WebInspector.GeneralTabBarItem.prototype.set title):
(WebInspector.GeneralTabBarItem.prototype._handleContextMenuEvent):
Split from TabBarItem.js to make pinned tab bar items more distinct.

  • UserInterface/Views/Main.css:

(body):
Removed tab-size.

  • UserInterface/Views/PinnedTabBarItem.js: Added.

(WebInspector.PinnedTabBarItem):
Split from TabBarItem.js to make pinned tab bar items more distinct.

  • UserInterface/Views/SettingsTabContentView.css: Added.

(.content-view.settings):
(.content-view.settings > .header):
(.content-view.settings > .setting-container):
(.content-view.settings > .setting-container > .setting-name):
(.content-view.settings > .setting-container > .setting-value-controller):
(.content-view.settings > .setting-container > .setting-value-controller input[type="number"]):

  • UserInterface/Views/SettingsTabContentView.js:

(WebInspector.SettingsTabContentView):
(WebInspector.SettingsTabContentView.tabInfo):
(WebInspector.SettingsTabContentView.isEphemeral):
(WebInspector.SettingsTabContentView.shouldSaveTab):
(WebInspector.SettingsTabContentView.prototype.initialLayout):
(WebInspector.SettingsTabContentView.isTabAllowed): Deleted.
(WebInspector.SettingsTabContentView.prototype.get type): Deleted.
Added logic to display an appropriate editor for each item in WebInspector.settings.

  • UserInterface/Views/SourceCodeTextEditor.js:

(WebInspector.SourceCodeTextEditor.prototype.close):
Add call to super.close().

  • UserInterface/Views/TabBar.css:

(.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover):
(.tab-bar > .item:not(.pinned) > .flex-space:last-child):
(.tab-bar > .item.pinned > .icon):
(.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon):
(.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover,): Deleted.
(.tab-bar > .item > .flex-space:last-child): Deleted.
(.tab-bar > .item.new-tab-button > .icon): Deleted.
(.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon,): Deleted.
Removed rules specifically targeting .new-tab-button.

  • UserInterface/Views/TabBar.js:

(WebInspector.TabBar):
(WebInspector.TabBar.prototype.get newTabTabBarItem):
(WebInspector.TabBar.prototype.updateNewTabTabBarItemState):
(WebInspector.TabBar.prototype.insertTabBarItem):
(WebInspector.TabBar.prototype.removeTabBarItem.animateTabs):
(WebInspector.TabBar.prototype.removeTabBarItem):
(WebInspector.TabBar.prototype.selectPreviousTab):
(WebInspector.TabBar.prototype.selectNextTab):
(WebInspector.TabBar.prototype.set selectedTabBarItem):
(WebInspector.TabBar.prototype.hasNormalTab):
(WebInspector.TabBar.prototype.layout):
(WebInspector.TabBar.prototype._hasMoreThanOneNormalTab):
(WebInspector.TabBar.prototype._handleMouseDown):
(WebInspector.TabBar.prototype._handleMouseMoved):
(WebInspector.TabBar.prototype._handleMouseLeave):
(WebInspector.TabBar.prototype._handleNewTabClick):
(WebInspector.TabBar.prototype._handleNewTabMouseEnter):
(WebInspector.TabBar.prototype.get newTabItem): Deleted.
(WebInspector.TabBar.prototype.set newTabItem): Deleted.
Replaced the newTabItem setter by adding a saved pinned tab bar item (instead of relying
upon a different object to give it the pinned tab bar item) that changes modes depending on
whether a new tab is able to be created.

  • UserInterface/Views/TabBarItem.js:

(WebInspector.TabBarItem):
(WebInspector.TabBarItem.prototype.get element):
(WebInspector.TabBarItem.prototype.get representedObject):
(WebInspector.TabBarItem.prototype.set representedObject):
(WebInspector.TabBarItem.prototype.get parentTabBar):
(WebInspector.TabBarItem.prototype.set parentTabBar):
(WebInspector.TabBarItem.prototype.get image):
(WebInspector.TabBarItem.prototype.set image):
(WebInspector.TabBarItem.prototype.get title):
(WebInspector.TabBarItem.prototype.set title):
(WebInspector.TabBarItem.prototype.get pinned): Deleted.
(WebInspector.TabBarItem.prototype._handleContextMenuEvent): Deleted.
Split into GeneralTabBarItem and PinnedTabBarItem to simplify the logic of the DOM and allow
for easier checking of whether a tab bar item is pinned or not.

  • UserInterface/Views/TabBrowser.js:

(WebInspector.TabBrowser):
(WebInspector.TabBrowser.prototype.addTabForContentView):
(WebInspector.TabBrowser.prototype.closeTabForContentView):
(WebInspector.TabBrowser.prototype._tabBarItemSelected):
(WebInspector.TabBrowser.prototype._tabBarItemRemoved):
Replaced references to newTabItem with a set number (since each TabBar has a specific number
of pinned tabs).

  • UserInterface/Views/TextEditor.js:

(WebInspector.TextEditor):
(WebInspector.TextEditor.prototype.close):.
Remove settings update event listeners to allow garbage collection.

(WebInspector.TextEditor.prototype._startWorkerPrettyPrint):
(WebInspector.TextEditor.prototype._startCodeMirrorPrettyPrint):
Now uses the settings values in WebInspector.setting for settings on the CodeMirror
instance. Also updates the CodeMirror instance if any setting changes.

Location:
trunk/Source/WebInspectorUI
Files:
1 added
38 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r208072 r208091  
     12016-10-28  Devin Rousso  <dcrousso+webkit@gmail.com>
     2
     3        Web Inspector: Preferences for Text Editor behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=149120
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        * Localizations/en.lproj/localizedStrings.js:
     9
     10        * UserInterface/Base/Main.js:
     11        (WebInspector.loaded):
     12        (WebInspector.contentLoaded):
     13        (WebInspector.contentLoaded.setTabSize):
     14        (WebInspector.contentLoaded.setInvalidCharacterClassName):
     15        (WebInspector.contentLoaded.setWhitespaceCharacterClassName):
     16        (WebInspector._tryToRestorePendingTabs):
     17        (WebInspector.indentString):
     18        (WebInspector._updateNewTabButtonState): Deleted.
     19        (WebInspector._newTabItemClicked): Deleted.
     20        Removed calls to the New Tab tab bar item on the Tab Bar instance.
     21        Added listener to the indentUnit setting to change the tab-size value on <body>.
     22        Created helper function to generate the indentString value from settings.
     23
     24        * UserInterface/Base/Test.js:
     25        (WebInspector.indentString):
     26        Assume indent string is "    " for tests.
     27
     28        * UserInterface/Base/Setting.js:
     29        Added global WebInspector.settings dictionary for holding settings with UI editors.
     30
     31        * UserInterface/Main.html:
     32        Added GeneralTabBarItem, PinnedTabBarItem, and SettingsTabContentView.
     33
     34        * UserInterface/Models/CSSStyleDeclaration.js:
     35        (WebInspector.CSSStyleDeclaration.prototype.generateCSSRuleString):
     36        * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
     37        (WebInspector.CSSStyleDeclarationTextEditor.prototype._formattedContentFromEditor):
     38        (WebInspector.CSSStyleDeclarationTextEditor.prototype._resetContent.update):
     39        * UserInterface/Views/VisualStylePropertyEditor.js:
     40        (WebInspector.VisualStylePropertyEditor.generateFormattedTextForNewProperty):
     41        * UserInterface/Views/SourceCodeTextEditor.js:
     42        (WebInspector.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
     43        Now uses WebInspector.indentUnit for indentation values
     44
     45        * UserInterface/Views/CodeMirrorAdditions.js:
     46        Added "showWhitespaceCharacter" option to CodeMirror.  When enabled, it adds an overlay to
     47        the editor that will use pseudo-elements to display whitespace characters (unicode 00B7).
     48
     49        * UserInterface/Views/CodeMirrorOverrides.css:
     50        (.CodeMirror .cm-tab):
     51        (.show-whitespace-characters .CodeMirror .cm-tab::before):
     52        (.show-whitespace-characters .CodeMirror .cm-whitespace::before):
     53        (.show-whitespace-characters .CodeMirror .cm-whitespace-1::before):
     54        (.show-whitespace-characters .CodeMirror .cm-whitespace-2::before):
     55        (.show-whitespace-characters .CodeMirror .cm-whitespace-3::before):
     56        (.show-whitespace-characters .CodeMirror .cm-whitespace-4::before):
     57        (.show-whitespace-characters .CodeMirror .cm-whitespace-5::before):
     58        (.show-whitespace-characters .CodeMirror .cm-whitespace-6::before):
     59        (.show-whitespace-characters .CodeMirror .cm-whitespace-7::before):
     60        (.show-whitespace-characters .CodeMirror .cm-whitespace-8::before):
     61        (.show-whitespace-characters .CodeMirror .cm-whitespace-9::before):
     62        (.show-whitespace-characters .CodeMirror .cm-whitespace-10::before):
     63        (.show-whitespace-characters .CodeMirror .cm-whitespace-11::before):
     64        (.show-whitespace-characters .CodeMirror .cm-whitespace-12::before):
     65        (.show-whitespace-characters .CodeMirror .cm-whitespace-13::before):
     66        (.show-whitespace-characters .CodeMirror .cm-whitespace-14::before):
     67        (.show-whitespace-characters .CodeMirror .cm-whitespace-15::before):
     68        (.show-whitespace-characters .CodeMirror .cm-whitespace-16::before):
     69        (.show-invalid-characters .CodeMirror .cm-invalidchar):
     70        (.CodeMirror .cm-invalidchar): Deleted.
     71        Use unicode character 00B7 (middle dot) to display a space.  Also uses a grey border for
     72        visualizing tab characters.
     73
     74        * UserInterface/Views/ApplicationCacheFrameContentView.js:
     75        * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
     76        * UserInterface/Views/ClusterContentView.js:
     77        * UserInterface/Views/DOMTreeContentView.js:
     78        * UserInterface/Views/DatabaseContentView.js:
     79        * UserInterface/Views/IndexedDatabaseObjectStoreContentView.js:
     80        * UserInterface/Views/NetworkGridContentView.js:
     81        * UserInterface/Views/ResourceContentView.js:
     82        * UserInterface/Views/ScriptContentView.js:
     83        * UserInterface/Views/TabContentView.js:
     84        * UserInterface/Views/TimelineRecordingContentView.js:
     85        Add calls to super.shown(), super.hidden(), and super.closed().
     86
     87        * UserInterface/Views/ConsoleTabContentView.js:
     88        * UserInterface/Views/DebuggerTabContentView.js:
     89        * UserInterface/Views/ElementsTabContentView.js:
     90        * UserInterface/Views/NetworkTabContentView.js:
     91        * UserInterface/Views/NewTabContentView.js:
     92        * UserInterface/Views/ResourcesTabContentView.js:
     93        * UserInterface/Views/SearchTabContentView.js:
     94        * UserInterface/Views/StorageTabContentView.js:
     95        * UserInterface/Views/TimelineTabContentView.js:
     96        Now uses WebInspector.GeneralTabBarItem.
     97
     98        * UserInterface/Views/GeneralTabBarItem.js: Added.
     99        (WebInspector.GeneralTabBarItem):
     100        (WebInspector.GeneralTabBarItem.prototype.set title):
     101        (WebInspector.GeneralTabBarItem.prototype._handleContextMenuEvent):
     102        Split from TabBarItem.js to make pinned tab bar items more distinct.
     103
     104        * UserInterface/Views/Main.css:
     105        (body):
     106        Removed tab-size.
     107
     108        * UserInterface/Views/PinnedTabBarItem.js: Added.
     109        (WebInspector.PinnedTabBarItem):
     110        Split from TabBarItem.js to make pinned tab bar items more distinct.
     111
     112        * UserInterface/Views/SettingsTabContentView.css: Added.
     113        (.content-view.settings):
     114        (.content-view.settings > .header):
     115        (.content-view.settings > .setting-container):
     116        (.content-view.settings > .setting-container > .setting-name):
     117        (.content-view.settings > .setting-container > .setting-value-controller):
     118        (.content-view.settings > .setting-container > .setting-value-controller input[type="number"]):
     119
     120        * UserInterface/Views/SettingsTabContentView.js:
     121        (WebInspector.SettingsTabContentView):
     122        (WebInspector.SettingsTabContentView.tabInfo):
     123        (WebInspector.SettingsTabContentView.isEphemeral):
     124        (WebInspector.SettingsTabContentView.shouldSaveTab):
     125        (WebInspector.SettingsTabContentView.prototype.initialLayout):
     126        (WebInspector.SettingsTabContentView.isTabAllowed): Deleted.
     127        (WebInspector.SettingsTabContentView.prototype.get type): Deleted.
     128        Added logic to display an appropriate editor for each item in WebInspector.settings.
     129
     130        * UserInterface/Views/SourceCodeTextEditor.js:
     131        (WebInspector.SourceCodeTextEditor.prototype.close):
     132        Add call to super.close().
     133
     134        * UserInterface/Views/TabBar.css:
     135        (.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover):
     136        (.tab-bar > .item:not(.pinned) > .flex-space:last-child):
     137        (.tab-bar > .item.pinned > .icon):
     138        (.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon):
     139        (.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover,): Deleted.
     140        (.tab-bar > .item > .flex-space:last-child): Deleted.
     141        (.tab-bar > .item.new-tab-button > .icon): Deleted.
     142        (.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon,): Deleted.
     143        Removed rules specifically targeting `.new-tab-button`.
     144
     145        * UserInterface/Views/TabBar.js:
     146        (WebInspector.TabBar):
     147        (WebInspector.TabBar.prototype.get newTabTabBarItem):
     148        (WebInspector.TabBar.prototype.updateNewTabTabBarItemState):
     149        (WebInspector.TabBar.prototype.insertTabBarItem):
     150        (WebInspector.TabBar.prototype.removeTabBarItem.animateTabs):
     151        (WebInspector.TabBar.prototype.removeTabBarItem):
     152        (WebInspector.TabBar.prototype.selectPreviousTab):
     153        (WebInspector.TabBar.prototype.selectNextTab):
     154        (WebInspector.TabBar.prototype.set selectedTabBarItem):
     155        (WebInspector.TabBar.prototype.hasNormalTab):
     156        (WebInspector.TabBar.prototype.layout):
     157        (WebInspector.TabBar.prototype._hasMoreThanOneNormalTab):
     158        (WebInspector.TabBar.prototype._handleMouseDown):
     159        (WebInspector.TabBar.prototype._handleMouseMoved):
     160        (WebInspector.TabBar.prototype._handleMouseLeave):
     161        (WebInspector.TabBar.prototype._handleNewTabClick):
     162        (WebInspector.TabBar.prototype._handleNewTabMouseEnter):
     163        (WebInspector.TabBar.prototype.get newTabItem): Deleted.
     164        (WebInspector.TabBar.prototype.set newTabItem): Deleted.
     165        Replaced the newTabItem setter by adding a saved pinned tab bar item (instead of relying
     166        upon a different object to give it the pinned tab bar item) that changes modes depending on
     167        whether a new tab is able to be created.
     168
     169        * UserInterface/Views/TabBarItem.js:
     170        (WebInspector.TabBarItem):
     171        (WebInspector.TabBarItem.prototype.get element):
     172        (WebInspector.TabBarItem.prototype.get representedObject):
     173        (WebInspector.TabBarItem.prototype.set representedObject):
     174        (WebInspector.TabBarItem.prototype.get parentTabBar):
     175        (WebInspector.TabBarItem.prototype.set parentTabBar):
     176        (WebInspector.TabBarItem.prototype.get image):
     177        (WebInspector.TabBarItem.prototype.set image):
     178        (WebInspector.TabBarItem.prototype.get title):
     179        (WebInspector.TabBarItem.prototype.set title):
     180        (WebInspector.TabBarItem.prototype.get pinned): Deleted.
     181        (WebInspector.TabBarItem.prototype._handleContextMenuEvent): Deleted.
     182        Split into GeneralTabBarItem and PinnedTabBarItem to simplify the logic of the DOM and allow
     183        for easier checking of whether a tab bar item is pinned or not.
     184
     185        * UserInterface/Views/TabBrowser.js:
     186        (WebInspector.TabBrowser):
     187        (WebInspector.TabBrowser.prototype.addTabForContentView):
     188        (WebInspector.TabBrowser.prototype.closeTabForContentView):
     189        (WebInspector.TabBrowser.prototype._tabBarItemSelected):
     190        (WebInspector.TabBrowser.prototype._tabBarItemRemoved):
     191        Replaced references to newTabItem with a set number (since each TabBar has a specific number
     192        of pinned tabs).
     193
     194        * UserInterface/Views/TextEditor.js:
     195        (WebInspector.TextEditor):
     196        (WebInspector.TextEditor.prototype.close):.
     197        Remove settings update event listeners to allow garbage collection.
     198
     199        (WebInspector.TextEditor.prototype._startWorkerPrettyPrint):
     200        (WebInspector.TextEditor.prototype._startCodeMirrorPrettyPrint):
     201        Now uses the settings values in WebInspector.setting for settings on the CodeMirror
     202        instance.  Also updates the CodeMirror instance if any setting changes.
     203
    12042016-10-28  Joseph Pecoraro  <pecoraro@apple.com>
    2205
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r208009 r208091  
    392392localizedStrings["HTML Attributes"] = "HTML Attributes";
    393393localizedStrings["HTTP"] = "HTTP";
     394localizedStrings["Heading Level"] = "Heading Level";
    394395localizedStrings["Heap Snapshot Object (@%d)"] = "Heap Snapshot Object (@%d)";
    395396localizedStrings["Height"] = "Height";
    396 localizedStrings["Heading Level"] = "Heading Level";
    397 localizedStrings["Hierarchy Level"] = "Hierarchy Level";
    398397localizedStrings["Hide compositing borders"] = "Hide compositing borders";
    399398localizedStrings["Hide shadow DOM nodes"] = "Hide shadow DOM nodes";
     
    401400localizedStrings["Hide the navigation sidebar (%s)"] = "Hide the navigation sidebar (%s)";
    402401localizedStrings["Hide type information"] = "Hide type information";
     402localizedStrings["Hierarchy Level"] = "Hierarchy Level";
    403403localizedStrings["Highest: %s"] = "Highest: %s";
    404404localizedStrings["Horizontal"] = "Horizontal";
     
    415415localizedStrings["Immediate Pause Requested"] = "Immediate Pause Requested";
    416416localizedStrings["Indent"] = "Indent";
     417localizedStrings["Indent width:"] = "Indent width:";
    417418localizedStrings["Index"] = "Index";
    418419localizedStrings["Index Key \u2014 %s"] = "Index Key \u2014 %s";
     
    428429localizedStrings["Instances"] = "Instances";
    429430localizedStrings["Invalid"] = "Invalid";
     431localizedStrings["Invalid Characters:"] = "Invalid Characters:";
    430432localizedStrings["Inverted"] = "Inverted";
    431433localizedStrings["Invoke getter"] = "Invoke getter";
     
    454456localizedStrings["Line %d:%d"] = "Line %d:%d";
    455457localizedStrings["Line Number"] = "Line Number";
     458localizedStrings["Line wrapping:"] = "Line wrapping:";
    456459localizedStrings["Linear Gradient"] = "Linear Gradient";
    457460localizedStrings["List Styles"] = "List Styles";
     
    537540localizedStrings["Opacity"] = "Opacity";
    538541localizedStrings["Open"] = "Open";
     542localizedStrings["Open Settings"] = "Open Settings";
    539543localizedStrings["Open in New Tab"] = "Open in New Tab";
    540544localizedStrings["Option-click to show all units"] = "Option-click to show all units";
     
    576580localizedStrings["Position X"] = "Position X";
    577581localizedStrings["Position Y"] = "Position Y";
     582localizedStrings["Prefer indent using:"] = "Prefer indent using:";
    578583localizedStrings["Pressed"] = "Pressed";
    579584localizedStrings["Pretty print"] = "Pretty print";
     
    703708localizedStrings["Sort Descending"] = "Sort Descending";
    704709localizedStrings["Sources"] = "Sources";
     710localizedStrings["Spaces"] = "Spaces";
    705711localizedStrings["Spacing"] = "Spacing";
    706712localizedStrings["Specificity: (%d, %d, %d)"] = "Specificity: (%d, %d, %d)";
     
    739745localizedStrings["Stylesheet"] = "Stylesheet";
    740746localizedStrings["Stylesheets"] = "Stylesheets";
     747localizedStrings["Tab width:"] = "Tab width:";
     748localizedStrings["Tabs"] = "Tabs";
    741749localizedStrings["Take snapshot"] = "Take snapshot";
    742750localizedStrings["Template Content"] = "Template Content";
     
    805813localizedStrings["Vertical"] = "Vertical";
    806814localizedStrings["Visibility"] = "Visibility";
     815localizedStrings["Visible"] = "Visible";
    807816localizedStrings["Warning: "] = "Warning: ";
    808817localizedStrings["Warnings"] = "Warnings";
     
    811820localizedStrings["Weight"] = "Weight";
    812821localizedStrings["Whitespace"] = "Whitespace";
     822localizedStrings["Whitespace Characters:"] = "Whitespace Characters:";
    813823localizedStrings["Width"] = "Width";
    814824localizedStrings["With Object Properties"] = "With Object Properties";
     
    817827localizedStrings["Working Copy"] = "Working Copy";
    818828localizedStrings["Wrap"] = "Wrap";
     829localizedStrings["Wrap lines to editor width"] = "Wrap lines to editor width";
    819830localizedStrings["X"] = "X";
    820831localizedStrings["X1"] = "X1";
     
    830841localizedStrings["line "] = "line ";
    831842localizedStrings["originally %s"] = "originally %s";
     843localizedStrings["spaces"] = "spaces";
    832844localizedStrings["time before stopping"] = "time before stopping";
    833845localizedStrings["times before stopping"] = "times before stopping";
  • trunk/Source/WebInspectorUI/UserInterface/Base/Main.js

    r208009 r208091  
    233233    document.body.classList.add(this.debuggableType);
    234234
     235    function setTabSize() {
     236        document.body.style.tabSize = WebInspector.settings.tabSize.value;
     237    }
     238    WebInspector.settings.tabSize.addEventListener(WebInspector.Setting.Event.Changed, setTabSize);
     239    setTabSize();
     240
     241    function setInvalidCharacterClassName() {
     242        document.body.classList.toggle("show-invalid-characters", WebInspector.settings.showInvalidCharacters.value);
     243    }
     244    WebInspector.settings.showInvalidCharacters.addEventListener(WebInspector.Setting.Event.Changed, setInvalidCharacterClassName);
     245    setInvalidCharacterClassName();
     246
     247    function setWhitespaceCharacterClassName() {
     248        document.body.classList.toggle("show-whitespace-characters", WebInspector.settings.showWhitespaceCharacters.value);
     249    }
     250    WebInspector.settings.showWhitespaceCharacters.addEventListener(WebInspector.Setting.Event.Changed, setWhitespaceCharacterClassName);
     251    setWhitespaceCharacterClassName();
     252
     253    this.settingsTabContentView = new WebInspector.SettingsTabContentView;
     254
    235255    // Create the user interface elements.
    236256    this.toolbar = new WebInspector.Toolbar(document.getElementById("toolbar"), null, true);
     
    239259
    240260    this.tabBar = new WebInspector.TabBar(document.getElementById("tab-bar"));
    241     this.tabBar.addEventListener(WebInspector.TabBar.Event.NewTabItemClicked, this._newTabItemClicked, this);
    242261    this.tabBar.addEventListener(WebInspector.TabBar.Event.OpenDefaultTab, this._openDefaultTab, this);
    243262
     
    289308    this.tabBrowser = new WebInspector.TabBrowser(document.getElementById("tab-browser"), this.tabBar, this.navigationSidebar, this.detailsSidebar);
    290309    this.tabBrowser.addEventListener(WebInspector.TabBrowser.Event.SelectedTabContentViewDidChange, this._tabBrowserSelectedTabContentViewDidChange, this);
    291 
    292     this.tabBar.addEventListener(WebInspector.TabBar.Event.TabBarItemAdded, this._updateNewTabButtonState, this);
    293     this.tabBar.addEventListener(WebInspector.TabBar.Event.TabBarItemRemoved, this._updateNewTabButtonState, this);
    294310
    295311    this._reloadPageKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "R", this._reloadPage.bind(this));
     
    407423        WebInspector.ResourcesTabContentView,
    408424        WebInspector.SearchTabContentView,
     425        WebInspector.SettingsTabContentView,
    409426        WebInspector.StorageTabContentView,
    410427        WebInspector.TimelineTabContentView,
     
    448465        this.tabBar.selectedTabBarItem = 0;
    449466
    450     if (!this.tabBar.hasNormalTab())
     467    if (!this.tabBar.normalTabCount)
    451468        this.showNewTabTab();
    452469
     
    539556};
    540557
    541 WebInspector._updateNewTabButtonState = function(event)
    542 {
    543     this.tabBar.newTabItem.disabled = !this.isNewTabWithTypeAllowed(WebInspector.NewTabContentView.Type);
    544 };
    545 
    546 WebInspector._newTabItemClicked = function(event)
    547 {
    548     const shouldAnimate = true;
    549     this.showNewTabTab(shouldAnimate);
    550 };
    551 
    552558WebInspector._openDefaultTab = function(event)
    553559{
     
    575581    this._pendingOpenTabs = stillPendingOpenTabs;
    576582
    577     this._updateNewTabButtonState();
     583    this.tabBrowser.tabBar.updateNewTabTabBarItemState();
    578584};
    579585
     
    10321038
    10331039    return "LOCALIZED STRING NOT FOUND";
     1040};
     1041
     1042WebInspector.indentString = function()
     1043{
     1044    if (WebInspector.settings.indentWithTabs.value)
     1045        return "\t";
     1046    return " ".repeat(WebInspector.settings.indentUnit.value);
    10341047};
    10351048
  • trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js

    r205424 r208091  
    102102    Changed: "setting-changed"
    103103};
     104
     105WebInspector.settings = {
     106    enableLineWrapping: new WebInspector.Setting("enable-line-wrapping", false),
     107    indentUnit: new WebInspector.Setting("indent-unit", 4),
     108    tabSize: new WebInspector.Setting("tab-size", 4),
     109    indentWithTabs: new WebInspector.Setting("indent-with-tabs", false),
     110    showWhitespaceCharacters: new WebInspector.Setting("show-whitespace-characters", false),
     111    showInvalidCharacters: new WebInspector.Setting("show-invalid-characters", false),
     112};
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r208012 r208091  
    150150    <link rel="stylesheet" href="Views/SearchIcons.css">
    151151    <link rel="stylesheet" href="Views/SearchSidebarPanel.css">
     152    <link rel="stylesheet" href="Views/SettingsTabContentView.css">
    152153    <link rel="stylesheet" href="Views/Sidebar.css">
    153154    <link rel="stylesheet" href="Views/SidebarPanel.css">
     
    425426    <script src="Views/DOMTreeContentView.js"></script>
    426427    <script src="Views/DetailsSidebarPanel.js"></script>
     428    <script src="Views/GeneralTabBarItem.js"></script>
    427429    <script src="Views/GeneralTreeElement.js"></script>
    428430    <script src="Views/NavigationSidebarPanel.js"></script>
     431    <script src="Views/PinnedTabBarItem.js"></script>
    429432    <script src="Views/ResourceContentView.js"></script>
    430433    <script src="Views/TabContentView.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js

    r204370 r208091  
    303303    generateCSSRuleString()
    304304    {
    305         // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    306         const indentation = "    ";
     305        let indentString = WebInspector.indentString();
    307306        let styleText = "";
    308307        let mediaList = this.mediaList;
    309308        let mediaQueriesCount = mediaList.length;
    310309        for (let i = mediaQueriesCount - 1; i >= 0; --i)
    311             styleText += indentation.repeat(mediaQueriesCount - i - 1) + "@media " + mediaList[i].text + " {\n";
    312 
    313         styleText += indentation.repeat(mediaQueriesCount) + this.selectorText + " {\n";
     310            styleText += indentString.repeat(mediaQueriesCount - i - 1) + "@media " + mediaList[i].text + " {\n";
     311
     312        styleText += indentString.repeat(mediaQueriesCount) + this.selectorText + " {\n";
    314313
    315314        for (let property of this._properties) {
     
    317316                continue;
    318317
    319             styleText += indentation.repeat(mediaQueriesCount + 1) + property.text.trim();
     318            styleText += indentString.repeat(mediaQueriesCount + 1) + property.text.trim();
    320319
    321320            if (!styleText.endsWith(";"))
     
    326325
    327326        for (let i = mediaQueriesCount; i > 0; --i)
    328             styleText += indentation.repeat(i) + "}\n";
     327            styleText += indentString.repeat(i) + "}\n";
    329328
    330329        styleText += "}";
  • trunk/Source/WebInspectorUI/UserInterface/Test/Test.js

    r208009 r208091  
    102102WebInspector.UIString = (string) => string;
    103103
     104WebInspector.indentString = () => "    ";
     105
    104106// Add stubs that are called by the frontend API.
    105107WebInspector.updateDockedState = () => {};
  • trunk/Source/WebInspectorUI/UserInterface/Views/ApplicationCacheFrameContentView.js

    r205426 r208091  
    5050    shown()
    5151    {
     52        super.shown();
     53
    5254        this._maybeUpdate();
    5355    }
     
    5658    {
    5759        WebInspector.applicationCacheManager.removeEventListener(null, null, this);
     60
     61        super.closed();
    5862    }
    5963
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js

    r206339 r208091  
    14671467    _formattedContentFromEditor()
    14681468    {
    1469         // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    1470         var indentString = "    ";
    1471         var builder = new FormatterContentBuilder(indentString);
    1472         var formatter = new WebInspector.Formatter(this._codeMirror, builder);
    1473         var start = {line: 0, ch: 0};
    1474         var end = {line: this._codeMirror.lineCount() - 1};
     1469        let indentString = WebInspector.indentString();
     1470        let builder = new FormatterContentBuilder(indentString);
     1471        let formatter = new WebInspector.Formatter(this._codeMirror, builder);
     1472        let start = {line: 0, ch: 0};
     1473        let end = {line: this._codeMirror.lineCount() - 1};
    14751474        formatter.format(start, end);
    14761475
     
    15441543            let whitespaceRegex = /\s+/g;
    15451544
    1546             // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    1547             this._linePrefixWhitespace = "    ";
     1545            this._linePrefixWhitespace = WebInspector.indentString();
     1546
    15481547            let styleTextPrefixWhitespace = styleText.match(/^\s*/);
    15491548
  • trunk/Source/WebInspectorUI/UserInterface/Views/ClusterContentView.js

    r202932 r208091  
    6363    shown()
    6464    {
     65        super.shown();
     66
    6567        this._contentViewContainer.shown();
    6668    }
     
    6870    hidden()
    6971    {
     72        super.hidden();
     73
    7074        this._contentViewContainer.hidden();
    7175    }
     
    7377    closed()
    7478    {
     79        super.closed();
     80
    7581        this._contentViewContainer.closeAllContentViews();
    7682
  • trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorAdditions.js

    r206426 r208091  
    358358    });
    359359
     360    const maximumNeighboringWhitespaceCharacters = 16;
     361    CodeMirror.defineOption("showWhitespaceCharacters", false, function(cm, value, old) {
     362        if (!value || (old && old !== CodeMirror.Init)) {
     363            cm.removeOverlay("whitespace");
     364            return;
     365        }
     366
     367        cm.addOverlay({
     368            name: "whitespace",
     369            token(stream) {
     370                if (stream.peek() === " ") {
     371                    let count = 0;
     372                    while (count < maximumNeighboringWhitespaceCharacters && stream.peek() === " ") {
     373                        ++count;
     374                        stream.next();
     375                    }
     376                    return `whitespace whitespace-${count}`;
     377                }
     378
     379                while (!stream.eol() && stream.peek() !== " ")
     380                    stream.next();
     381
     382                return null;
     383            }
     384        });
     385    });
     386
    360387    CodeMirror.defineExtension("hasLineClass", function(line, where, className) {
    361388        // This matches the arguments to addLineClass and removeLineClass.
  • trunk/Source/WebInspectorUI/UserInterface/Views/CodeMirrorOverrides.css

    r205517 r208091  
    9292}
    9393
    94 /* FIXME: Add setting to show/hide invalid characters. */
    95 .CodeMirror .cm-invalidchar {
     94.CodeMirror .cm-tab {
     95    position: relative;
     96}
     97
     98.show-whitespace-characters .CodeMirror .cm-tab::before {
     99    position: absolute;
     100    width: 90%;
     101    bottom: 50%;
     102    left: 5%;
     103    content: "";
     104    border-bottom: 1px solid hsl(0, 0%, 70%);
     105}
     106
     107.show-whitespace-characters .CodeMirror .cm-whitespace::before {
     108    position: absolute;
     109    pointer-events: none;
     110}
     111
     112.show-whitespace-characters .CodeMirror .cm-whitespace-1::before {
     113    content: "\00B7";
     114}
     115
     116.show-whitespace-characters .CodeMirror .cm-whitespace-2::before {
     117    content: "\00B7\00B7";
     118}
     119
     120.show-whitespace-characters .CodeMirror .cm-whitespace-3::before {
     121    content: "\00B7\00B7\00B7";
     122}
     123
     124.show-whitespace-characters .CodeMirror .cm-whitespace-4::before {
     125    content: "\00B7\00B7\00B7\00B7";
     126}
     127
     128.show-whitespace-characters .CodeMirror .cm-whitespace-5::before {
     129    content: "\00B7\00B7\00B7\00B7\00B7";
     130}
     131
     132.show-whitespace-characters .CodeMirror .cm-whitespace-6::before {
     133    content: "\00B7\00B7\00B7\00B7\00B7\00B7";
     134}
     135
     136.show-whitespace-characters .CodeMirror .cm-whitespace-7::before {
     137    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     138}
     139
     140.show-whitespace-characters .CodeMirror .cm-whitespace-8::before {
     141    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     142}
     143
     144.show-whitespace-characters .CodeMirror .cm-whitespace-9::before {
     145    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     146}
     147
     148.show-whitespace-characters .CodeMirror .cm-whitespace-10::before {
     149    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     150}
     151
     152.show-whitespace-characters .CodeMirror .cm-whitespace-11::before {
     153    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     154}
     155
     156.show-whitespace-characters .CodeMirror .cm-whitespace-12::before {
     157    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     158}
     159
     160.show-whitespace-characters .CodeMirror .cm-whitespace-13::before {
     161    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     162}
     163
     164.show-whitespace-characters .CodeMirror .cm-whitespace-14::before {
     165    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     166}
     167
     168.show-whitespace-characters .CodeMirror .cm-whitespace-15::before {
     169    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     170}
     171
     172.show-whitespace-characters .CodeMirror .cm-whitespace-16::before {
     173    content: "\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7\00B7";
     174}
     175
     176.show-invalid-characters .CodeMirror .cm-invalidchar {
    96177    display: none;
    97178}
  • trunk/Source/WebInspectorUI/UserInterface/Views/ConsoleTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.ConsoleTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232
    3333        super(identifier || "console", "console", tabBarItem, null, null, true);
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.js

    r205426 r208091  
    8484    shown()
    8585    {
     86        super.shown();
     87
    8688        this._domTreeOutline.setVisible(true, WebInspector.isConsoleFocused());
    8789        this._updateCompositingBordersButtonToMatchPageSettings();
     
    9092    hidden()
    9193    {
     94        super.hidden();
     95
    9296        WebInspector.domTreeManager.hideDOMNodeHighlight();
    9397        this._domTreeOutline.setVisible(false);
     
    96100    closed()
    97101    {
     102        super.closed();
     103
    98104        WebInspector.showPaintRectsSetting.removeEventListener(null, null, this);
    99105        WebInspector.showShadowDOMSetting.removeEventListener(null, null, this);
  • trunk/Source/WebInspectorUI/UserInterface/Views/DatabaseContentView.js

    r192165 r208091  
    4444    shown()
    4545    {
     46        super.shown();
     47
    4648        // FIXME: remove once <https://webkit.org/b/150741> is fixed.
    4749        this._prompt.shown();
  • trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.DebuggerTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.scopeChainDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.ElementsTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/IndexedDatabaseObjectStoreContentView.js

    r205041 r208091  
    9494    closed()
    9595    {
     96        super.closed();
     97
    9698        this._reset();
    9799    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/Main.css

    r201304 r208091  
    4949
    5050    -webkit-font-smoothing: subpixel-antialiased;
    51 
    52     tab-size: 4; /* FIXME: This should be controlled by a setting. <rdar://problem/10593948> */
    5351}
    5452
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkGridContentView.js

    r206464 r208091  
    158158    closed()
    159159    {
     160        super.closed();
     161
    160162        this._dataGrid.closed();
    161163    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.NetworkTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/NewTabContentView.js

    r205872 r208091  
    2929    {
    3030        let {image, title} = WebInspector.NewTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        tabBarItem.isDefaultTab = true;
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/PinnedTabBarItem.js

    r208090 r208091  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016 Devin Rousso <dcrousso+webkit@gmail.com>. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.SettingsTabContentView = class SettingsTabContentView extends WebInspector.TabContentView
     26WebInspector.PinnedTabBarItem = class PinnedTabBarItem extends WebInspector.TabBarItem
    2727{
    28     constructor(identifier)
     28    constructor(image, title, representedObject)
    2929    {
    30         var tabBarItem = new WebInspector.TabBarItem("Images/Gear.svg", WebInspector.UIString("Settings"), true);
     30        super(image, title, representedObject);
    3131
    32         super(identifier || "settings", "settings", tabBarItem);
    33     }
    34 
    35     static isTabAllowed()
    36     {
    37         // FIXME (149284): This tab isn't ready to be shown yet.
    38         return false;
    39     }
    40 
    41     static shouldSaveTab()
    42     {
    43         return false;
    44     }
    45 
    46     // Public
    47 
    48     get type()
    49     {
    50         return WebInspector.SettingsTabContentView.Type;
     32        this.element.classList.add("pinned");
    5133    }
    5234};
    53 
    54 WebInspector.SettingsTabContentView.Type = "settings";
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceContentView.js

    r200064 r208091  
    7777    closed()
    7878    {
     79        super.closed();
     80
    7981        if (!this.managesOwnIssues)
    8082            WebInspector.issueManager.removeEventListener(null, null, this);
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourcesTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.ResourcesTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptContentView.js

    r205674 r208091  
    108108    shown()
    109109    {
     110        super.shown();
     111
    110112        this._textEditor.shown();
    111113    }
     
    113115    hidden()
    114116    {
     117        super.hidden();
     118
    115119        this._textEditor.hidden();
    116120    }
     
    118122    closed()
    119123    {
     124        super.closed();
     125
    120126        WebInspector.showJavaScriptTypeInformationSetting.removeEventListener(null, null, this);
    121127
  • trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js

    r193432 r208091  
    2929    {
    3030        let {image, title} = WebInspector.SearchTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel,
    3333            WebInspector.domNodeDetailsSidebarPanel, WebInspector.cssStyleDetailsSidebarPanel];
  • trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.css

    r208090 r208091  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016 Devin Rousso <dcrousso+webkit@gmail.com>. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.SettingsTabContentView = class SettingsTabContentView extends WebInspector.TabContentView
    27 {
    28     constructor(identifier)
    29     {
    30         var tabBarItem = new WebInspector.TabBarItem("Images/Gear.svg", WebInspector.UIString("Settings"), true);
     26.content-view.settings {
     27    display: flex;
     28    flex-direction: column;
     29    font-weight: lighter;
     30}
    3131
    32         super(identifier || "settings", "settings", tabBarItem);
    33     }
     32.content-view.settings > .header {
     33    margin: 70px auto 40px;
     34    text-align: center;
     35    font-size: 48px;
     36}
    3437
    35     static isTabAllowed()
    36     {
    37         // FIXME (149284): This tab isn't ready to be shown yet.
    38         return false;
    39     }
     38.content-view.settings > .setting-container {
     39    display: flex;
     40    align-items: center;
     41    padding: 10px;
     42    font-size: 14px;
     43}
    4044
    41     static shouldSaveTab()
    42     {
    43         return false;
    44     }
     45.content-view.settings > .setting-container > .setting-name {
     46    width: 50%;
     47    margin-right: 2px;
     48    text-align: right;
     49}
    4550
    46     // Public
     51.content-view.settings > .setting-container > .setting-value-controller {
     52    display: flex;
     53    align-items: center;
     54    width: 50%;
     55    margin-left: 2px;
     56}
    4757
    48     get type()
    49     {
    50         return WebInspector.SettingsTabContentView.Type;
    51     }
    52 };
    53 
    54 WebInspector.SettingsTabContentView.Type = "settings";
     58.content-view.settings > .setting-container > .setting-value-controller input[type="number"] {
     59    max-width: 50px;
     60    margin: 0 5px;
     61    text-align: right;
     62}
  • trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js

    r193432 r208091  
    11/*
    22 * Copyright (C) 2015 Apple Inc. All rights reserved.
     3 * Copyright (C) 2016 Devin Rousso <dcrousso+webkit@gmail.com>. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2829    constructor(identifier)
    2930    {
    30         var tabBarItem = new WebInspector.TabBarItem("Images/Gear.svg", WebInspector.UIString("Settings"), true);
     31        let tabBarItem = new WebInspector.PinnedTabBarItem("Images/Gear.svg", WebInspector.UIString("Open Settings"));
    3132
    3233        super(identifier || "settings", "settings", tabBarItem);
     34
     35        // Ensures that the Settings tab is displayable from a pinned tab bar item.
     36        tabBarItem.representedObject = this;
    3337    }
    3438
    35     static isTabAllowed()
     39    static tabInfo()
    3640    {
    37         // FIXME (149284): This tab isn't ready to be shown yet.
    38         return false;
     41        return {
     42            image: "Images/Gear.svg",
     43            title: WebInspector.UIString("Settings"),
     44        };
     45    }
     46
     47    static isEphemeral()
     48    {
     49        return true;
    3950    }
    4051
     
    5061        return WebInspector.SettingsTabContentView.Type;
    5162    }
     63
     64    initialLayout()
     65    {
     66        let header = this.element.createChild("div", "header");
     67        header.textContent = WebInspector.UIString("Settings");
     68
     69        let createContainer = (title, createValueController) => {
     70            let container = this.element.createChild("div", "setting-container");
     71
     72            let titleContainer = container.createChild("div", "setting-name");
     73            titleContainer.textContent = title;
     74
     75            let valueControllerContainer = container.createChild("div", "setting-value-controller");
     76            if (typeof createValueController === "function")
     77                createValueController(valueControllerContainer);
     78        };
     79
     80        let createCheckbox = (setting) => {
     81            let checkbox = document.createElement("input");
     82            checkbox.type = "checkbox";
     83            checkbox.checked = setting.value;
     84            checkbox.addEventListener("change", (event) => {
     85                setting.value = checkbox.checked;
     86            });
     87            return checkbox;
     88        };
     89
     90        createContainer(WebInspector.UIString("Prefer indent using:"), (valueControllerContainer) => {
     91            let select = valueControllerContainer.createChild("select");
     92            select.addEventListener("change", (event) => {
     93                WebInspector.settings.indentWithTabs.value = select.value === "tabs";
     94            });
     95
     96            let tabsOption = select.createChild("option");
     97            tabsOption.value = "tabs";
     98            tabsOption.textContent = WebInspector.UIString("Tabs");
     99            tabsOption.selected = WebInspector.settings.indentWithTabs.value;
     100
     101            let spacesOption = select.createChild("option");
     102            spacesOption.value = "spaces";
     103            spacesOption.textContent = WebInspector.UIString("Spaces");
     104            spacesOption.selected = !WebInspector.settings.indentWithTabs.value;
     105        });
     106
     107        createContainer(WebInspector.UIString("Tab width:"), (valueControllerContainer) => {
     108            let input = valueControllerContainer.createChild("input");
     109            input.type = "number";
     110            input.min = 1;
     111            input.value = WebInspector.settings.tabSize.value;
     112            input.addEventListener("change", (event) => {
     113                WebInspector.settings.tabSize.value = parseInt(input.value) || 4;
     114            });
     115
     116            valueControllerContainer.append(WebInspector.UIString("spaces"));
     117        });
     118
     119        createContainer(WebInspector.UIString("Indent width:"), (valueControllerContainer) => {
     120            let input = valueControllerContainer.createChild("input");
     121            input.type = "number";
     122            input.min = 1;
     123            input.value = WebInspector.settings.indentUnit.value;
     124            input.addEventListener("change", (event) => {
     125                WebInspector.settings.indentUnit.value = parseInt(input.value) || 4;
     126            });
     127
     128            valueControllerContainer.append(WebInspector.UIString("spaces"));
     129        });
     130
     131        createContainer(WebInspector.UIString("Line wrapping:"), (valueControllerContainer) => {
     132            let checkbox = createCheckbox(WebInspector.settings.enableLineWrapping);
     133            valueControllerContainer.appendChild(checkbox);
     134
     135            valueControllerContainer.append(WebInspector.UIString("Wrap lines to editor width"));
     136        });
     137
     138        createContainer(WebInspector.UIString("Whitespace Characters:"), (valueControllerContainer) => {
     139            let checkbox = createCheckbox(WebInspector.settings.showWhitespaceCharacters);
     140            valueControllerContainer.appendChild(checkbox);
     141
     142            valueControllerContainer.append(WebInspector.UIString("Visible"));
     143        });
     144
     145        createContainer(WebInspector.UIString("Invalid Characters:"), (valueControllerContainer) => {
     146            let checkbox = createCheckbox(WebInspector.settings.showInvalidCharacters);
     147            valueControllerContainer.appendChild(checkbox);
     148
     149            valueControllerContainer.append(WebInspector.UIString("Visible"));
     150        });
     151    }
    52152};
    53153
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js

    r207371 r208091  
    145145    close()
    146146    {
     147        super.close();
     148
    147149        if (this._supportsDebugging) {
    148150            WebInspector.Breakpoint.removeEventListener(null, null, this);
     
    16471649            });
    16481650
    1649             // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    16501651            const isModule = false;
     1652            const indentString = WebInspector.indentString();
     1653            const includeSourceMapData = false;
    16511654            let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
    1652             workerProxy.formatJavaScript(data.description, isModule, "    ", false, ({formattedText}) => {
     1655            workerProxy.formatJavaScript(data.description, isModule, indentString, includeSourceMapData, ({formattedText}) => {
    16531656                codeMirror.setValue(formattedText || data.description);
    16541657            });
  • trunk/Source/WebInspectorUI/UserInterface/Views/StorageTabContentView.js

    r205043 r208091  
    2929    {
    3030        let {image, title} = WebInspector.StorageTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.applicationCacheDetailsSidebarPanel, WebInspector.indexedDatabaseDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/TabBar.css

    r198065 r208091  
    120120}
    121121
    122 .tab-bar:not(.animating) > .item:not(.selected, .disabled):hover,
    123 .tab-bar > .item.new-tab-button:not(.disabled):hover {
     122.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover {
    124123    background-position: 0 100%;
    125124    border-top-color: hsl(0, 0%, 59%);
     
    192191}
    193192
    194 .tab-bar > .item > .flex-space:last-child {
     193.tab-bar > .item:not(.pinned) > .flex-space:last-child {
    195194    margin-right: 16px;
    196195}
     
    208207}
    209208
    210 .tab-bar > .item.selected > .icon {
    211     opacity: 0.7;
    212 }
    213 
    214 .tab-bar > .item.disabled > .icon {
    215     opacity: 0.35;
    216 }
    217 
    218 .tab-bar > .item.new-tab-button > .icon {
     209.tab-bar > .item.pinned > .icon {
    219210    width: 15px;
    220211    height: 15px;
     
    223214}
    224215
    225 .tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon,
    226 .tab-bar > .item.new-tab-button:not(.disabled):hover > .icon {
     216.tab-bar > .item.selected > .icon {
     217    opacity: 0.7;
     218}
     219
     220.tab-bar > .item.disabled > .icon {
     221    opacity: 0.35;
     222}
     223
     224.tab-bar:not(.animating) > .item:not(.selected, .disabled):hover > .icon {
    227225    opacity: 0.6;
    228226}
  • trunk/Source/WebInspectorUI/UserInterface/Views/TabBar.js

    r201620 r208091  
    3232        this.element.classList.add("tab-bar");
    3333        this.element.setAttribute("role", "tablist");
    34 
    35         var topBorderElement = document.createElement("div");
    36         topBorderElement.classList.add("top-border");
    37         this.element.appendChild(topBorderElement);
    38 
    3934        this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));
    4035        this.element.addEventListener("click", this._handleClick.bind(this));
    4136        this.element.addEventListener("mouseleave", this._handleMouseLeave.bind(this));
    4237
     38        this.element.createChild("div", "top-border");
     39
    4340        this._tabBarItems = [];
    4441
    4542        if (tabBarItems) {
    46             for (var tabBarItem in tabBarItems)
     43            for (let tabBarItem in tabBarItems)
    4744                this.addTabBarItem(tabBarItem);
    4845        }
     46
     47        this.addTabBarItem(WebInspector.settingsTabContentView.tabBarItem, true);
     48
     49        this._newTabTabBarItem = new WebInspector.PinnedTabBarItem("Images/NewTabPlus.svg", WebInspector.UIString("Create a new tab"));
     50        this._newTabTabBarItem.element.addEventListener("mouseenter", this._handleNewTabMouseEnter.bind(this));
     51        this._newTabTabBarItem.element.addEventListener("click", this._handleNewTabClick.bind(this));
     52        this.addTabBarItem(this._newTabTabBarItem, true);
    4953    }
    5054
    5155    // Public
    5256
    53     get newTabItem()
    54     {
    55         return this._newTabItem || null;
    56     }
    57 
    58     set newTabItem(newTabItem)
    59     {
    60         if (!this._handleNewTabClickListener)
    61             this._handleNewTabClickListener = this._handleNewTabClick.bind(this);
    62 
    63         if (!this._handleNewTabMouseEnterListener)
    64             this._handleNewTabMouseEnterListener = this._handleNewTabMouseEnter.bind(this);
    65 
    66         if (this._newTabItem) {
    67             this._newTabItem.element.classList.remove("new-tab-button");
    68             this._newTabItem.element.removeEventListener("click", this._handleNewTabClickListener);
    69             this._newTabItem.element.removeEventListener("mouseenter", this._handleNewTabMouseEnterListener);
    70             this.removeTabBarItem(this._newTabItem, true);
    71         }
    72 
    73         if (newTabItem) {
    74             newTabItem.element.classList.add("new-tab-button");
    75             newTabItem.element.addEventListener("click", this._handleNewTabClickListener);
    76             newTabItem.element.addEventListener("mouseenter", this._handleNewTabMouseEnterListener);
    77             this.addTabBarItem(newTabItem, true);
    78         }
    79 
    80         this._newTabItem = newTabItem || null;
     57    get newTabTabBarItem() { return this._newTabTabBarItem; }
     58
     59    updateNewTabTabBarItemState()
     60    {
     61        let newTabExists = !WebInspector.isNewTabWithTypeAllowed(WebInspector.NewTabContentView.Type);
     62        this._newTabTabBarItem.disabled = newTabExists;
    8163    }
    8264
     
    10890        tabBarItem.parentTabBar = this;
    10991
    110         var lastIndex = this._newTabItem ? this._tabBarItems.length - 1 : this._tabBarItems.length;
    111         index = Math.max(0, Math.min(index, lastIndex));
     92        index = Number.constrain(index, 0, this.normalTabCount);
    11293
    11394        if (this.element.classList.contains("animating")) {
     
    123104
    124105        var nextSibling = this._tabBarItems[index + 1];
    125         var nextSiblingElement = nextSibling ? nextSibling.element : (this._newTabItem ? this._newTabItem.element : null);
    126 
    127         this.element.insertBefore(tabBarItem.element, nextSiblingElement);
     106        let nextSiblingElement = nextSibling ? nextSibling.element : this._tabBarItems.lastValue.element;
     107
     108        if (this.element.isAncestor(nextSiblingElement))
     109            this.element.insertBefore(tabBarItem.element, nextSiblingElement);
     110        else
     111            this.element.appendChild(tabBarItem.element);
    128112
    129113        this.element.classList.toggle("single-tab", !this._hasMoreThanOneNormalTab());
     
    179163            this.needsLayout();
    180164
     165        if (!(tabBarItem instanceof WebInspector.PinnedTabBarItem))
     166            this.updateNewTabTabBarItemState();
     167
    181168        this.dispatchEventToListeners(WebInspector.TabBar.Event.TabBarItemAdded, {tabBarItem});
    182169
     
    186173    removeTabBarItem(tabBarItemOrIndex, doNotAnimate, doNotExpand)
    187174    {
    188         var tabBarItem = this._findTabBarItem(tabBarItemOrIndex);
    189         if (!tabBarItem)
     175        let tabBarItem = this._findTabBarItem(tabBarItemOrIndex);
     176        if (!tabBarItem || tabBarItem instanceof WebInspector.PinnedTabBarItem)
    190177            return null;
    191178
    192179        tabBarItem.parentTabBar = null;
    193 
    194         if (tabBarItem === this._newTabItem)
    195             this.newTabItem = null;
    196180
    197181        if (this._selectedTabBarItem === tabBarItem) {
    198182            var index = this._tabBarItems.indexOf(tabBarItem);
    199183            var nextTabBarItem = this._tabBarItems[index + 1];
    200             if (!nextTabBarItem || nextTabBarItem.pinned)
     184            if (!nextTabBarItem || nextTabBarItem instanceof WebInspector.PinnedTabBarItem)
    201185                nextTabBarItem = this._tabBarItems[index - 1];
    202186
     
    213197            beforeTabSizesAndPositions = this._recordTabBarItemSizesAndPositions();
    214198
    215         var wasLastNormalTab = this._tabBarItems.indexOf(tabBarItem) === (this._newTabItem ? this._tabBarItems.length - 2 : this._tabBarItems.length - 1);
     199        // Subtract 1 from normalTabCount since arrays begin indexing at 0.
     200        let wasLastNormalTab = this._tabBarItems.indexOf(tabBarItem) === this.normalTabCount - 1;
    216201
    217202        this._tabBarItems.remove(tabBarItem);
     
    221206        this.element.classList.toggle("single-tab", !hasMoreThanOneNormalTab);
    222207
    223         const shouldOpenDefaultTab = !tabBarItem.isDefaultTab && !this.hasNormalTab();
     208        const shouldOpenDefaultTab = !tabBarItem.isDefaultTab && !this.normalTabCount;
    224209        if (shouldOpenDefaultTab)
    225210            doNotAnimate = true;
     
    232217                this.needsLayout();
    233218
     219            this.updateNewTabTabBarItemState();
     220
    234221            this.dispatchEventToListeners(WebInspector.TabBar.Event.TabBarItemRemoved, {tabBarItem});
    235222
     
    251238                var sizeAndPosition = beforeTabSizesAndPositions.get(currentTabBarItem);
    252239
    253                 if (!currentTabBarItem.pinned) {
     240                if (!(currentTabBarItem instanceof WebInspector.PinnedTabBarItem)) {
    254241                    currentTabBarItem.element.style.left = left + "px";
    255242                    left += sizeAndPosition.width;
     
    295282        } else
    296283            this.needsLayout();
     284
     285        this.updateNewTabTabBarItemState();
    297286
    298287        this.dispatchEventToListeners(WebInspector.TabBar.Event.TabBarItemRemoved, {tabBarItem});
     
    317306                newIndex--;
    318307
    319             if (!this._tabBarItems[newIndex].pinned)
     308            if (!(this._tabBarItems[newIndex] instanceof WebInspector.PinnedTabBarItem))
    320309                break;
    321310        } while (newIndex !== startIndex);
     
    340329                newIndex++;
    341330
    342             if (!this._tabBarItems[newIndex].pinned)
     331            if (!(this._tabBarItems[newIndex] instanceof WebInspector.PinnedTabBarItem))
    343332                break;
    344333        } while (newIndex !== startIndex);
     
    357346    set selectedTabBarItem(tabBarItemOrIndex)
    358347    {
    359         var tabBarItem = this._findTabBarItem(tabBarItemOrIndex);
    360         if (tabBarItem === this._newTabItem)
    361             tabBarItem = this._tabBarItems[this._tabBarItems.length - 2];
     348        let tabBarItem = this._findTabBarItem(tabBarItemOrIndex);
     349        if (tabBarItem === this._newTabTabBarItem) {
     350            // Get the item before the New-Tab item since it is not selectable.
     351            tabBarItem = this._tabBarItems[this.normalTabCount - 1];
     352        }
    362353
    363354        if (this._selectedTabBarItem === tabBarItem)
     
    380371    }
    381372
    382     hasNormalTab()
    383     {
    384         return this._tabBarItems.some((tab) => !tab.pinned);
     373    get normalTabCount()
     374    {
     375        return this._tabBarItems.filter((item) => !(item instanceof WebInspector.PinnedTabBarItem)).length;
    385376    }
    386377
     
    397388        let firstNormalTabItem = null;
    398389        for (let tabItem of this._tabBarItems) {
    399             if (tabItem.pinned)
     390            if (tabItem instanceof WebInspector.PinnedTabBarItem)
    400391                continue;
     392
    401393            firstNormalTabItem = tabItem;
    402394            break;
     
    434426    _hasMoreThanOneNormalTab()
    435427    {
    436         var normalTabCount = 0;
    437         for (var tabBarItem of this._tabBarItems) {
    438             if (tabBarItem.pinned)
     428        let normalTabCount = 0;
     429        for (let tabBarItem of this._tabBarItems) {
     430            if (tabBarItem instanceof WebInspector.PinnedTabBarItem)
    439431                continue;
     432
    440433            ++normalTabCount;
    441434            if (normalTabCount >= 2)
     
    540533            return;
    541534
    542         var itemElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.TabBarItem.StyleClassName);
     535        let itemElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.TabBarItem.StyleClassName);
    543536        if (!itemElement)
    544537            return;
    545538
    546         var tabBarItem = itemElement[WebInspector.TabBarItem.ElementReferenceSymbol];
     539        let tabBarItem = itemElement[WebInspector.TabBarItem.ElementReferenceSymbol];
    547540        if (!tabBarItem)
    548541            return;
     
    551544            return;
    552545
    553         if (tabBarItem === this._newTabItem)
    554             return;
    555 
    556         var closeButtonElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.TabBarItem.CloseButtonStyleClassName);
     546        if (tabBarItem === this._newTabTabBarItem)
     547            return;
     548
     549        let closeButtonElement = event.target.enclosingNodeOrSelfWithClass(WebInspector.TabBarItem.CloseButtonStyleClassName);
    557550        if (closeButtonElement)
    558551            return;
     
    560553        this.selectedTabBarItem = tabBarItem;
    561554
    562         if (tabBarItem.pinned || !this._hasMoreThanOneNormalTab())
     555        if (tabBarItem instanceof WebInspector.PinnedTabBarItem || !this._hasMoreThanOneNormalTab())
    563556            return;
    564557
    565558        this._firstNormalTabItemIndex = 0;
    566         for (var i = 0; i < this._tabBarItems.length; ++i) {
    567             if (this._tabBarItems[i].pinned)
     559        for (let i = 0; i < this._tabBarItems.length; ++i) {
     560            if (this._tabBarItems[i] instanceof WebInspector.PinnedTabBarItem)
    568561                continue;
     562
    569563            this._firstNormalTabItemIndex = i;
    570564            break;
     
    642636        var newIndex = currentIndex;
    643637
    644         for (var tabBarItem of this._tabBarItems) {
     638        for (let tabBarItem of this._tabBarItems) {
    645639            if (tabBarItem === this._selectedTabBarItem)
    646640                continue;
     
    655649        }
    656650
    657         newIndex = Math.max(this._firstNormalTabItemIndex, newIndex);
    658         newIndex = Math.min(this._newTabItem ? this._tabBarItems.length - 2 : this._tabBarItems.length - 1, newIndex);
     651        // Subtract 1 from normalTabCount since arrays begin indexing at 0.
     652        newIndex = Number.constrain(newIndex, this._firstNormalTabItemIndex, this.normalTabCount - 1);
    659653
    660654        if (currentIndex === newIndex)
     
    664658        this._tabBarItems.splice(newIndex, 0, this._selectedTabBarItem);
    665659
    666         var nextSibling = this._tabBarItems[newIndex + 1];
    667         var nextSiblingElement = nextSibling ? nextSibling.element : (this._newTabItem ? this._newTabItem.element : null);
     660        let nextSibling = this._tabBarItems[newIndex + 1];
     661        let nextSiblingElement = nextSibling ? nextSibling.element : this._newTabTabBarItem.element;
    668662
    669663        this.element.insertBefore(this._selectedTabBarItem.element, nextSiblingElement);
     
    671665        // FIXME: Animate the tabs that move to make room for the selected tab. This was causing me trouble when I tried.
    672666
    673         var left = 0;
    674         for (var tabBarItem of this._tabBarItems) {
    675             if (tabBarItem !== this._selectedTabBarItem && tabBarItem !== this._newTabItem && parseFloat(tabBarItem.element.style.left) !== left)
     667        let left = 0;
     668        for (let tabBarItem of this._tabBarItems) {
     669            if (tabBarItem !== this._selectedTabBarItem && tabBarItem !== this._newTabTabBarItem && parseFloat(tabBarItem.element.style.left) !== left)
    676670                tabBarItem.element.style.left = left + "px";
    677671            left += parseFloat(tabBarItem.element.style.width);
     
    724718        // FIXME: Is this a WebKit bug or correct behavior?
    725719        const barRect = this.element.getBoundingClientRect();
    726         const newTabItemRect = this._newTabItem ? this._newTabItem.element.getBoundingClientRect() : null;
     720        const newTabItemRect = this._newTabTabBarItem.element.getBoundingClientRect();
    727721        if (event.pageY > barRect.top && event.pageY < barRect.bottom && event.pageX > barRect.left && event.pageX < (newTabItemRect ? newTabItemRect.right : barRect.right))
    728722            return;
     
    733727    _handleNewTabClick(event)
    734728    {
    735         if (this._newTabItem.disabled)
    736             return;
    737         this.dispatchEventToListeners(WebInspector.TabBar.Event.NewTabItemClicked);
     729        const shouldAnimate = true;
     730        WebInspector.showNewTabTab(shouldAnimate);
    738731    }
    739732
     
    752745    TabBarItemRemoved: "tab-bar-tab-bar-item-removed",
    753746    TabBarItemsReordered: "tab-bar-tab-bar-items-reordered",
    754     NewTabItemClicked: "tab-bar-new-tab-item-clicked",
    755747    OpenDefaultTab: "tab-bar-open-default-tab"
    756748};
  • trunk/Source/WebInspectorUI/UserInterface/Views/TabBarItem.js

    r202711 r208091  
    11/*
    22 * Copyright (C) 2015 Apple Inc. All rights reserved.
     3 * Copyright (C) 2016 Devin Rousso <dcrousso+webkit@gmail.com>. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2627WebInspector.TabBarItem = class TabBarItem extends WebInspector.Object
    2728{
    28     constructor(image, title, pinned, representedObject)
     29    constructor(image, title, representedObject)
    2930    {
    3031        super();
     
    3637        this._element.setAttribute("role", "tab");
    3738        this._element.tabIndex = 0;
    38         if (pinned)
    39             this._element.classList.add("pinned");
    4039        this._element[WebInspector.TabBarItem.ElementReferenceSymbol] = this;
    4140
    42         if (!pinned) {
    43             this._closeButtonElement = document.createElement("div");
    44             this._closeButtonElement.classList.add(WebInspector.TabBarItem.CloseButtonStyleClassName);
    45             this._closeButtonElement.title = WebInspector.UIString("Click to close this tab");
    46             this._element.appendChild(this._closeButtonElement);
    47 
    48             var flexSpaceElement = document.createElement("div");
    49             flexSpaceElement.classList.add("flex-space");
    50             this._element.appendChild(flexSpaceElement);
    51 
    52             this._element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
    53         }
     41        this._element.createChild("div", "flex-space");
    5442
    5543        this._iconElement = document.createElement("img");
     
    5745        this._element.appendChild(this._iconElement);
    5846
    59         if (!pinned) {
    60             var flexSpaceElement = document.createElement("div");
    61             flexSpaceElement.classList.add("flex-space");
    62             this._element.appendChild(flexSpaceElement);
    63         }
     47        this._element.createChild("div", "flex-space");
    6448
    6549        this.title = title;
     
    7054    // Public
    7155
    72     get element()
    73     {
    74         return this._element;
    75     }
     56    get element() { return this._element; }
    7657
    77     get representedObject()
    78     {
    79         return this._representedObject;
    80     }
     58    get representedObject() { return this._representedObject; }
     59    set representedObject(representedObject) { this._representedObject = representedObject || null; }
    8160
    82     set representedObject(representedObject)
    83     {
    84         this._representedObject = representedObject || null;
    85     }
    86 
    87     get parentTabBar()
    88     {
    89         return this._parentTabBar;
    90     }
    91 
    92     set parentTabBar(tabBar)
    93     {
    94         this._parentTabBar = tabBar || null;
    95     }
     61    get parentTabBar() { return this._parentTabBar; }
     62    set parentTabBar(tabBar){ this._parentTabBar = tabBar || null; }
    9663
    9764    get selected()
     
    13097    }
    13198
    132     get pinned()
    133     {
    134         return this._element.classList.contains("pinned");
    135     }
     99    get image() { return this._iconElement.src; }
     100    set image(url) { this._iconElement.src = url || ""; }
    136101
    137     get image()
    138     {
    139         return this._iconElement.src;
    140     }
    141 
    142     set image(url)
    143     {
    144         this._iconElement.src = url || "";
    145     }
    146 
    147     get title()
    148     {
    149         return this._element.title || "";
    150     }
    151 
    152     set title(title)
    153     {
    154         if (title && !this.pinned) {
    155             this._titleElement = document.createElement("span");
    156             this._titleElement.classList.add("title");
    157 
    158             this._titleContentElement = document.createElement("span");
    159             this._titleContentElement.classList.add("content");
    160             this._titleElement.appendChild(this._titleContentElement);
    161 
    162             this._titleContentElement.textContent = title;
    163 
    164             this._element.insertBefore(this._titleElement, this._element.lastChild);
    165         } else {
    166             if (this._titleElement)
    167                 this._titleElement.remove();
    168 
    169             this._titleContentElement = null;
    170             this._titleElement = null;
    171         }
    172 
    173         this._element.title = title || "";
    174     }
    175 
    176     // Private
    177 
    178     _handleContextMenuEvent(event)
    179     {
    180         if (!this._parentTabBar)
    181             return;
    182 
    183         let closeTab = () => {
    184             this._parentTabBar.removeTabBarItem(this);
    185         };
    186 
    187         let closeOtherTabs = () => {
    188             let tabBarItems = this._parentTabBar.tabBarItems;
    189             for (let i = tabBarItems.length - 1; i >= 0; --i) {
    190                 let item = tabBarItems[i];
    191                 if (item === this || item.pinned)
    192                     continue;
    193                 this._parentTabBar.removeTabBarItem(item);
    194             }
    195         };
    196 
    197         let hasOtherNonPinnedTabs = this._parentTabBar.tabBarItems.some((item) => item !== this && !item.pinned);
    198         let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
    199         contextMenu.appendItem(WebInspector.UIString("Close Tab"), closeTab, this.isDefaultTab);
    200         contextMenu.appendItem(WebInspector.UIString("Close Other Tabs"), closeOtherTabs, !hasOtherNonPinnedTabs);
    201     }
     102    get title() { return this._element.title || ""; }
     103    set title(title) { this._element.title = title || ""; }
    202104};
    203105
  • trunk/Source/WebInspectorUI/UserInterface/Views/TabBrowser.js

    r205425 r208091  
    5454        let closeCurrentTab = () => {
    5555            let selectedTabBarItem = this._tabBar.selectedTabBarItem;
    56             if (this._tabBar.tabBarItems.length > 2 || !selectedTabBarItem.isDefaultTab)
     56            if (this._tabBar.tabBarItems.length > 3 || !selectedTabBarItem.isDefaultTab)
    5757                this._tabBar.removeTabBarItem(selectedTabBarItem);
    5858        };
     
    7070        this._showPreviousTabKeyboardShortcut3.implicitlyPreventsDefault = false;
    7171
    72         this._tabBar.newTabItem = new WebInspector.TabBarItem("Images/NewTabPlus.svg", WebInspector.UIString("Create a new tab"), true);
    73 
    7472        this._tabBar.addEventListener(WebInspector.TabBar.Event.TabBarItemSelected, this._tabBarItemSelected, this);
    7573        this._tabBar.addEventListener(WebInspector.TabBar.Event.TabBarItemRemoved, this._tabBarItemRemoved, this);
     
    130128            return false;
    131129
    132         var tabBarItem = tabContentView.tabBarItem;
     130        let tabBarItem = tabContentView.tabBarItem;
    133131
    134132        console.assert(tabBarItem instanceof WebInspector.TabBarItem);
     
    156154            this._tabBar.addTabBarItem(tabBarItem, doNotAnimate);
    157155
    158         console.assert(this._recentTabContentViews.length === this._tabBar.tabBarItems.length - (this._tabBar.newTabItem ? 1 : 0));
     156        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
    159157        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
    160158
     
    194192        this._tabBar.removeTabBarItem(tabContentView.tabBarItem, doNotAnimate);
    195193
    196         console.assert(this._recentTabContentViews.length === this._tabBar.tabBarItems.length - (this._tabBar.newTabItem ? 1 : 0));
     194        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
    197195        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
    198196
     
    215213    _tabBarItemSelected(event)
    216214    {
    217         var tabContentView = this._tabBar.selectedTabBarItem ? this._tabBar.selectedTabBarItem.representedObject : null;
     215        let tabContentView = this._tabBar.selectedTabBarItem ? this._tabBar.selectedTabBarItem.representedObject : null;
    218216
    219217        if (tabContentView) {
    220             this._recentTabContentViews.remove(tabContentView);
    221             this._recentTabContentViews.unshift(tabContentView);
     218            let isSettingsTab = tabContentView instanceof WebInspector.SettingsTabContentView;
     219            if (!isSettingsTab) {
     220                this._recentTabContentViews.remove(tabContentView);
     221                this._recentTabContentViews.unshift(tabContentView);
     222            }
    222223
    223224            this._contentViewContainer.showContentView(tabContentView);
    224225
    225226            console.assert(this.selectedTabContentView);
    226             console.assert(this._recentTabContentViews.length === this._tabBar.tabBarItems.length - (this._tabBar.newTabItem ? 1 : 0));
    227             console.assert(this.selectedTabContentView === this._recentTabContentViews[0]);
     227            console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
     228            console.assert(this.selectedTabContentView === this._recentTabContentViews[0] || isSettingsTab);
    228229        } else {
    229230            this._contentViewContainer.closeAllContentViews();
     
    246247    _tabBarItemRemoved(event)
    247248    {
    248         var tabContentView = event.data.tabBarItem.representedObject;
     249        let tabContentView = event.data.tabBarItem.representedObject;
    249250
    250251        console.assert(tabContentView);
     
    257258        tabContentView.parentTabBrowser = null;
    258259
    259         console.assert(this._recentTabContentViews.length === this._tabBar.tabBarItems.length - (this._tabBar.newTabItem ? 1 : 0));
     260        console.assert(this._recentTabContentViews.length === this._tabBar.normalTabCount);
    260261        console.assert(!this.selectedTabContentView || this.selectedTabContentView === this._recentTabContentViews[0]);
    261262    }
  • trunk/Source/WebInspectorUI/UserInterface/Views/TabContentView.js

    r203912 r208091  
    127127    shown()
    128128    {
     129        super.shown();
     130
    129131        if (this._shouldRestoreStateWhenShown)
    130132            this.restoreStateFromCookie(WebInspector.StateRestorationType.Delayed);
  • trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js

    r207358 r208091  
    3232        this.element.classList.add("text-editor", WebInspector.SyntaxHighlightedStyleClassName);
    3333
    34         // FIXME: <https://webkit.org/b/149120> Web Inspector: Preferences for Text Editor behavior
    3534        this._codeMirror = WebInspector.CodeMirrorEditor.create(this.element, {
    3635            readOnly: true,
    37             indentWithTabs: true,
    38             indentUnit: 4,
     36            indentWithTabs: WebInspector.settings.indentWithTabs.value,
     37            indentUnit: WebInspector.settings.indentUnit.value,
     38            tabSize: WebInspector.settings.tabSize.value,
    3939            lineNumbers: true,
    40             lineWrapping: false,
     40            lineWrapping: WebInspector.settings.enableLineWrapping.value,
    4141            matchBrackets: true,
    4242            autoCloseBrackets: true,
     43            showWhitespaceCharacters: WebInspector.settings.showWhitespaceCharacters.value,
    4344            styleSelectedText: true,
     45        });
     46
     47        WebInspector.settings.indentWithTabs.addEventListener(WebInspector.Setting.Event.Changed, (event) => {
     48            this._codeMirror.setOption("indentWithTabs", WebInspector.settings.indentWithTabs.value);
     49        });
     50
     51        WebInspector.settings.indentUnit.addEventListener(WebInspector.Setting.Event.Changed, (event) => {
     52            this._codeMirror.setOption("indentUnit", WebInspector.settings.indentUnit.value);
     53        });
     54
     55        WebInspector.settings.tabSize.addEventListener(WebInspector.Setting.Event.Changed, (event) => {
     56            this._codeMirror.setOption("tabSize", WebInspector.settings.tabSize.value);
     57        });
     58
     59        WebInspector.settings.enableLineWrapping.addEventListener(WebInspector.Setting.Event.Changed, (event) => {
     60            this._codeMirror.setOption("lineWrapping", WebInspector.settings.enableLineWrapping.value);
     61        });
     62
     63        WebInspector.settings.showWhitespaceCharacters.addEventListener(WebInspector.Setting.Event.Changed, (event) => {
     64            this._codeMirror.setOption("showWhitespaceCharacters", WebInspector.settings.showWhitespaceCharacters.value);
    4465        });
    4566
     
    531552    {
    532553        this._visible = false;
     554    }
     555
     556    close()
     557    {
     558        WebInspector.settings.indentWithTabs.removeEventListener(null, null, this);
     559        WebInspector.settings.indentUnit.removeEventListener(null, null, this);
     560        WebInspector.settings.tabSize.removeEventListener(null, null, this);
     561        WebInspector.settings.enableLineWrapping.removeEventListener(null, null, this);
     562        WebInspector.settings.showWhitespaceCharacters.removeEventListener(null, null, this);
    533563    }
    534564
     
    808838    _startWorkerPrettyPrint(beforePrettyPrintState, callback)
    809839    {
    810         // <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    811         let indentString = "    ";
    812840        let sourceText = this._codeMirror.getValue();
    813         let includeSourceMapData = true;
     841        let indentString = WebInspector.indentString();
     842        const includeSourceMapData = true;
    814843
    815844        // FIXME: Properly pass if this is a module or script.
     
    829858    _startCodeMirrorPrettyPrint(beforePrettyPrintState, callback)
    830859    {
    831         // <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    832         let indentString = "    ";
     860        let indentString = WebInspector.indentString();
    833861        let start = {line: 0, ch: 0};
    834862        let end = {line: this._codeMirror.lineCount() - 1};
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js

    r207473 r208091  
    175175    shown()
    176176    {
     177        super.shown();
     178
    177179        this._timelineOverview.shown();
    178180        this._timelineContentBrowser.shown();
     
    187189    hidden()
    188190    {
     191        super.hidden();
     192
    189193        this._timelineOverview.hidden();
    190194        this._timelineContentBrowser.hidden();
     
    196200    closed()
    197201    {
     202        super.closed();
     203
    198204        this._timelineContentBrowser.contentViewContainer.closeAllContentViews();
    199205
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

    r205425 r208091  
    2929    {
    3030        let {image, title} = WebInspector.TimelineTabContentView.tabInfo();
    31         let tabBarItem = new WebInspector.TabBarItem(image, title);
     31        let tabBarItem = new WebInspector.GeneralTabBarItem(image, title);
    3232        let detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
    3333
  • trunk/Source/WebInspectorUI/UserInterface/Views/VisualStylePropertyEditor.js

    r205426 r208091  
    123123        styleText = styleText || "";
    124124
    125         // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
    126         let linePrefixText = "    ";
     125        let linePrefixText = WebInspector.indentString();
    127126        let lineSuffixWhitespace = "\n";
    128127        let trimmedText = styleText.trimRight();
Note: See TracChangeset for help on using the changeset viewer.