summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/devtools/front_end
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Source/devtools/front_end
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/devtools/front_end')
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/AdvancedSearchController.js802
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowCollectionsView.js433
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowView.js256
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorUtils.js104
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ConsoleModel.js325
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ConsoleView.js1079
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/DOMCountersGraph.js388
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/DevToolsExtensionAPI.js65
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/DockController.js177
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Drawer.js395
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanelDescriptor.js199
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/FlameChart.js907
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ForwardedInputEventHandler.js31
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotView.js1858
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint.pngbin0 -> 154 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2.pngbin161 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2_2x.pngbin233 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointBorder.pngbin190 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional.pngbin0 -> 157 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2.pngbin162 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2_2x.pngbin235 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalBorder.pngbin191 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalCounterBorder.pngbin348 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional_2x.pngbin0 -> 230 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointCounterBorder.pngbin343 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint_2x.pngbin0 -> 228 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeader.pngbin87 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderPressed.pngbin86 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelected.pngbin121 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelectedPressed.pngbin121 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/namedFlowOverflow.pngbin107 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/programCounterBorder.pngbin216 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/regionEmpty.pngbin97 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/regionFit.pngbin87 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/regionOverset.pngbin107 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign.pngbin0 -> 412 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign_2x.pngbin0 -> 781 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.pngbin550 -> 540 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove_2x.pngbin754 -> 741 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/spinner.gifbin1684 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActive.gifbin3208 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActiveSelected.gifbin3208 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactive.gifbin3208 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactiveSelected.gifbin3208 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoint.svg6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpointConditional.svg6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoints2.svg104
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/responsiveDesign.svg11
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingListRemove.svg195
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingsListRemove.svg16
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/statusbarButtonGlyphs.svg2508
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs.pngbin6731 -> 6313 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs2x.pngbin16194 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs_2x.pngbin0 -> 14957 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillBlue.pngbin745 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGray.pngbin436 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGreen.pngbin748 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillOrange.pngbin740 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillPurple.pngbin736 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillRed.pngbin752 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillYellow.pngbin739 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillBlue.pngbin612 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGray.pngbin371 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGreen.pngbin618 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillOrange.pngbin617 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillPurple.pngbin632 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillRed.pngbin609 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillYellow.pngbin612 -> 0 bytes
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/InspectorBackend.js408
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendAPI.js114
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendEventSink.js43
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendHostStub.js195
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/LayerTreeModel.js488
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Layers3DView.js450
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/LayersPanel.js171
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/MediaQueryInspector.js371
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/MemoryStatistics.js428
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/NavigatorOverlayController.js179
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/NetworkUISourceCodeProvider.js145
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/OWNERS1
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/OverridesSupport.js547
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/OverridesView.js1089
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/RawSourceCode.js0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ResponsiveDesignView.js518
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ScreencastView.js384
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ShortcutsScreen.js213
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SidebarOverlay.js180
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SidebarView.js117
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SourcesNavigator.js251
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanel.js1730
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanelDescriptor.js159
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/SplitView.js525
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TempFile.js165
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TestController.js2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/Tests.js169
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameController.js188
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelineGrid.js254
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelineModel.js528
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanel.js2108
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanelDescriptor.js62
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js1891
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/TracingAgent.js114
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ViewportControl.js172
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/WorkerManager.js298
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategories.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditCategories.js)16
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategory.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/LayersPanelDescriptor.js)35
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditController.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditController.js)19
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditFormatters.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditFormatters.js)25
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditLauncherView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditLauncherView.js)26
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditResultView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditResultView.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditRules.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditRules.js)519
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditsPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AuditsPanel.js)42
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/audits/module.json12
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/auditsPanel.css20
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/breakpointsList.css13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/buildSystemOnly.js7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/canvasProfiler.css13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/clike.js3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js133
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/cmdevtools.css23
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.css51
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.js5542
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/coffeescript.js631
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/comment.js28
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/css.js116
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/headlesscodemirror.js219
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/htmlmixed.js2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/javascript.js362
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/markselection.js25
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/matchbrackets.js121
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/php.js8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/python.js39
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cm/xml.js10
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Color.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Color.js)7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/CompletionDictionary.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CompletionDictionary.js)9
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/DOMExtension.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMExtension.js)296
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Geometry.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Geometry.js)83
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/MessageSink.js79
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/ModuleManager.js487
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Object.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Object.js)53
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ParsedURL.js)20
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Platform.js161
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Progress.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Progress.js)11
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Settings.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Settings.js)398
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/TextRange.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TextRange.js)72
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/Throttler.js88
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/UIString.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/UIString.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/UserMetrics.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/UserMetrics.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/WebInspector.js46
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/modules.js1
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/common/utilities.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/utilities.js)524
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/CookiesTable.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CookiesTable.js)9
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMBreakpointsSidebarPane.js)79
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMPresentationUtils.js)61
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/DockController.js198
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/Drawer.js333
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/ExecutionContextSelector.js134
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/ExtensionServerProxy.js69
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/FilterBar.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FilterBar.js)265
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/FilterSuggestionBuilder.js193
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/FlameChart.js967
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HandlerRegistry.js)108
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/HelpScreen.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HelpScreen.js)50
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/InspectElementModeController.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/InspectElementModeController.js)70
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/InspectedPagePlaceholder.js123
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/InspectorView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/InspectorView.js)428
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/NativeBreakpointsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NativeBreakpointsSidebarPane.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ObjectPopoverHelper.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ObjectPropertiesSection.js)123
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/OverviewGrid.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/OverviewGrid.js)20
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/Panel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Panel.js)197
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/PropertiesSection.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSection.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/SearchableView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SearchableView.js)202
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/Section.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Section.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/ShortcutsScreen.js534
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/TimelineGrid.js353
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/components/WorkerFrontendManager.js172
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/console/ConsolePanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ConsolePanel.js)112
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js1228
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ConsoleMessage.js)629
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/console/module.json55
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/cssNamedFlows.css99
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/dataGrid.css91
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js186
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/devices/module.json13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/devicesView.css53
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/dialog.css6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/DOMSyntaxHighlighter.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMSyntaxHighlighter.js)10
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanel.js)782
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ElementsTreeOutline.js)401
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/EventListenersSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/EventListenersSidebarPane.js)98
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/MetricsSidebarPane.js)77
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/OverridesView.js653
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/PlatformFontsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PlatformFontsSidebarPane.js)26
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/PropertiesSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSidebarPane.js)5
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/RenderingOptionsView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RenderingOptionsView.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Spectrum.js)26
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/StylesSidebarPane.js)846
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elements/module.json92
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/elementsPanel.css97
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAPI.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAPI.js)238
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAuditCategory.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAuditCategory.js)44
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionPanel.js)12
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionRegistryStub.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionRegistryStub.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionServer.js)292
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ExtensionView.js)8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/extensions/module.json10
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/externs.js281
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/filter.css39
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/filteredItemSelectionDialog.css31
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/flameChart.css45
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/heapProfiler.css219
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/helpScreen.css59
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/inspector.css630
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/inspector.html298
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/inspector.js966
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/inspectorCommon.css36
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/inspectorSyntaxHighlight.css13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerDetailsView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/LayerDetailsView.js)62
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerPaintProfilerView.js59
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeOutline.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/LayerTree.js)65
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/LayersPanel.js233
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/PaintProfilerView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PaintProfilerView.js)235
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layers/module.json18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/layersPanel.css80
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/AdvancedApp.js198
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/App.js68
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/HelpScreenUntilReload.js57
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/Main.js830
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/ScreencastApp.js90
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/SimpleApp.js23
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/main/module.json169
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/navigatorView.css3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/HAREntry.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HAREntry.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkItemView.js)39
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanel.js)1118
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestCookiesView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestCookiesView.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestHTMLView.js)3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHeadersView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestHeadersView.js)57
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestJSONView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestJSONView.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestPreviewView.js)70
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestResponseView.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestTimingView.js)38
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/RequestView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RequestView.js)15
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceWebSocketFrameView.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/network/module.json23
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/networkLogView.css142
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/networkPanel.css41
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/overrides.css161
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/panelEnablerView.css15
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/popover.css2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileBottomUpDataGrid.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/BottomUpProfileDataGridTree.js)9
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileDataGrid.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ProfileDataGridTree.js)99
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js650
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileTopDownDataGrid.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TopDownProfileDataGridTree.js)1
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CPUProfileView.js)623
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasProfileView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CanvasProfileView.js)166
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasReplayStateView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CanvasReplayStateView.js)16
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotCommon.js349
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotDataGrids.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotDataGrids.js)696
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotGridNodes.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotGridNodes.js)964
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotProxy.js)364
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js2285
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfileLauncherView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ProfileLauncherView.js)39
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanel.js)904
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/AllocationProfile.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/AllocationProfile.js)228
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshot.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshot.js)1220
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotLoader.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotLoader.js)15
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorker.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorker.js)8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorkerDispatcher.js)10
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/JSHeapSnapshot.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/JSHeapSnapshot.js)303
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profiler/module.json31
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/profilesPanel.css115
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resourceView.css13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheItemsView.js)28
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CookieItemsView.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMStorageItemsView.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DatabaseQueryView.js)34
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DatabaseTableView.js)8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/DirectoryContentView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DirectoryContentView.js)3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/FileContentView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileContentView.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileSystemView.js)14
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBViews.js)36
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourcesPanel.js)179
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resources/module.json18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/resourcesPanel.css16
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/responsiveDesignView.css494
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/screencastView.css54
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/CSSFormatter.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CSSFormatter.js)8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/JavaScriptFormatter.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptFormatter.js)14
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/ScriptFormatterWorker.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatterWorker.js)219
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ApplicationCacheModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheModel.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/BreakpointManager.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/BreakpointManager.js)560
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileModel.js288
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanelDescriptor.js)105
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CSSMetadata.js)68
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js129
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleModel.js)1003
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleSheetMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleSheetMapping.js)6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CompilerScriptMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CompilerScriptMapping.js)57
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js468
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProvider.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ContentProvider.js)11
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviderBasedProjectDelegate.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ContentProviderBasedProjectDelegate.js)97
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviders.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ContentProviders.js)33
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CookieParser.js)10
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMAgent.js)529
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMStorage.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DOMStorage.js)32
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Database.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Database.js)22
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DebuggerModel.js)508
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerScriptMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DebuggerScriptMapping.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/DefaultScriptMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DefaultScriptMapping.js)51
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileManager.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileManager.js)2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileSystemMapping.js)12
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileSystemModel.js)39
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemWorkspaceBinding.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileSystemProjectDelegate.js)381
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileUtils.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FileUtils.js)35
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBModel.js)57
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js877
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystem.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystem.js)51
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystemManager.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystemManager.js)26
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/LayerTreeModel.js1187
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Linkifier.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Linkifier.js)140
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/LiveEditSupport.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/LiveEditSupport.js)122
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkLog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkLog.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkManager.js)90
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkRequest.js)107
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkUISourceCodeProvider.js265
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkWorkspaceBinding.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SimpleWorkspaceProvider.js)116
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/NotificationService.js22
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/OverridesSupport.js1091
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/PaintProfiler.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PieChart.js)58
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/PowerProfiler.js55
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/PresentationConsoleMessageHelper.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/PresentationConsoleMessageHelper.js)53
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RemoteObject.js)475
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Resource.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Resource.js)60
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceScriptMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceScriptMapping.js)148
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceTreeModel.js)98
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceType.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceType.js)7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceUtils.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceUtils.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RuntimeModel.js)342
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/SASSSourceMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SASSSourceMapping.js)36
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Script.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Script.js)83
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/ScriptSnippetModel.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ScriptSnippetModel.js)433
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/SearchConfig.js180
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/SnippetStorage.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SnippetStorage.js)7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SourceMap.js)44
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SourceMapping.js)7
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/StylesSourceMapping.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/StylesSourceMapping.js)106
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Target.js339
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/TempFile.js359
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/TimelineManager.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TimelineManager.js)111
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/UISourceCode.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/UISourceCode.js)314
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerManager.js209
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerTargetManager.js77
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Workspace.js)238
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkspaceController.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/WorkspaceController.js)3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/search/AdvancedSearchView.js442
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/search/FileBasedSearchResultsPane.js231
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/search/SourcesSearchScope.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SourcesSearchScope.js)109
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/search/module.json27
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/EditFileSystemDialog.js)34
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SettingsScreen.js)458
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/settings/module.json23
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sidebarPane.css30
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js)1058
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorUtils.js174
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/FontView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FontView.js)3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/GoToLineDialog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/GoToLineDialog.js)33
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ImageView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ImageView.js)3
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ResourceView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ResourceView.js)24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/SourceFrame.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SourceFrame.js)243
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/source_frame/module.json26
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/BreakpointsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/BreakpointsSidebarPane.js)267
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CSSSourceFrame.js)2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/CallStackSidebarPane.js)151
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/EditingLocationHistoryManager.js196
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FilePathScoreFunction.js)0
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/FilteredItemSelectionDialog.js)253
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js115
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptSourceFrame.js)598
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NavigatorView.js)333
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/Placard.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Placard.js)20
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/RevisionHistoryView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/RevisionHistoryView.js)13
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ScopeChainSidebarPane.js)28
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatter.js)4
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js379
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/SimpleHistoryManager.js167
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js205
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js1479
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js708
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/StyleSheetOutlineDialog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/StyleSheetOutlineDialog.js)77
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TabbedEditorContainer.js)66
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/TargetsToolbar.js78
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/UISourceCodeFrame.js)50
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/WatchExpressionsSidebarPane.js)64
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/WorkersSidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/WorkersSidebarPane.js)36
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sources/module.json173
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sourcesPanel.css175
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/sourcesView.css89
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/spectrum.css6
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/splitView.css130
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/suggestBox.css (renamed from chromium/third_party/WebKit/Source/devtools/front_end/textPrompt.css)71
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/tabbedPane.css24
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/temp_storage_shared_worker/TempStorageSharedWorker.js141
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/test-runner.html366
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/CountersGraph.js563
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js750
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/MemoryCountersGraph.js100
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TimelineEventOverview.js)54
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js980
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js569
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameOverview.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameOverview.js)158
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js92
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLayersView.js91
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineMemoryOverview.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TimelineMemoryOverview.js)94
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js497
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModelImpl.js739
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineOverviewPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TimelineOverviewPane.js)279
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js1453
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerGraph.js50
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerOverview.js217
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePresentationModel.js607
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTracingView.js556
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js654
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtilsImpl.js571
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineView.js1304
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingModel.js558
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineModel.js661
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineUIUtils.js729
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/TransformController.js237
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timeline/module.json12
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/timelinePanel.css312
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ActionRegistry.js79
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/Checkbox.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Checkbox.js)2
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/Context.js119
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ContextMenu.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ContextMenu.js)57
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/DataGrid.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/DataGrid.js)357
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Dialog.js)60
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/DropDownMenu.js68
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/EmptyView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/EmptyView.js)8
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/InplaceEditor.js260
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/KeyboardShortcut.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/KeyboardShortcut.js)73
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/PieChart.js115
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/Popover.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/Popover.js)18
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ProgressIndicator.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ProgressIndicator.js)9
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ResizerWidget.js156
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SettingsUI.js265
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ShortcutRegistry.js214
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ShowMoreDataGridNode.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/ShowMoreDataGridNode.js)38
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SidebarPane.js)15
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarTreeElement.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SidebarTreeElement.js)44
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SoftContextMenu.js)1
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SplitView.js888
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/StackView.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanelDescriptor.js)51
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/StatusBarButton.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/StatusBarButton.js)222
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/SuggestBox.js)222
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TabbedPane.js)302
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/TextEditor.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TextEditor.js)69
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TextPrompt.js)88
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/TextUtils.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/TextUtils.js)42
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/UIUtils.js)654
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/View.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/View.js)285
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js529
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/ZoomManager.js42
-rw-r--r--chromium/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js (renamed from chromium/third_party/WebKit/Source/devtools/front_end/treeoutline.js)18
467 files changed, 63658 insertions, 39256 deletions
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AdvancedSearchController.js b/chromium/third_party/WebKit/Source/devtools/front_end/AdvancedSearchController.js
deleted file mode 100644
index 54e8f5475df..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AdvancedSearchController.js
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @implements {WebInspector.ViewFactory}
- */
-WebInspector.AdvancedSearchController = function()
-{
- this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
- this._searchId = 0;
-
- WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));
-
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
- WebInspector.inspectorView.registerViewInDrawer("search", WebInspector.UIString("Search"), this);
-}
-
-/**
- * @return {!WebInspector.KeyboardShortcut.Descriptor}
- */
-WebInspector.AdvancedSearchController.createShortcut = function()
-{
- if (WebInspector.isMac())
- return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt);
- else
- return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift);
-}
-
-WebInspector.AdvancedSearchController.prototype = {
- /**
- * @param {string=} id
- * @return {?WebInspector.View}
- */
- createView: function(id)
- {
- if (!this._searchView)
- this._searchView = new WebInspector.SearchView(this);
- return this._searchView;
- },
-
- /**
- * @param {!KeyboardEvent} event
- * @return {boolean}
- */
- handleShortcut: function(event)
- {
- if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
- if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) {
- WebInspector.showPanel("sources");
- this.show();
- } else
- WebInspector.inspectorView.closeDrawer();
- event.consume(true);
- return true;
- }
- return false;
- },
-
- _frameNavigated: function()
- {
- this.resetSearch();
- },
-
- /**
- * @param {!WebInspector.SearchScope} searchScope
- */
- registerSearchScope: function(searchScope)
- {
- // FIXME: implement multiple search scopes.
- this._searchScope = searchScope;
- },
-
- show: function()
- {
- var selection = window.getSelection();
- var queryCandidate;
- if (selection.rangeCount)
- queryCandidate = selection.toString().replace(/\r?\n.*/, "");
-
- if (!this._searchView || !this._searchView.isShowing())
- WebInspector.inspectorView.showViewInDrawer("search");
- if (queryCandidate)
- this._searchView._search.value = queryCandidate;
- this._searchView.focus();
-
- this.startIndexing();
- },
-
- /**
- * @param {boolean} finished
- */
- _onIndexingFinished: function(finished)
- {
- delete this._isIndexing;
- this._searchView.indexingFinished(finished);
- if (!finished)
- delete this._pendingSearchConfig;
- if (!this._pendingSearchConfig)
- return;
- var searchConfig = this._pendingSearchConfig
- delete this._pendingSearchConfig;
- this._innerStartSearch(searchConfig);
- },
-
- startIndexing: function()
- {
- this._isIndexing = true;
- // FIXME: this._currentSearchScope should be initialized based on searchConfig
- this._currentSearchScope = this._searchScope;
- if (this._progressIndicator)
- this._progressIndicator.done();
- this._progressIndicator = new WebInspector.ProgressIndicator();
- this._searchView.indexingStarted(this._progressIndicator);
- this._currentSearchScope.performIndexing(this._progressIndicator, this._onIndexingFinished.bind(this));
- },
-
- /**
- * @param {number} searchId
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- */
- _onSearchResult: function(searchId, searchResult)
- {
- if (searchId !== this._searchId)
- return;
- this._searchView.addSearchResult(searchResult);
- if (!searchResult.searchMatches.length)
- return;
- if (!this._searchResultsPane)
- this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);
- this._searchView.resultsPane = this._searchResultsPane;
- this._searchResultsPane.addSearchResult(searchResult);
- },
-
- /**
- * @param {number} searchId
- * @param {boolean} finished
- */
- _onSearchFinished: function(searchId, finished)
- {
- if (searchId !== this._searchId)
- return;
- if (!this._searchResultsPane)
- this._searchView.nothingFound();
- this._searchView.searchFinished(finished);
- delete this._searchConfig;
- },
-
- /**
- * @param {!WebInspector.SearchConfig} searchConfig
- */
- startSearch: function(searchConfig)
- {
- this.resetSearch();
- ++this._searchId;
- if (!this._isIndexing)
- this.startIndexing();
- this._pendingSearchConfig = searchConfig;
- },
-
- /**
- * @param {!WebInspector.SearchConfig} searchConfig
- */
- _innerStartSearch: function(searchConfig)
- {
- this._searchConfig = searchConfig;
- // FIXME: this._currentSearchScope should be initialized based on searchConfig
- this._currentSearchScope = this._searchScope;
-
- if (this._progressIndicator)
- this._progressIndicator.done();
- this._progressIndicator = new WebInspector.ProgressIndicator();
- this._searchView.searchStarted(this._progressIndicator);
- this._currentSearchScope.performSearch(searchConfig, this._progressIndicator, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
- },
-
- resetSearch: function()
- {
- this.stopSearch();
-
- if (this._searchResultsPane) {
- this._searchView.resetResults();
- delete this._searchResultsPane;
- }
- },
-
- stopSearch: function()
- {
- if (this._progressIndicator)
- this._progressIndicator.cancel();
- if (this._currentSearchScope)
- this._currentSearchScope.stopSearch();
- delete this._searchConfig;
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.AdvancedSearchController} controller
- */
-WebInspector.SearchView = function(controller)
-{
- WebInspector.View.call(this);
-
- this._controller = controller;
-
- this.element.className = "search-view vbox";
-
- this._searchPanelElement = this.element.createChild("div", "search-drawer-header");
- this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
-
- this._searchResultsElement = this.element.createChild("div");
- this._searchResultsElement.className = "search-results";
-
- this._search = this._searchPanelElement.createChild("input");
- this._search.placeholder = WebInspector.UIString("Search sources");
- this._search.setAttribute("type", "text");
- this._search.classList.add("search-config-search");
- this._search.setAttribute("results", "0");
- this._search.setAttribute("size", 30);
-
- this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
- this._ignoreCaseLabel.classList.add("search-config-label");
- this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
- this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
- this._ignoreCaseCheckbox.classList.add("search-config-checkbox");
- this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));
-
- this._regexLabel = this._searchPanelElement.createChild("label");
- this._regexLabel.classList.add("search-config-label");
- this._regexCheckbox = this._regexLabel.createChild("input");
- this._regexCheckbox.setAttribute("type", "checkbox");
- this._regexCheckbox.classList.add("search-config-checkbox");
- this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));
-
- this._searchStatusBarElement = this.element.createChild("div", "search-status-bar-summary");
- this._searchMessageElement = this._searchStatusBarElement.createChild("span");
- this._searchResultsMessageElement = document.createElement("span");
-
- this._load();
-}
-
-// Number of recent search queries to store.
-WebInspector.SearchView.maxQueriesCount = 20;
-
-WebInspector.SearchView.prototype = {
- /**
- * @return {!WebInspector.SearchConfig}
- */
- get searchConfig()
- {
- return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
- },
-
- /**
- * @type {!WebInspector.SearchResultsPane}
- */
- set resultsPane(resultsPane)
- {
- this.resetResults();
- this._searchResultsElement.appendChild(resultsPane.element);
- },
-
- /**
- * @param {!WebInspector.ProgressIndicator} progressIndicator
- */
- searchStarted: function(progressIndicator)
- {
- this.resetResults();
- this._resetCounters();
-
- this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
- progressIndicator.show(this._searchStatusBarElement);
- this._updateSearchResultsMessage();
-
- if (!this._searchingView)
- this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
- this._searchingView.show(this._searchResultsElement);
- },
-
- /**
- * @param {!WebInspector.ProgressIndicator} progressIndicator
- */
- indexingStarted: function(progressIndicator)
- {
- this._searchMessageElement.textContent = WebInspector.UIString("Indexing...");
- progressIndicator.show(this._searchStatusBarElement);
- },
-
- /**
- * @param {boolean} finished
- */
- indexingFinished: function(finished)
- {
- this._searchMessageElement.textContent = finished ? "" : WebInspector.UIString("Indexing interrupted.");
- },
-
- _updateSearchResultsMessage: function()
- {
- if (this._searchMatchesCount && this._searchResultsCount)
- this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
- else
- this._searchResultsMessageElement.textContent = "";
- },
-
- resetResults: function()
- {
- if (this._searchingView)
- this._searchingView.detach();
- if (this._notFoundView)
- this._notFoundView.detach();
- this._searchResultsElement.removeChildren();
- },
-
- _resetCounters: function()
- {
- this._searchMatchesCount = 0;
- this._searchResultsCount = 0;
- this._nonEmptySearchResultsCount = 0;
- },
-
- nothingFound: function()
- {
- this.resetResults();
-
- if (!this._notFoundView)
- this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
- this._notFoundView.show(this._searchResultsElement);
- this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
- },
-
- /**
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- */
- addSearchResult: function(searchResult)
- {
- this._searchMatchesCount += searchResult.searchMatches.length;
- this._searchResultsCount++;
- if (searchResult.searchMatches.length)
- this._nonEmptySearchResultsCount++;
- this._updateSearchResultsMessage();
- },
-
- /**
- * @param {boolean} finished
- */
- searchFinished: function(finished)
- {
- this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
- },
-
- focus: function()
- {
- WebInspector.setCurrentFocusElement(this._search);
- this._search.select();
- },
-
- afterShow: function()
- {
- this.focus();
- },
-
- willHide: function()
- {
- this._controller.stopSearch();
- },
-
- /**
- * @param {?Event} event
- */
- _onKeyDown: function(event)
- {
- switch (event.keyCode) {
- case WebInspector.KeyboardShortcut.Keys.Enter.code:
- this._onAction();
- break;
- }
- },
-
- _save: function()
- {
- WebInspector.settings.advancedSearchConfig.set(this.searchConfig);
- },
-
- _load: function()
- {
- var searchConfig = WebInspector.settings.advancedSearchConfig.get();
- this._search.value = searchConfig.query;
- this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase;
- this._regexCheckbox.checked = searchConfig.isRegex;
- },
-
- _onAction: function()
- {
- var searchConfig = this.searchConfig;
- if (!searchConfig.query || !searchConfig.query.length)
- return;
-
- this._save();
- this._controller.startSearch(searchConfig);
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-
-/**
- * @constructor
- * @param {string} query
- * @param {boolean} ignoreCase
- * @param {boolean} isRegex
- */
-WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
-{
- this.query = query;
- this.ignoreCase = ignoreCase;
- this.isRegex = isRegex;
- this._parse();
-}
-
-WebInspector.SearchConfig.prototype = {
- _parse: function()
- {
- var filePattern = "file:(([^\\\\ ]|\\\\.)+)"; // After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
- var quotedPattern = "\"(([^\\\\\"]|\\\\.)+)\""; // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
- var unquotedPattern = "(([^\\\\ ]|\\\\.)+)"; // any symbol except space and backslash or any symbol escaped with a backslash.
-
- var pattern = "(" + filePattern + ")|(" + quotedPattern + ")|(" + unquotedPattern + ")";
- var regexp = new RegExp(pattern, "g");
- var queryParts = this.query.match(regexp) || [];
-
- this._fileQueries = [];
- this._queries = [];
-
- for (var i = 0; i < queryParts.length; ++i) {
- var queryPart = queryParts[i];
- if (!queryPart)
- continue;
- if (queryPart.startsWith("file:")) {
- this._fileQueries.push(this._parseFileQuery(queryPart));
- continue;
- }
- if (queryPart.startsWith("\"")) {
- if (!queryPart.endsWith("\""))
- continue;
- this._queries.push(this._parseQuotedQuery(queryPart));
- continue;
- }
- this._queries.push(this._parseUnquotedQuery(queryPart));
- }
- },
-
- fileQueries: function()
- {
- return this._fileQueries;
- },
-
- queries: function()
- {
- return this._queries;
- },
-
- _parseUnquotedQuery: function(query)
- {
- return query.replace(/\\(.)/g, "$1");
- },
-
- _parseQuotedQuery: function(query)
- {
- return query.substring(1, query.length - 1).replace(/\\(.)/g, "$1");
- },
-
- _parseFileQuery: function(query)
- {
- query = query.substr("file:".length);
- var result = "";
- for (var i = 0; i < query.length; ++i) {
- var char = query[i];
- if (char === "*") {
- result += ".*";
- } else if (char === "\\") {
- ++i;
- var nextChar = query[i];
- if (nextChar === " ")
- result += " ";
- } else {
- if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1)
- result += "\\";
- result += query.charAt(i);
- }
- }
- return result;
- }
-}
-
-/**
- * @interface
- */
-WebInspector.SearchScope = function()
-{
-}
-
-WebInspector.SearchScope.prototype = {
- /**
- * @param {!WebInspector.SearchConfig} searchConfig
- * @param {!WebInspector.Progress} progress
- * @param {function(!WebInspector.FileBasedSearchResultsPane.SearchResult)} searchResultCallback
- * @param {function(boolean)} searchFinishedCallback
- */
- performSearch: function(searchConfig, progress, searchResultCallback, searchFinishedCallback) { },
-
- stopSearch: function() { },
-
- /**
- * @param {!WebInspector.SearchConfig} searchConfig
- * @return {!WebInspector.SearchResultsPane}
- */
- createSearchResultsPane: function(searchConfig) { }
-}
-
-/**
- * @constructor
- * @param {!WebInspector.SearchConfig} searchConfig
- */
-WebInspector.SearchResultsPane = function(searchConfig)
-{
- this._searchConfig = searchConfig;
- this.element = document.createElement("div");
-}
-
-WebInspector.SearchResultsPane.prototype = {
- /**
- * @return {!WebInspector.SearchConfig}
- */
- get searchConfig()
- {
- return this._searchConfig;
- },
-
- /**
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- */
- addSearchResult: function(searchResult) { }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.SearchResultsPane}
- * @param {!WebInspector.SearchConfig} searchConfig
- */
-WebInspector.FileBasedSearchResultsPane = function(searchConfig)
-{
- WebInspector.SearchResultsPane.call(this, searchConfig);
-
- this._searchResults = [];
-
- this.element.id = "search-results-pane-file-based";
-
- this._treeOutlineElement = document.createElement("ol");
- this._treeOutlineElement.className = "search-results-outline-disclosure";
- this.element.appendChild(this._treeOutlineElement);
- this._treeOutline = new TreeOutline(this._treeOutlineElement);
-
- this._matchesExpandedCount = 0;
-}
-
-WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
-WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;
-
-WebInspector.FileBasedSearchResultsPane.prototype = {
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {!Element}
- */
- _createAnchor: function(uiSourceCode, lineNumber, columnNumber)
- {
- var anchor = document.createElement("a");
- anchor.preferredPanel = "sources";
- anchor.href = sanitizeHref(uiSourceCode.originURL());
- anchor.uiSourceCode = uiSourceCode;
- anchor.lineNumber = lineNumber;
- return anchor;
- },
-
- /**
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- */
- addSearchResult: function(searchResult)
- {
- this._searchResults.push(searchResult);
- var uiSourceCode = searchResult.uiSourceCode;
- if (!uiSourceCode)
- return;
- var searchMatches = searchResult.searchMatches;
-
- var fileTreeElement = this._addFileTreeElement(uiSourceCode.fullDisplayName(), searchMatches.length, this._searchResults.length - 1);
- },
-
- /**
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- * @param {!TreeElement} fileTreeElement
- */
- _fileTreeElementExpanded: function(searchResult, fileTreeElement)
- {
- if (fileTreeElement._initialized)
- return;
-
- var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
- if (toIndex < searchResult.searchMatches.length) {
- this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1);
- this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1);
- } else
- this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex);
-
- fileTreeElement._initialized = true;
- },
-
- /**
- * @param {!TreeElement} fileTreeElement
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- * @param {number} fromIndex
- * @param {number} toIndex
- */
- _appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex)
- {
- var uiSourceCode = searchResult.uiSourceCode;
- var searchMatches = searchResult.searchMatches;
-
- var queries = this._searchConfig.queries();
- var regexes = [];
- for (var i = 0; i < queries.length; ++i)
- regexes.push(createSearchRegex(queries[i], !this._searchConfig.ignoreCase, this._searchConfig.isRegex));
-
- for (var i = fromIndex; i < toIndex; ++i) {
- var lineNumber = searchMatches[i].lineNumber;
- var lineContent = searchMatches[i].lineContent;
- var matchRanges = [];
- for (var j = 0; j < regexes.length; ++j)
- matchRanges = matchRanges.concat(this._regexMatchRanges(lineContent, regexes[j]));
-
- var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);
-
- var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
- var lineNumberSpan = document.createElement("span");
- lineNumberSpan.classList.add("search-match-line-number");
- lineNumberSpan.textContent = numberString;
- anchor.appendChild(lineNumberSpan);
-
- var contentSpan = this._createContentSpan(lineContent, matchRanges);
- anchor.appendChild(contentSpan);
-
- var searchMatchElement = new TreeElement("");
- searchMatchElement.selectable = false;
- fileTreeElement.appendChild(searchMatchElement);
- searchMatchElement.listItemElement.className = "search-match source-code";
- searchMatchElement.listItemElement.appendChild(anchor);
- }
- },
-
- /**
- * @param {!TreeElement} fileTreeElement
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- * @param {number} startMatchIndex
- */
- _appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex)
- {
- var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex;
- var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
- var showMoreMatchesElement = new TreeElement(showMoreMatchesText);
- fileTreeElement.appendChild(showMoreMatchesElement);
- showMoreMatchesElement.listItemElement.classList.add("show-more-matches");
- showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement);
- },
-
- /**
- * @param {!WebInspector.FileBasedSearchResultsPane.SearchResult} searchResult
- * @param {number} startMatchIndex
- * @param {!TreeElement} showMoreMatchesElement
- * @return {boolean}
- */
- _showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement)
- {
- var fileTreeElement = showMoreMatchesElement.parent;
- fileTreeElement.removeChild(showMoreMatchesElement);
- this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length);
- return false;
- },
-
- /**
- * @param {string} fileName
- * @param {number} searchMatchesCount
- * @param {number} searchResultIndex
- */
- _addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex)
- {
- var fileTreeElement = new TreeElement("", null, true);
- fileTreeElement.toggleOnClick = true;
- fileTreeElement.selectable = false;
-
- this._treeOutline.appendChild(fileTreeElement);
- fileTreeElement.listItemElement.classList.add("search-result");
-
- var fileNameSpan = document.createElement("span");
- fileNameSpan.className = "search-result-file-name";
- fileNameSpan.textContent = fileName;
- fileTreeElement.listItemElement.appendChild(fileNameSpan);
-
- var matchesCountSpan = document.createElement("span");
- matchesCountSpan.className = "search-result-matches-count";
- if (searchMatchesCount === 1)
- matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
- else
- matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
-
- fileTreeElement.listItemElement.appendChild(matchesCountSpan);
-
- var searchResult = this._searchResults[searchResultIndex];
- fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement);
-
- // Expand until at least certain amount of matches is expanded.
- if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
- fileTreeElement.expand();
- this._matchesExpandedCount += searchResult.searchMatches.length;
-
- return fileTreeElement;
- },
-
- /**
- * @param {string} lineContent
- * @param {!RegExp} regex
- * @return {!Array.<!WebInspector.SourceRange>}
- */
- _regexMatchRanges: function(lineContent, regex)
- {
- regex.lastIndex = 0;
- var match;
- var offset = 0;
- var matchRanges = [];
- while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
- matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
-
- return matchRanges;
- },
-
- /**
- * @param {string} lineContent
- * @param {!Array.<!WebInspector.SourceRange>} matchRanges
- */
- _createContentSpan: function(lineContent, matchRanges)
- {
- var contentSpan = document.createElement("span");
- contentSpan.className = "search-match-content";
- contentSpan.textContent = lineContent;
- WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
- return contentSpan;
- },
-
- __proto__: WebInspector.SearchResultsPane.prototype
-}
-
-/**
- * @constructor
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {!Array.<!Object>} searchMatches
- */
-WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) {
- this.uiSourceCode = uiSourceCode;
- this.searchMatches = searchMatches;
-}
-
-/**
- * @type {!WebInspector.AdvancedSearchController}
- */
-WebInspector.advancedSearchController;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowCollectionsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowCollectionsView.js
deleted file mode 100644
index 24da59ce66c..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowCollectionsView.js
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.SidebarView}
- */
-WebInspector.CSSNamedFlowCollectionsView = function()
-{
- WebInspector.SidebarView.call(this, WebInspector.SidebarView.SidebarPosition.Start);
- this.registerRequiredCSS("cssNamedFlows.css");
-
- this._namedFlows = {};
- this._contentNodes = {};
- this._regionNodes = {};
-
- this.element.classList.add("css-named-flow-collections-view");
- this.element.classList.add("fill");
-
- this._statusElement = document.createElement("span");
- this._statusElement.textContent = WebInspector.UIString("CSS Named Flows");
-
- var sidebarHeader = this.firstElement().createChild("div", "tabbed-pane-header selected sidebar-header");
- var tab = sidebarHeader.createChild("div", "tabbed-pane-header-tab");
- tab.createChild("span", "tabbed-pane-header-tab-title").textContent = WebInspector.UIString("CSS Named Flows");
-
- this._sidebarContentElement = this.firstElement().createChild("div", "sidebar-content outline-disclosure");
- this._flowListElement = this._sidebarContentElement.createChild("ol");
- this._flowTree = new TreeOutline(this._flowListElement);
-
- this._emptyElement = document.createElement("div");
- this._emptyElement.classList.add("info");
- this._emptyElement.textContent = WebInspector.UIString("No CSS Named Flows");
-
- this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.closeableTabs = true;
- this._tabbedPane.show(this.secondElement());
-}
-
-WebInspector.CSSNamedFlowCollectionsView.prototype = {
- showInDrawer: function()
- {
- WebInspector.inspectorView.showCloseableViewInDrawer("css-flows", WebInspector.UIString("CSS Flows"), this);
- },
-
- reset: function()
- {
- if (!this._document)
- return;
-
- WebInspector.cssModel.getNamedFlowCollectionAsync(this._document.id, this._resetNamedFlows.bind(this));
- },
-
- /**
- * @param {!WebInspector.DOMDocument} document
- */
- _setDocument: function(document)
- {
- this._document = document;
- this.reset();
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _documentUpdated: function(event)
- {
- var document = /** @type {!WebInspector.DOMDocument} */ (event.data);
- this._setDocument(document);
- },
-
- /**
- * @param {boolean} hasContent
- */
- _setSidebarHasContent: function(hasContent)
- {
- if (hasContent) {
- if (!this._emptyElement.parentNode)
- return;
-
- this._sidebarContentElement.removeChild(this._emptyElement);
- this._sidebarContentElement.appendChild(this._flowListElement);
- } else {
- if (!this._flowListElement.parentNode)
- return;
-
- this._sidebarContentElement.removeChild(this._flowListElement);
- this._sidebarContentElement.appendChild(this._emptyElement);
- }
- },
-
- /**
- * @param {!WebInspector.NamedFlow} flow
- */
- _appendNamedFlow: function(flow)
- {
- var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
- var flowContainer = { flow: flow, flowHash: flowHash };
-
- for (var i = 0; i < flow.content.length; ++i)
- this._contentNodes[flow.content[i]] = flowHash;
- for (var i = 0; i < flow.regions.length; ++i)
- this._regionNodes[flow.regions[i].nodeId] = flowHash;
-
- var flowTreeItem = new WebInspector.FlowTreeElement(flowContainer);
- flowTreeItem.onselect = this._selectNamedFlowTab.bind(this, flowHash);
-
- flowContainer.flowTreeItem = flowTreeItem;
- this._namedFlows[flowHash] = flowContainer;
-
- if (!this._flowTree.children.length)
- this._setSidebarHasContent(true);
- this._flowTree.appendChild(flowTreeItem);
- },
-
- /**
- * @param {string} flowHash
- */
- _removeNamedFlow: function(flowHash)
- {
- var flowContainer = this._namedFlows[flowHash];
-
- if (this._tabbedPane._tabsById[flowHash])
- this._tabbedPane.closeTab(flowHash);
- this._flowTree.removeChild(flowContainer.flowTreeItem);
-
- var flow = flowContainer.flow;
- for (var i = 0; i < flow.content.length; ++i)
- delete this._contentNodes[flow.content[i]];
- for (var i = 0; i < flow.regions.length; ++i)
- delete this._regionNodes[flow.regions[i].nodeId];
-
- delete this._namedFlows[flowHash];
-
- if (!this._flowTree.children.length)
- this._setSidebarHasContent(false);
- },
-
- /**
- * @param {!WebInspector.NamedFlow} flow
- */
- _updateNamedFlow: function(flow)
- {
- var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
- var flowContainer = this._namedFlows[flowHash];
-
- if (!flowContainer)
- return;
-
- var oldFlow = flowContainer.flow;
- flowContainer.flow = flow;
-
- for (var i = 0; i < oldFlow.content.length; ++i)
- delete this._contentNodes[oldFlow.content[i]];
- for (var i = 0; i < oldFlow.regions.length; ++i)
- delete this._regionNodes[oldFlow.regions[i].nodeId];
-
- for (var i = 0; i < flow.content.length; ++i)
- this._contentNodes[flow.content[i]] = flowHash;
- for (var i = 0; i < flow.regions.length; ++i)
- this._regionNodes[flow.regions[i].nodeId] = flowHash;
-
- flowContainer.flowTreeItem.setOverset(flow.overset);
-
- if (flowContainer.flowView)
- flowContainer.flowView.flow = flow;
- },
-
- /**
- * @param {?WebInspector.NamedFlowCollection} namedFlowCollection
- */
- _resetNamedFlows: function(namedFlowCollection)
- {
- for (var flowHash in this._namedFlows)
- this._removeNamedFlow(flowHash);
-
- var namedFlows = namedFlowCollection ? namedFlowCollection.namedFlowMap : {};
- for (var flowName in namedFlows)
- this._appendNamedFlow(namedFlows[flowName]);
-
- if (!this._flowTree.children.length)
- this._setSidebarHasContent(false);
- else
- this._showNamedFlowForNode(WebInspector.panel("elements").treeOutline.selectedDOMNode());
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _namedFlowCreated: function(event)
- {
- // FIXME: We only have support for Named Flows in the main document.
- if (event.data.documentNodeId !== this._document.id)
- return;
-
- var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
- this._appendNamedFlow(flow);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _namedFlowRemoved: function(event)
- {
- // FIXME: We only have support for Named Flows in the main document.
- if (event.data.documentNodeId !== this._document.id)
- return;
-
- this._removeNamedFlow(this._hashNamedFlow(event.data.documentNodeId, event.data.flowName));
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _regionLayoutUpdated: function(event)
- {
- // FIXME: We only have support for Named Flows in the main document.
- if (event.data.documentNodeId !== this._document.id)
- return;
-
- var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
- this._updateNamedFlow(flow);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _regionOversetChanged: function(event)
- {
- // FIXME: We only have support for Named Flows in the main document.
- if (event.data.documentNodeId !== this._document.id)
- return;
-
- var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
- this._updateNamedFlow(flow);
- },
-
- /**
- * @param {!DOMAgent.NodeId} documentNodeId
- * @param {string} flowName
- */
- _hashNamedFlow: function(documentNodeId, flowName)
- {
- return documentNodeId + "|" + flowName;
- },
-
- /**
- * @param {string} flowHash
- */
- _showNamedFlow: function(flowHash)
- {
- this._selectNamedFlowInSidebar(flowHash);
- this._selectNamedFlowTab(flowHash);
- },
-
- /**
- * @param {string} flowHash
- */
- _selectNamedFlowInSidebar: function(flowHash)
- {
- this._namedFlows[flowHash].flowTreeItem.select(true);
- },
-
- /**
- * @param {string} flowHash
- * @return {boolean}
- */
- _selectNamedFlowTab: function(flowHash)
- {
- var flowContainer = this._namedFlows[flowHash];
-
- if (this._tabbedPane.selectedTabId === flowHash)
- return false;
-
- if (!this._tabbedPane.selectTab(flowHash)) {
- if (!flowContainer.flowView)
- flowContainer.flowView = new WebInspector.CSSNamedFlowView(flowContainer.flow);
-
- this._tabbedPane.appendTab(flowHash, flowContainer.flow.name, flowContainer.flowView);
- this._tabbedPane.selectTab(flowHash);
- }
- return false;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _selectedNodeChanged: function(event)
- {
- var node = /** @type {!WebInspector.DOMNode} */ (event.data);
- this._showNamedFlowForNode(node);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _tabSelected: function(event)
- {
- this._selectNamedFlowInSidebar(event.data.tabId);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _tabClosed: function(event)
- {
- this._namedFlows[event.data.tabId].flowTreeItem.deselect();
- },
-
- /**
- * @param {?WebInspector.DOMNode} node
- */
- _showNamedFlowForNode: function(node)
- {
- if (!node)
- return;
-
- if (this._regionNodes[node.id]) {
- this._showNamedFlow(this._regionNodes[node.id]);
- return;
- }
-
- while (node) {
- if (this._contentNodes[node.id]) {
- this._showNamedFlow(this._contentNodes[node.id]);
- return;
- }
-
- node = node.parentNode;
- }
- },
-
- wasShown: function()
- {
- WebInspector.SidebarView.prototype.wasShown.call(this);
-
- WebInspector.domAgent.requestDocument(this._setDocument.bind(this));
-
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
-
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);
-
- WebInspector.panel("elements").treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
-
- this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
- this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
- },
-
- willHide: function()
- {
- WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
-
- WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
- WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
- WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
- WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);
-
- WebInspector.panel("elements").treeOutline.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
-
- this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
- this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
- },
-
- __proto__: WebInspector.SidebarView.prototype
-}
-
-/**
- * @constructor
- * @extends {TreeElement}
- */
-WebInspector.FlowTreeElement = function(flowContainer)
-{
- var container = document.createElement("div");
- container.createChild("div", "selection");
- container.createChild("span", "title").createChild("span").textContent = flowContainer.flow.name;
-
- TreeElement.call(this, container, flowContainer, false);
-
- this._overset = false;
- this.setOverset(flowContainer.flow.overset);
-}
-
-WebInspector.FlowTreeElement.prototype = {
- /**
- * @param {boolean} newOverset
- */
- setOverset: function(newOverset)
- {
- if (this._overset === newOverset)
- return;
-
- if (newOverset) {
- this.title.classList.add("named-flow-overflow");
- this.tooltip = WebInspector.UIString("Overflows.");
- } else {
- this.title.classList.remove("named-flow-overflow");
- this.tooltip = "";
- }
-
- this._overset = newOverset;
- },
-
- __proto__: TreeElement.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowView.js b/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowView.js
deleted file mode 100644
index 0542b0eab43..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSNamedFlowView.js
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.NamedFlow} flow
- */
-WebInspector.CSSNamedFlowView = function(flow)
-{
- WebInspector.View.call(this);
- this.element.classList.add("css-named-flow");
- this.element.classList.add("outline-disclosure");
-
- this._treeOutline = new TreeOutline(this.element.createChild("ol"), true);
-
- this._contentTreeItem = new TreeElement(WebInspector.UIString("content"), null, true);
- this._treeOutline.appendChild(this._contentTreeItem);
-
- this._regionsTreeItem = new TreeElement(WebInspector.UIString("region chain"), null, true);
- this._regionsTreeItem.expand();
- this._treeOutline.appendChild(this._regionsTreeItem);
-
- this._flow = flow;
-
- var content = flow.content;
- for (var i = 0; i < content.length; ++i)
- this._insertContentNode(content[i]);
-
- var regions = flow.regions;
- for (var i = 0; i < regions.length; ++i)
- this._insertRegion(regions[i]);
-}
-
-WebInspector.CSSNamedFlowView.OversetTypeMessageMap = {
- empty: "empty",
- fit: "fit",
- overset: "overset"
-}
-
-WebInspector.CSSNamedFlowView.prototype = {
- /**
- * @param {?WebInspector.DOMNode} rootDOMNode
- * @return {?WebInspector.ElementsTreeOutline}
- */
- _createFlowTreeOutline: function(rootDOMNode)
- {
- if (!rootDOMNode)
- return null;
-
- var treeOutline = new WebInspector.ElementsTreeOutline(false, false);
- treeOutline.element.classList.add("named-flow-element");
- treeOutline.setVisible(true);
- treeOutline.rootDOMNode = rootDOMNode;
- treeOutline.wireToDomAgent();
- WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, treeOutline._elementsTreeUpdater._documentUpdated, treeOutline._elementsTreeUpdater);
-
- return treeOutline;
- },
-
- /**
- * @param {!DOMAgent.NodeId} contentNodeId
- * @param {number=} index
- */
- _insertContentNode: function(contentNodeId, index)
- {
- var treeOutline = this._createFlowTreeOutline(WebInspector.domAgent.nodeForId(contentNodeId));
- var treeItem = new TreeElement(treeOutline.element, treeOutline);
-
- if (index === undefined) {
- this._contentTreeItem.appendChild(treeItem);
- return;
- }
-
- this._contentTreeItem.insertChild(treeItem, index);
- },
-
- /**
- * @param {!CSSAgent.Region} region
- * @param {number=} index
- */
- _insertRegion: function(region, index)
- {
- var treeOutline = this._createFlowTreeOutline(WebInspector.domAgent.nodeForId(region.nodeId));
- treeOutline.element.classList.add("region-" + region.regionOverset);
-
- var treeItem = new TreeElement(treeOutline.element, treeOutline);
- var oversetText = WebInspector.UIString(WebInspector.CSSNamedFlowView.OversetTypeMessageMap[region.regionOverset]);
- treeItem.tooltip = WebInspector.UIString("Region is %s.", oversetText);
-
- if (index === undefined) {
- this._regionsTreeItem.appendChild(treeItem);
- return;
- }
-
- this._regionsTreeItem.insertChild(treeItem, index);
- },
-
- get flow()
- {
- return this._flow;
- },
-
- set flow(newFlow)
- {
- this._update(newFlow);
- },
-
- /**
- * @param {!TreeElement} regionTreeItem
- * @param {string} newRegionOverset
- * @param {string} oldRegionOverset
- */
- _updateRegionOverset: function(regionTreeItem, newRegionOverset, oldRegionOverset)
- {
- var element = regionTreeItem.representedObject.element;
- element.classList.remove("region-" + oldRegionOverset);
- element.classList.add("region-" + newRegionOverset);
-
- var oversetText = WebInspector.UIString(WebInspector.CSSNamedFlowView.OversetTypeMessageMap[newRegionOverset]);
- regionTreeItem.tooltip = WebInspector.UIString("Region is %s." , oversetText);
- },
-
- /**
- * @param {!Array.<!DOMAgent.NodeId>} oldContent
- * @param {!Array.<!DOMAgent.NodeId>} newContent
- */
- _mergeContentNodes: function(oldContent, newContent)
- {
- var nodeIdSet = {};
- for (var i = 0; i < newContent.length; ++i)
- nodeIdSet[newContent[i]] = true;
-
- var oldContentIndex = 0;
- var newContentIndex = 0;
- var contentTreeChildIndex = 0;
-
- while (oldContentIndex < oldContent.length || newContentIndex < newContent.length) {
- if (oldContentIndex === oldContent.length) {
- this._insertContentNode(newContent[newContentIndex]);
- ++newContentIndex;
- continue;
- }
-
- if (newContentIndex === newContent.length) {
- this._contentTreeItem.removeChildAtIndex(contentTreeChildIndex);
- ++oldContentIndex;
- continue;
- }
-
- if (oldContent[oldContentIndex] === newContent[newContentIndex]) {
- ++oldContentIndex;
- ++newContentIndex;
- ++contentTreeChildIndex;
- continue;
- }
-
- if (nodeIdSet[oldContent[oldContentIndex]]) {
- this._insertContentNode(newContent[newContentIndex], contentTreeChildIndex);
- ++newContentIndex;
- ++contentTreeChildIndex;
- continue;
- }
-
- this._contentTreeItem.removeChildAtIndex(contentTreeChildIndex);
- ++oldContentIndex;
- }
- },
-
- /**
- * @param {!Array.<!CSSAgent.Region>} oldRegions
- * @param {!Array.<!CSSAgent.Region>} newRegions
- */
- _mergeRegions: function(oldRegions, newRegions)
- {
- var nodeIdSet = {};
- for (var i = 0; i < newRegions.length; ++i)
- nodeIdSet[newRegions[i].nodeId] = true;
-
- var oldRegionsIndex = 0;
- var newRegionsIndex = 0;
- var regionsTreeChildIndex = 0;
-
- while (oldRegionsIndex < oldRegions.length || newRegionsIndex < newRegions.length) {
- if (oldRegionsIndex === oldRegions.length) {
- this._insertRegion(newRegions[newRegionsIndex]);
- ++newRegionsIndex;
- continue;
- }
-
- if (newRegionsIndex === newRegions.length) {
- this._regionsTreeItem.removeChildAtIndex(regionsTreeChildIndex);
- ++oldRegionsIndex;
- continue;
- }
-
- if (oldRegions[oldRegionsIndex].nodeId === newRegions[newRegionsIndex].nodeId) {
- if (oldRegions[oldRegionsIndex].regionOverset !== newRegions[newRegionsIndex].regionOverset)
- this._updateRegionOverset(this._regionsTreeItem.children[regionsTreeChildIndex], newRegions[newRegionsIndex].regionOverset, oldRegions[oldRegionsIndex].regionOverset);
- ++oldRegionsIndex;
- ++newRegionsIndex;
- ++regionsTreeChildIndex;
- continue;
- }
-
- if (nodeIdSet[oldRegions[oldRegionsIndex].nodeId]) {
- this._insertRegion(newRegions[newRegionsIndex], regionsTreeChildIndex);
- ++newRegionsIndex;
- ++regionsTreeChildIndex;
- continue;
- }
-
- this._regionsTreeItem.removeChildAtIndex(regionsTreeChildIndex);
- ++oldRegionsIndex;
- }
- },
-
- /**
- * @param {!WebInspector.NamedFlow} newFlow
- */
- _update: function(newFlow)
- {
- this._mergeContentNodes(this._flow.content, newFlow.content);
- this._mergeRegions(this._flow.regions, newFlow.regions);
-
- this._flow = newFlow;
- },
-
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorUtils.js
deleted file mode 100644
index 5353fb34560..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorUtils.js
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-WebInspector.CodeMirrorUtils = {
- /**
- * @param {string} mimeType
- * @return {function(string, function(string, string, number, number))}
- */
- createTokenizer: function(mimeType)
- {
- var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
- var state = CodeMirror.startState(mode);
- function tokenize(line, callback)
- {
- var stream = new CodeMirror.StringStream(line);
- while (!stream.eol()) {
- var style = mode.token(stream, state);
- var value = stream.current();
- callback(value, style, stream.start, stream.start + value.length);
- stream.start = stream.pos;
- }
- }
- return tokenize;
- },
-
- /**
- * @param {string} tokenType
- */
- convertTokenType: function(tokenType)
- {
- if (tokenType.startsWith("js-variable") || tokenType.startsWith("js-property") || tokenType === "js-def")
- return "javascript-ident";
- if (tokenType === "js-string-2")
- return "javascript-regexp";
- if (tokenType === "js-number" || tokenType === "js-comment" || tokenType === "js-string" || tokenType === "js-keyword")
- return "javascript-" + tokenType.substring("js-".length);
- if (tokenType === "css-number")
- return "css-number";
- return null;
- },
-
- /**
- * @param {string} modeName
- * @param {string} tokenPrefix
- */
- overrideModeWithPrefixedTokens: function(modeName, tokenPrefix)
- {
- var oldModeName = modeName + "-old";
- if (CodeMirror.modes[oldModeName])
- return;
-
- CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]);
- CodeMirror.defineMode(modeName, modeConstructor);
-
- function modeConstructor(config, parserConfig)
- {
- var innerConfig = {};
- for (var i in parserConfig)
- innerConfig[i] = parserConfig[i];
- innerConfig.name = oldModeName;
- var codeMirrorMode = CodeMirror.getMode(config, innerConfig);
- codeMirrorMode.name = modeName;
- codeMirrorMode.token = tokenOverride.bind(null, codeMirrorMode.token);
- return codeMirrorMode;
- }
-
- function tokenOverride(superToken, stream, state)
- {
- var token = superToken(stream, state);
- return token ? tokenPrefix + token : token;
- }
- }
-}
-
-WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("css-base", "css-");
-WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("javascript", "js-");
-WebInspector.CodeMirrorUtils.overrideModeWithPrefixedTokens("xml", "xml-");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleModel.js
deleted file mode 100644
index 8170533b54f..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleModel.js
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.ConsoleModel = function()
-{
- this.messages = [];
- this.warnings = 0;
- this.errors = 0;
- this._interruptRepeatCount = false;
- InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
-}
-
-WebInspector.ConsoleModel.Events = {
- ConsoleCleared: "console-cleared",
- MessageAdded: "console-message-added",
- RepeatCountUpdated: "repeat-count-updated"
-}
-
-WebInspector.ConsoleModel.prototype = {
- enableAgent: function()
- {
- if (WebInspector.settings.monitoringXHREnabled.get())
- ConsoleAgent.setMonitoringXHREnabled(true);
-
- this._enablingConsole = true;
-
- /**
- * @this {WebInspector.ConsoleModel}
- */
- function callback()
- {
- delete this._enablingConsole;
- }
- ConsoleAgent.enable(callback.bind(this));
- },
-
- /**
- * @return {boolean}
- */
- enablingConsole: function()
- {
- return !!this._enablingConsole;
- },
-
- /**
- * @param {!WebInspector.ConsoleMessage} msg
- * @param {boolean=} isFromBackend
- */
- addMessage: function(msg, isFromBackend)
- {
- if (isFromBackend && WebInspector.SourceMap.hasSourceMapRequestHeader(msg.request()))
- return;
-
- msg.index = this.messages.length;
- this.messages.push(msg);
- this._incrementErrorWarningCount(msg);
-
- if (isFromBackend)
- this._previousMessage = msg;
-
- this._interruptRepeatCount = !isFromBackend;
-
- this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
- },
-
- /**
- * @param {!WebInspector.ConsoleMessage} msg
- */
- _incrementErrorWarningCount: function(msg)
- {
- switch (msg.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- this.warnings += msg.repeatDelta;
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- this.errors += msg.repeatDelta;
- break;
- }
- },
-
- requestClearMessages: function()
- {
- ConsoleAgent.clearMessages();
- this.clearMessages();
- },
-
- clearMessages: function()
- {
- this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
-
- this.messages = [];
- delete this._previousMessage;
-
- this.errors = 0;
- this.warnings = 0;
- },
-
- /**
- * @param {number} count
- */
- _messageRepeatCountUpdated: function(count)
- {
- var msg = this._previousMessage;
- if (!msg)
- return;
-
- var prevRepeatCount = msg.totalRepeatCount;
-
- if (!this._interruptRepeatCount) {
- msg.repeatDelta = count - prevRepeatCount;
- msg.repeatCount = msg.repeatCount + msg.repeatDelta;
- msg.totalRepeatCount = count;
- msg.updateRepeatCount();
-
- this._incrementErrorWarningCount(msg);
- this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg);
- } else {
- var msgCopy = msg.clone();
- msgCopy.totalRepeatCount = count;
- msgCopy.repeatCount = (count - prevRepeatCount) || 1;
- msgCopy.repeatDelta = msgCopy.repeatCount;
- this.addMessage(msgCopy, true);
- }
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {string} source
- * @param {string} level
- * @param {string=} url
- * @param {number=} line
- * @param {number=} column
- * @param {number=} repeatCount
- */
-WebInspector.ConsoleMessage = function(source, level, url, line, column, repeatCount)
-{
- this.source = source;
- this.level = level;
- this.url = url || null;
- this.line = line || 0;
- this.column = column || 0;
- this.message = "";
-
- repeatCount = repeatCount || 1;
- this.repeatCount = repeatCount;
- this.repeatDelta = repeatCount;
- this.totalRepeatCount = repeatCount;
-}
-
-WebInspector.ConsoleMessage.prototype = {
- /**
- * @return {boolean}
- */
- isErrorOrWarning: function()
- {
- return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
- },
-
- updateRepeatCount: function()
- {
- // Implemented by concrete instances
- },
-
- /**
- * @return {!WebInspector.ConsoleMessage}
- */
- clone: function()
- {
- // Implemented by concrete instances
- },
-
- /**
- * @return {!WebInspector.DebuggerModel.Location}
- */
- location: function()
- {
- // Implemented by concrete instances
- }
-}
-
-/**
- * @param {string} source
- * @param {string} level
- * @param {string} message
- * @param {string=} type
- * @param {string=} url
- * @param {number=} line
- * @param {number=} column
- * @param {number=} repeatCount
- * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
- * @param {!ConsoleAgent.StackTrace=} stackTrace
- * @param {!NetworkAgent.RequestId=} requestId
- * @param {boolean=} isOutdated
- * @return {!WebInspector.ConsoleMessage}
- */
-WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, column, repeatCount, parameters, stackTrace, requestId, isOutdated)
-{
-}
-
-// Note: Keep these constants in sync with the ones in Console.h
-WebInspector.ConsoleMessage.MessageSource = {
- XML: "xml",
- JS: "javascript",
- Network: "network",
- ConsoleAPI: "console-api",
- Storage: "storage",
- AppCache: "appcache",
- Rendering: "rendering",
- CSS: "css",
- Security: "security",
- Other: "other",
- Deprecation: "deprecation"
-}
-
-WebInspector.ConsoleMessage.MessageType = {
- Log: "log",
- Dir: "dir",
- DirXML: "dirxml",
- Table: "table",
- Trace: "trace",
- Clear: "clear",
- StartGroup: "startGroup",
- StartGroupCollapsed: "startGroupCollapsed",
- EndGroup: "endGroup",
- Assert: "assert",
- Result: "result",
- Profile: "profile",
- ProfileEnd: "profileEnd",
- Command: "command"
-}
-
-WebInspector.ConsoleMessage.MessageLevel = {
- Log: "log",
- Info: "info",
- Warning: "warning",
- Error: "error",
- Debug: "debug"
-}
-
-
-/**
- * @constructor
- * @implements {ConsoleAgent.Dispatcher}
- * @param {!WebInspector.ConsoleModel} console
- */
-WebInspector.ConsoleDispatcher = function(console)
-{
- this._console = console;
-}
-
-WebInspector.ConsoleDispatcher.prototype = {
- /**
- * @param {!ConsoleAgent.ConsoleMessage} payload
- */
- messageAdded: function(payload)
- {
- var consoleMessage = WebInspector.ConsoleMessage.create(
- payload.source,
- payload.level,
- payload.text,
- payload.type,
- payload.url,
- payload.line,
- payload.column,
- payload.repeatCount,
- payload.parameters,
- payload.stackTrace,
- payload.networkRequestId,
- this._console._enablingConsole);
- this._console.addMessage(consoleMessage, true);
- },
-
- /**
- * @param {number} count
- */
- messageRepeatCountUpdated: function(count)
- {
- this._console._messageRepeatCountUpdated(count);
- },
-
- messagesCleared: function()
- {
- if (!WebInspector.settings.preserveConsoleLog.get())
- this._console.clearMessages();
- }
-}
-
-/**
- * @type {!WebInspector.ConsoleModel}
- */
-WebInspector.console;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleView.js b/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleView.js
deleted file mode 100644
index 173cb55db62..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleView.js
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @extends {WebInspector.View}
- * @implements {WebInspector.Searchable}
- * @constructor
- * @param {boolean} hideContextSelector
- */
-WebInspector.ConsoleView = function(hideContextSelector)
-{
- WebInspector.View.call(this);
- this.registerRequiredCSS("filter.css");
-
- this._searchableView = new WebInspector.SearchableView(this);
- this._searchableView.setMinimalSearchQuerySize(0);
- this._searchableView.show(this.element);
-
- this._contentsElement = this._searchableView.element;
- this._contentsElement.classList.add("fill", "vbox", "console-view");
- this._visibleMessagesIndices = [];
- this._urlToMessageCount = {};
-
- this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
- this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);
-
- this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context");
- this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context");
-
- this._filter = new WebInspector.ConsoleViewFilter();
- this._filter.addEventListener(WebInspector.ConsoleViewFilter.Events.FilterChanged, this._updateMessageList.bind(this));
-
- if (hideContextSelector) {
- this._frameSelector.element.classList.add("hidden");
- this._contextSelector.element.classList.add("hidden");
- }
-
- this._filterBar = new WebInspector.FilterBar();
-
- var statusBarElement = this._contentsElement.createChild("div", "console-status-bar");
- statusBarElement.appendChild(this._clearConsoleButton.element);
- statusBarElement.appendChild(this._filterBar.filterButton().element);
- statusBarElement.appendChild(this._frameSelector.element);
- statusBarElement.appendChild(this._contextSelector.element);
-
- this._filtersContainer = this._contentsElement.createChild("div", "console-filters-header hidden");
- this._filtersContainer.appendChild(this._filterBar.filtersElement());
- this._filterBar.addEventListener(WebInspector.FilterBar.Events.FiltersToggled, this._onFiltersToggled, this);
- this._filter.addFilters(this._filterBar);
-
- this.messagesElement = document.createElement("div");
- this.messagesElement.id = "console-messages";
- this.messagesElement.className = "monospace";
- this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
- this._contentsElement.appendChild(this.messagesElement);
- this._scrolledToBottom = true;
-
- this.promptElement = document.createElement("div");
- this.promptElement.id = "console-prompt";
- this.promptElement.className = "source-code";
- this.promptElement.spellcheck = false;
- this.messagesElement.appendChild(this.promptElement);
- this.messagesElement.appendChild(document.createElement("br"));
-
- this.topGroup = new WebInspector.ConsoleGroup(null);
- this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
- this.currentGroup = this.topGroup;
-
- this._registerShortcuts();
- this.registerRequiredCSS("textPrompt.css");
-
- this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
-
- WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this));
-
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
-
- this._linkifier = new WebInspector.Linkifier();
-
- this.prompt = new WebInspector.TextPromptWithHistory(WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
- this.prompt.setSuggestBoxEnabled("generic-suggest");
- this.prompt.renderAsBlock();
- this.prompt.attach(this.promptElement);
- this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
- this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get());
-
- WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
-
- this._filterStatusMessageElement = document.createElement("div");
- this._filterStatusMessageElement.classList.add("console-message");
- this._filterStatusTextElement = this._filterStatusMessageElement.createChild("span", "console-info");
- this._filterStatusMessageElement.createTextChild(" ");
- var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "console-info node-link");
- resetFiltersLink.textContent = WebInspector.UIString("Show all messages.");
- resetFiltersLink.addEventListener("click", this._filter.reset.bind(this._filter), true);
-
- this.messagesElement.insertBefore(this._filterStatusMessageElement, this.topGroup.element);
-
- this._updateFilterStatus();
-}
-
-WebInspector.ConsoleView.prototype = {
- /**
- * @return {!Element}
- */
- defaultFocusedElement: function()
- {
- return this.promptElement
- },
-
- _onFiltersToggled: function(event)
- {
- var toggled = /** @type {boolean} */ (event.data);
- this._filtersContainer.enableStyleClass("hidden", !toggled);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _frameAdded: function(event)
- {
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- this._addFrame(contextList);
- },
-
- /**
- * @param {!WebInspector.FrameExecutionContextList} contextList
- */
- _addFrame: function(contextList)
- {
- var option = this._frameSelector.createOption(contextList.displayName, contextList.url);
- option._contextList = contextList;
- contextList._consoleOption = option;
- contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this);
- contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this);
- this._frameChanged();
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _frameRemoved: function(event)
- {
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- this._frameSelector.removeOption(contextList._consoleOption);
- this._frameChanged();
- },
-
- _frameChanged: function()
- {
- var context = this._currentFrame();
- if (!context) {
- WebInspector.runtimeModel.setCurrentExecutionContext(null);
- this._contextSelector.element.classList.add("hidden");
- return;
- }
-
- var executionContexts = context.executionContexts();
- if (executionContexts.length)
- WebInspector.runtimeModel.setCurrentExecutionContext(executionContexts[0]);
-
- if (executionContexts.length === 1) {
- this._contextSelector.element.classList.add("hidden");
- return;
- }
- this._contextSelector.element.classList.remove("hidden");
- this._contextSelector.removeOptions();
- for (var i = 0; i < executionContexts.length; ++i)
- this._appendContextOption(executionContexts[i]);
- },
-
- /**
- * @param {!WebInspector.ExecutionContext} executionContext
- */
- _appendContextOption: function(executionContext)
- {
- if (!WebInspector.runtimeModel.currentExecutionContext())
- WebInspector.runtimeModel.setCurrentExecutionContext(executionContext);
- var option = this._contextSelector.createOption(executionContext.name, executionContext.id);
- option._executionContext = executionContext;
- },
-
- _contextChanged: function()
- {
- var option = this._contextSelector.selectedOption();
- WebInspector.runtimeModel.setCurrentExecutionContext(option ? option._executionContext : null);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _frameUpdated: function(event)
- {
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- var option = contextList._consoleOption;
- option.text = contextList.displayName;
- option.title = contextList.url;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _contextAdded: function(event)
- {
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- if (contextList === this._currentFrame())
- this._frameChanged();
- },
-
- /**
- * @return {!WebInspector.FrameExecutionContextList|undefined}
- */
- _currentFrame: function()
- {
- var option = this._frameSelector.selectedOption();
- return option ? option._contextList : undefined;
- },
-
- willHide: function()
- {
- this.prompt.hideSuggestBox();
- this.prompt.clearAutoComplete(true);
- },
-
- wasShown: function()
- {
- if (!this.prompt.isCaretInsidePrompt())
- this.prompt.moveCaretToEndOfPrompt();
- },
-
- afterShow: function()
- {
- WebInspector.setCurrentFocusElement(this.promptElement);
- },
-
- storeScrollPositions: function()
- {
- WebInspector.View.prototype.storeScrollPositions.call(this);
- this._scrolledToBottom = this.messagesElement.isScrolledToBottom();
- },
-
- restoreScrollPositions: function()
- {
- if (this._scrolledToBottom)
- this._immediatelyScrollIntoView();
- else
- WebInspector.View.prototype.restoreScrollPositions.call(this);
- },
-
- onResize: function()
- {
- this.restoreScrollPositions();
- },
-
- _isScrollIntoViewScheduled: function()
- {
- return !!this._scrollIntoViewTimer;
- },
-
- _scheduleScrollIntoView: function()
- {
- if (this._scrollIntoViewTimer)
- return;
-
- /**
- * @this {WebInspector.ConsoleView}
- */
- function scrollIntoView()
- {
- delete this._scrollIntoViewTimer;
- this.messagesElement.scrollTop = this.messagesElement.scrollHeight - this.messagesElement.clientHeight;
- }
- this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
- },
-
- _immediatelyScrollIntoView: function()
- {
- this.promptElement.scrollIntoView(true);
- this._cancelScheduledScrollIntoView();
- },
-
- _cancelScheduledScrollIntoView: function()
- {
- if (!this._isScrollIntoViewScheduled())
- return;
-
- clearTimeout(this._scrollIntoViewTimer);
- delete this._scrollIntoViewTimer;
- },
-
- /**
- * @param {number=} count
- */
- _updateFilterStatus: function(count) {
- count = (typeof count === "undefined") ? (WebInspector.console.messages.length - this._visibleMessagesIndices.length) : count;
- this._filterStatusTextElement.textContent = WebInspector.UIString(count == 1 ? "%d message is hidden by filters." : "%d messages are hidden by filters.", count);
- this._filterStatusMessageElement.style.display = count ? "" : "none";
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _consoleMessageAdded: function(event)
- {
- var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
- var index = message.index;
-
- if (this._urlToMessageCount[message.url])
- this._urlToMessageCount[message.url]++;
- else
- this._urlToMessageCount[message.url] = 1;
-
- if (this._filter.shouldBeVisible(message))
- this._showConsoleMessage(index);
- else
- this._updateFilterStatus();
- },
-
- _showConsoleMessage: function(index)
- {
- var message = WebInspector.console.messages[index];
-
- // this.messagesElement.isScrolledToBottom() is forcing style recalculation.
- // We just skip it if the scroll action has been scheduled.
- if (!this._isScrollIntoViewScheduled() && ((message instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom()))
- this._scheduleScrollIntoView();
-
- this._visibleMessagesIndices.push(index);
-
- if (message.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
- var parentGroup = this.currentGroup.parentGroup;
- if (parentGroup)
- this.currentGroup = parentGroup;
- } else {
- if (message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
- var group = new WebInspector.ConsoleGroup(this.currentGroup);
- this.currentGroup.messagesElement.appendChild(group.element);
- this.currentGroup = group;
- message.group = group;
- }
- this.currentGroup.addMessage(message);
- }
-
- if (this._searchRegex && message.matchesRegex(this._searchRegex)) {
- this._searchResultsIndices.push(index);
- this._searchableView.updateSearchMatchesCount(this._searchResultsIndices.length);
- }
- },
-
- _consoleCleared: function()
- {
- this._scrolledToBottom = true;
- for (var i = 0; i < this._visibleMessagesIndices.length; ++i)
- WebInspector.console.messages[this._visibleMessagesIndices[i]].willHide();
- this._visibleMessagesIndices = [];
- this._searchResultsIndices = [];
-
- if (this._searchRegex)
- this._searchableView.updateSearchMatchesCount(0);
-
- this.currentGroup = this.topGroup;
- this.topGroup.messagesElement.removeChildren();
-
- this._clearCurrentSearchResultHighlight();
- this._updateFilterStatus(0);
-
- this._linkifier.reset();
- },
-
- _handleContextMenuEvent: function(event)
- {
- if (!window.getSelection().isCollapsed) {
- // If there is a selection, we want to show our normal context menu
- // (with Copy, etc.), and not Clear Console.
- return;
- }
-
- if (event.target.enclosingNodeOrSelfWithNodeName("a"))
- return;
-
- var contextMenu = new WebInspector.ContextMenu(event);
-
- function monitoringXHRItemAction()
- {
- WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
- }
- contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get());
-
- function preserveLogItemAction()
- {
- WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
- }
- contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get());
-
- var sourceElement = event.target.enclosingNodeOrSelfWithClass("console-message");
-
- var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Filter"));
-
- if (sourceElement && sourceElement.message.url) {
- var menuTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Hide messages from %s" : "Hide Messages from %s", new WebInspector.ParsedURL(sourceElement.message.url).displayName);
- filterSubMenu.appendItem(menuTitle, this._filter.addMessageURLFilter.bind(this._filter, sourceElement.message.url));
- }
-
- filterSubMenu.appendSeparator();
- var unhideAll = filterSubMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Unhide all" : "Unhide All"), this._filter.removeMessageURLFilter.bind(this._filter));
- filterSubMenu.appendSeparator();
-
- var hasFilters = false;
-
- for (var url in this._filter.messageURLFilters) {
- filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)", new WebInspector.ParsedURL(url).displayName, this._urlToMessageCount[url]), this._filter.removeMessageURLFilter.bind(this._filter, url), true);
- hasFilters = true;
- }
-
- filterSubMenu.setEnabled(hasFilters || (sourceElement && sourceElement.message.url));
- unhideAll.setEnabled(hasFilters);
-
- contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));
-
- var request = (sourceElement && sourceElement.message) ? sourceElement.message.request() : null;
- if (request && request.type === WebInspector.resourceTypes.XHR) {
- contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString("Replay XHR"), NetworkAgent.replayXHR.bind(null, request.requestId));
- }
-
- contextMenu.show();
- },
-
- _updateMessageList: function()
- {
- var group = this.topGroup;
- var sourceMessages = WebInspector.console.messages;
- var visibleMessageIndex = 0;
- var newVisibleMessages = [];
-
- if (this._searchRegex)
- this._searchResultsIndices = [];
-
- var anchor = null;
- for (var i = 0; i < sourceMessages.length; ++i) {
- var sourceMessage = sourceMessages[i];
- var visibleMessage = WebInspector.console.messages[this._visibleMessagesIndices[visibleMessageIndex]];
-
- if (visibleMessage === sourceMessage) {
- if (this._filter.shouldBeVisible(visibleMessage)) {
- newVisibleMessages.push(this._visibleMessagesIndices[visibleMessageIndex]);
-
- if (this._searchRegex && sourceMessage.matchesRegex(this._searchRegex))
- this._searchResultsIndices.push(i);
-
- if (sourceMessage.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
- anchor = group.element;
- group = group.parentGroup || group;
- } else if (sourceMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroup || sourceMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
- group = sourceMessage.group;
- anchor = group.messagesElement.firstChild;
- } else
- anchor = visibleMessage.toMessageElement();
- } else {
- visibleMessage.willHide();
- visibleMessage.toMessageElement().remove();
- }
- ++visibleMessageIndex;
- } else {
- if (this._filter.shouldBeVisible(sourceMessage)) {
-
- if (this._searchRegex && sourceMessage.matchesRegex(this._searchRegex))
- this._searchResultsIndices.push(i);
-
- group.addMessage(sourceMessage, anchor ? anchor.nextSibling : group.messagesElement.firstChild);
- newVisibleMessages.push(i);
- anchor = sourceMessage.toMessageElement();
- }
- }
- }
-
- if (this._searchRegex)
- this._searchableView.updateSearchMatchesCount(this._searchResultsIndices.length);
-
- this._visibleMessagesIndices = newVisibleMessages;
- this._updateFilterStatus();
- },
-
- _monitoringXHREnabledSettingChanged: function(event)
- {
- ConsoleAgent.setMonitoringXHREnabled(event.data);
- },
-
- _messagesClicked: function()
- {
- if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
- this.prompt.moveCaretToEndOfPrompt();
- },
-
- _registerShortcuts: function()
- {
- this._shortcuts = {};
-
- var shortcut = WebInspector.KeyboardShortcut;
- var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
-
- var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
- this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);
- var keys = [shortcutL];
- if (WebInspector.isMac()) {
- var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
- this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
- keys.unshift(shortcutK);
- }
- section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
-
- section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector.UIString("Autocomplete common prefix"));
- section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
-
- keys = [
- shortcut.makeDescriptor(shortcut.Keys.Down),
- shortcut.makeDescriptor(shortcut.Keys.Up)
- ];
- section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
-
- if (WebInspector.isMac()) {
- keys = [
- shortcut.makeDescriptor("N", shortcut.Modifiers.Alt),
- shortcut.makeDescriptor("P", shortcut.Modifiers.Alt)
- ];
- section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
- }
-
- section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
- },
-
- _requestClearMessages: function()
- {
- WebInspector.console.requestClearMessages();
- },
-
- _promptKeyDown: function(event)
- {
- if (isEnterKey(event)) {
- this._enterKeyPressed(event);
- return;
- }
-
- var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
- var handler = this._shortcuts[shortcut];
- if (handler) {
- handler();
- event.preventDefault();
- }
- },
-
- /**
- * @param {string} expression
- * @param {boolean} showResultOnly
- */
- evaluateUsingTextPrompt: function(expression, showResultOnly)
- {
- this._appendCommand(expression, this.prompt.text, false, showResultOnly);
- },
-
- _enterKeyPressed: function(event)
- {
- if (event.altKey || event.ctrlKey || event.shiftKey)
- return;
-
- event.consume(true);
-
- this.prompt.clearAutoComplete(true);
-
- var str = this.prompt.text;
- if (!str.length)
- return;
- this._appendCommand(str, "", true, false);
- },
-
- /**
- * @param {!WebInspector.RemoteObject} result
- * @param {boolean} wasThrown
- * @param {!WebInspector.ConsoleCommand} originatingCommand
- */
- _printResult: function(result, wasThrown, originatingCommand)
- {
- if (!result)
- return;
-
- /**
- * @param {string=} url
- * @param {number=} lineNumber
- * @param {number=} columnNumber
- * @this {WebInspector.ConsoleView}
- */
- function addMessage(url, lineNumber, columnNumber)
- {
- var message = new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier, url, lineNumber, columnNumber);
- WebInspector.console.addMessage(message);
- }
-
- if (result.type !== "function") {
- addMessage.call(this);
- return;
- }
-
- DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this));
-
- /**
- * @param {?Protocol.Error} error
- * @param {!DebuggerAgent.FunctionDetails} response
- * @this {WebInspector.ConsoleView}
- */
- function didGetDetails(error, response)
- {
- if (error) {
- console.error(error);
- addMessage.call(this);
- return;
- }
-
- var url;
- var lineNumber;
- var columnNumber;
- var script = WebInspector.debuggerModel.scriptForId(response.location.scriptId);
- if (script && script.sourceURL) {
- url = script.sourceURL;
- lineNumber = response.location.lineNumber + 1;
- columnNumber = response.location.columnNumber + 1;
- }
- addMessage.call(this, url, lineNumber, columnNumber);
- }
- },
-
- /**
- * @param {string} text
- * @param {string} newPromptText
- * @param {boolean} useCommandLineAPI
- * @param {boolean} showResultOnly
- */
- _appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly)
- {
- if (!showResultOnly) {
- var commandMessage = new WebInspector.ConsoleCommand(text);
- WebInspector.console.addMessage(commandMessage);
- }
- this.prompt.text = newPromptText;
-
- /**
- * @param {?WebInspector.RemoteObject} result
- * @param {boolean} wasThrown
- * @param {?RuntimeAgent.RemoteObject=} valueResult
- * @this {WebInspector.ConsoleView}
- */
- function printResult(result, wasThrown, valueResult)
- {
- if (!result)
- return;
-
- if (!showResultOnly) {
- this.prompt.pushHistoryItem(text);
- WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30));
- }
-
- this._printResult(result, wasThrown, commandMessage);
- }
- WebInspector.runtimeModel.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(this));
-
- WebInspector.userMetrics.ConsoleEvaluated.record();
- },
-
- elementsToRestoreScrollPositionsFor: function()
- {
- return [this.messagesElement];
- },
-
- searchCanceled: function()
- {
- this._clearCurrentSearchResultHighlight();
- delete this._searchResultsIndices;
- delete this._searchRegex;
- },
-
- /**
- * @param {string} query
- * @param {boolean} shouldJump
- */
- performSearch: function(query, shouldJump)
- {
- this.searchCanceled();
- this._searchableView.updateSearchMatchesCount(0);
- this._searchRegex = createPlainTextSearchRegex(query, "gi");
-
- this._searchResultsIndices = [];
- for (var i = 0; i < this._visibleMessagesIndices.length; i++) {
- if (WebInspector.console.messages[this._visibleMessagesIndices[i]].matchesRegex(this._searchRegex))
- this._searchResultsIndices.push(this._visibleMessagesIndices[i]);
- }
- this._searchableView.updateSearchMatchesCount(this._searchResultsIndices.length);
- this._currentSearchResultIndex = -1;
- if (shouldJump && this._searchResultsIndices.length)
- this._jumpToSearchResult(0);
- },
-
- jumpToNextSearchResult: function()
- {
- if (!this._searchResultsIndices || !this._searchResultsIndices.length)
- return;
- this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResultsIndices.length);
- },
-
- jumpToPreviousSearchResult: function()
- {
- if (!this._searchResultsIndices || !this._searchResultsIndices.length)
- return;
- var index = this._currentSearchResultIndex - 1;
- if (index === -1)
- index = this._searchResultsIndices.length - 1;
- this._jumpToSearchResult(index);
- },
-
- _clearCurrentSearchResultHighlight: function()
- {
- if (!this._searchResultsIndices)
- return;
- var highlightedMessage = WebInspector.console.messages[this._searchResultsIndices[this._currentSearchResultIndex]];
- if (highlightedMessage)
- highlightedMessage.clearHighlight();
- this._currentSearchResultIndex = -1;
- },
-
- _jumpToSearchResult: function(index)
- {
- this._clearCurrentSearchResultHighlight();
- this._currentSearchResultIndex = index;
- this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
- WebInspector.console.messages[this._searchResultsIndices[index]].highlightSearchResults(this._searchRegex);
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @extends {WebInspector.Object}
- * @constructor
- */
-WebInspector.ConsoleViewFilter = function()
-{
- this._messageURLFilters = WebInspector.settings.messageURLFilters.get();
- this._filterChanged = this.dispatchEventToListeners.bind(this, WebInspector.ConsoleViewFilter.Events.FilterChanged);
-};
-
-WebInspector.ConsoleViewFilter.Events = {
- FilterChanged: "FilterChanged"
-};
-
-WebInspector.ConsoleViewFilter.prototype = {
- addFilters: function(filterBar)
- {
- this._textFilterUI = new WebInspector.TextFilterUI(true);
- this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._textFilterChanged, this);
- filterBar.addFilter(this._textFilterUI);
-
- this._levelFilterUI = new WebInspector.NamedBitSetFilterUI();
- this._levelFilterUI.addBit("error", WebInspector.UIString("Errors"));
- this._levelFilterUI.addBit("warning", WebInspector.UIString("Warnings"));
- this._levelFilterUI.addBit("info", WebInspector.UIString("Info"));
- this._levelFilterUI.addBit("log", WebInspector.UIString("Logs"));
- this._levelFilterUI.addBit("debug", WebInspector.UIString("Debug"));
- this._levelFilterUI.bindSetting(WebInspector.settings.messageLevelFilters);
- this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
- filterBar.addFilter(this._levelFilterUI);
- },
-
- _textFilterChanged: function(event)
- {
- this._filterRegex = this._textFilterUI.regex();
-
- this._filterChanged();
- },
-
- /**
- * @param {string} url
- */
- addMessageURLFilter: function(url)
- {
- this._messageURLFilters[url] = true;
- WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
- this._filterChanged();
- },
-
- /**
- * @param {string} url
- */
- removeMessageURLFilter: function(url)
- {
- if (!url)
- this._messageURLFilters = {};
- else
- delete this._messageURLFilters[url];
-
- WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
- this._filterChanged();
- },
-
- /**
- * @returns {!Object}
- */
- get messageURLFilters()
- {
- return this._messageURLFilters;
- },
-
- /**
- * @param {!WebInspector.ConsoleMessage} message
- * @return {boolean}
- */
- shouldBeVisible: function(message)
- {
- if ((message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed || message.type === WebInspector.ConsoleMessage.MessageType.EndGroup))
- return true;
-
- if (message.type === WebInspector.ConsoleMessage.MessageType.Result || message.type === WebInspector.ConsoleMessage.MessageType.Command)
- return true;
-
- if (message.url && this._messageURLFilters[message.url])
- return false;
-
- if (message.level && !this._levelFilterUI.accept(message.level))
- return false;
-
- if (this._filterRegex) {
- this._filterRegex.lastIndex = 0;
- if (!message.matchesRegex(this._filterRegex))
- return false;
- }
-
- return true;
- },
-
- reset: function()
- {
- this._messageURLFilters = {};
- WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
- WebInspector.settings.messageLevelFilters.set({});
- this._filterChanged();
- },
-
- __proto__: WebInspector.Object.prototype
-};
-
-
-/**
- * @constructor
- * @extends WebInspector.ConsoleMessage
- */
-WebInspector.ConsoleCommand = function(text)
-{
- this.text = text;
- this.type = WebInspector.ConsoleMessage.MessageType.Command;
-}
-
-WebInspector.ConsoleCommand.prototype = {
- wasShown: function()
- {
- },
-
- willHide: function()
- {
- },
-
- clearHighlight: function()
- {
- var highlightedMessage = this._formattedCommand;
- delete this._formattedCommand;
- this._formatCommand();
- this._element.replaceChild(this._formattedCommand, highlightedMessage);
- },
-
- /**
- * @param {!RegExp} regexObject
- */
- highlightSearchResults: function(regexObject)
- {
- regexObject.lastIndex = 0;
- var match = regexObject.exec(this.text);
- var matchRanges = [];
- while (match) {
- matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
- match = regexObject.exec(this.text);
- }
- WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
- this._element.scrollIntoViewIfNeeded();
- },
-
- /**
- * @param {!RegExp} regexObject
- */
- matchesRegex: function(regexObject)
- {
- regexObject.lastIndex = 0;
- return regexObject.test(this.text);
- },
-
- toMessageElement: function()
- {
- if (!this._element) {
- this._element = document.createElement("div");
- this._element.command = this;
- this._element.className = "console-user-command";
-
- this._formatCommand();
- this._element.appendChild(this._formattedCommand);
- }
- return this._element;
- },
-
- _formatCommand: function()
- {
- this._formattedCommand = document.createElement("span");
- this._formattedCommand.className = "console-message-text source-code";
- this._formattedCommand.textContent = this.text;
- },
-
- __proto__: WebInspector.ConsoleMessage.prototype
-}
-
-/**
- * @extends {WebInspector.ConsoleMessageImpl}
- * @constructor
- * @param {!WebInspector.RemoteObject} result
- * @param {boolean} wasThrown
- * @param {!WebInspector.ConsoleCommand} originatingCommand
- * @param {!WebInspector.Linkifier} linkifier
- * @param {string=} url
- * @param {number=} lineNumber
- * @param {number=} columnNumber
- */
-WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier, url, lineNumber, columnNumber)
-{
- var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
- this.originatingCommand = originatingCommand;
- WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, url, lineNumber, columnNumber, undefined, [result]);
-}
-
-WebInspector.ConsoleCommandResult.prototype = {
- /**
- * @override
- * @param {!WebInspector.RemoteObject} array
- * @return {boolean}
- */
- useArrayPreviewInFormatter: function(array)
- {
- return false;
- },
-
- toMessageElement: function()
- {
- var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this);
- element.classList.add("console-user-command-result");
- return element;
- },
-
- __proto__: WebInspector.ConsoleMessageImpl.prototype
-}
-
-/**
- * @constructor
- */
-WebInspector.ConsoleGroup = function(parentGroup)
-{
- this.parentGroup = parentGroup;
-
- var element = document.createElement("div");
- element.className = "console-group";
- element.group = this;
- this.element = element;
-
- if (parentGroup) {
- var bracketElement = document.createElement("div");
- bracketElement.className = "console-group-bracket";
- element.appendChild(bracketElement);
- }
-
- var messagesElement = document.createElement("div");
- messagesElement.className = "console-group-messages";
- element.appendChild(messagesElement);
- this.messagesElement = messagesElement;
-}
-
-WebInspector.ConsoleGroup.prototype = {
- /**
- * @param {!WebInspector.ConsoleMessage} message
- * @param {!Node=} node
- */
- addMessage: function(message, node)
- {
- var element = message.toMessageElement();
-
- if (message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
- this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
- element.addEventListener("click", this._titleClicked.bind(this), false);
- var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
- if (groupElement && message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
- groupElement.classList.add("collapsed");
- } else {
- this.messagesElement.insertBefore(element, node || null);
- message.wasShown();
- }
-
- if (element.previousSibling && message.originatingCommand && element.previousSibling.command === message.originatingCommand)
- element.previousSibling.classList.add("console-adjacent-user-command-result");
- },
-
- _titleClicked: function(event)
- {
- var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
- if (groupTitleElement) {
- var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
- if (groupElement && !groupElement.classList.toggle("collapsed")) {
- if (groupElement.group) {
- groupElement.group.wasShown();
- }
- }
- groupTitleElement.scrollIntoViewIfNeeded(true);
- }
- event.consume(true);
- },
-
- wasShown: function()
- {
- if (this.element.classList.contains("collapsed"))
- return;
- var node = this.messagesElement.firstChild;
- while (node) {
- if (node.classList.contains("console-message") && node.message)
- node.message.wasShown();
- if (node.classList.contains("console-group") && node.group)
- node.group.wasShown();
- node = node.nextSibling;
- }
- }
-}
-
-/**
- * @type {!WebInspector.ConsoleView}
- */
-WebInspector.consoleView;
-
-WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, column, repeatCount, parameters, stackTrace, requestId, isOutdated)
-{
- return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, column, repeatCount, parameters, stackTrace, requestId, isOutdated);
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMCountersGraph.js b/chromium/third_party/WebKit/Source/devtools/front_end/DOMCountersGraph.js
deleted file mode 100644
index b55900f6682..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMCountersGraph.js
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.MemoryStatistics}
- * @param {!WebInspector.TimelinePanel} timelinePanel
- * @param {!WebInspector.TimelineModel} model
- */
-WebInspector.DOMCountersGraph = function(timelinePanel, model)
-{
- WebInspector.MemoryStatistics.call(this, timelinePanel, model);
-}
-
-/**
- * @constructor
- * @extends {WebInspector.CounterUIBase}
- * @param {!WebInspector.DOMCountersGraph} memoryCountersPane
- * @param {string} title
- * @param {string} currentValueLabel
- * @param {!string} color
- * @param {function(!WebInspector.DOMCountersGraph.Counter):number} valueGetter
- */
-WebInspector.DOMCounterUI = function(memoryCountersPane, title, currentValueLabel, color, valueGetter)
-{
- WebInspector.CounterUIBase.call(this, memoryCountersPane, title, color, valueGetter)
- this._range = this._swatch.element.createChild("span");
-
- this._value = memoryCountersPane._currentValuesBar.createChild("span", "memory-counter-value");
- this._value.style.color = color;
- this._currentValueLabel = currentValueLabel;
-
- this.graphColor = color;
- this.graphYValues = [];
-}
-
-/**
- * @constructor
- * @extends {WebInspector.MemoryStatistics.Counter}
- * @param {number} time
- * @param {number} documentCount
- * @param {number} nodeCount
- * @param {number} listenerCount
- */
-WebInspector.DOMCountersGraph.Counter = function(time, documentCount, nodeCount, listenerCount, usedGPUMemoryKBytes)
-{
- WebInspector.MemoryStatistics.Counter.call(this, time);
- this.documentCount = documentCount;
- this.nodeCount = nodeCount;
- this.listenerCount = listenerCount;
- this.usedGPUMemoryKBytes = usedGPUMemoryKBytes;
-}
-
-WebInspector.DOMCounterUI.prototype = {
- /**
- * @param {number} minValue
- * @param {number} maxValue
- */
- setRange: function(minValue, maxValue)
- {
- this._range.textContent = WebInspector.UIString("[%d:%d]", minValue, maxValue);
- },
-
- updateCurrentValue: function(countersEntry)
- {
- this._value.textContent = WebInspector.UIString(this._currentValueLabel, this.valueGetter(countersEntry));
- },
-
- clearCurrentValueAndMarker: function(ctx)
- {
- this._value.textContent = "";
- this.restoreImageUnderMarker(ctx);
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- * @param {number} x
- * @param {number} y
- * @param {number} radius
- */
- saveImageUnderMarker: function(ctx, x, y, radius)
- {
- const w = radius + 1;
- var imageData = ctx.getImageData(x - w, y - w, 2 * w, 2 * w);
- this._imageUnderMarker = {
- x: x - w,
- y: y - w,
- imageData: imageData
- };
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- */
- restoreImageUnderMarker: function(ctx)
- {
- if (!this.visible)
- return;
- if (this._imageUnderMarker)
- ctx.putImageData(this._imageUnderMarker.imageData, this._imageUnderMarker.x, this._imageUnderMarker.y);
- this.discardImageUnderMarker();
- },
-
- discardImageUnderMarker: function()
- {
- delete this._imageUnderMarker;
- },
-
- __proto__: WebInspector.CounterUIBase.prototype
-}
-
-
-WebInspector.DOMCountersGraph.prototype = {
- _createCurrentValuesBar: function()
- {
- this._currentValuesBar = this._canvasContainer.createChild("div");
- this._currentValuesBar.id = "counter-values-bar";
- this._canvasContainer.classList.add("dom-counters");
- },
-
- /**
- * @return {!Element}
- */
- resizeElement: function()
- {
- return this._currentValuesBar;
- },
-
- /**
- * @return {!Array.<!WebInspector.DOMCounterUI>}
- */
- _createCounterUIList: function()
- {
- function getDocumentCount(entry)
- {
- return entry.documentCount;
- }
- function getNodeCount(entry)
- {
- return entry.nodeCount;
- }
- function getListenerCount(entry)
- {
- return entry.listenerCount;
- }
- function getUsedGPUMemoryKBytes(entry)
- {
- return entry.usedGPUMemoryKBytes || 0;
- }
- var counterUIs = [
- new WebInspector.DOMCounterUI(this, "Documents", "Documents: %d", "#d00", getDocumentCount),
- new WebInspector.DOMCounterUI(this, "Nodes", "Nodes: %d", "#0a0", getNodeCount),
- new WebInspector.DOMCounterUI(this, "Listeners", "Listeners: %d", "#00d", getListenerCount)
- ];
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
- counterUIs.push(new WebInspector.DOMCounterUI(this, "GPU Memory", "GPU Memory [KB]: %d", "#c0c", getUsedGPUMemoryKBytes));
- return counterUIs;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onRecordAdded: function(event)
- {
- /**
- * @param {!Array.<!T>} array
- * @param {!S} item
- * @param {!function(!T,!S):!number} comparator
- * @return {!number}
- * @template T,S
- */
- function findInsertionLocation(array, item, comparator)
- {
- var index = array.length;
- while (index > 0 && comparator(array[index - 1], item) > 0)
- --index;
- return index;
- }
-
- /**
- * @this {WebInspector.DOMCountersGraph}
- */
- function addStatistics(record)
- {
- var counters = record["counters"];
- var isGPURecord = record.data && typeof record.data["usedGPUMemoryBytes"] !== "undefined";
- if (isGPURecord) {
- counters = counters || {
- "startTime": record.startTime,
- "endTime": record.endTime
- };
- counters["usedGPUMemoryKBytes"] = Math.round(record.data["usedGPUMemoryBytes"] / 1024);
- }
- if (!counters)
- return;
-
- var time = record.endTime || record.startTime;
- var counter = new WebInspector.DOMCountersGraph.Counter(
- time,
- counters["documents"],
- counters["nodes"],
- counters["jsEventListeners"],
- counters["usedGPUMemoryKBytes"]
- );
-
- function compare(record, time)
- {
- return record.time - time;
- }
- var index = findInsertionLocation(this._counters, time, compare);
- this._counters.splice(index, 0, counter);
- if (isGPURecord) {
- // Populate missing values from preceeding records.
- // FIXME: Refactor the code to make each WebInspector.DOMCountersGraph.Counter
- // be responsible for a single graph to avoid such synchronizations.
- for (var i = index - 1; i >= 0 && typeof this._counters[i].usedGPUMemoryKBytes === "undefined"; --i) { }
- var usedGPUMemoryKBytes = this._counters[i >= 0 ? i : index].usedGPUMemoryKBytes;
- for (i = Math.max(i, 0); i < index; ++i)
- this._counters[i].usedGPUMemoryKBytes = usedGPUMemoryKBytes;
- var copyFrom = index > 0 ? index - 1 : index + 1;
- if (copyFrom < this._counters.length) {
- this._counters[index].documentCount = this._counters[copyFrom].documentCount;
- this._counters[index].nodeCount = this._counters[copyFrom].nodeCount;
- this._counters[index].listenerCount = this._counters[copyFrom].listenerCount;
- } else {
- this._counters[index].documentCount = 0;
- this._counters[index].nodeCount = 0;
- this._counters[index].listenerCount = 0;
- }
- }
- }
- WebInspector.TimelinePresentationModel.forAllRecords([event.data], null, addStatistics.bind(this));
- },
-
- draw: function()
- {
- WebInspector.MemoryStatistics.prototype.draw.call(this);
- for (var i = 0; i < this._counterUI.length; i++)
- this._drawGraph(this._counterUI[i]);
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- */
- _restoreImageUnderMarker: function(ctx)
- {
- for (var i = 0; i < this._counterUI.length; i++) {
- var counterUI = this._counterUI[i];
- if (!counterUI.visible)
- continue;
- counterUI.restoreImageUnderMarker(ctx);
- }
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- * @param {number} x
- * @param {number} index
- */
- _saveImageUnderMarker: function(ctx, x, index)
- {
- const radius = 2;
- for (var i = 0; i < this._counterUI.length; i++) {
- var counterUI = this._counterUI[i];
- if (!counterUI.visible)
- continue;
- var y = counterUI.graphYValues[index];
- counterUI.saveImageUnderMarker(ctx, x, y, radius);
- }
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- * @param {number} x
- * @param {number} index
- */
- _drawMarker: function(ctx, x, index)
- {
- this._saveImageUnderMarker(ctx, x, index);
- const radius = 2;
- for (var i = 0; i < this._counterUI.length; i++) {
- var counterUI = this._counterUI[i];
- if (!counterUI.visible)
- continue;
- var y = counterUI.graphYValues[index];
- ctx.beginPath();
- ctx.arc(x + 0.5, y + 0.5, radius, 0, Math.PI * 2, true);
- ctx.lineWidth = 1;
- ctx.fillStyle = counterUI.graphColor;
- ctx.strokeStyle = counterUI.graphColor;
- ctx.fill();
- ctx.stroke();
- ctx.closePath();
- }
- },
-
- /**
- * @param {!WebInspector.CounterUIBase} counterUI
- */
- _drawGraph: function(counterUI)
- {
- var canvas = this._canvas;
- var ctx = canvas.getContext("2d");
- var width = canvas.width;
- var height = this._clippedHeight;
- var originY = this._originY;
- var valueGetter = counterUI.valueGetter;
-
- if (!this._counters.length)
- return;
-
- var maxValue;
- var minValue;
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
- var value = valueGetter(this._counters[i]);
- if (minValue === undefined || value < minValue)
- minValue = value;
- if (maxValue === undefined || value > maxValue)
- maxValue = value;
- }
-
- counterUI.setRange(minValue, maxValue);
-
- if (!counterUI.visible)
- return;
-
- var yValues = counterUI.graphYValues;
- yValues.length = this._counters.length;
-
- var maxYRange = maxValue - minValue;
- var yFactor = maxYRange ? height / (maxYRange) : 1;
-
- ctx.save();
- ctx.translate(0.5, 0.5);
- ctx.beginPath();
- var currentY = Math.round(originY + (height - (valueGetter(this._counters[this._minimumIndex]) - minValue) * yFactor));
- ctx.moveTo(0, currentY);
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
- var x = Math.round(this._counters[i].x);
- ctx.lineTo(x, currentY);
- currentY = Math.round(originY + (height - (valueGetter(this._counters[i]) - minValue) * yFactor));
- ctx.lineTo(x, currentY);
- yValues[i] = currentY;
- }
- ctx.lineTo(width, currentY);
- ctx.lineWidth = 1;
- ctx.strokeStyle = counterUI.graphColor;
- ctx.stroke();
- ctx.closePath();
- ctx.restore();
- },
-
- _discardImageUnderMarker: function()
- {
- for (var i = 0; i < this._counterUI.length; i++)
- this._counterUI[i].discardImageUnderMarker();
- },
-
- __proto__: WebInspector.MemoryStatistics.prototype
-}
-
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DevToolsExtensionAPI.js b/chromium/third_party/WebKit/Source/devtools/front_end/DevToolsExtensionAPI.js
deleted file mode 100644
index 44f7c218a7c..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DevToolsExtensionAPI.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-function platformExtensionAPI(coreAPI)
-{
- function getTabId()
- {
- return tabId;
- }
- chrome = window.chrome || {};
- // Override chrome.devtools as a workaround for a error-throwing getter being exposed
- // in extension pages loaded into a non-extension process (only happens for remote client
- // extensions)
- var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
- if (!devtools_descriptor || devtools_descriptor.get)
- Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });
- // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
- chrome.devtools.inspectedWindow = {};
- chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
- chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
- chrome.devtools.network = coreAPI.network;
- chrome.devtools.panels = coreAPI.panels;
-
- // default to expose experimental APIs for now.
- if (extensionInfo.exposeExperimentalAPIs !== false) {
- chrome.experimental = chrome.experimental || {};
- chrome.experimental.devtools = chrome.experimental.devtools || {};
-
- var properties = Object.getOwnPropertyNames(coreAPI);
- for (var i = 0; i < properties.length; ++i) {
- var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
- Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
- }
- chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
- }
- if (extensionInfo.exposeWebInspectorNamespace)
- window.webInspector = coreAPI;
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DockController.js b/chromium/third_party/WebKit/Source/devtools/front_end/DockController.js
deleted file mode 100644
index 6934d0fa52c..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DockController.js
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.DockController = function()
-{
- this._dockToggleButton = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
- this._dockToggleButtonOption = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
- this._dockToggleButton.addEventListener("click", this._toggleDockState, this);
- this._dockToggleButtonOption.addEventListener("click", this._toggleDockState, this);
- this._dockToggleButton.setLongClickOptionsEnabled(this._createDockOptions.bind(this));
-
- this.setDockSide(WebInspector.queryParamsObject["can_dock"] ? (WebInspector.queryParamsObject["dockSide"] || "bottom") : "undocked");
-}
-
-WebInspector.DockController.State = {
- DockedToBottom: "bottom",
- DockedToRight: "right",
- Undocked: "undocked"
-}
-
-WebInspector.DockController.Events = {
- DockSideChanged: "DockSideChanged"
-}
-
-WebInspector.DockController.prototype = {
- /**
- * @return {!Element}
- */
- get element()
- {
- return this._dockToggleButton.element;
- },
-
- /**
- * @return {string}
- */
- dockSide: function()
- {
- return this._dockSide;
- },
-
- /**
- * @param {string} dockSide
- */
- setDockSide: function(dockSide)
- {
- if (this._dockSide === dockSide)
- return;
-
- if (this._dockSide)
- WebInspector.settings.lastDockState.set(this._dockSide);
-
- this._dockSide = dockSide;
- if (dockSide === WebInspector.DockController.State.Undocked)
- WebInspector.userMetrics.WindowDocked.record();
- else
- WebInspector.userMetrics.WindowUndocked.record();
- this._updateUI();
- this.dispatchEventToListeners(WebInspector.DockController.Events.DockSideChanged, this._dockSide);
- },
-
- _updateUI: function()
- {
- var body = document.body;
- switch (this._dockSide) {
- case WebInspector.DockController.State.DockedToBottom:
- body.classList.remove("undocked");
- body.classList.remove("dock-to-right");
- body.classList.add("dock-to-bottom");
- break;
- case WebInspector.DockController.State.DockedToRight:
- body.classList.remove("undocked");
- body.classList.add("dock-to-right");
- body.classList.remove("dock-to-bottom");
- break;
- case WebInspector.DockController.State.Undocked:
- body.classList.add("undocked");
- body.classList.remove("dock-to-right");
- body.classList.remove("dock-to-bottom");
- break;
- }
-
- this._dockToggleButton.setEnabled(true);
-
- // Choose different last state based on the current one if missing or if is the same.
- var sides = [WebInspector.DockController.State.DockedToBottom, WebInspector.DockController.State.Undocked, WebInspector.DockController.State.DockedToRight];
- sides.remove(this._dockSide);
- var lastState = WebInspector.settings.lastDockState.get();
-
- sides.remove(lastState);
- if (sides.length === 2) { // last state was not from the list of potential values
- lastState = sides[0];
- sides.remove(lastState);
- }
- this._decorateButtonForTargetState(this._dockToggleButton, lastState);
- this._decorateButtonForTargetState(this._dockToggleButtonOption, sides[0]);
- },
-
- /**
- * @param {!WebInspector.StatusBarButton} button
- * @param {string} state
- */
- _decorateButtonForTargetState: function(button, state)
- {
- switch (state) {
- case WebInspector.DockController.State.DockedToBottom:
- button.title = WebInspector.UIString("Dock to main window.");
- button.state = "bottom";
- break;
- case WebInspector.DockController.State.DockedToRight:
- button.title = WebInspector.UIString("Dock to main window.");
- button.state = "right";
- break;
- case WebInspector.DockController.State.Undocked:
- button.title = WebInspector.UIString("Undock into separate window.");
- button.state = "undock";
- break;
- }
- },
-
- _createDockOptions: function()
- {
- return [this._dockToggleButtonOption];
- },
-
- /**
- * @param {!WebInspector.Event} e
- */
- _toggleDockState: function(e)
- {
- var action;
- switch (e.target.state) {
- case "bottom": action = "bottom"; break;
- case "right": action = "right"; break;
- case "undock": action = "undocked"; break;
- }
- InspectorFrontendHost.requestSetDockSide(action);
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @type {!WebInspector.DockController}
- */
-WebInspector.dockController;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Drawer.js b/chromium/third_party/WebKit/Source/devtools/front_end/Drawer.js
deleted file mode 100644
index 4e60a51cedd..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Drawer.js
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @implements {WebInspector.ViewFactory}
- * @param {!WebInspector.InspectorView} inspectorView
- */
-WebInspector.Drawer = function(inspectorView)
-{
- this._inspectorView = inspectorView;
-
- this.element = this._inspectorView.devtoolsElement().createChild("div", "drawer");
- this.element.style.flexBasis = 0;
-
- this._savedHeight = 200; // Default.
-
- this._drawerContentsElement = this.element.createChild("div");
- this._drawerContentsElement.id = "drawer-contents";
-
- this._toggleDrawerButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show drawer."), "console-status-bar-item");
- this._toggleDrawerButton.addEventListener("click", this.toggle, this);
-
- this._viewFactories = [];
- this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.closeableTabs = false;
- this._tabbedPane.markAsRoot();
-
- // Register console early for it to be the first in the list.
- this.registerView("console", WebInspector.UIString("Console"), this);
-
- this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._updateTabStrip, this);
- this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
- WebInspector.installDragHandle(this._tabbedPane.headerElement(), this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize");
- this._tabbedPane.element.createChild("div", "drawer-resizer");
- this._showDrawerOnLoadSetting = WebInspector.settings.createSetting("WebInspector.Drawer.showOnLoad", false);
- this._lastSelectedViewSetting = WebInspector.settings.createSetting("WebInspector.Drawer.lastSelectedView", "console");
-}
-
-WebInspector.Drawer.prototype = {
- /**
- * @return {!Element}
- */
- toggleButtonElement: function()
- {
- return this._toggleDrawerButton.element;
- },
-
- _constrainHeight: function(height)
- {
- return Number.constrain(height, Preferences.minConsoleHeight, this._inspectorView.devtoolsElement().offsetHeight - Preferences.minConsoleHeight);
- },
-
- isHiding: function()
- {
- return this._isHiding;
- },
-
- /**
- * @param {string} tabId
- * @param {string} title
- * @param {!WebInspector.View} view
- */
- _addView: function(tabId, title, view)
- {
- if (!this._tabbedPane.hasTab(tabId)) {
- this._tabbedPane.appendTab(tabId, title, view, undefined, false);
- } else {
- this._tabbedPane.changeTabTitle(tabId, title);
- this._tabbedPane.changeTabView(tabId, view);
- }
- },
-
- /**
- * @param {string} id
- * @param {string} title
- * @param {!WebInspector.ViewFactory} factory
- */
- registerView: function(id, title, factory)
- {
- if (this._tabbedPane.hasTab(id))
- this._tabbedPane.closeTab(id);
- this._viewFactories[id] = factory;
- this._tabbedPane.appendTab(id, title, new WebInspector.View());
- },
-
- /**
- * @param {string} id
- */
- unregisterView: function(id)
- {
- if (this._tabbedPane.hasTab(id))
- this._tabbedPane.closeTab(id);
- delete this._viewFactories[id];
- },
-
- /**
- * @param {string=} id
- * @return {?WebInspector.View}
- */
- createView: function(id)
- {
- return WebInspector.panel("console").createView(id);
- },
-
- /**
- * @param {string} id
- */
- closeView: function(id)
- {
- this._tabbedPane.closeTab(id);
- },
-
- /**
- * @param {string} id
- * @param {boolean=} immediately
- */
- showView: function(id, immediately)
- {
- if (!this._toggleDrawerButton.enabled())
- return;
- if (this._viewFactories[id])
- this._tabbedPane.changeTabView(id, this._viewFactories[id].createView(id));
- this._innerShow(immediately);
- this._tabbedPane.selectTab(id, true);
- this._updateTabStrip();
- },
-
- /**
- * @param {string} id
- * @param {string} title
- * @param {!WebInspector.View} view
- */
- showCloseableView: function(id, title, view)
- {
- if (!this._toggleDrawerButton.enabled())
- return;
- if (!this._tabbedPane.hasTab(id)) {
- this._tabbedPane.appendTab(id, title, view, undefined, false, true);
- } else {
- this._tabbedPane.changeTabView(id, view);
- this._tabbedPane.changeTabTitle(id, title);
- }
- this._innerShow();
- this._tabbedPane.selectTab(id, true);
- this._updateTabStrip();
- },
-
- /**
- * @param {boolean=} immediately
- */
- show: function(immediately)
- {
- this.showView(this._tabbedPane.selectedTabId, immediately);
- },
-
- showOnLoadIfNecessary: function()
- {
- if (this._showDrawerOnLoadSetting.get())
- this.showView(this._lastSelectedViewSetting.get(), true);
- },
-
- /**
- * @param {boolean=} immediately
- */
- _innerShow: function(immediately)
- {
- this._immediatelyFinishAnimation();
-
- if (this._toggleDrawerButton.toggled)
- return;
- this._showDrawerOnLoadSetting.set(true);
- this._toggleDrawerButton.toggled = true;
- this._toggleDrawerButton.title = WebInspector.UIString("Hide drawer.");
-
- document.body.classList.add("drawer-visible");
- this._tabbedPane.show(this._drawerContentsElement);
-
- var height = this._constrainHeight(this._savedHeight);
- var animations = [
- {element: this.element, start: {"flex-basis": 23}, end: {"flex-basis": height}},
- ];
-
- /**
- * @param {boolean} finished
- * @this {WebInspector.Drawer}
- */
- function animationCallback(finished)
- {
- if (this._inspectorView.currentPanel())
- this._inspectorView.currentPanel().doResize();
- if (!finished)
- return;
- this._updateTabStrip();
- if (this._visibleView()) {
- // Get console content back
- this._tabbedPane.changeTabView(this._tabbedPane.selectedTabId, this._visibleView());
- if (this._visibleView().afterShow)
- this._visibleView().afterShow();
- }
- delete this._currentAnimation;
- }
-
- this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(immediately), animationCallback.bind(this));
-
- if (immediately)
- this._currentAnimation.forceComplete();
- },
-
- /**
- * @param {boolean=} immediately
- */
- hide: function(immediately)
- {
- this._immediatelyFinishAnimation();
-
- if (!this._toggleDrawerButton.toggled)
- return;
- this._showDrawerOnLoadSetting.set(false);
- this._toggleDrawerButton.toggled = false;
- this._toggleDrawerButton.title = WebInspector.UIString("Show console.");
-
- this._isHiding = true;
- this._savedHeight = this.element.offsetHeight;
-
- WebInspector.restoreFocusFromElement(this.element);
-
- // Temporarily set properties and classes to mimic the post-animation values so panels
- // like Elements in their updateStatusBarItems call will size things to fit the final location.
- document.body.classList.remove("drawer-visible");
- this._inspectorView.currentPanel().statusBarResized();
- document.body.classList.add("drawer-visible");
-
- var animations = [
- {element: this.element, start: {"flex-basis": this.element.offsetHeight }, end: {"flex-basis": 23}},
- ];
-
- /**
- * @param {boolean} finished
- * @this {WebInspector.Drawer}
- */
- function animationCallback(finished)
- {
- var panel = this._inspectorView.currentPanel();
- if (!finished) {
- panel.doResize();
- return;
- }
- this._tabbedPane.detach();
- this._drawerContentsElement.removeChildren();
- document.body.classList.remove("drawer-visible");
- panel.doResize();
- delete this._currentAnimation;
- delete this._isHiding;
- }
-
- this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(immediately), animationCallback.bind(this));
-
- if (immediately)
- this._currentAnimation.forceComplete();
- },
-
- resize: function()
- {
- if (!this._toggleDrawerButton.toggled)
- return;
-
- this._visibleView().storeScrollPositions();
- var height = this._constrainHeight(this.element.offsetHeight);
- this.element.style.flexBasis = height + "px";
- this._tabbedPane.doResize();
- },
-
- _immediatelyFinishAnimation: function()
- {
- if (this._currentAnimation)
- this._currentAnimation.forceComplete();
- },
-
- /**
- * @param {boolean=} immediately
- * @return {number}
- */
- _animationDuration: function(immediately)
- {
- return immediately ? 0 : 50;
- },
-
- /**
- * @return {boolean}
- */
- _startStatusBarDragging: function(event)
- {
- if (!this._toggleDrawerButton.toggled || event.target !== this._tabbedPane.headerElement())
- return false;
-
- this._visibleView().storeScrollPositions();
- this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop();
- return true;
- },
-
- _statusBarDragging: function(event)
- {
- var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
- height = Number.constrain(height, Preferences.minConsoleHeight, this._inspectorView.devtoolsElement().offsetHeight - Preferences.minConsoleHeight);
-
- this.element.style.flexBasis = height + "px";
- if (this._inspectorView.currentPanel())
- this._inspectorView.currentPanel().doResize();
- this._tabbedPane.doResize();
-
- event.consume(true);
- },
-
- _endStatusBarDragging: function(event)
- {
- this._savedHeight = this.element.offsetHeight;
- delete this._statusBarDragOffset;
-
- event.consume();
- },
-
- /**
- * @return {!WebInspector.View} view
- */
- _visibleView: function()
- {
- return this._tabbedPane.visibleView;
- },
-
- _updateTabStrip: function()
- {
- this._tabbedPane.onResize();
- this._tabbedPane.doResize();
- },
-
- _tabSelected: function()
- {
- var tabId = this._tabbedPane.selectedTabId;
- if (!this._tabbedPane.isTabCloseable(tabId))
- this._lastSelectedViewSetting.set(tabId);
- if (this._viewFactories[tabId])
- this._tabbedPane.changeTabView(tabId, this._viewFactories[tabId].createView(tabId));
- },
-
- toggle: function()
- {
- if (this._toggleDrawerButton.toggled)
- this.hide();
- else
- this.show();
- },
-
- /**
- * @return {boolean}
- */
- visible: function()
- {
- return this._toggleDrawerButton.toggled;
- },
-
- /**
- * @return {string}
- */
- selectedViewId: function()
- {
- return this._tabbedPane.selectedTabId;
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanelDescriptor.js
deleted file mode 100644
index 4d1d801026f..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanelDescriptor.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.PanelDescriptor}
- * @implements {WebInspector.ContextMenu.Provider}
- * @implements {WebInspector.ViewFactory}
- */
-WebInspector.ElementsPanelDescriptor = function()
-{
- WebInspector.PanelDescriptor.call(this, "elements", WebInspector.UIString("Elements"), "ElementsPanel", "ElementsPanel.js");
- WebInspector.ContextMenu.registerProvider(this);
-}
-
-WebInspector.ElementsPanelDescriptor.prototype = {
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
- */
- appendApplicableItems: function(event, contextMenu, target)
- {
- if (target instanceof WebInspector.RemoteObject) {
- var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
- if (remoteObject.subtype !== "node")
- return;
- } else if (!(target instanceof WebInspector.DOMNode))
- return;
- this.panel().appendApplicableItems(event, contextMenu, target);
- },
-
- registerShortcuts: function()
- {
- var elementsSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
-
- var navigate = WebInspector.ElementsPanelDescriptor.ShortcutKeys.NavigateUp.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.NavigateDown);
- elementsSection.addRelatedKeys(navigate, WebInspector.UIString("Navigate elements"));
-
- var expandCollapse = WebInspector.ElementsPanelDescriptor.ShortcutKeys.Expand.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.Collapse);
- elementsSection.addRelatedKeys(expandCollapse, WebInspector.UIString("Expand/collapse"));
-
- elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.EditAttribute, WebInspector.UIString("Edit attribute"));
- elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.HideElement, WebInspector.UIString("Hide element"));
- elementsSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.ToggleEditAsHTML, WebInspector.UIString("Toggle edit as HTML"));
-
- var stylesPaneSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));
-
- var nextPreviousProperty = WebInspector.ElementsPanelDescriptor.ShortcutKeys.NextProperty.concat(WebInspector.ElementsPanelDescriptor.ShortcutKeys.PreviousProperty);
- stylesPaneSection.addRelatedKeys(nextPreviousProperty, WebInspector.UIString("Next/previous property"));
-
- stylesPaneSection.addRelatedKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementValue, WebInspector.UIString("Increment value"));
- stylesPaneSection.addRelatedKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementValue, WebInspector.UIString("Decrement value"));
-
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy10, WebInspector.UIString("Increment by %f", 10));
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy10, WebInspector.UIString("Decrement by %f", 10));
-
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy100, WebInspector.UIString("Increment by %f", 100));
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy100, WebInspector.UIString("Decrement by %f", 100));
-
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.IncrementBy01, WebInspector.UIString("Increment by %f", 0.1));
- stylesPaneSection.addAlternateKeys(WebInspector.ElementsPanelDescriptor.ShortcutKeys.DecrementBy01, WebInspector.UIString("Decrement by %f", 0.1));
-
- /**
- * Install emulation view.
- * @this {WebInspector.ElementsPanelDescriptor}
- */
- function toggleEmulationView()
- {
- if (WebInspector.settings.showEmulationViewInDrawer.get())
- WebInspector.inspectorView.registerViewInDrawer("emulation", WebInspector.UIString("Emulation"), this);
- else
- WebInspector.inspectorView.unregisterViewInDrawer("emulation");
- }
- WebInspector.settings.showEmulationViewInDrawer.addChangeListener(toggleEmulationView, this);
- toggleEmulationView.call(this);
-
- /**
- * Install rendering view.
- * @this {WebInspector.ElementsPanelDescriptor}
- */
- function toggleRenderingView()
- {
- if (WebInspector.settings.showRenderingViewInDrawer.get())
- WebInspector.inspectorView.registerViewInDrawer("rendering", WebInspector.UIString("Rendering"), this);
- else
- WebInspector.inspectorView.unregisterViewInDrawer("rendering");
- }
- WebInspector.settings.showRenderingViewInDrawer.addChangeListener(toggleRenderingView, this);
- toggleRenderingView.call(this);
- },
-
- /**
- * @param {string=} id
- * @return {?WebInspector.View}
- */
- createView: function(id)
- {
- return this.panel().createView(id);
- },
-
- __proto__: WebInspector.PanelDescriptor.prototype
-}
-
-WebInspector.ElementsPanelDescriptor.ShortcutKeys = {
- NavigateUp: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
- ],
-
- NavigateDown: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
- ],
-
- Expand: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right)
- ],
-
- Collapse: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left)
- ],
-
- EditAttribute: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter)
- ],
-
- HideElement: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.H)
- ],
-
- ToggleEditAsHTML: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F2)
- ],
-
- NextProperty: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab)
- ],
-
- PreviousProperty: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab, WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- IncrementValue: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
- ],
-
- DecrementValue: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
- ],
-
- IncrementBy10: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- DecrementBy10: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- IncrementBy100: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- DecrementBy100: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- IncrementBy01: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ],
-
- DecrementBy01: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ]
-};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FlameChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/FlameChart.js
deleted file mode 100644
index 71d0928599d..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FlameChart.js
+++ /dev/null
@@ -1,907 +0,0 @@
-/**
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.FlameChartDataProvider} dataProvider
- */
-WebInspector.FlameChart = function(dataProvider)
-{
- WebInspector.View.call(this);
- this.registerRequiredCSS("flameChart.css");
- this.element.className = "fill";
- this.element.id = "cpu-flame-chart";
-
- this._overviewPane = new WebInspector.FlameChart.OverviewPane(dataProvider);
- this._overviewPane.show(this.element);
-
- this._mainPane = new WebInspector.FlameChart.MainPane(dataProvider, this._overviewPane);
- this._mainPane.show(this.element);
- this._mainPane.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
- this._overviewPane._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-
- if (!WebInspector.FlameChart._colorGenerator)
- WebInspector.FlameChart._colorGenerator = new WebInspector.FlameChart.ColorGenerator();
-}
-
-WebInspector.FlameChart.prototype = {
- /**
- * @param {!WebInspector.Event} event
- */
- _onWindowChanged: function(event)
- {
- this._mainPane.changeWindow(this._overviewPane._overviewGrid.windowLeft(), this._overviewPane._overviewGrid.windowRight());
- },
-
- /**
- * @param {!number} timeLeft
- * @param {!number} timeRight
- */
- selectRange: function(timeLeft, timeRight)
- {
- this._overviewPane._selectRange(timeLeft, timeRight);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onEntrySelected: function(event)
- {
- this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, event.data);
- },
-
- update: function()
- {
- this._overviewPane.update();
- this._mainPane.update();
- },
-
- __proto__: WebInspector.View.prototype
-};
-
-/**
- * @interface
- */
-WebInspector.FlameChartDataProvider = function()
-{
-}
-
-WebInspector.FlameChartDataProvider.prototype = {
- /**
- * @param {!WebInspector.FlameChart.ColorGenerator} colorGenerator
- * @return {!Object}
- */
- timelineData: function(colorGenerator) { },
-
- /**
- * @param {number} entryIndex
- */
- prepareHighlightedEntryInfo: function(entryIndex) { },
-
- /**
- * @param {number} entryIndex
- * @return {boolean}
- */
- canJumpToEntry: function(entryIndex) { },
-
- /**
- * @param {number} entryIndex
- * @return {!Object}
- */
- entryData: function(entryIndex) { }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.TimelineGrid.Calculator}
- */
-WebInspector.FlameChart.Calculator = function()
-{
-}
-
-WebInspector.FlameChart.Calculator.prototype = {
- /**
- * @param {!WebInspector.FlameChart.MainPane} mainPane
- */
- _updateBoundaries: function(mainPane)
- {
- function log10(x)
- {
- return Math.log(x) / Math.LN10;
- }
- this._decimalDigits = Math.max(0, -Math.floor(log10(mainPane._timelineGrid.gridSliceTime * 1.01)));
- var totalTime = mainPane._timelineData().totalTime;
- this._minimumBoundaries = mainPane._windowLeft * totalTime;
- this._maximumBoundaries = mainPane._windowRight * totalTime;
- this.paddingLeft = mainPane._paddingLeft;
- this._width = mainPane._canvas.width - this.paddingLeft;
- this._timeToPixel = this._width / this.boundarySpan();
- },
-
- /**
- * @param {number} time
- * @return {number}
- */
- computePosition: function(time)
- {
- return (time - this._minimumBoundaries) * this._timeToPixel + this.paddingLeft;
- },
-
- /**
- * @param {number} value
- * @param {boolean=} hires
- * @return {string}
- */
- formatTime: function(value, hires)
- {
- var format = "%." + this._decimalDigits + "f\u2009ms";
- return WebInspector.UIString(format, value + this._minimumBoundaries);
- },
-
- /**
- * @return {number}
- */
- maximumBoundary: function()
- {
- return this._maximumBoundaries;
- },
-
- /**
- * @return {number}
- */
- minimumBoundary: function()
- {
- return this._minimumBoundaries;
- },
-
- /**
- * @return {number}
- */
- zeroTime: function()
- {
- return 0;
- },
-
- /**
- * @return {number}
- */
- boundarySpan: function()
- {
- return this._maximumBoundaries - this._minimumBoundaries;
- }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.TimelineGrid.Calculator}
- */
-WebInspector.FlameChart.OverviewCalculator = function()
-{
-}
-
-WebInspector.FlameChart.OverviewCalculator.prototype = {
- /**
- * @param {!WebInspector.FlameChart.OverviewPane} overviewPane
- */
- _updateBoundaries: function(overviewPane)
- {
- this._minimumBoundaries = 0;
- var totalTime = overviewPane._timelineData().totalTime;
- this._maximumBoundaries = totalTime;
- this._xScaleFactor = overviewPane._overviewCanvas.width / totalTime;
- },
-
- /**
- * @param {number} time
- * @return {number}
- */
- computePosition: function(time)
- {
- return (time - this._minimumBoundaries) * this._xScaleFactor;
- },
-
- /**
- * @param {number} value
- * @param {boolean=} hires
- * @return {string}
- */
- formatTime: function(value, hires)
- {
- return Number.secondsToString((value + this._minimumBoundaries) / 1000, hires);
- },
-
- /**
- * @return {number}
- */
- maximumBoundary: function()
- {
- return this._maximumBoundaries;
- },
-
- /**
- * @return {number}
- */
- minimumBoundary: function()
- {
- return this._minimumBoundaries;
- },
-
- /**
- * @return {number}
- */
- zeroTime: function()
- {
- return this._minimumBoundaries;
- },
-
- /**
- * @return {number}
- */
- boundarySpan: function()
- {
- return this._maximumBoundaries - this._minimumBoundaries;
- }
-}
-
-WebInspector.FlameChart.Events = {
- EntrySelected: "EntrySelected"
-}
-
-/**
- * @constructor
- */
-WebInspector.FlameChart.ColorGenerator = function()
-{
- this._colorPairs = {};
- this._colorIndexes = [];
- this._currentColorIndex = 0;
- this._colorPairForID("(idle)::0", 50);
- this._colorPairForID("(program)::0", 50);
- this._colorPairForID("(garbage collector)::0", 50);
-}
-
-WebInspector.FlameChart.ColorGenerator.prototype = {
- /**
- * @param {!string} id
- * @param {number=} sat
- */
- _colorPairForID: function(id, sat)
- {
- if (typeof sat !== "number")
- sat = 100;
- var colorPairs = this._colorPairs;
- var colorPair = colorPairs[id];
- if (!colorPair) {
- colorPairs[id] = colorPair = this._createPair(this._currentColorIndex++, sat);
- this._colorIndexes[colorPair.index] = colorPair;
- }
- return colorPair;
- },
-
- /**
- * @param {!number} index
- */
- _colorPairForIndex: function(index)
- {
- return this._colorIndexes[index];
- },
-
- /**
- * @param {!number} index
- * @param {!number} sat
- */
- _createPair: function(index, sat)
- {
- var hue = (index * 7 + 12 * (index % 2)) % 360;
- return {index: index, highlighted: "hsla(" + hue + ", " + sat + "%, 33%, 0.7)", normal: "hsla(" + hue + ", " + sat + "%, 66%, 0.7)"}
- }
-}
-
-/**
- * @interface
- */
-WebInspector.FlameChart.OverviewPaneInterface = function()
-{
-}
-
-WebInspector.FlameChart.OverviewPaneInterface.prototype = {
- /**
- * @param {number} zoom
- * @param {number} referencePoint
- */
- zoom: function(zoom, referencePoint) { },
-
- /**
- * @param {number} windowLeft
- * @param {number} windowRight
- */
- setWindow: function(windowLeft, windowRight) { },
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @implements {WebInspector.FlameChart.OverviewPaneInterface}
- * @param {!WebInspector.FlameChartDataProvider} dataProvider
- */
-WebInspector.FlameChart.OverviewPane = function(dataProvider)
-{
- WebInspector.View.call(this);
- this._overviewContainer = this.element.createChild("div", "overview-container");
- this._overviewGrid = new WebInspector.OverviewGrid("flame-chart");
- this._overviewGrid.element.classList.add("fill");
- this._overviewCanvas = this._overviewContainer.createChild("canvas", "flame-chart-overview-canvas");
- this._overviewContainer.appendChild(this._overviewGrid.element);
- this._overviewCalculator = new WebInspector.FlameChart.OverviewCalculator();
- this._dataProvider = dataProvider;
-}
-
-WebInspector.FlameChart.OverviewPane.prototype = {
- /**
- * @param {number} zoom
- * @param {number} referencePoint
- */
- zoom: function(zoom, referencePoint)
- {
- this._overviewGrid.zoom(zoom, referencePoint);
- },
-
- /**
- * @param {number} windowLeft
- * @param {number} windowRight
- */
- setWindow: function(windowLeft, windowRight)
- {
- this._overviewGrid.setWindow(windowLeft, windowRight);
- },
-
- /**
- * @param {!number} timeLeft
- * @param {!number} timeRight
- */
- _selectRange: function(timeLeft, timeRight)
- {
- var timelineData = this._timelineData();
- if (!timelineData)
- return;
- this._overviewGrid.setWindow(timeLeft / timelineData._totalTime, timeRight / timelineData._totalTime);
- },
-
- _timelineData: function()
- {
- return this._dataProvider.timelineData(WebInspector.FlameChart._colorGenerator);
- },
-
- onResize: function()
- {
- this._scheduleUpdate();
- },
-
- _scheduleUpdate: function()
- {
- if (this._updateTimerId)
- return;
- this._updateTimerId = setTimeout(this.update.bind(this), 10);
- },
-
- update: function()
- {
- this._updateTimerId = 0;
- var timelineData = this._timelineData();
- if (!timelineData)
- return;
- this._resetCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
- this._overviewCalculator._updateBoundaries(this);
- this._overviewGrid.updateDividers(this._overviewCalculator);
- WebInspector.FlameChart.OverviewPane.drawOverviewCanvas(
- timelineData,
- this._overviewCanvas.getContext("2d"),
- this._overviewContainer.clientWidth,
- this._overviewContainer.clientHeight - 20
- );
- },
-
- /**
- * @param {!number} width
- * @param {!number} height
- */
- _resetCanvas: function(width, height)
- {
- var ratio = window.devicePixelRatio;
- this._overviewCanvas.width = width * ratio;
- this._overviewCanvas.height = height * ratio;
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @param {!Object} timelineData
- * @param {!number} width
- */
-WebInspector.FlameChart.OverviewPane.calculateDrawData = function(timelineData, width)
-{
- var entryOffsets = timelineData.entryOffsets;
- var entryTotalTimes = timelineData.entryTotalTimes;
- var entryLevels = timelineData.entryLevels;
- var length = entryOffsets.length;
-
- var drawData = new Uint8Array(width);
- var scaleFactor = width / timelineData.totalTime;
-
- for (var entryIndex = 0; entryIndex < length; ++entryIndex) {
- var start = Math.floor(entryOffsets[entryIndex] * scaleFactor);
- var finish = Math.floor((entryOffsets[entryIndex] + entryTotalTimes[entryIndex]) * scaleFactor);
- for (var x = start; x <= finish; ++x)
- drawData[x] = Math.max(drawData[x], entryLevels[entryIndex] + 1);
- }
- return drawData;
-}
-
-/**
- * @param {!Object} timelineData
- * @param {!Object} context
- * @param {!number} width
- * @param {!number} height
- */
-WebInspector.FlameChart.OverviewPane.drawOverviewCanvas = function(timelineData, context, width, height)
-{
- var drawData = WebInspector.FlameChart.OverviewPane.calculateDrawData(timelineData, width);
- if (!drawData)
- return;
-
- var ratio = window.devicePixelRatio;
- var canvasWidth = width * ratio;
- var canvasHeight = height * ratio;
-
- var yScaleFactor = canvasHeight / (timelineData.maxStackDepth * 1.1);
- context.lineWidth = 1;
- context.translate(0.5, 0.5);
- context.strokeStyle = "rgba(20,0,0,0.4)";
- context.fillStyle = "rgba(214,225,254,0.8)";
- context.moveTo(-1, canvasHeight - 1);
- if (drawData)
- context.lineTo(-1, Math.round(height - drawData[0] * yScaleFactor - 1));
- var value;
- for (var x = 0; x < width; ++x) {
- value = Math.round(canvasHeight - drawData[x] * yScaleFactor - 1);
- context.lineTo(x * ratio, value);
- }
- context.lineTo(canvasWidth + 1, value);
- context.lineTo(canvasWidth + 1, canvasHeight - 1);
- context.fill();
- context.stroke();
- context.closePath();
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.FlameChartDataProvider} dataProvider
- * @param {!WebInspector.FlameChart.OverviewPaneInterface} overviewPane
- */
-WebInspector.FlameChart.MainPane = function(dataProvider, overviewPane)
-{
- WebInspector.View.call(this);
- this._overviewPane = overviewPane;
- this._chartContainer = this.element.createChild("div", "chart-container");
- this._timelineGrid = new WebInspector.TimelineGrid();
- this._chartContainer.appendChild(this._timelineGrid.element);
- this._calculator = new WebInspector.FlameChart.Calculator();
-
- this._canvas = this._chartContainer.createChild("canvas");
- this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this));
- this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), false);
- this._canvas.addEventListener("click", this._onClick.bind(this), false);
- WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind(this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "col-resize");
-
- this._entryInfo = this._chartContainer.createChild("div", "entry-info");
-
- this._dataProvider = dataProvider;
-
- this._windowLeft = 0.0;
- this._windowRight = 1.0;
- this._windowWidth = 1.0;
- this._barHeight = 15;
- this._minWidth = 1;
- this._paddingLeft = 15;
- this._highlightedEntryIndex = -1;
-}
-
-WebInspector.FlameChart.MainPane.prototype = {
- _timelineData: function()
- {
- return this._dataProvider.timelineData(WebInspector.FlameChart._colorGenerator);
- },
-
- /**
- * @param {!number} windowLeft
- * @param {!number} windowRight
- */
- changeWindow: function(windowLeft, windowRight)
- {
- this._windowLeft = windowLeft;
- this._windowRight = windowRight;
- this._windowWidth = this._windowRight - this._windowLeft;
-
- this._scheduleUpdate();
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _startCanvasDragging: function(event)
- {
- if (!this._timelineData())
- return false;
- this._isDragging = true;
- this._wasDragged = false;
- this._dragStartPoint = event.pageX;
- this._dragStartWindowLeft = this._windowLeft;
- this._dragStartWindowRight = this._windowRight;
-
- return true;
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _canvasDragging: function(event)
- {
- var pixelShift = this._dragStartPoint - event.pageX;
- var windowShift = pixelShift / this._totalPixels;
-
- var windowLeft = Math.max(0, this._dragStartWindowLeft + windowShift);
- if (windowLeft === this._windowLeft)
- return;
- windowShift = windowLeft - this._dragStartWindowLeft;
-
- var windowRight = Math.min(1, this._dragStartWindowRight + windowShift);
- if (windowRight === this._windowRight)
- return;
- windowShift = windowRight - this._dragStartWindowRight;
- this._overviewPane.setWindow(this._dragStartWindowLeft + windowShift, this._dragStartWindowRight + windowShift);
- this._wasDragged = true;
- },
-
- _endCanvasDragging: function()
- {
- this._isDragging = false;
- },
-
- /**
- * @param {?MouseEvent} event
- */
- _onMouseMove: function(event)
- {
- if (this._isDragging)
- return;
-
- var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offsetY);
-
- if (this._highlightedEntryIndex === entryIndex)
- return;
-
- if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex))
- this._canvas.style.cursor = "default";
- else
- this._canvas.style.cursor = "pointer";
-
- this._highlightedEntryIndex = entryIndex;
- this._scheduleUpdate();
- },
-
- _onClick: function()
- {
- // onClick comes after dragStart and dragEnd events.
- // So if there was drag (mouse move) in the middle of that events
- // we skip the click. Otherwise we jump to the sources.
- if (this._wasDragged)
- return;
- if (this._highlightedEntryIndex === -1)
- return;
- var data = this._dataProvider.entryData(this._highlightedEntryIndex);
- this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, data);
- },
-
- /**
- * @param {?MouseEvent} e
- */
- _onMouseWheel: function(e)
- {
- if (e.wheelDeltaY) {
- const zoomFactor = 1.1;
- const mouseWheelZoomSpeed = 1 / 120;
-
- var zoom = Math.pow(zoomFactor, -e.wheelDeltaY * mouseWheelZoomSpeed);
- var referencePoint = (this._pixelWindowLeft + e.offsetX - this._paddingLeft) / this._totalPixels;
- this._overviewPane.zoom(zoom, referencePoint);
- } else {
- var shift = Number.constrain(-1 * this._windowWidth / 4 * e.wheelDeltaX / 120, -this._windowLeft, 1 - this._windowRight);
- this._overviewPane.setWindow(this._windowLeft + shift, this._windowRight + shift);
- }
- },
-
- /**
- * @param {!number} x
- * @param {!number} y
- */
- _coordinatesToEntryIndex: function(x, y)
- {
- var timelineData = this._timelineData();
- if (!timelineData)
- return -1;
- var cursorTime = (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTime;
- var cursorLevel = Math.floor((this._canvas.height / window.devicePixelRatio - y) / this._barHeight);
-
- var entryOffsets = timelineData.entryOffsets;
- var entryTotalTimes = timelineData.entryTotalTimes;
- var entryLevels = timelineData.entryLevels;
- var length = entryOffsets.length;
- for (var i = 0; i < length; ++i) {
- if (cursorTime < entryOffsets[i])
- return -1;
- if (cursorTime < (entryOffsets[i] + entryTotalTimes[i])
- && cursorLevel === entryLevels[i])
- return i;
- }
- return -1;
- },
-
- /**
- * @param {!number} height
- * @param {!number} width
- */
- draw: function(width, height)
- {
- var timelineData = this._timelineData();
- if (!timelineData)
- return;
-
- var ratio = window.devicePixelRatio;
- this._canvas.width = width * ratio;
- this._canvas.height = height * ratio;
- this._canvas.style.width = width + "px";
- this._canvas.style.height = height + "px";
-
- var context = this._canvas.getContext("2d");
- context.scale(ratio, ratio);
- var timeWindowRight = this._timeWindowRight;
- var timeToPixel = this._timeToPixel;
- var pixelWindowLeft = this._pixelWindowLeft;
- var paddingLeft = this._paddingLeft;
- var minWidth = this._minWidth;
- var entryTotalTimes = timelineData.entryTotalTimes;
- var entryOffsets = timelineData.entryOffsets;
- var entryLevels = timelineData.entryLevels;
- var colorEntryIndexes = timelineData.colorEntryIndexes;
- var entryTitles = timelineData.entryTitles;
- var entryDeoptFlags = timelineData.entryDeoptFlags;
-
- var colorGenerator = WebInspector.FlameChart._colorGenerator;
- var titleIndexes = new Uint32Array(timelineData.entryTotalTimes);
- var lastTitleIndex = 0;
- var dotsWidth = context.measureText("\u2026").width;
- var textPaddingLeft = 2;
- this._minTextWidth = context.measureText("\u2026").width + textPaddingLeft;
- var minTextWidth = this._minTextWidth;
-
- var marksField = [];
- for (var i = 0; i < timelineData.maxStackDepth; ++i)
- marksField.push(new Uint16Array(width));
-
- var barHeight = this._barHeight;
- var barX = 0;
- var barWidth = 0;
- var barRight = 0;
- var barLevel = 0;
- var bHeight = height - barHeight;
- context.strokeStyle = "black";
- var colorPair;
- var entryIndex = 0;
- var entryOffset = 0;
- for (var colorIndex = 0; colorIndex < colorEntryIndexes.length; ++colorIndex) {
- colorPair = colorGenerator._colorPairForIndex(colorIndex);
- context.fillStyle = colorPair.normal;
- var indexes = colorEntryIndexes[colorIndex];
- if (!indexes)
- continue;
- context.beginPath();
- for (var i = 0; i < indexes.length; ++i) {
- entryIndex = indexes[i];
- entryOffset = entryOffsets[entryIndex];
- if (entryOffset > timeWindowRight)
- break;
- barX = Math.ceil(entryOffset * timeToPixel) - pixelWindowLeft + paddingLeft;
- if (barX >= width)
- continue;
- barRight = Math.floor((entryOffset + entryTotalTimes[entryIndex]) * timeToPixel) - pixelWindowLeft + paddingLeft;
- if (barRight < 0)
- continue;
- barWidth = (barRight - barX) || minWidth;
- barLevel = entryLevels[entryIndex];
- var marksRow = marksField[barLevel];
- if (barWidth <= marksRow[barX])
- continue;
- marksRow[barX] = barWidth;
- if (entryIndex === this._highlightedEntryIndex) {
- context.fill();
- context.beginPath();
- context.fillStyle = colorPair.highlighted;
- }
- context.rect(barX, bHeight - barLevel * barHeight, barWidth, barHeight);
- if (entryIndex === this._highlightedEntryIndex) {
- context.fill();
- context.beginPath();
- context.fillStyle = colorPair.normal;
- }
- if (barWidth > minTextWidth)
- titleIndexes[lastTitleIndex++] = entryIndex;
- }
- context.fill();
- }
-
- var font = (barHeight - 4) + "px " + window.getComputedStyle(this.element, null).getPropertyValue("font-family");
- var boldFont = "bold " + font;
- var isBoldFontSelected = false;
- context.font = font;
- context.textBaseline = "alphabetic";
- context.fillStyle = "#333";
- this._dotsWidth = context.measureText("\u2026").width;
-
- var textBaseHeight = bHeight + barHeight - 4;
- for (var i = 0; i < lastTitleIndex; ++i) {
- entryIndex = titleIndexes[i];
- if (isBoldFontSelected) {
- if (!entryDeoptFlags[entryIndex]) {
- context.font = font;
- isBoldFontSelected = false;
- }
- } else {
- if (entryDeoptFlags[entryIndex]) {
- context.font = boldFont;
- isBoldFontSelected = true;
- }
- }
-
- entryOffset = entryOffsets[entryIndex];
- barX = Math.floor(entryOffset * timeToPixel) - pixelWindowLeft + paddingLeft;
- barRight = Math.ceil((entryOffset + entryTotalTimes[entryIndex]) * timeToPixel) - pixelWindowLeft + paddingLeft;
- barWidth = (barRight - barX) || minWidth;
- var xText = Math.max(0, barX);
- var widthText = barWidth - textPaddingLeft + barX - xText;
- var title = this._prepareText(context, entryTitles[entryIndex], widthText);
- if (title)
- context.fillText(title, xText + textPaddingLeft, textBaseHeight - entryLevels[entryIndex] * barHeight);
- }
-
- this._entryInfo.removeChildren();
- if (!this._isDragging) {
- var entryInfo = this._dataProvider.prepareHighlightedEntryInfo(this._highlightedEntryIndex);
- if (entryInfo)
- this._entryInfo.appendChild(this._buildEntryInfo(entryInfo));
- }
- },
-
- _buildEntryInfo: function(entryInfo)
- {
- var infoTable = document.createElement("table");
- infoTable.className = "info-table";
- for (var i = 0; i < entryInfo.length; ++i) {
- var row = infoTable.createChild("tr");
- var titleCell = row.createChild("td");
- titleCell.textContent = entryInfo[i].title;
- titleCell.className = "title";
- var textCell = row.createChild("td");
- textCell.textContent = entryInfo[i].text;
- }
- return infoTable;
- },
-
- _prepareText: function(context, title, maxSize)
- {
- if (maxSize < this._dotsWidth)
- return null;
- var titleWidth = context.measureText(title).width;
- if (maxSize > titleWidth)
- return title;
- maxSize -= this._dotsWidth;
- var dotRegExp=/[\.\$]/g;
- var match = dotRegExp.exec(title);
- if (!match) {
- var visiblePartSize = maxSize / titleWidth;
- var newTextLength = Math.floor(title.length * visiblePartSize) + 1;
- var minTextLength = 4;
- if (newTextLength < minTextLength)
- return null;
- var substring;
- do {
- --newTextLength;
- substring = title.substring(0, newTextLength);
- } while (context.measureText(substring).width > maxSize);
- return title.substring(0, newTextLength) + "\u2026";
- }
- while (match) {
- var substring = title.substring(match.index + 1);
- var width = context.measureText(substring).width;
- if (maxSize > width)
- return "\u2026" + substring;
- match = dotRegExp.exec(title);
- }
- var i = 0;
- do {
- ++i;
- } while (context.measureText(title.substring(0, i)).width < maxSize);
- return title.substring(0, i - 1) + "\u2026";
- },
-
- _updateBoundaries: function()
- {
- this._totalTime = this._timelineData().totalTime;
- this._timeWindowLeft = this._windowLeft * this._totalTime;
- this._timeWindowRight = this._windowRight * this._totalTime;
-
- this._pixelWindowWidth = this._chartContainer.clientWidth - this._paddingLeft;
- this._totalPixels = Math.floor(this._pixelWindowWidth / this._windowWidth);
- this._pixelWindowLeft = Math.floor(this._totalPixels * this._windowLeft);
- this._pixelWindowRight = Math.floor(this._totalPixels * this._windowRight);
-
- this._timeToPixel = this._totalPixels / this._totalTime;
- this._pixelToTime = this._totalTime / this._totalPixels;
- this._paddingLeftTime = this._paddingLeft / this._timeToPixel;
- },
-
- onResize: function()
- {
- this._scheduleUpdate();
- },
-
- _scheduleUpdate: function()
- {
- if (this._updateTimerId)
- return;
- this._updateTimerId = setTimeout(this.update.bind(this), 10);
- },
-
- update: function()
- {
- this._updateTimerId = 0;
- if (!this._timelineData())
- return;
- this._updateBoundaries();
- this.draw(this._chartContainer.clientWidth, this._chartContainer.clientHeight);
- this._calculator._updateBoundaries(this);
- this._timelineGrid.element.style.width = this.element.clientWidth;
- this._timelineGrid.updateDividers(this._calculator);
- },
-
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ForwardedInputEventHandler.js b/chromium/third_party/WebKit/Source/devtools/front_end/ForwardedInputEventHandler.js
new file mode 100644
index 00000000000..93cc2569029
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ForwardedInputEventHandler.js
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ */
+WebInspector.ForwardedInputEventHandler = function()
+{
+}
+
+WebInspector.ForwardedInputEventHandler.prototype = {
+ /**
+ * @param {string} type
+ * @param {string} keyIdentifier
+ * @param {number} keyCode
+ * @param {number} modifiers
+ */
+ keyEventReceived: function(type, keyIdentifier, keyCode, modifiers)
+ {
+ if (type !== "keydown")
+ return;
+
+ WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut, WebInspector.ShortcutRegistry.ForwardedShortcut.instance)
+ WebInspector.shortcutRegistry.handleKey(WebInspector.KeyboardShortcut.makeKey(keyCode, modifiers), keyIdentifier);
+ WebInspector.context.setFlavor(WebInspector.ShortcutRegistry.ForwardedShortcut, null);
+ }
+}
+
+/** @type {!WebInspector.ForwardedInputEventHandler} */
+WebInspector.forwardedEventHandler = new WebInspector.ForwardedInputEventHandler();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotView.js b/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotView.js
deleted file mode 100644
index b86bc3fb591..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotView.js
+++ /dev/null
@@ -1,1858 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.ProfilesPanel} parent
- * @param {!WebInspector.HeapProfileHeader} profile
- */
-WebInspector.HeapSnapshotView = function(parent, profile)
-{
- WebInspector.View.call(this);
-
- this.element.classList.add("heap-snapshot-view");
-
- this.parent = parent;
- this.parent.addEventListener("profile added", this._onProfileHeaderAdded, this);
-
- if (profile._profileType.id === WebInspector.TrackingHeapSnapshotProfileType.TypeId) {
- this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile);
- this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
- this._trackingOverviewGrid.show(this.element);
- }
-
- this.viewsContainer = document.createElement("div");
- this.viewsContainer.classList.add("views-container");
- this.element.appendChild(this.viewsContainer);
-
- this.containmentView = new WebInspector.View();
- this.containmentView.element.classList.add("view");
- this.containmentDataGrid = new WebInspector.HeapSnapshotContainmentDataGrid();
- this.containmentDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
- this.containmentDataGrid.show(this.containmentView.element);
- this.containmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-
- this.constructorsView = new WebInspector.View();
- this.constructorsView.element.classList.add("view");
- this.constructorsView.element.appendChild(this._createToolbarWithClassNameFilter());
-
- this.constructorsDataGrid = new WebInspector.HeapSnapshotConstructorsDataGrid();
- this.constructorsDataGrid.element.classList.add("class-view-grid");
- this.constructorsDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
- this.constructorsDataGrid.show(this.constructorsView.element);
- this.constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-
- this.dataGrid = /** @type {!WebInspector.HeapSnapshotSortableDataGrid} */ (this.constructorsDataGrid);
- this.currentView = this.constructorsView;
- this.currentView.show(this.viewsContainer);
-
- this.diffView = new WebInspector.View();
- this.diffView.element.classList.add("view");
- this.diffView.element.appendChild(this._createToolbarWithClassNameFilter());
-
- this.diffDataGrid = new WebInspector.HeapSnapshotDiffDataGrid();
- this.diffDataGrid.element.classList.add("class-view-grid");
- this.diffDataGrid.show(this.diffView.element);
- this.diffDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-
- this.dominatorView = new WebInspector.View();
- this.dominatorView.element.classList.add("view");
- this.dominatorDataGrid = new WebInspector.HeapSnapshotDominatorsDataGrid();
- this.dominatorDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
- this.dominatorDataGrid.show(this.dominatorView.element);
- this.dominatorDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
-
- if (WebInspector.HeapSnapshot.enableAllocationProfiler) {
- this.allocationView = new WebInspector.View();
- this.allocationView.element.classList.add("view");
- this.allocationDataGrid = new WebInspector.AllocationDataGrid();
- this.allocationDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
- this.allocationDataGrid.show(this.allocationView.element);
- this.allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
- }
-
- this.retainmentViewHeader = document.createElement("div");
- this.retainmentViewHeader.classList.add("retainers-view-header");
- WebInspector.installDragHandle(this.retainmentViewHeader, this._startRetainersHeaderDragging.bind(this), this._retainersHeaderDragging.bind(this), this._endRetainersHeaderDragging.bind(this), "row-resize");
- var retainingPathsTitleDiv = document.createElement("div");
- retainingPathsTitleDiv.className = "title";
- var retainingPathsTitle = document.createElement("span");
- retainingPathsTitle.textContent = WebInspector.UIString("Object's retaining tree");
- retainingPathsTitleDiv.appendChild(retainingPathsTitle);
- this.retainmentViewHeader.appendChild(retainingPathsTitleDiv);
- this.element.appendChild(this.retainmentViewHeader);
-
- this.retainmentView = new WebInspector.View();
- this.retainmentView.element.classList.add("view");
- this.retainmentView.element.classList.add("retaining-paths-view");
- this.retainmentDataGrid = new WebInspector.HeapSnapshotRetainmentDataGrid();
- this.retainmentDataGrid.show(this.retainmentView.element);
- this.retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
- this.retainmentView.show(this.element);
- this.retainmentDataGrid.reset();
-
- this.viewSelect = new WebInspector.StatusBarComboBox(this._onSelectedViewChanged.bind(this));
-
- this.views = [{title: "Summary", view: this.constructorsView, grid: this.constructorsDataGrid},
- {title: "Comparison", view: this.diffView, grid: this.diffDataGrid},
- {title: "Containment", view: this.containmentView, grid: this.containmentDataGrid}];
- if (WebInspector.settings.showAdvancedHeapSnapshotProperties.get())
- this.views.push({title: "Dominators", view: this.dominatorView, grid: this.dominatorDataGrid});
- if (WebInspector.HeapSnapshot.enableAllocationProfiler)
- this.views.push({title: "Allocation", view: this.allocationView, grid: this.allocationDataGrid});
- this.views.current = 0;
- for (var i = 0; i < this.views.length; ++i)
- this.viewSelect.createOption(WebInspector.UIString(this.views[i].title));
-
- this._profile = profile;
-
- this.baseSelect = new WebInspector.StatusBarComboBox(this._changeBase.bind(this));
- this.baseSelect.element.classList.add("hidden");
- this._updateBaseOptions();
-
- this.filterSelect = new WebInspector.StatusBarComboBox(this._changeFilter.bind(this));
- this._updateFilterOptions();
-
- this.selectedSizeText = new WebInspector.StatusBarText("");
-
- this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true);
-
- this._refreshView();
-}
-
-WebInspector.HeapSnapshotView.prototype = {
- _refreshView: function()
- {
- this.profile.load(profileCallback.bind(this));
-
- /**
- * @this {WebInspector.HeapSnapshotView}
- */
- function profileCallback(heapSnapshotProxy)
- {
- var list = this._profiles();
- var profileIndex = list.indexOf(this._profile);
- this.baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
- this.dataGrid.setDataSource(heapSnapshotProxy);
- if (this._trackingOverviewGrid)
- this._trackingOverviewGrid._updateGrid();
- }
- },
-
- _onIdsRangeChanged: function(event)
- {
- var minId = event.data.minId;
- var maxId = event.data.maxId;
- this.selectedSizeText.setText(WebInspector.UIString("Selected size: %s", Number.bytesToString(event.data.size)));
- if (this.constructorsDataGrid.snapshot)
- this.constructorsDataGrid.setSelectionRange(minId, maxId);
- },
-
- dispose: function()
- {
- this.parent.removeEventListener("profile added", this._onProfileHeaderAdded, this);
- this.profile.dispose();
- if (this.baseProfile)
- this.baseProfile.dispose();
- this.containmentDataGrid.dispose();
- this.constructorsDataGrid.dispose();
- this.diffDataGrid.dispose();
- this.dominatorDataGrid.dispose();
- this.retainmentDataGrid.dispose();
- },
-
- get statusBarItems()
- {
- return [this.viewSelect.element, this.baseSelect.element, this.filterSelect.element, this.selectedSizeText.element];
- },
-
- get profile()
- {
- return this._profile;
- },
-
- get baseProfile()
- {
- return this._profile.profileType().getProfile(this._baseProfileUid);
- },
-
- wasShown: function()
- {
- // FIXME: load base and current snapshots in parallel
- this.profile.load(profileCallback.bind(this));
-
- /**
- * @this {WebInspector.HeapSnapshotView}
- */
- function profileCallback() {
- this.profile._wasShown();
- if (this.baseProfile)
- this.baseProfile.load(function() { });
- }
- },
-
- willHide: function()
- {
- this._currentSearchResultIndex = -1;
- this._popoverHelper.hidePopover();
- if (this.helpPopover && this.helpPopover.isShowing())
- this.helpPopover.hide();
- },
-
- onResize: function()
- {
- var height = this.retainmentView.element.clientHeight;
- this._updateRetainmentViewHeight(height);
- },
-
- searchCanceled: function()
- {
- if (this._searchResults) {
- for (var i = 0; i < this._searchResults.length; ++i) {
- var node = this._searchResults[i].node;
- delete node._searchMatched;
- node.refresh();
- }
- }
-
- delete this._searchFinishedCallback;
- this._currentSearchResultIndex = -1;
- this._searchResults = [];
- },
-
- /**
- * @param {string} query
- * @param {function(!WebInspector.View, number)} finishedCallback
- */
- performSearch: function(query, finishedCallback)
- {
- // Call searchCanceled since it will reset everything we need before doing a new search.
- this.searchCanceled();
-
- query = query.trim();
-
- if (!query)
- return;
- if (this.currentView !== this.constructorsView && this.currentView !== this.diffView)
- return;
-
- /**
- * @param {boolean} found
- * @this {WebInspector.HeapSnapshotView}
- */
- function didHighlight(found)
- {
- finishedCallback(this, found ? 1 : 0);
- }
-
- if (query.charAt(0) === "@") {
- var snapshotNodeId = parseInt(query.substring(1), 10);
- if (!isNaN(snapshotNodeId))
- this.dataGrid.highlightObjectByHeapSnapshotId(String(snapshotNodeId), didHighlight.bind(this));
- else
- finishedCallback(this, 0);
- return;
- }
-
- this._searchFinishedCallback = finishedCallback;
- var nameRegExp = createPlainTextSearchRegex(query, "i");
-
- function matchesByName(gridNode) {
- return ("_name" in gridNode) && nameRegExp.test(gridNode._name);
- }
-
- function matchesQuery(gridNode)
- {
- delete gridNode._searchMatched;
- if (matchesByName(gridNode)) {
- gridNode._searchMatched = true;
- gridNode.refresh();
- return true;
- }
- return false;
- }
-
- var current = this.dataGrid.rootNode().children[0];
- var depth = 0;
- var info = {};
-
- // Restrict to type nodes and instances.
- const maxDepth = 1;
-
- while (current) {
- if (matchesQuery(current))
- this._searchResults.push({ node: current });
- current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
- depth += info.depthChange;
- }
-
- finishedCallback(this, this._searchResults.length);
- },
-
- jumpToFirstSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- this._currentSearchResultIndex = 0;
- this._jumpToSearchResult(this._currentSearchResultIndex);
- },
-
- jumpToLastSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- this._currentSearchResultIndex = (this._searchResults.length - 1);
- this._jumpToSearchResult(this._currentSearchResultIndex);
- },
-
- jumpToNextSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- if (++this._currentSearchResultIndex >= this._searchResults.length)
- this._currentSearchResultIndex = 0;
- this._jumpToSearchResult(this._currentSearchResultIndex);
- },
-
- jumpToPreviousSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- if (--this._currentSearchResultIndex < 0)
- this._currentSearchResultIndex = (this._searchResults.length - 1);
- this._jumpToSearchResult(this._currentSearchResultIndex);
- },
-
- showingFirstSearchResult: function()
- {
- return (this._currentSearchResultIndex === 0);
- },
-
- showingLastSearchResult: function()
- {
- return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
- },
-
- currentSearchResultIndex: function() {
- return this._currentSearchResultIndex;
- },
-
- _jumpToSearchResult: function(index)
- {
- var searchResult = this._searchResults[index];
- if (!searchResult)
- return;
-
- var node = searchResult.node;
- node.revealAndSelect();
- },
-
- refreshVisibleData: function()
- {
- var child = this.dataGrid.rootNode().children[0];
- while (child) {
- child.refresh();
- child = child.traverseNextNode(false, null, true);
- }
- },
-
- _changeBase: function()
- {
- if (this._baseProfileUid === this._profiles()[this.baseSelect.selectedIndex()].uid)
- return;
-
- this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
- var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this.dataGrid);
- // Change set base data source only if main data source is already set.
- if (dataGrid.snapshot)
- this.baseProfile.load(dataGrid.setBaseDataSource.bind(dataGrid));
-
- if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
- return;
-
- // The current search needs to be performed again. First negate out previous match
- // count by calling the search finished callback with a negative number of matches.
- // Then perform the search again with the same query and callback.
- this._searchFinishedCallback(this, -this._searchResults.length);
- this.performSearch(this.currentQuery, this._searchFinishedCallback);
- },
-
- _changeFilter: function()
- {
- var profileIndex = this.filterSelect.selectedIndex() - 1;
- this.dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);
-
- WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
- action: WebInspector.UserMetrics.UserActionNames.HeapSnapshotFilterChanged,
- label: this.filterSelect.selectedOption().label
- });
-
- if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
- return;
-
- // The current search needs to be performed again. First negate out previous match
- // count by calling the search finished callback with a negative number of matches.
- // Then perform the search again with the same query and callback.
- this._searchFinishedCallback(this, -this._searchResults.length);
- this.performSearch(this.currentQuery, this._searchFinishedCallback);
- },
-
- _createToolbarWithClassNameFilter: function()
- {
- var toolbar = document.createElement("div");
- toolbar.classList.add("class-view-toolbar");
- var classNameFilter = document.createElement("input");
- classNameFilter.classList.add("class-name-filter");
- classNameFilter.setAttribute("placeholder", WebInspector.UIString("Class filter"));
- classNameFilter.addEventListener("keyup", this._changeNameFilter.bind(this, classNameFilter), false);
- toolbar.appendChild(classNameFilter);
- return toolbar;
- },
-
- _changeNameFilter: function(classNameInputElement)
- {
- var filter = classNameInputElement.value;
- this.dataGrid.changeNameFilter(filter);
- },
-
- /**
- * @return {!Array.<!WebInspector.ProfileHeader>}
- */
- _profiles: function()
- {
- return this._profile.profileType().getProfiles();
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {?Event} event
- */
- populateContextMenu: function(contextMenu, event)
- {
- this.dataGrid.populateContextMenu(this.parent, contextMenu, event);
- },
-
- _selectionChanged: function(event)
- {
- var selectedNode = event.target.selectedNode;
- this._setRetainmentDataGridSource(selectedNode);
- this._inspectedObjectChanged(event);
- },
-
- _inspectedObjectChanged: function(event)
- {
- var selectedNode = event.target.selectedNode;
- if (!this.profile.fromFile() && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode)
- ConsoleAgent.addInspectedHeapObject(selectedNode.snapshotNodeId);
- },
-
- _setRetainmentDataGridSource: function(nodeItem)
- {
- if (nodeItem && nodeItem.snapshotNodeIndex)
- this.retainmentDataGrid.setDataSource(nodeItem.isDeletedNode ? nodeItem.dataGrid.baseSnapshot : nodeItem.dataGrid.snapshot, nodeItem.snapshotNodeIndex);
- else
- this.retainmentDataGrid.reset();
- },
-
- _mouseDownInContentsGrid: function(event)
- {
- if (event.detail < 2)
- return;
-
- var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
- if (!cell || (!cell.classList.contains("count-column") && !cell.classList.contains("shallowSize-column") && !cell.classList.contains("retainedSize-column")))
- return;
-
- event.consume(true);
- },
-
- changeView: function(viewTitle, callback)
- {
- var viewIndex = null;
- for (var i = 0; i < this.views.length; ++i) {
- if (this.views[i].title === viewTitle) {
- viewIndex = i;
- break;
- }
- }
- if (this.views.current === viewIndex || viewIndex == null) {
- setTimeout(callback, 0);
- return;
- }
-
- /**
- * @this {WebInspector.HeapSnapshotView}
- */
- function dataGridContentShown(event)
- {
- var dataGrid = event.data;
- dataGrid.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
- if (dataGrid === this.dataGrid)
- callback();
- }
- this.views[viewIndex].grid.addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
-
- this.viewSelect.setSelectedIndex(viewIndex);
- this._changeView(viewIndex);
- },
-
- _updateDataSourceAndView: function()
- {
- var dataGrid = this.dataGrid;
- if (dataGrid.snapshot)
- return;
-
- this.profile.load(didLoadSnapshot.bind(this));
-
- /**
- * @this {WebInspector.HeapSnapshotView}
- */
- function didLoadSnapshot(snapshotProxy)
- {
- if (this.dataGrid !== dataGrid)
- return;
- if (dataGrid.snapshot !== snapshotProxy)
- dataGrid.setDataSource(snapshotProxy);
- if (dataGrid === this.diffDataGrid) {
- if (!this._baseProfileUid)
- this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
- this.baseProfile.load(didLoadBaseSnaphot.bind(this));
- }
- }
-
- /**
- * @this {WebInspector.HeapSnapshotView}
- */
- function didLoadBaseSnaphot(baseSnapshotProxy)
- {
- if (this.diffDataGrid.baseSnapshot !== baseSnapshotProxy)
- this.diffDataGrid.setBaseDataSource(baseSnapshotProxy);
- }
- },
-
- _onSelectedViewChanged: function(event)
- {
- this._changeView(event.target.selectedIndex);
- },
-
- _updateSelectorsVisibility: function()
- {
- if (this.currentView === this.diffView)
- this.baseSelect.element.classList.remove("hidden");
- else
- this.baseSelect.element.classList.add("hidden");
-
- if (this.currentView === this.constructorsView) {
- if (this._trackingOverviewGrid) {
- this._trackingOverviewGrid.element.classList.remove("hidden");
- this._trackingOverviewGrid.update();
- this.viewsContainer.classList.add("reserve-80px-at-top");
- }
- this.filterSelect.element.classList.remove("hidden");
- } else {
- this.filterSelect.element.classList.add("hidden");
- if (this._trackingOverviewGrid) {
- this._trackingOverviewGrid.element.classList.add("hidden");
- this.viewsContainer.classList.remove("reserve-80px-at-top");
- }
- }
- },
-
- _changeView: function(selectedIndex)
- {
- if (selectedIndex === this.views.current)
- return;
-
- this.views.current = selectedIndex;
- this.currentView.detach();
- var view = this.views[this.views.current];
- this.currentView = view.view;
- this.dataGrid = view.grid;
- this.currentView.show(this.viewsContainer);
- this.refreshVisibleData();
- this.dataGrid.updateWidths();
-
- this._updateSelectorsVisibility();
-
- this._updateDataSourceAndView();
-
- if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
- return;
-
- // The current search needs to be performed again. First negate out previous match
- // count by calling the search finished callback with a negative number of matches.
- // Then perform the search again the with same query and callback.
- this._searchFinishedCallback(this, -this._searchResults.length);
- this.performSearch(this.currentQuery, this._searchFinishedCallback);
- },
-
- _getHoverAnchor: function(target)
- {
- var span = target.enclosingNodeOrSelfWithNodeName("span");
- if (!span)
- return;
- var row = target.enclosingNodeOrSelfWithNodeName("tr");
- if (!row)
- return;
- span.node = row._dataGridNode;
- return span;
- },
-
- _resolveObjectForPopover: function(element, showCallback, objectGroupName)
- {
- if (this.profile.fromFile())
- return;
- element.node.queryObjectContent(showCallback, objectGroupName);
- },
-
- /**
- * @return {boolean}
- */
- _startRetainersHeaderDragging: function(event)
- {
- if (!this.isShowing())
- return false;
-
- this._previousDragPosition = event.pageY;
- return true;
- },
-
- _retainersHeaderDragging: function(event)
- {
- var height = this.retainmentView.element.clientHeight;
- height += this._previousDragPosition - event.pageY;
- this._previousDragPosition = event.pageY;
- this._updateRetainmentViewHeight(height);
- event.consume(true);
- },
-
- _endRetainersHeaderDragging: function(event)
- {
- delete this._previousDragPosition;
- event.consume();
- },
-
- _updateRetainmentViewHeight: function(height)
- {
- height = Number.constrain(height, Preferences.minConsoleHeight, this.element.clientHeight - Preferences.minConsoleHeight);
- this.viewsContainer.style.bottom = (height + this.retainmentViewHeader.clientHeight) + "px";
- if (this._trackingOverviewGrid && this.currentView === this.constructorsView)
- this.viewsContainer.classList.add("reserve-80px-at-top");
- this.retainmentView.element.style.height = height + "px";
- this.retainmentViewHeader.style.bottom = height + "px";
- this.currentView.doResize();
- },
-
- _updateBaseOptions: function()
- {
- var list = this._profiles();
- // We're assuming that snapshots can only be added.
- if (this.baseSelect.size() === list.length)
- return;
-
- for (var i = this.baseSelect.size(), n = list.length; i < n; ++i) {
- var title = list[i].title;
- this.baseSelect.createOption(title);
- }
- },
-
- _updateFilterOptions: function()
- {
- var list = this._profiles();
- // We're assuming that snapshots can only be added.
- if (this.filterSelect.size() - 1 === list.length)
- return;
-
- if (!this.filterSelect.size())
- this.filterSelect.createOption(WebInspector.UIString("All objects"));
-
- for (var i = this.filterSelect.size() - 1, n = list.length; i < n; ++i) {
- var title = list[i].title;
- if (!i)
- title = WebInspector.UIString("Objects allocated before %s", title);
- else
- title = WebInspector.UIString("Objects allocated between %s and %s", list[i - 1].title, title);
- this.filterSelect.createOption(title);
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onProfileHeaderAdded: function(event)
- {
- if (!event.data || event.data.type !== this._profile.profileType().id)
- return;
- this._updateBaseOptions();
- this._updateFilterOptions();
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @constructor
- * @implements {HeapProfilerAgent.Dispatcher}
- */
-WebInspector.HeapProfilerDispatcher = function()
-{
- this._dispatchers = [];
- InspectorBackend.registerHeapProfilerDispatcher(this);
-}
-
-WebInspector.HeapProfilerDispatcher.prototype = {
- /**
- * @param {!HeapProfilerAgent.Dispatcher} dispatcher
- */
- register: function(dispatcher)
- {
- this._dispatchers.push(dispatcher);
- },
-
- _genericCaller: function(eventName)
- {
- var args = Array.prototype.slice.call(arguments.callee.caller.arguments);
- for (var i = 0; i < this._dispatchers.length; ++i)
- this._dispatchers[i][eventName].apply(this._dispatchers[i], args);
- },
-
- /**
- * @override
- * @param {!Array.<number>} samples
- */
- heapStatsUpdate: function(samples)
- {
- this._genericCaller("heapStatsUpdate");
- },
-
- /**
- * @override
- * @param {number} lastSeenObjectId
- * @param {number} timestamp
- */
- lastSeenObjectId: function(lastSeenObjectId, timestamp)
- {
- this._genericCaller("lastSeenObjectId");
- },
-
- /**
- * @param {!HeapProfilerAgent.ProfileHeader} profileHeader
- */
- addProfileHeader: function(profileHeader)
- {
- this._genericCaller("addProfileHeader");
- },
-
- /**
- * @override
- * @param {number} uid
- * @param {string} chunk
- */
- addHeapSnapshotChunk: function(uid, chunk)
- {
- this._genericCaller("addHeapSnapshotChunk");
- },
-
- /**
- * @override
- * @param {number} done
- * @param {number} total
- */
- reportHeapSnapshotProgress: function(done, total)
- {
- this._genericCaller("reportHeapSnapshotProgress");
- },
-
- /**
- * @override
- */
- resetProfiles: function()
- {
- this._genericCaller("resetProfiles");
- }
-}
-
-WebInspector.HeapProfilerDispatcher._dispatcher = new WebInspector.HeapProfilerDispatcher();
-
-/**
- * @constructor
- * @extends {WebInspector.ProfileType}
- * @implements {HeapProfilerAgent.Dispatcher}
- */
-WebInspector.HeapSnapshotProfileType = function()
-{
- WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("Take Heap Snapshot"));
- WebInspector.HeapProfilerDispatcher._dispatcher.register(this);
-}
-
-WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
-WebInspector.HeapSnapshotProfileType.SnapshotReceived = "SnapshotReceived";
-
-WebInspector.HeapSnapshotProfileType.prototype = {
- /**
- * @override
- * @return {string}
- */
- fileExtension: function()
- {
- return ".heapsnapshot";
- },
-
- get buttonTooltip()
- {
- return WebInspector.UIString("Take heap snapshot.");
- },
-
- /**
- * @override
- * @return {boolean}
- */
- isInstantProfile: function()
- {
- return true;
- },
-
- /**
- * @override
- * @return {boolean}
- */
- buttonClicked: function()
- {
- this._takeHeapSnapshot(function() {});
- WebInspector.userMetrics.ProfilesHeapProfileTaken.record();
- return false;
- },
-
- /**
- * @override
- * @param {!Array.<number>} samples
- */
- heapStatsUpdate: function(samples)
- {
- },
-
- /**
- * @override
- * @param {number} lastSeenObjectId
- * @param {number} timestamp
- */
- lastSeenObjectId: function(lastSeenObjectId, timestamp)
- {
- },
-
- get treeItemTitle()
- {
- return WebInspector.UIString("HEAP SNAPSHOTS");
- },
-
- get description()
- {
- return WebInspector.UIString("Heap snapshot profiles show memory distribution among your page's JavaScript objects and related DOM nodes.");
- },
-
- /**
- * @override
- * @param {!string} title
- * @return {!WebInspector.ProfileHeader}
- */
- createProfileLoadedFromFile: function(title)
- {
- return new WebInspector.HeapProfileHeader(this, title);
- },
-
- _takeHeapSnapshot: function(callback)
- {
- if (this.profileBeingRecorded())
- return;
- this._profileBeingRecorded = new WebInspector.HeapProfileHeader(this, WebInspector.UIString("Snapshotting\u2026"));
- this.addProfile(this._profileBeingRecorded);
- HeapProfilerAgent.takeHeapSnapshot(true, callback);
- },
-
- /**
- * @param {!HeapProfilerAgent.ProfileHeader} profileHeader
- */
- addProfileHeader: function(profileHeader)
- {
- var profile = this.profileBeingRecorded();
- if (!profile)
- return;
- profile.title = profileHeader.title;
- profile.uid = profileHeader.uid;
- profile.maxJSObjectId = profileHeader.maxJSObjectId || 0;
-
- profile.sidebarElement.mainTitle = profile.title;
- profile.sidebarElement.subtitle = "";
- profile.sidebarElement.wait = false;
-
- this._profileSamples = null;
- this._profileBeingRecorded = null;
-
- WebInspector.panels.profiles._showProfile(profile);
- profile.existingView()._refreshView();
- },
-
- /**
- * @override
- * @param {number} uid
- * @param {string} chunk
- */
- addHeapSnapshotChunk: function(uid, chunk)
- {
- var profile = this.getProfile(uid);
- if (profile)
- profile.transferChunk(chunk);
- },
-
- /**
- * @override
- * @param {number} done
- * @param {number} total
- */
- reportHeapSnapshotProgress: function(done, total)
- {
- var profile = this.profileBeingRecorded();
- if (!profile)
- return;
- profile.sidebarElement.subtitle = WebInspector.UIString("%.0f%", (done / total) * 100);
- profile.sidebarElement.wait = true;
- },
-
- /**
- * @override
- */
- resetProfiles: function()
- {
- this._reset();
- },
-
- /**
- * @override
- * @param {!WebInspector.ProfileHeader} profile
- */
- removeProfile: function(profile)
- {
- if (this._profileBeingRecorded !== profile && !profile.fromFile())
- HeapProfilerAgent.removeProfile(profile.uid);
- WebInspector.ProfileType.prototype.removeProfile.call(this, profile);
- },
-
- _snapshotReceived: function(profile)
- {
- if (this._profileBeingRecorded === profile)
- this._profileBeingRecorded = null;
- this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile);
- },
-
- __proto__: WebInspector.ProfileType.prototype
-}
-
-
-/**
- * @constructor
- * @extends {WebInspector.HeapSnapshotProfileType}
- * @param {!WebInspector.ProfilesPanel} profilesPanel
- */
-WebInspector.TrackingHeapSnapshotProfileType = function(profilesPanel)
-{
- WebInspector.ProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Heap Allocations"));
- this._profilesPanel = profilesPanel;
- WebInspector.HeapProfilerDispatcher._dispatcher.register(this);
-}
-
-WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
-
-WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate = "HeapStatsUpdate";
-WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted = "TrackingStarted";
-WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped = "TrackingStopped";
-
-WebInspector.TrackingHeapSnapshotProfileType.prototype = {
-
- /**
- * @override
- * @param {!Array.<number>} samples
- */
- heapStatsUpdate: function(samples)
- {
- if (!this._profileSamples)
- return;
- var index;
- for (var i = 0; i < samples.length; i += 3) {
- index = samples[i];
- var count = samples[i+1];
- var size = samples[i+2];
- this._profileSamples.sizes[index] = size;
- if (!this._profileSamples.max[index] || size > this._profileSamples.max[index])
- this._profileSamples.max[index] = size;
- }
- this._lastUpdatedIndex = index;
- },
-
- /**
- * @override
- * @param {number} lastSeenObjectId
- * @param {number} timestamp
- */
- lastSeenObjectId: function(lastSeenObjectId, timestamp)
- {
- var profileSamples = this._profileSamples;
- if (!profileSamples)
- return;
- var currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1);
- profileSamples.ids[currentIndex] = lastSeenObjectId;
- if (!profileSamples.max[currentIndex]) {
- profileSamples.max[currentIndex] = 0;
- profileSamples.sizes[currentIndex] = 0;
- }
- profileSamples.timestamps[currentIndex] = timestamp;
- if (profileSamples.totalTime < timestamp - profileSamples.timestamps[0])
- profileSamples.totalTime *= 2;
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
- var profile = this._profileBeingRecorded;
- profile.sidebarElement.wait = true;
- if (profile.sidebarElement && !profile.sidebarElement.wait)
- profile.sidebarElement.wait = true;
- },
-
- /**
- * @override
- * @return {boolean}
- */
- hasTemporaryView: function()
- {
- return true;
- },
-
- get buttonTooltip()
- {
- return this._recording ? WebInspector.UIString("Stop recording heap profile.") : WebInspector.UIString("Start recording heap profile.");
- },
-
- /**
- * @override
- * @return {boolean}
- */
- isInstantProfile: function()
- {
- return false;
- },
-
- /**
- * @override
- * @return {boolean}
- */
- buttonClicked: function()
- {
- return this._toggleRecording();
- },
-
- _startRecordingProfile: function()
- {
- if (this.profileBeingRecorded())
- return;
- this._profileBeingRecorded = new WebInspector.HeapProfileHeader(this, WebInspector.UIString("Recording\u2026"));
- this._lastSeenIndex = -1;
- this._profileSamples = {
- 'sizes': [],
- 'ids': [],
- 'timestamps': [],
- 'max': [],
- 'totalTime': 30000
- };
- this._profileBeingRecorded._profileSamples = this._profileSamples;
- this._recording = true;
- this.addProfile(this._profileBeingRecorded);
- HeapProfilerAgent.startTrackingHeapObjects();
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted);
- },
-
- _stopRecordingProfile: function()
- {
- HeapProfilerAgent.stopTrackingHeapObjects(true);
- this._recording = false;
- this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped);
- },
-
- _toggleRecording: function()
- {
- if (this._recording)
- this._stopRecordingProfile();
- else
- this._startRecordingProfile();
- return this._recording;
- },
-
- get treeItemTitle()
- {
- return WebInspector.UIString("HEAP TIMELINES");
- },
-
- get description()
- {
- return WebInspector.UIString("Record JavaScript object allocations over time. Use this profile type to isolate memory leaks.");
- },
-
- _reset: function()
- {
- WebInspector.HeapSnapshotProfileType.prototype._reset.call(this);
- if (this._recording)
- this._stopRecordingProfile();
- this._profileSamples = null;
- this._lastSeenIndex = -1;
- },
-
- __proto__: WebInspector.HeapSnapshotProfileType.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.ProfileHeader}
- * @param {!WebInspector.ProfileType} type
- * @param {string} title
- * @param {number=} uid
- * @param {number=} maxJSObjectId
- */
-WebInspector.HeapProfileHeader = function(type, title, uid, maxJSObjectId)
-{
- WebInspector.ProfileHeader.call(this, type, title, uid);
- this.maxJSObjectId = maxJSObjectId;
- /**
- * @type {?WebInspector.OutputStream}
- */
- this._receiver = null;
- /**
- * @type {?WebInspector.HeapSnapshotProxy}
- */
- this._snapshotProxy = null;
- this._totalNumberOfChunks = 0;
- this._transferHandler = null;
-}
-
-WebInspector.HeapProfileHeader.prototype = {
- /**
- * @override
- */
- createSidebarTreeElement: function()
- {
- return new WebInspector.ProfileSidebarTreeElement(this, "heap-snapshot-sidebar-tree-item");
- },
-
- /**
- * @override
- * @param {!WebInspector.ProfilesPanel} profilesPanel
- */
- createView: function(profilesPanel)
- {
- return new WebInspector.HeapSnapshotView(profilesPanel, this);
- },
-
- /**
- * @override
- * @param {function(!WebInspector.HeapSnapshotProxy):void} callback
- */
- load: function(callback)
- {
- if (this.uid === -1)
- return;
- if (this._snapshotProxy) {
- callback(this._snapshotProxy);
- return;
- }
-
- this._numberOfChunks = 0;
- if (!this._receiver) {
- this._setupWorker();
- this._transferHandler = new WebInspector.BackendSnapshotLoader(this);
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
- this.sidebarElement.wait = true;
- this._transferSnapshot();
- }
- var loaderProxy = /** @type {?WebInspector.HeapSnapshotLoaderProxy} */ (this._receiver);
- console.assert(loaderProxy);
- loaderProxy.addConsumer(callback);
- },
-
- _transferSnapshot: function()
- {
- /**
- * @this {WebInspector.HeapProfileHeader}
- */
- function finishTransfer()
- {
- if (this._transferHandler) {
- this._transferHandler.finishTransfer();
- this._totalNumberOfChunks = this._transferHandler._totalNumberOfChunks;
- }
- }
- HeapProfilerAgent.getHeapSnapshot(this.uid, finishTransfer.bind(this));
- },
-
- snapshotConstructorName: function()
- {
- return "JSHeapSnapshot";
- },
-
- snapshotProxyConstructor: function()
- {
- return WebInspector.HeapSnapshotProxy;
- },
-
- _setupWorker: function()
- {
- /**
- * @this {WebInspector.HeapProfileHeader}
- */
- function setProfileWait(event)
- {
- this.sidebarElement.wait = event.data;
- }
- var worker = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
- worker.addEventListener("wait", setProfileWait, this);
- var loaderProxy = worker.createLoader(this.snapshotConstructorName(), this.snapshotProxyConstructor());
- loaderProxy.addConsumer(this._snapshotReceived.bind(this));
- this._receiver = loaderProxy;
- },
-
- /**
- * @param {string} eventName
- * @param {*} data
- */
- _handleWorkerEvent: function(eventName, data)
- {
- if (WebInspector.HeapSnapshotProgress.Event.Update !== eventName)
- return;
- this._updateSubtitle(data);
- },
-
- /**
- * @override
- */
- dispose: function()
- {
- if (this._receiver)
- this._receiver.close();
- else if (this._snapshotProxy)
- this._snapshotProxy.dispose();
- if (this._view) {
- var view = this._view;
- this._view = null;
- view.dispose();
- }
- },
-
- _updateSubtitle: function(value)
- {
- this.sidebarElement.subtitle = value;
- },
-
- _didCompleteSnapshotTransfer: function()
- {
- this.sidebarElement.subtitle = Number.bytesToString(this._snapshotProxy.totalSize);
- this.sidebarElement.wait = false;
- },
-
- /**
- * @param {string} chunk
- */
- transferChunk: function(chunk)
- {
- this._transferHandler.transferChunk(chunk);
- },
-
- _snapshotReceived: function(snapshotProxy)
- {
- this._receiver = null;
- if (snapshotProxy)
- this._snapshotProxy = snapshotProxy;
- this._didCompleteSnapshotTransfer();
- var worker = /** @type {!WebInspector.HeapSnapshotWorkerProxy} */ (this._snapshotProxy.worker);
- worker.startCheckingForLongRunningCalls();
- this.notifySnapshotReceived();
-
- /**
- * @this {WebInspector.HeapProfileHeader}
- */
- function didGetMaxNodeId(id)
- {
- this.maxJSObjectId = id;
- }
-
- if (this.fromFile())
- snapshotProxy.maxJsNodeId(didGetMaxNodeId.bind(this));
- },
-
- notifySnapshotReceived: function()
- {
- this._profileType._snapshotReceived(this);
- },
-
- // Hook point for tests.
- _wasShown: function()
- {
- },
-
- /**
- * @override
- * @return {boolean}
- */
- canSaveToFile: function()
- {
- return !this.fromFile() && !!this._snapshotProxy && !this._receiver;
- },
-
- /**
- * @override
- */
- saveToFile: function()
- {
- var fileOutputStream = new WebInspector.FileOutputStream();
-
- /**
- * @param {boolean} accepted
- * @this {WebInspector.HeapProfileHeader}
- */
- function onOpen(accepted)
- {
- if (!accepted)
- return;
- this._receiver = fileOutputStream;
- this._transferHandler = new WebInspector.SaveSnapshotHandler(this);
- this._transferSnapshot();
- }
- this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
- fileOutputStream.open(this._fileName, onOpen.bind(this));
- },
-
- /**
- * @override
- * @param {!File} file
- */
- loadFromFile: function(file)
- {
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
- this.sidebarElement.wait = true;
- this._setupWorker();
-
- var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this);
- var fileReader = this._createFileReader(file, delegate);
- fileReader.start(this._receiver);
- },
-
- _createFileReader: function(file, delegate)
- {
- return new WebInspector.ChunkedFileReader(file, 10000000, delegate);
- },
-
- __proto__: WebInspector.ProfileHeader.prototype
-}
-
-
-/**
- * @constructor
- * @param {!WebInspector.HeapProfileHeader} header
- * @param {string} title
- */
-WebInspector.SnapshotTransferHandler = function(header, title)
-{
- this._numberOfChunks = 0;
- this._savedChunks = 0;
- this._header = header;
- this._totalNumberOfChunks = 0;
- this._title = title;
-}
-
-
-WebInspector.SnapshotTransferHandler.prototype = {
- /**
- * @param {string} chunk
- */
- transferChunk: function(chunk)
- {
- ++this._numberOfChunks;
- this._header._receiver.write(chunk, this._didTransferChunk.bind(this));
- },
-
- finishTransfer: function()
- {
- },
-
- _didTransferChunk: function()
- {
- this._updateProgress(++this._savedChunks, this._totalNumberOfChunks);
- },
-
- _updateProgress: function(value, total)
- {
- }
-}
-
-
-/**
- * @constructor
- * @param {!WebInspector.HeapProfileHeader} header
- * @extends {WebInspector.SnapshotTransferHandler}
- */
-WebInspector.SaveSnapshotHandler = function(header)
-{
- WebInspector.SnapshotTransferHandler.call(this, header, "Saving\u2026 %d\%");
- this._totalNumberOfChunks = header._totalNumberOfChunks;
- this._updateProgress(0, this._totalNumberOfChunks);
-}
-
-
-WebInspector.SaveSnapshotHandler.prototype = {
- _updateProgress: function(value, total)
- {
- var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
- this._header._updateSubtitle(WebInspector.UIString(this._title, percentValue));
- if (value === total) {
- this._header._receiver.close();
- this._header._didCompleteSnapshotTransfer();
- }
- },
-
- __proto__: WebInspector.SnapshotTransferHandler.prototype
-}
-
-
-/**
- * @constructor
- * @param {!WebInspector.HeapProfileHeader} header
- * @extends {WebInspector.SnapshotTransferHandler}
- */
-WebInspector.BackendSnapshotLoader = function(header)
-{
- WebInspector.SnapshotTransferHandler.call(this, header, "Loading\u2026 %d\%");
-}
-
-
-WebInspector.BackendSnapshotLoader.prototype = {
- finishTransfer: function()
- {
- this._header._receiver.close(this._didFinishTransfer.bind(this));
- this._totalNumberOfChunks = this._numberOfChunks;
- },
-
- _didFinishTransfer: function()
- {
- console.assert(this._totalNumberOfChunks === this._savedChunks, "Not all chunks were transfered.");
- },
-
- __proto__: WebInspector.SnapshotTransferHandler.prototype
-}
-
-
-/**
- * @constructor
- * @implements {WebInspector.OutputStreamDelegate}
- */
-WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader)
-{
- this._snapshotHeader = snapshotHeader;
-}
-
-WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = {
- onTransferStarted: function()
- {
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- */
- onChunkTransferred: function(reader)
- {
- },
-
- onTransferFinished: function()
- {
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- */
- onError: function (reader, e)
- {
- switch(e.target.error.code) {
- case e.target.error.NOT_FOUND_ERR:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' not found.", reader.fileName()));
- break;
- case e.target.error.NOT_READABLE_ERR:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' is not readable", reader.fileName()));
- break;
- case e.target.error.ABORT_ERR:
- break;
- default:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code));
- }
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.HeapProfileHeader} heapProfileHeader
- */
-WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader)
-{
- WebInspector.View.call(this);
- this.registerRequiredCSS("flameChart.css");
- this.element.id = "heap-recording-view";
-
- this._overviewContainer = this.element.createChild("div", "overview-container");
- this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
- this._overviewGrid.element.classList.add("fill");
-
- this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-recording-overview-canvas");
- this._overviewContainer.appendChild(this._overviewGrid.element);
- this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator();
- this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-
- this._profileSamples = heapProfileHeader._profileSamples;
- if (heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) {
- this._profileType = heapProfileHeader._profileType;
- this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
- this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
- }
- var timestamps = this._profileSamples.timestamps;
- var totalTime = this._profileSamples.totalTime;
- this._windowLeft = 0.0;
- this._windowRight = totalTime && timestamps.length ? (timestamps[timestamps.length - 1] - timestamps[0]) / totalTime : 1.0;
- this._overviewGrid.setWindow(this._windowLeft, this._windowRight);
- this._yScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
- this._xScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
-}
-
-WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged";
-
-WebInspector.HeapTrackingOverviewGrid.prototype = {
- _onStopTracking: function(event)
- {
- this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
- this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
- },
-
- _onHeapStatsUpdate: function(event)
- {
- this._profileSamples = event.data;
- this._scheduleUpdate();
- },
-
- /**
- * @param {number} width
- * @param {number} height
- */
- _drawOverviewCanvas: function(width, height)
- {
- if (!this._profileSamples)
- return;
- var profileSamples = this._profileSamples;
- var sizes = profileSamples.sizes;
- var topSizes = profileSamples.max;
- var timestamps = profileSamples.timestamps;
- var startTime = timestamps[0];
- var endTime = timestamps[timestamps.length - 1];
-
- var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
- var maxSize = 0;
- /**
- * @param {!Array.<number>} sizes
- * @param {function(number, number):void} callback
- */
- function aggregateAndCall(sizes, callback)
- {
- var size = 0;
- var currentX = 0;
- for (var i = 1; i < timestamps.length; ++i) {
- var x = Math.floor((timestamps[i] - startTime) * scaleFactor);
- if (x !== currentX) {
- if (size)
- callback(currentX, size);
- size = 0;
- currentX = x;
- }
- size += sizes[i];
- }
- callback(currentX, size);
- }
-
- /**
- * @param {number} x
- * @param {number} size
- */
- function maxSizeCallback(x, size)
- {
- maxSize = Math.max(maxSize, size);
- }
-
- aggregateAndCall(sizes, maxSizeCallback);
-
- var yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0);
-
- this._overviewCanvas.width = width * window.devicePixelRatio;
- this._overviewCanvas.height = height * window.devicePixelRatio;
- this._overviewCanvas.style.width = width + "px";
- this._overviewCanvas.style.height = height + "px";
-
- var context = this._overviewCanvas.getContext("2d");
- context.scale(window.devicePixelRatio, window.devicePixelRatio);
-
- context.beginPath();
- context.lineWidth = 2;
- context.strokeStyle = "rgba(192, 192, 192, 0.6)";
- var currentX = (endTime - startTime) * scaleFactor;
- context.moveTo(currentX, height - 1);
- context.lineTo(currentX, 0);
- context.stroke();
- context.closePath();
-
- var gridY;
- var gridValue;
- var gridLabelHeight = 14;
- if (yScaleFactor) {
- const maxGridValue = (height - gridLabelHeight) / yScaleFactor;
- // The round value calculation is a bit tricky, because
- // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer,
- // e.g. a round value 10KB is 10240 bytes.
- gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024)));
- gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10));
- if (gridValue * 5 <= maxGridValue)
- gridValue *= 5;
- gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5;
- context.beginPath();
- context.lineWidth = 1;
- context.strokeStyle = "rgba(0, 0, 0, 0.2)";
- context.moveTo(0, gridY);
- context.lineTo(width, gridY);
- context.stroke();
- context.closePath();
- }
-
- /**
- * @param {number} x
- * @param {number} size
- */
- function drawBarCallback(x, size)
- {
- context.moveTo(x, height - 1);
- context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
- }
-
- context.beginPath();
- context.lineWidth = 2;
- context.strokeStyle = "rgba(192, 192, 192, 0.6)";
- aggregateAndCall(topSizes, drawBarCallback);
- context.stroke();
- context.closePath();
-
- context.beginPath();
- context.lineWidth = 2;
- context.strokeStyle = "rgba(0, 0, 192, 0.8)";
- aggregateAndCall(sizes, drawBarCallback);
- context.stroke();
- context.closePath();
-
- if (gridValue) {
- var label = Number.bytesToString(gridValue);
- var labelPadding = 4;
- var labelX = 0;
- var labelY = gridY - 0.5;
- var labelWidth = 2 * labelPadding + context.measureText(label).width;
- context.beginPath();
- context.textBaseline = "bottom";
- context.font = "10px " + window.getComputedStyle(this.element, null).getPropertyValue("font-family");
- context.fillStyle = "rgba(255, 255, 255, 0.75)";
- context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight);
- context.fillStyle = "rgb(64, 64, 64)";
- context.fillText(label, labelX + labelPadding, labelY);
- context.fill();
- context.closePath();
- }
- },
-
- onResize: function()
- {
- this._updateOverviewCanvas = true;
- this._scheduleUpdate();
- },
-
- _onWindowChanged: function()
- {
- if (!this._updateGridTimerId)
- this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10);
- },
-
- _scheduleUpdate: function()
- {
- if (this._updateTimerId)
- return;
- this._updateTimerId = setTimeout(this.update.bind(this), 10);
- },
-
- _updateBoundaries: function()
- {
- this._windowLeft = this._overviewGrid.windowLeft();
- this._windowRight = this._overviewGrid.windowRight();
- this._windowWidth = this._windowRight - this._windowLeft;
- },
-
- update: function()
- {
- this._updateTimerId = null;
- if (!this.isShowing())
- return;
- this._updateBoundaries();
- this._overviewCalculator._updateBoundaries(this);
- this._overviewGrid.updateDividers(this._overviewCalculator);
- this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
- },
-
- _updateGrid: function()
- {
- this._updateGridTimerId = 0;
- this._updateBoundaries();
- var ids = this._profileSamples.ids;
- var timestamps = this._profileSamples.timestamps;
- var sizes = this._profileSamples.sizes;
- var startTime = timestamps[0];
- var totalTime = this._profileSamples.totalTime;
- var timeLeft = startTime + totalTime * this._windowLeft;
- var timeRight = startTime + totalTime * this._windowRight;
- var minId = 0;
- var maxId = ids[ids.length - 1] + 1;
- var size = 0;
- for (var i = 0; i < timestamps.length; ++i) {
- if (!timestamps[i])
- continue;
- if (timestamps[i] > timeRight)
- break;
- maxId = ids[i];
- if (timestamps[i] < timeLeft) {
- minId = ids[i];
- continue;
- }
- size += sizes[i];
- }
-
- this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-
-/**
- * @constructor
- */
-WebInspector.HeapTrackingOverviewGrid.SmoothScale = function()
-{
- this._lastUpdate = 0;
- this._currentScale = 0.0;
-}
-
-WebInspector.HeapTrackingOverviewGrid.SmoothScale.prototype = {
- /**
- * @param {number} target
- * @return {number}
- */
- nextScale: function(target) {
- target = target || this._currentScale;
- if (this._currentScale) {
- var now = Date.now();
- var timeDeltaMs = now - this._lastUpdate;
- this._lastUpdate = now;
- var maxChangePerSec = 20;
- var maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000);
- var scaleChange = target / this._currentScale;
- this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta);
- } else
- this._currentScale = target;
- return this._currentScale;
- }
-}
-
-
-/**
- * @constructor
- * @implements {WebInspector.TimelineGrid.Calculator}
- */
-WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = function()
-{
-}
-
-WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = {
- /**
- * @param {!WebInspector.HeapTrackingOverviewGrid} chart
- */
- _updateBoundaries: function(chart)
- {
- this._minimumBoundaries = 0;
- this._maximumBoundaries = chart._profileSamples.totalTime;
- this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries;
- },
-
- /**
- * @param {number} time
- */
- computePosition: function(time)
- {
- return (time - this._minimumBoundaries) * this._xScaleFactor;
- },
-
- /**
- * @param {number} value
- * @param {boolean=} hires
- * @return {string}
- */
- formatTime: function(value, hires)
- {
- return Number.secondsToString((value + this._minimumBoundaries) / 1000, hires);
- },
-
- maximumBoundary: function()
- {
- return this._maximumBoundaries;
- },
-
- minimumBoundary: function()
- {
- return this._minimumBoundaries;
- },
-
- zeroTime: function()
- {
- return this._minimumBoundaries;
- },
-
- boundarySpan: function()
- {
- return this._maximumBoundaries - this._minimumBoundaries;
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint.png
new file mode 100644
index 00000000000..1eaea297489
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2.png
deleted file mode 100644
index 6d87745c4f5..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2_2x.png
deleted file mode 100644
index f77370df034..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint2_2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointBorder.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointBorder.png
deleted file mode 100644
index f15e02f4668..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointBorder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional.png
new file mode 100644
index 00000000000..8a222838f6f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2.png
deleted file mode 100644
index 87bbc0e19d7..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2_2x.png
deleted file mode 100644
index e2aa575e840..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional2_2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalBorder.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalBorder.png
deleted file mode 100644
index 4bd5806ed06..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalBorder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalCounterBorder.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalCounterBorder.png
deleted file mode 100644
index 897b7a0358b..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditionalCounterBorder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional_2x.png
new file mode 100644
index 00000000000..851adfc00e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointConditional_2x.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointCounterBorder.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointCounterBorder.png
deleted file mode 100644
index 0b3ea14aee2..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpointCounterBorder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint_2x.png
new file mode 100644
index 00000000000..a227bac2695
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/breakpoint_2x.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeader.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeader.png
deleted file mode 100644
index 6b779997d56..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeader.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderPressed.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderPressed.png
deleted file mode 100644
index 9a64b7c3660..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderPressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelected.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelected.png
deleted file mode 100644
index f7d615c48d9..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelected.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelectedPressed.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelectedPressed.png
deleted file mode 100644
index 75d37fb4497..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/glossyHeaderSelectedPressed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/namedFlowOverflow.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/namedFlowOverflow.png
deleted file mode 100644
index f966b1a83f9..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/namedFlowOverflow.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/programCounterBorder.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/programCounterBorder.png
deleted file mode 100644
index 10b02509c5f..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/programCounterBorder.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionEmpty.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionEmpty.png
deleted file mode 100644
index ed64c22637b..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionEmpty.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionFit.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionFit.png
deleted file mode 100644
index 90d4d50c169..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionFit.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionOverset.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionOverset.png
deleted file mode 100644
index 0738f1b361d..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/regionOverset.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign.png
new file mode 100644
index 00000000000..1f0e93a3ed8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign_2x.png
new file mode 100644
index 00000000000..12d5e93acaf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/responsiveDesign_2x.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.png
index 315daabd1a1..1c30a871921 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.png
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove_2x.png
index 32eca10c809..c5ff088b098 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove_2x.png
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove_2x.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinner.gif b/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinner.gif
deleted file mode 100644
index 5f68c02f145..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinner.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActive.gif b/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActive.gif
deleted file mode 100644
index b75745c2444..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActive.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActiveSelected.gif b/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActiveSelected.gif
deleted file mode 100644
index 1ffb18bfd9d..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerActiveSelected.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactive.gif b/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactive.gif
deleted file mode 100644
index 309cca0c350..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactive.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactiveSelected.gif b/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactiveSelected.gif
deleted file mode 100644
index 40bc27499f8..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/spinnerInactiveSelected.gif
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoint.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoint.svg
new file mode 100644
index 00000000000..4b5f7070160
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoint.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?><svg height="11" version="1.1" width="26" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+><defs
+/><sodipodi:namedview showgrid="true"
+><inkscape:grid empspacing="5" enabled="true" id="grid2985" snapvisiblegridlinesonly="true" type="xygrid" visible="true"/></sodipodi:namedview
+><path d="m22.8 0.5 2.7 5-2.7 5-22.3 0 0-10z" fill="#698cfe" stroke="#4073f4"/></svg
+> \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpointConditional.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpointConditional.svg
new file mode 100644
index 00000000000..97b9913c5a4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpointConditional.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?><svg height="11" version="1.1" width="26" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+><defs
+/><sodipodi:namedview showgrid="true"
+><inkscape:grid empspacing="5" enabled="true" id="grid2985" snapvisiblegridlinesonly="true" type="xygrid" visible="true"/></sodipodi:namedview
+><path d="m22.8 0.5 2.7 5-2.7 5-22.3 0 0-10z" fill="#ef9d0d" stroke="#a36c01"/></svg
+> \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoints2.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoints2.svg
deleted file mode 100644
index 0ae7d3d4f5e..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/breakpoints2.svg
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09448819"
- height="1052.3622047"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="breakpoints2.svg"
- inkscape:export-filename="/usr/local/google/home/lushnikov/Desktop/bp.png"
- inkscape:export-xdpi="44.838322"
- inkscape:export-ydpi="44.838322">
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient4408"
- osb:paint="solid">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4410" />
- </linearGradient>
- <marker
- inkscape:stockid="Arrow1Lstart"
- orient="auto"
- refY="0.0"
- refX="0.0"
- id="Arrow1Lstart"
- style="overflow:visible">
- <path
- id="path3786"
- d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
- transform="scale(0.8) translate(12.5,0)" />
- </marker>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="22.627417"
- inkscape:cx="26.649581"
- inkscape:cy="19.595518"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- inkscape:snap-grids="true"
- inkscape:snap-page="false"
- inkscape:window-width="2495"
- inkscape:window-height="1576"
- inkscape:window-x="65"
- inkscape:window-y="24"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid2985"
- empspacing="5"
- visible="true"
- enabled="true"
- snapvisiblegridlinesonly="true" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- style="fill:#698cfe;fill-opacity:1;fill-rule:nonzero;stroke:#4073f4;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- d="m 9.52174,1029.3622 38.04348,0 5.434781,10 -5.434781,10 -44.56522,0 0,-6 0,-8 c 0,-1.662 0,-4 0,-6 2.173914,0 4.715218,0 6.52174,0 z"
- id="rect3816"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccc"
- inkscape:transform-center-x="-1.0000005" />
- <path
- style="fill:#ef9d0d;fill-opacity:1;fill-rule:nonzero;stroke:#a36c01;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- d="m 9.52174,993.36218 38.04348,0 5.43478,10.00002 -5.43478,10 -44.56522,0 0,-6 0,-8.00002 c 0,-1.662 0,-4 0,-6 2.173912,0 4.715218,0 6.52174,0 z"
- id="rect3816-2"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccc" />
- </g>
-</svg>
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
new file mode 100644
index 00000000000..272e8468bf9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -0,0 +1,7 @@
+{
+ "statusbarButtonGlyphs.svg": "3f642dca97434b4cbb6491e2854dc69f",
+ "breakpoint.svg": "69cd92d807259c022791112809b97799",
+ "responsiveDesign.svg": "bc00a0a7fb0a47453929f94c9a4e003c",
+ "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
+ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28"
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/responsiveDesign.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/responsiveDesign.svg
new file mode 100644
index 00000000000..626027e76ab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/responsiveDesign.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?><svg height="16" version="1.1" width="64" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+><defs
+/><sodipodi:namedview showgrid="true"
+><inkscape:grid empspacing="5" enabled="true" id="grid3005" snapvisiblegridlinesonly="true" type="xygrid" visible="true"/></sodipodi:namedview
+><path d="M4.5 2.97 1.66 5.78 2.38 6.5 4 4.84 4 13 11.59 13 10 14.59 10.72 15.31 13.53 12.5 10.72 9.66 10 10.38 11.66 12 5 12 5 4.88 6.59 6.5 7.31 5.78z"
+/><path d="m21 3 0 10 10 0 0-10zm1 1 8 0 0 8-8 0z"
+/><path d="M23 5 23 8 24 8 24 6.72 27.28 10 26 10l0 1 3 0 0-3-1 0 0 1.31L24.69 6 26 6 26 5z"
+/><path d="m40 2.25c-2.4 0-4.49 1.5-5.34 3.63L34.34 4.94 33.38 5.28 34.41 8.13 37.25 7.09 36.91 6.16 36.06 6.47C36.68 4.91 38.19 3.78 40 3.78c2.02 0 3.67 1.37 4.13 3.22l1.53 0C45.18 4.3 42.81 2.25 40 2.25zM45.41 7.81 42.69 9.09 43.09 10 43.91 9.63C43.26 11.15 41.78 12.25 40 12.25 37.98 12.25 36.32 10.85 35.88 9l-1.53 0c0.47 2.71 2.85 4.78 5.66 4.78 2.41 0 4.5-1.54 5.34-3.69l0.41 0.88 0.91-0.44z"
+/><path d="m50 4 5 4 5-4" fill="none" stroke="#000"
+/><path d="m50 8 5 4 5-4" fill="none" stroke="#000"/></svg
+> \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingListRemove.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingListRemove.svg
deleted file mode 100644
index c279b0017a0..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingListRemove.svg
+++ /dev/null
@@ -1,195 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="48"
- height="16"
- id="svg5918"
- version="1.1"
- inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="settingListRemove.svg"
- inkscape:export-filename="/usr/local/google/home/vsevik/chromium/src/third_party/WebKit/Source/devtools/front_end/Images/settingsListRemove.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs5920" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="15.839192"
- inkscape:cx="26.852098"
- inkscape:cy="0.76985413"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1055"
- inkscape:window-height="869"
- inkscape:window-x="714"
- inkscape:window-y="142"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata5923">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3622)">
- <g
- id="g5551-9"
- transform="matrix(0.03826531,-0.03826531,0.03826531,0.03826531,-44.131211,1031.4147)">
- <g
- transform="matrix(0.93333336,0,0,0.93333336,26.666656,54.82412)"
- id="g5535-7-8">
- <rect
- style="fill:#8d8d8d;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-0-95-0"
- width="40"
- height="240"
- x="500"
- y="732.36218"
- ry="0" />
- <rect
- style="fill:#8d8d8d;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-0-4-8-6"
- width="40"
- height="240"
- x="-872.36218"
- y="400"
- ry="0"
- transform="matrix(0,-1,1,0,0,0)" />
- </g>
- <g
- transform="translate(348.49752,26.101501)"
- id="g5539-0-7">
- <rect
- style="fill:#cccccc;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-7-7"
- width="26"
- height="214"
- x="-842.26068"
- y="51.502476"
- ry="0"
- transform="matrix(0,-1,1,0,0,0)" />
- <rect
- style="fill:#cccccc;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-222-3-5"
- width="26"
- height="214"
- x="-171.50247"
- y="-936.26068"
- ry="0"
- transform="scale(-1,-1)" />
- </g>
- </g>
- <g
- id="g5709-5"
- transform="matrix(0.0382653,-0.0382653,0.0382653,0.0382653,-28.1312,1031.4147)">
- <g
- transform="translate(294.96455,4.0405884)"
- id="g5689-0">
- <rect
- style="fill:#121212;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-0-1-2"
- width="37.333336"
- height="224"
- x="198.3688"
- y="734.32159"
- ry="0" />
- <rect
- style="fill:#121212;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-0-4-7-1"
- width="37.333336"
- height="224"
- x="-864.98822"
- y="105.03545"
- ry="0"
- transform="matrix(0,-1,1,0,0,0)" />
- </g>
- <g
- id="g5685-7">
- <rect
- style="fill:#26262f;fill-opacity:0.94117647;stroke:none"
- id="rect5225-3-5-6-4-6-8"
- width="26"
- height="214"
- x="-868.36218"
- y="400"
- ry="0"
- transform="matrix(0,-1,1,0,0,0)" />
- <rect
- style="fill:#26262f;fill-opacity:0.94117647;stroke:none"
- id="rect5225-3-5-6-4-222-9-0"
- width="26"
- height="214"
- x="-520"
- y="-962.36218"
- ry="0"
- transform="scale(-1,-1)" />
- </g>
- </g>
- <g
- id="g6585">
- <rect
- transform="matrix(0.70710669,-0.70710687,0.70710687,0.70710669,0,0)"
- ry="0"
- y="760.69879"
- x="-711.20154"
- height="12.12183"
- width="2.0203052"
- id="rect5225-3-5-6-4-0-60-7"
- style="fill:#2e2e2e;fill-opacity:1;stroke:none" />
- <g
- transform="matrix(0.0382653,-0.03826531,0.03826531,0.0382653,-12.560872,1026.5897)"
- id="g5781-6">
- <rect
- style="fill:#2e2e2e;fill-opacity:1;stroke:none"
- id="rect5225-3-5-6-4-0-4-9-7"
- width="37.333336"
- height="224"
- x="-937.68872"
- y="342.56863"
- ry="0"
- transform="matrix(0,-1,1,0,0,0)" />
- </g>
- <rect
- transform="matrix(-0.70710687,-0.70710669,0.70710669,-0.70710687,0,0)"
- ry="0"
- y="-716.25226"
- x="-767.73376"
- height="11.580677"
- width="1.4069982"
- id="rect5225-3-5-6-4-9-6"
- style="fill:#787878;fill-opacity:1;stroke:none" />
- <rect
- transform="matrix(-0.70710669,0.70710687,-0.70710687,-0.70710669,0,0)"
- ry="0"
- y="-772.82062"
- x="709.75842"
- height="11.580677"
- width="1.4069982"
- id="rect5225-3-5-6-4-222-8-6"
- style="fill:#787878;fill-opacity:1;stroke:none" />
- </g>
- </g>
-</svg>
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingsListRemove.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingsListRemove.svg
new file mode 100644
index 00000000000..66db651e03e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/settingsListRemove.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?><svg height="16" version="1.1" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+><defs
+/><sodipodi:namedview showgrid="false"
+/><path d="M3 4.43 4.43 3 13 11.57 11.57 13z" fill="#8d8d8d"
+/><path d="M4.43 13 3 11.57 11.57 3 13 4.43z" fill="#8d8d8d"
+/><path d="M4.4 12.97 3.41 11.98 11.6 3.79 12.59 4.79z" fill="#ccc"
+/><path d="M12.59 11.98 11.6 12.97 3.41 4.79 4.4 3.79z" fill="#ccc"
+/><path d="m19 4.43 1.43-1.43 8.57 8.57-1.43 1.43z" fill="#121212"
+/><path d="m20.43 13-1.43-1.43 8.57-8.57 1.43 1.43z" fill="#121212"
+/><path d="m20.4 12.97-0.99-0.99 8.19-8.19 0.99 0.99z" fill="#26262f" fill-opacity="0.94"
+/><path d="m28.59 11.98-0.99 0.99-8.19-8.19 0.99-0.99z" fill="#26262f" fill-opacity="0.94"
+/><path d="m35 4.43 1.43-1.43 8.57 8.57-1.43 1.43z" fill="#2e2e2e"
+/><path d="m36.43 13-1.43-1.43 8.57-8.57 1.43 1.43z" fill="#2e2e2e"
+/><path d="m36.4 12.97-0.99-0.99 8.19-8.19 0.99 0.99z" fill="#787878"
+/><path d="m44.59 11.98-0.99 0.99-8.19-8.19 0.99-0.99z" fill="#787878"/></svg
+> \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/statusbarButtonGlyphs.svg b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/statusbarButtonGlyphs.svg
index 8f123aca2c2..6e2ef6bb6ce 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/statusbarButtonGlyphs.svg
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/statusbarButtonGlyphs.svg
@@ -8,1822 +8,702 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- height="120"
- id="svg2"
+ height="144"
version="1.1"
width="320"
xml:space="preserve"
+ id="svg3395"
inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="statusbarButtonGlyphs.svg"
- inkscape:export-filename="../statusbarButtonGlyphs.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"><metadata
- id="metadata3317"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="2"
- gridtolerance="2"
- guidetolerance="2"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1518"
- inkscape:window-height="876"
- id="namedview3315"
- showgrid="true"
- width="640px"
- inkscape:zoom="22.627417"
- inkscape:cx="222.67601"
- inkscape:cy="17.704972"
- inkscape:window-x="109"
- inkscape:window-y="93"
- inkscape:window-maximized="0"
- inkscape:current-layer="info-message"><inkscape:grid
- empspacing="2"
- visible="true"
- enabled="true"
- snapvisiblegridlinesonly="true"
- spacingx="32px"
- spacingy="24px"
- type="xygrid"
- id="grid3327"
- dotted="false" /></sodipodi:namedview>
- <defs
- id="defs6"><linearGradient
- id="linearGradient4153"><stop
- style="stop-color:#606eda;stop-opacity:1;"
- offset="0"
- id="stop4155" /><stop
- style="stop-color:#021db2;stop-opacity:1;"
- offset="1"
- id="stop4157" /></linearGradient><linearGradient
- inkscape:collect="always"
- id="linearGradient5619"><stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop5621" /><stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop5623" /></linearGradient><linearGradient
- id="linearGradient5337"><stop
- style="stop-color:#e59290;stop-opacity:1;"
- offset="0"
- id="stop5339" /><stop
- style="stop-color:#e99890;stop-opacity:1;"
- offset="1"
- id="stop5341" /></linearGradient><linearGradient
- id="linearGradient5329"><stop
- id="stop5331"
- offset="0"
- style="stop-color:#c0544f;stop-opacity:1;" /><stop
- id="stop5333"
- offset="1"
- style="stop-color:#d08481;stop-opacity:1;" /></linearGradient><linearGradient
- id="linearGradient5667"><stop
- style="stop-color:#ffa801;stop-opacity:0;"
- offset="0"
- id="stop5669" /><stop
- style="stop-color:#f0fb3d;stop-opacity:1;"
- offset="1"
- id="stop5671" /></linearGradient><linearGradient
- id="linearGradient5655"><stop
- id="stop5657"
- offset="0"
- style="stop-color:#ffbd00;stop-opacity:0.64957267;" /><stop
- id="stop5659"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0.90598291;" /></linearGradient><linearGradient
- id="linearGradient5647"><stop
- style="stop-color:#a16a00;stop-opacity:1;"
- offset="0"
- id="stop5649" /><stop
- style="stop-color:#c68200;stop-opacity:1;"
- offset="1"
- id="stop5651" /></linearGradient><linearGradient
- id="linearGradient5505"><stop
- style="stop-color:#00d600;stop-opacity:0;"
- offset="0"
- id="stop5507" /><stop
- style="stop-color:#d8fc7b;stop-opacity:0.81196582;"
- offset="1"
- id="stop5509" /></linearGradient><linearGradient
- id="linearGradient5497"><stop
- id="stop5499"
- offset="0"
- style="stop-color:#00ba00;stop-opacity:1;" /><stop
- id="stop5501"
- offset="1"
- style="stop-color:#ffffff;stop-opacity:0.90598291;" /></linearGradient><linearGradient
- id="linearGradient5489"><stop
- style="stop-color:#00a104;stop-opacity:1;"
- offset="0"
- id="stop5491" /><stop
- style="stop-color:#00c605;stop-opacity:1;"
- offset="1"
- id="stop5493" /></linearGradient><linearGradient
- id="linearGradient5441"><stop
- id="stop5443"
- offset="0"
- style="stop-color:#ff0000;stop-opacity:0;" /><stop
- id="stop5445"
- offset="1"
- style="stop-color:#f0cb68;stop-opacity:0.70940173;" /></linearGradient><linearGradient
- id="linearGradient5429"><stop
- style="stop-color:#e60000;stop-opacity:0.64957267;"
- offset="0"
- id="stop5431" /><stop
- style="stop-color:#ffffff;stop-opacity:0.90598291;"
- offset="1"
- id="stop5433" /></linearGradient><linearGradient
- id="linearGradient5421"><stop
- style="stop-color:#ff0000;stop-opacity:1;"
- offset="0"
- id="stop5423" /><stop
- style="stop-color:#9f0000;stop-opacity:1;"
- offset="1"
- id="stop5425" /></linearGradient><linearGradient
- id="linearGradient5409"><stop
- id="stop5411"
- offset="0"
- style="stop-color:#a10000;stop-opacity:1;" /><stop
- id="stop5413"
- offset="1"
- style="stop-color:#c60000;stop-opacity:1;" /></linearGradient><linearGradient
- id="linearGradient5401"><stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop5403" /><stop
- style="stop-color:#000000;stop-opacity:0;"
- offset="1"
- id="stop5405" /></linearGradient><linearGradient
- id="linearGradient5093"><stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop5095" /><stop
- style="stop-color:#5c5c5c;stop-opacity:1;"
- offset="1"
- id="stop5097" /></linearGradient><linearGradient
- id="linearGradient5083"><stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop5085" /><stop
- style="stop-color:#929292;stop-opacity:1;"
- offset="1"
- id="stop5087" /></linearGradient><linearGradient
- id="linearGradient4925"><stop
- style="stop-color:#ac1f10;stop-opacity:1;"
- offset="0"
- id="stop4927" /><stop
- style="stop-color:#f48f84;stop-opacity:1;"
- offset="1"
- id="stop4929" /></linearGradient><linearGradient
- id="linearGradient4827"><stop
- id="stop4829"
- offset="0"
- style="stop-color:#d7687d;stop-opacity:1;" /><stop
- id="stop4831"
- offset="1"
- style="stop-color:#b21402;stop-opacity:1;" /></linearGradient><linearGradient
- id="linearGradient4643"><stop
- style="stop-color:#d76f7d;stop-opacity:1;"
- offset="0"
- id="stop4645" /><stop
- style="stop-color:#b21402;stop-opacity:1;"
- offset="1"
- id="stop4647" /></linearGradient>
- <mask
- id="mask16" />
- <clipPath
- id="clipPath26">
- <path
- d="M 0,560 960,560 960,0 0,0 0,560 z"
- id="path28"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- id="clipPath34">
- <path
- d="m 160,296 16.125,0 0,-14 -16.125,0 0,14 z"
- id="path36"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- id="clipPath50">
- <path
- d="m 358,303 22,0 0,-4 -22,0 0,4 z"
- id="path52"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- id="clipPath64">
- <path
- d="m 484.867,399.559 22.705,0 0,-19.118 -22.705,0 0,19.118 z"
- id="path66"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- id="clipPath96">
- <path
- d="M 0,560 960,560 960,0 0,0 0,560 z"
- id="path98"
- inkscape:connector-curvature="0" />
- </clipPath>
- <clipPath
- id="clipPath200">
- <path
- d="m 662,341 c 0,-9.941 8.059,-18 18,-18 l 0,0 c 9.942,0 18,8.059 18,18 l 0,0 c 0,9.941 -8.058,18 -18,18 l 0,0 c -9.941,0 -18,-8.059 -18,-18"
- id="path202"
- inkscape:connector-curvature="0" />
- </clipPath>
- <radialGradient
- cx="0"
- cy="0"
- fx="0"
- fy="0"
- gradientTransform="matrix(17.999599,0,0,-17.999599,680,340.99951)"
- gradientUnits="userSpaceOnUse"
- id="radialGradient208"
- r="1"
- spreadMethod="pad">
- <stop
- id="stop210"
- offset="0"
- style="stop-color:#000000;stop-opacity:1" />
- <stop
- id="stop212"
- offset="1"
- style="stop-color:#000000;stop-opacity:0" />
- </radialGradient>
- <clipPath
- id="clipPath220">
- <path
- d="M 0,560 960,560 960,0 0,0 0,560 z"
- id="path222"
- inkscape:connector-curvature="0" />
- </clipPath>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <radialGradient
- inkscape:collect="always"
- xlink:href="#radialGradient208"
- id="radialGradient3862"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(17.999599,0,0,-17.999599,680,340.99951)"
- spreadMethod="pad"
- cx="0"
- cy="0"
- fx="0"
- fy="0"
- r="1" /><radialGradient
- inkscape:collect="always"
- xlink:href="#radialGradient208"
- id="radialGradient6632"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(17.999599,0,0,-17.999599,680,340.99951)"
- spreadMethod="pad"
- cx="0"
- cy="0"
- fx="0"
- fy="0"
- r="1" /><radialGradient
- inkscape:collect="always"
- xlink:href="#radialGradient208"
- id="radialGradient6811"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(17.999599,0,0,-17.999599,680,340.99951)"
- spreadMethod="pad"
- cx="0"
- cy="0"
- fx="0"
- fy="0"
- r="1" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4671"
- x1="0"
- y1="0"
- x2="24"
- y2="0"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4759"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4769"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4785"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4807"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient4825"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4833"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient4857"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" />
-
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient4890"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" />
-
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4643"
- id="linearGradient4915"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(-1,0,0,-1,24,0)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4925"
- id="linearGradient4931"
- x1="0"
- y1="0"
- x2="24"
- y2="0"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient4965"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.58333333,-0.58333333,0,120,111)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5083"
- id="linearGradient5089"
- x1="113"
- y1="104"
- x2="127"
- y2="104"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5093"
- id="linearGradient5099"
- x1="113"
- y1="104"
- x2="127"
- y2="104"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient5103"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.58333333,-0.58333333,0,120,111)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4827"
- id="linearGradient5281"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-0.58333333,-0.58333333,0,120,111)"
- x1="0"
- y1="0"
- x2="24"
- y2="0" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5409"
- id="linearGradient5737"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5489"
- id="linearGradient5743"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5497"
- id="linearGradient5753"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5505"
- id="linearGradient5755"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5429"
- id="linearGradient5767"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5441"
- id="linearGradient5769"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5655"
- id="linearGradient5835"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5667"
- id="linearGradient5837"
- gradientUnits="userSpaceOnUse"
- x1="227.875"
- y1="103.15625"
- x2="235.125"
- y2="103.15625" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5329"
- id="linearGradient5327"
- x1="113"
- y1="104"
- x2="127"
- y2="104"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-1,1,0,16,224)" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5329"
- id="linearGradient5335"
- gradientUnits="userSpaceOnUse"
- x1="113"
- y1="104"
- x2="127"
- y2="104"
- gradientTransform="matrix(0,-1,1,0,16,224)" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5337"
- id="linearGradient5343"
- x1="96.5"
- y1="103"
- x2="109.5"
- y2="103"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,1,-1,0,206,0)" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5329"
- id="linearGradient5354"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-1,1,0,16,224)"
- x1="113"
- y1="104"
- x2="127"
- y2="104" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5329"
- id="linearGradient5356"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,-1,1,0,16,224)"
- x1="113"
- y1="104"
- x2="127"
- y2="104" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5337"
- id="linearGradient5358"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,1,-1,0,206,0)"
- x1="96.5"
- y1="103"
- x2="109.5"
- y2="103" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5337"
- id="linearGradient5365"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0,1,-1,0,206,0)"
- x1="96.5"
- y1="103"
- x2="109.5"
- y2="103" /><linearGradient
- id="linearGradient4827-3"><stop
- id="stop4829-3"
- offset="0"
- style="stop-color:#d7687d;stop-opacity:1;" /><stop
- id="stop4831-1"
- offset="1"
- style="stop-color:#b21402;stop-opacity:1;" /></linearGradient><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient5619"
- id="linearGradient5627"
- x1="220.1884"
- y1="100.38527"
- x2="223.78215"
- y2="100.38527"
- gradientUnits="userSpaceOnUse"
- gradientTransform="translate(-11.397753,-1.4419419)" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4153"
- id="linearGradient5635"
- x1="113"
- y1="104"
- x2="127"
- y2="104"
- gradientUnits="userSpaceOnUse" /></defs>
-
-<g
- inkscape:groupmode="layer"
- id="layer1"
- inkscape:label="grid"
- style="display:inline"
- transform="translate(0,-580)" /><g
- id="g12"
- transform="matrix(0.50028185,0,0,-0.5104134,-36.680797,258.16231)">
- <g
- transform="matrix(639.91985,0,0,143.98197,72.039148,269.00968)"
- id="g14" />
- </g><g
- id="g30"
- transform="matrix(0.50028185,0,0,-0.5104134,-36.013832,209.91231)">
- <g
- id="g32" />
- <g
- id="g38">
- <g
- style="opacity:0.5"
- id="g40"
- clip-path="url(#clipPath34)">
- <g
- transform="translate(160,296)"
- id="g42">
- <path
- inkscape:connector-curvature="0"
- style="fill:#424242;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path44"
- d="m 0,0 4,-5 0,-9 8,0 0,9 4.125,5 L 0,0 z" />
- </g>
- </g>
- </g>
- </g><g
- id="g60"
- transform="matrix(0.50650085,0,0,-0.52309465,-41.085547,214.0068)">
- <g
- id="g62" />
- <g
- id="g68">
- <g
- style="opacity:0.39999402"
- id="g70"
- clip-path="url(#clipPath64)">
- <g
- transform="translate(491.5488,386.3623)"
- id="g72">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path74"
- d="M 0,0 -3.618,4.311 -6.682,1.739 -0.254,-5.921 2.58,-3.076 16.023,10.367 13.195,13.196 0,0 z" />
- </g>
- </g>
- </g>
- </g><path
- d="M 57,12 53.58829,8 39,8 l 0,8 14.58829,0"
- id="path78"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="M 25,36 21.362197,32 19.570257,32 14,40 21.362197,40 25,36 z"
- id="path82"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="M 7,32 7,40 9.0527005,40 14,32 7,32 z"
- id="path86"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="M 9.668154,44.54737 8.07369,43.22813 18.831348,27.45264 20.42631,28.77187 9.668154,44.54737 z"
- id="path90"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><g
- transform="matrix(0.5063291,0,0,-0.5063291,16,15.10127)"
- id="g100">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path102"
- d="m 0,0 c -3.452,0 -6.25,2.798 -6.25,6.25 0,3.452 2.798,6.25 6.25,6.25 L 0,16 c -5.454,0 -9.875,-4.421 -9.875,-9.875 0,-5.454 4.421,-9.875 9.875,-9.875 5.454,0 9.875,4.421 9.875,9.875 l -3.631,0 C 6.176,2.731 3.41,0 0,0" />
- </g><g
- transform="matrix(0.49315069,0,0,-0.5303633,16,5)"
- id="g104">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path106"
- d="M 0,0 9.125,-5.657 0,-11.313" />
- </g><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path108"
- d="m 53,37 -10,0 0,-5 10,0 0,5 z m -12,5 14,0 0,-12 -14,0 0,12 z" /><g
- transform="matrix(0.5,0,0,-0.5,10,57)"
- id="g110">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path112"
- d="m 0,0 -4,0 0,-14 0,-4 4,0 18,0 0,4 -18,0 0,14 z" />
- </g><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path114"
- d="m 13,56 7,0 0,5 -7,0 0,-5 z m 7,-2 -7,0 -2,0 0,2 0,5 0,2 2,0 7,0 2,0 0,-2 0,-5 0,-2 -2,0 z" /><g
- id="g5185"><path
- d="m 86,33 -8,0 0,-2 8,0 0,2 z"
- id="path116"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><g
- id="g118"
- transform="matrix(0.49494449,0,0,-0.50824235,71.5,31.43731)">
- <path
- d="M 0,0 8.485,-8.485 0,-16.971 l 2.829,-2.828 8.485,8.485 2.829,2.829 -2.829,2.828 L 2.829,2.828 0,0 z"
- id="path120"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><path
- d="m 86,37 -6,0 0,-2 6,0 0,2 z"
- id="path122"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 86,41 -8,0 0,-2 8,0 0,2 z"
- id="path124"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><g
- transform="matrix(0.5,0,0,-0.5,80.4375,16.9375)"
- id="g126">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path128"
- d="m 0,0 c -4.97,0 -9,4.03 -9,9 0,1.76 0.513,3.397 1.387,4.785 L 4.785,1.387 C 3.397,0.513 1.76,0 0,0 M 9,9 C 9,7.24 8.487,5.603 7.613,4.215 L -4.785,16.613 C -3.397,17.487 -1.76,18 0,18 4.97,18 9,13.97 9,9 M 0.125,21.875 c -7.18,0 -13,-5.82 -13,-13 0,-7.18 5.82,-13 13,-13 7.18,0 13,5.82 13,13 0,7.18 -5.82,13 -13,13" />
- </g><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path130"
- d="m 117,65 -10,0 0,-10 10,0 0,10 z" /><g
- transform="matrix(0.5,0,0,-0.5,116,37)"
- id="g132">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path134"
- d="m 0,0 0,-8 -16,0 0,6 -2,0 0,-6 0,-2 2,0 18,0 0,2 0,8 -2,0 z" />
- </g><g
- transform="matrix(0.50647405,0,0,-0.52309465,111.88426,35.90276)"
- id="g136">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path138"
- d="m 0,0 -3.618,4.311 -3.064,-2.572 6.428,-7.66 2.835,2.845 13.443,13.443 -2.828,2.829 L 0,0 z" />
- </g><g
- transform="matrix(0.47140904,0,0,-0.47140904,149,8.33314)"
- id="g140">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path142"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g><g
- transform="matrix(0.5,0,0,-0.50757125,46.5,65.23466)"
- id="g144">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path146"
- d="m 0,0 c 0.639,-0.265 1.688,-0.478 2.933,-0.478 1.183,0 2.288,0.192 3.067,0.519 l 0,7.744 8,9 0,0.379 -22,0 0,-0.43 8,-9 L 0,0 z m 2.933,-3.478 c -2.31,0 -4.336,0.565 -5.42,1.512 L -3,-1.518 l 0,8.111 -8,9 0,4.571 28,0 0,-4.622 -8,-9 L 9,-1.601 8.381,-2.05 C 7.132,-2.958 5.146,-3.478 2.933,-3.478" />
- </g><g
- transform="matrix(0.5263158,0,0,-0.5058169,86,60)"
- id="g148">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path150"
- d="m 0,0 -19,9.885 0,-19.77" />
- </g><g
- id="g4283"
- transform="matrix(0.5,0,0,0.5,0,-1)"><g
- transform="matrix(1.0000001,0,0,-1,-74.000026,414.99999)"
- id="g46">
- <g
- id="g48" />
- <g
- id="g54">
- <g
- clip-path="url(#clipPath50)"
- id="g56"
- style="opacity:0.19999701">
- <path
- d="m 380,299 -22,0 0,4 22,0 0,-4 z"
- id="path58"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- </g><g
- id="g152"
- transform="matrix(1.0000001,0,0,-1,270,110)">
- <path
- d="m 0,0 0,2 -2,0 -2,0 0,-2 0,-24 0,-2 2,0 2,0 0,2 -2,0 0,24 2,0 z"
- id="path154"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><path
- d="M 283.99999,116 272,116 l 0,-4.00001 11.99999,0 0,4.00001 z"
- id="path156"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="M 289.99999,122 278,122 l 0,-4.00001 11.99999,0 0,4.00001 z"
- id="path158"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 300,127.99999 -12.00001,0 0,-4 12.00001,0 0,4 z"
- id="path160"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 303.99999,133.99999 -11.99999,0 0,-4 11.99999,0 0,4 z"
- id="path162"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><g
- id="g4275"
- transform="scale(0.5,0.5)"><path
- d="M 339.99999,134 336,134 l 0,-18 3.99999,0 0,18 z"
- id="path164"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 346,134 -4,0 0,-22 4,0 0,22 z"
- id="path166"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 352,134 -4.00001,0 0,-26 4.00001,0 0,26 z"
- id="path168"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 358,134 -4,0 0,-8 4,0 0,8 z"
- id="path170"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="M 363.99999,134 360,134 l 0,-18 3.99999,0 0,18 z"
- id="path172"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 370,134 -4,0 0,-22 4,0 0,22 z"
- id="path174"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><g
- id="g4266"
- transform="scale(0.5,0.5)"><path
- d="m 416,114 -20,0 0,-4 20,0 0,4 z"
- id="path176"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 434,114 -10,0 0,-4 10,0 0,4 z"
- id="path178"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 400,122 -4,0 0,-4.00001 4,0 0,4.00001 z"
- id="path180"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 426,122 -20.00001,0 0,-4.00001 20.00001,0 0,4.00001 z"
- id="path182"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 434,122 -4.00001,0 0,-4.00001 4.00001,0 0,4.00001 z"
- id="path184"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 410,130 -14,0 0,-4 14,0 0,4 z"
- id="path186"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 434,130 -16,0 0,-4 16,0 0,4 z"
- id="path188"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path190"
- d="m 274,64 -7,0 0,-8 7,0 0,8 z m -9,2 14,0 0,-12 -14,0 0,12 z" /><g
- transform="matrix(0.5,0,0,-0.5,298,12)"
- id="g192">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path194"
- d="m 0,0 c 0,-6.627 5.372,-12 12,-12 6.628,0 12,5.373 12,12 C 24,6.627 18.628,12 12,12 5.372,12 0,6.627 0,0" />
- </g><g
- clip-path="url(#clipPath200)"
- id="g198"
- transform="matrix(0.5,0,0,-0.5,-36,206.5)"
- style="fill-rule:nonzero">
- <g
- id="g204"
- style="fill-rule:nonzero">
- <g
- id="g206"
- style="fill-rule:nonzero">
- <path
- d="m 662,341 c 0,-9.941 8.059,-18 18,-18 l 0,0 c 9.942,0 18,8.059 18,18 l 0,0 c 0,9.941 -8.058,18 -18,18 l 0,0 c -9.941,0 -18,-8.059 -18,-18"
- id="path214"
- style="fill:url(#radialGradient6811);fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- </g><g
- transform="matrix(0.5,0,0,-0.5,298,36)"
- id="g224">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path226"
- d="m 0,0 c 0,-6.627 5.372,-12 12,-12 6.628,0 12,5.373 12,12 C 24,6.627 18.628,12 12,12 5.372,12 0,6.627 0,0" />
- </g><g
- transform="matrix(0.50695545,0,0,-0.50695545,239.06259,38.10433)"
- id="g228">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path230"
- d="m 0,0 c -3.313,0 -6,2.686 -6,6 0,3.314 2.687,6 6,6 C 3.313,12 6,9.314 6,6 6,2.686 3.313,0 0,0 M 15.657,-6.829 7.613,1.215 C 8.487,2.603 9,4.24 9,6 c 0,4.971 -4.029,9 -9,9 -4.971,0 -9,-4.029 -9,-9 0,-4.971 4.029,-9 9,-9 1.761,0 3.397,0.513 4.785,1.387 l 8.043,-8.044 2.829,2.828 z" />
- </g><g
- transform="matrix(0.48874711,0,0,-0.49652038,233.7329,63.76329)"
- id="g232">
- <path
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"
- id="path234"
- d="M 0,0 10.75,6.5 21.625,2 31.75,10.125" />
- </g><g
- transform="matrix(0.50028185,0,0,-0.5,231.00056,67)"
- id="g236">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path238"
- d="m 0,0 0,26 -2,0 0,-28 1,0 1,0 40,0 0,2 -40,0 z" />
- </g><g
- id="g4258"
- transform="scale(0.5,0.5)"><path
- d="m 474,22 -8,0 0,-8 8,0 0,8 z"
- id="path240"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 494,18 -18.00001,0 0,-4 18.00001,0 0,4 z"
- id="path242"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 494,22 -18.00001,0 0,-2 18.00001,0 0,2 z"
- id="path244"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 494,30 -18.00001,0 0,-4.000001 18.00001,0 L 494,30 z"
- id="path246"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 474,34 -8,0 0,-8.000001 8,0 L 474,34 z"
- id="path248"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- d="m 494,34 -18.00001,0 0,-2 18.00001,0 0,2 z"
- id="path250"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><g
- transform="matrix(0.53333335,0,0,-0.53333335,176,38.13333)"
- id="g252">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path254"
- d="M 0,0 C -2.209,0 -4,1.791 -4,4 -4,6.209 -2.209,8 0,8 2.209,8 4,6.209 4,4 4,1.791 2.209,0 0,0 M 15,7 9.5,8 12.728,12.485 8.485,16.728 3.875,13.375 3,19 -3,19 -3.75,13.125 -8.485,16.728 -12.728,12.485 -9,7.625 -15,7 l 0,-6 6.25,-0.625 -3.978,-4.86 4.243,-4.243 4.735,3.978 0.75,-6.25 6,0 0.75,6 4.735,-3.728 4.243,4.243 L 9.375,0.125 15,1 15,7 z" />
- </g><g
- transform="matrix(0.49058085,0,0,-0.5028495,174.9687,18.62521)"
- id="g256">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path258"
- d="M 0,0 C 0,1.788 0.87,2.682 2.61,2.682 3.462,2.682 4.114,2.448 4.563,1.979 5.013,1.513 5.238,0.853 5.238,0 5.238,-0.84 5.009,-1.506 4.555,-1.998 4.099,-2.488 3.45,-2.734 2.61,-2.734 1.77,-2.734 1.124,-2.495 0.674,-2.015 0.225,-1.536 0,-0.863 0,0 m 0.728,5.665 0,1.135 c 0,1.303 0.237,2.386 0.71,3.25 0.474,0.865 1.303,1.758 2.486,2.681 1.409,1.113 2.317,1.977 2.726,2.593 0.408,0.615 0.611,1.349 0.611,2.202 0,0.993 -0.331,1.757 -0.994,2.289 -0.662,0.535 -1.615,0.8 -2.858,0.8 -1.125,0 -2.166,-0.16 -3.125,-0.48 -0.958,-0.32 -1.894,-0.704 -2.806,-1.154 l -1.491,3.125 c 2.403,1.338 4.978,2.007 7.724,2.007 2.32,0 4.16,-0.569 5.521,-1.705 1.362,-1.136 2.043,-2.704 2.043,-4.705 0,-0.888 -0.13,-1.678 -0.39,-2.37 C 10.624,14.64 10.229,13.979 9.703,13.353 9.177,12.725 8.268,11.909 6.978,10.902 5.876,10.038 5.14,9.322 4.767,8.754 4.394,8.186 4.207,7.422 4.207,6.464 l 0,-0.799 -3.479,0 z" />
- </g><g
- transform="matrix(0.4940336,0,0,-0.48455482,210.33624,38.32707)"
- id="g260">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path262"
- d="m 0,0 c 0,-1.637 0.163,-2.862 0.487,-3.674 0.324,-0.813 0.848,-1.22 1.574,-1.22 1.438,0 2.157,1.631 2.157,4.894 0,3.218 -0.719,4.828 -2.157,4.828 C 1.335,4.828 0.811,4.432 0.487,3.642 0.163,2.851 0,1.637 0,0 m 7.416,0 c 0,-2.526 -0.457,-4.421 -1.369,-5.685 -0.911,-1.263 -2.24,-1.895 -3.986,-1.895 -1.67,0 -2.966,0.651 -3.889,1.953 -0.923,1.301 -1.385,3.177 -1.385,5.627 0,5.02 1.758,7.53 5.274,7.53 1.691,0 3.006,-0.648 3.946,-1.945 C 6.946,4.29 7.416,2.427 7.416,0 M 2.521,16.839 -10.84,-7.25 l -3.198,0 13.364,24.089 3.195,0 z M -15.686,9.622 c 0,-1.637 0.16,-2.855 0.478,-3.658 0.319,-0.801 0.841,-1.202 1.566,-1.202 1.451,0 2.174,1.619 2.174,4.86 0,3.241 -0.723,4.861 -2.174,4.861 -0.725,0 -1.247,-0.4 -1.566,-1.203 -0.318,-0.801 -0.478,-2.021 -0.478,-3.658 m 7.416,0.033 c 0,-2.526 -0.454,-4.424 -1.36,-5.692 -0.906,-1.27 -2.243,-1.904 -4.012,-1.904 -1.67,0 -2.964,0.656 -3.881,1.969 -0.917,1.313 -1.375,3.189 -1.375,5.627 0,5.02 1.752,7.53 5.256,7.53 1.725,0 3.05,-0.651 3.979,-1.952 0.928,-1.302 1.393,-3.161 1.393,-5.578" />
- </g><g
- transform="matrix(0.59916115,0,0,-0.5,268.00899,35.993)"
- id="g264">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path266"
- d="m 0,0 c 0.7,-0.458 1.185,-0.989 1.452,-1.596 0.268,-0.607 0.4,-1.653 0.4,-3.136 l 0,-2.039 c 0,-0.937 0.077,-1.526 0.231,-1.768 0.153,-0.24 0.443,-0.404 0.871,-0.489 0.104,-0.027 0.256,-0.055 0.461,-0.082 1.051,-0.154 1.577,-0.659 1.577,-1.514 0,-0.418 -0.153,-0.753 -0.459,-1.008 -0.305,-0.255 -0.713,-0.382 -1.221,-0.382 -0.65,0 -1.277,0.106 -1.883,0.317 -0.607,0.212 -1.109,0.502 -1.507,0.871 -0.435,0.395 -0.743,0.907 -0.923,1.533 -0.182,0.626 -0.271,1.698 -0.271,3.218 l 0,1.644 c 0,1.667 -0.768,2.625 -2.306,2.875 -0.066,0.019 -0.111,0.028 -0.139,0.028 -0.444,0.074 -0.772,0.234 -0.986,0.477 -0.214,0.242 -0.319,0.593 -0.319,1.051 0,0.402 0.089,0.719 0.271,0.953 0.18,0.234 0.47,0.402 0.868,0.505 0.176,0.056 0.43,0.116 0.764,0.18 1.23,0.23 1.847,1.144 1.847,2.74 l 0,1.647 c 0,1.413 0.068,2.405 0.209,2.973 0.137,0.569 0.374,1.065 0.708,1.49 0.388,0.472 0.909,0.84 1.561,1.103 0.654,0.263 1.373,0.395 2.16,0.395 0.49,0 0.885,-0.128 1.182,-0.382 0.295,-0.255 0.444,-0.59 0.444,-1.007 0,-0.87 -0.563,-1.394 -1.688,-1.57 C 3.2,9.019 3.127,9.009 3.08,9 2.615,8.926 2.295,8.757 2.118,8.495 1.941,8.231 1.852,7.634 1.852,6.703 l 0,-2.035 C 1.852,3.279 1.714,2.26 1.437,1.611 1.161,0.963 0.682,0.426 0,0" />
- </g><g
- transform="matrix(0.59904155,0,0,-0.5,276.98263,35.986)"
- id="g268">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path270"
- d="m 0,0 c -0.674,0.425 -1.147,0.961 -1.425,1.608 -0.276,0.647 -0.414,1.664 -0.414,3.051 l 0,2.018 0,0.88 c 0,0.43 -0.112,0.757 -0.336,0.982 -0.222,0.224 -0.595,0.374 -1.115,0.446 -0.679,0.094 -1.13,0.253 -1.353,0.477 -0.224,0.225 -0.336,0.566 -0.336,1.023 0,0.468 0.142,0.832 0.424,1.094 0.283,0.262 0.683,0.393 1.202,0.393 0.685,0 1.325,-0.102 1.916,-0.306 0.593,-0.204 1.088,-0.49 1.487,-0.86 C 0.504,10.39 0.822,9.874 1.008,9.259 1.193,8.644 1.285,7.559 1.285,6.005 l 0,-1.635 C 1.285,2.777 1.921,1.856 3.188,1.609 3.494,1.563 3.729,1.517 3.896,1.472 4.285,1.368 4.572,1.196 4.759,0.956 4.943,0.715 5.037,0.396 5.037,0 5.037,-0.415 4.938,-0.748 4.744,-0.999 4.55,-1.248 4.259,-1.42 3.869,-1.515 3.721,-1.542 3.512,-1.579 3.244,-1.626 1.938,-1.875 1.285,-2.815 1.285,-4.445 l 0,-1.611 c 0,-1.463 -0.068,-2.48 -0.207,-3.048 -0.14,-0.57 -0.375,-1.054 -0.709,-1.452 -0.362,-0.435 -0.882,-0.789 -1.562,-1.063 -0.681,-0.273 -1.392,-0.409 -2.133,-0.409 -0.518,0 -0.923,0.131 -1.215,0.396 -0.292,0.263 -0.438,0.631 -0.438,1.104 0,0.435 0.11,0.763 0.329,0.986 0.218,0.222 0.671,0.389 1.36,0.5 0.566,0.083 0.95,0.236 1.15,0.458 0.201,0.223 0.301,0.579 0.301,1.069 l 0,0.737 0,2.055 c 0,1.481 0.133,2.525 0.401,3.13 C -1.171,-0.988 -0.691,-0.457 0,0" />
- </g><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path272"
- d="m 275.23077,14.69231 -2.15384,0 0,-5.38462 2.15384,0 0,5.38462 z m -4.3077,0 -2.15384,0 0,-5.38462 2.15384,0 0,5.38462 z M 274.92277,5 269.07722,5 265,9.03792 265,14.88238 269.07722,19 274.92277,19 279,14.88238 279,9.03792 274.92277,5 z" /><g
- transform="matrix(0.5000139,0,0,-0.5,112.03125,15.5)"
- id="g274">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path276"
- d="m 0,0 c -3.866,0 -7,3.134 -7,7 0,3.866 3.134,7 7,7 C 3.866,14 7,10.866 7,7 7,3.134 3.866,0 0,0 m -0.062,17 c -4.875,0 -9.251,-1.667 -18,-10 8.624,-8.333 13.125,-10 18,-10 4.874,0 9.25,1.667 17.999,10 C 9.313,15.333 4.812,17 -0.062,17" />
- </g><g
- transform="matrix(0.5,0,0,-0.5,110.5,12)"
- id="g278">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path280"
- d="M 0,0 C 0,-1.657 1.343,-3 3,-3 4.657,-3 6,-1.657 6,0 6,1.657 4.657,3 3,3 1.343,3 0,1.657 0,0" />
- </g><g
- transform="matrix(0.5,0,0,-0.5,139.5,33)"
- id="g282">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path284"
- d="M 0,0 18,0 15,-20 3,-20" />
- </g><g
- transform="matrix(0.5,0,0,-0.5,147.5,30)"
- id="g286">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path288"
- d="m 0,0 -4,0 0,2 -6,0 0,-2 -4,0 c -1.104,0 -2,-0.964 -2,-2 l 0,-2 2,0 14,0 2,0 0,2 C 2,-0.964 1.104,0 0,0" />
- </g><g
- transform="matrix(0.5,0,0,-0.5,317,69)"
- id="g290">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path292"
- d="M 0,0 0,10 -10,0 0,0 z" />
- </g><g
- transform="matrix(0.5,0,0,-0.5,212,13)"
- id="g294">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path296"
- d="m 0,0 0,-8 -16,0 0,6 -2,0 0,-6 0,-2 2.428,0 L 2,-10 2,-8 2,0 0,0 z" />
- </g><g
- id="g3120"
- transform="matrix(0.5,0,0,0.5,2,0)"><g
- transform="matrix(0.84210526,0,0,-1.0116338,42,168)"
- id="g3114">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3116"
- d="m 0,0 -19,9.885 0,-19.77" />
- </g><path
+ sodipodi:docname="statusbarButtonGlyphs.svg"><metadata
+ id="metadata3773"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+ showgrid="true"
+ id="namedview3397"
+ inkscape:zoom="6.7175144"
+ inkscape:cx="177.68421"
+ inkscape:cy="134.39918"
+ inkscape:window-width="913"
+ inkscape:window-height="641"
+ inkscape:window-x="795"
+ inkscape:window-y="565"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg3395"
+ inkscape:snap-global="false"><inkscape:grid
+ dotted="false"
+ empspacing="2"
+ enabled="true"
+ id="grid3327"
+ snapvisiblegridlinesonly="true"
+ spacingx="32px"
+ spacingy="24px"
+ type="xygrid"
+ visible="true" /></sodipodi:namedview><defs
+ id="defs3400"><linearGradient
+ id="a"><stop
+ offset="0"
+ stop-color="#606eda"
+ id="stop3403" /><stop
+ offset="1"
+ stop-color="#021db2"
+ id="stop3405" /></linearGradient><linearGradient
+ id="b"><stop
+ offset="0"
+ stop-color="#e59290"
+ id="stop3408" /><stop
+ offset="1"
+ stop-color="#e99890"
+ id="stop3410" /></linearGradient><linearGradient
+ id="c"><stop
+ offset="0"
+ stop-color="#c0544f"
+ id="stop3413" /><stop
+ offset="1"
+ stop-color="#d08481"
+ id="stop3415" /></linearGradient><linearGradient
+ id="d"><stop
+ offset="0"
+ stop-color="#ffa801"
+ stop-opacity="0"
+ id="stop3418" /><stop
+ offset="1"
+ stop-color="#f0fb3d"
+ id="stop3420" /></linearGradient><linearGradient
+ id="e"><stop
+ offset="0"
+ stop-color="#ffbd00"
+ stop-opacity="0.65"
+ id="stop3423" /><stop
+ offset="1"
+ stop-color="#fff"
+ stop-opacity="0.91"
+ id="stop3425" /></linearGradient><linearGradient
+ id="f"><stop
+ offset="0"
+ stop-color="#00d600"
+ stop-opacity="0"
+ id="stop3428" /><stop
+ offset="1"
+ stop-color="#d8fc7b"
+ stop-opacity="0.81"
+ id="stop3430" /></linearGradient><linearGradient
+ id="g"><stop
+ offset="0"
+ stop-color="#00ba00"
+ id="stop3433" /><stop
+ offset="1"
+ stop-color="#fff"
+ stop-opacity="0.91"
+ id="stop3435" /></linearGradient><linearGradient
+ id="h"><stop
+ offset="0"
+ stop-color="#00a104"
+ id="stop3438" /><stop
+ offset="1"
+ stop-color="#00c605"
+ id="stop3440" /></linearGradient><linearGradient
+ id="i"><stop
+ offset="0"
+ stop-color="#f00"
+ stop-opacity="0"
+ id="stop3443" /><stop
+ offset="1"
+ stop-color="#f0cb68"
+ stop-opacity="0.71"
+ id="stop3445" /></linearGradient><linearGradient
+ id="j"><stop
+ offset="0"
+ stop-color="#e60000"
+ stop-opacity="0.65"
+ id="stop3448" /><stop
+ offset="1"
+ stop-color="#fff"
+ stop-opacity="0.91"
+ id="stop3450" /></linearGradient><linearGradient
+ id="k"><stop
+ offset="0"
+ stop-color="#a10000"
+ id="stop3453" /><stop
+ offset="1"
+ stop-color="#c60000"
+ id="stop3455" /></linearGradient><linearGradient
+ id="l"><stop
+ offset="0"
+ stop-color="#d7687d"
+ id="stop3458" /><stop
+ offset="1"
+ stop-color="#b21402"
+ id="stop3460" /></linearGradient><radialGradient
+ cx="0"
+ cy="0"
+ fx="0"
+ fy="0"
+ gradientTransform="matrix(18,0,0,-18,680,341)"
+ gradientUnits="userSpaceOnUse"
+ id="z"
+ r="1"
+ spreadMethod="pad"><stop
+ offset="0"
+ id="stop3463" /><stop
+ offset="1"
+ stop-opacity="0"
+ id="stop3465" /></radialGradient><radialGradient
+ cx="0"
+ cy="0"
+ fx="0"
+ fy="0"
+ gradientTransform="matrix(9,0,0,9,304,36)"
+ gradientUnits="userSpaceOnUse"
+ id="A"
+ r="1"
+ spreadMethod="pad"
+ xlink:href="#z" /><linearGradient
+ gradientTransform="matrix(0,-0.58333333,-0.58333333,0,118,110)"
+ gradientUnits="userSpaceOnUse"
+ id="m"
+ x1="0"
+ x2="24"
+ xlink:href="#l"
+ y1="0"
+ y2="0" /><linearGradient
+ gradientTransform="matrix(0,1,-1,0,206,0)"
+ gradientUnits="userSpaceOnUse"
+ id="n"
+ x1="96.5"
+ x2="109.5"
+ xlink:href="#b"
+ y1="103"
+ y2="103" /><linearGradient
+ gradientTransform="matrix(0,1,-1,0,207,-17)"
+ gradientUnits="userSpaceOnUse"
+ id="o"
+ x1="113"
+ x2="127"
+ xlink:href="#c"
+ y1="104"
+ y2="104" /><linearGradient
+ gradientTransform="matrix(0,-0.41666666,-0.41666666,0,218,106)"
+ gradientUnits="userSpaceOnUse"
+ id="p"
+ x1="0"
+ x2="24"
+ xlink:href="#l"
+ y1="0"
+ y2="0" /><linearGradient
+ gradientTransform="matrix(0.71428571,0,0,0.71428571,132.28571,37.714287)"
+ gradientUnits="userSpaceOnUse"
+ id="q"
+ x1="113"
+ x2="127"
+ xlink:href="#a"
+ y1="104"
+ y2="104" /><linearGradient
+ gradientTransform="matrix(0,1.3793103,-1.3008129,0,363.08462,-218.35335)"
+ gradientUnits="userSpaceOnUse"
+ id="r"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#k"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(0,-0.62931035,0.92682926,0,133.46895,244.52849)"
+ gradientUnits="userSpaceOnUse"
+ id="s"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#j"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(0,0.43965518,0.78048781,0,148.48744,2.1206316)"
+ gradientUnits="userSpaceOnUse"
+ id="t"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#i"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(-0.01506784,1.3792098,-1.3007182,-0.01421029,377.66542,-216.8212)"
+ gradientUnits="userSpaceOnUse"
+ id="u"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#h"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(0.00687469,-0.62926454,0.92676181,0.01012483,142.86511,243.44332)"
+ gradientUnits="userSpaceOnUse"
+ id="v"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#g"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(-0.00480288,0.43962318,0.780431,0.00852617,160.60265,1.1603253)"
+ gradientUnits="userSpaceOnUse"
+ id="w"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#f"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(0,-0.62931035,0.92682926,0,155.46895,244.52849)"
+ gradientUnits="userSpaceOnUse"
+ id="x"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#e"
+ y1="103.15625"
+ y2="103.15625" /><linearGradient
+ gradientTransform="matrix(0,0.43965518,0.78048781,0,170.44325,2.076437)"
+ gradientUnits="userSpaceOnUse"
+ id="y"
+ x1="227.875"
+ x2="235.125"
+ xlink:href="#d"
+ y1="103.15625"
+ y2="103.15625" /></defs><path
+ d="M57 12 53.5 8 39 8l0 8 14.5 0"
+ id="path3481" /><path
+ d="m25 36-3.64-4-1.79 0-5.57 8 7.36 0 3.64-4z"
+ id="path3483" /><path
+ d="m7 32 0 8 2.05 0 4.95-8-7 0z"
+ id="path3485" /><path
+ d="m9.67 44.55-1.59-1.32 10.76-15.78 1.59 1.32-10.76 15.78z"
+ id="path3487" /><path
+ d="M16 5L16 7C13.24 7 11 9.24 11 12C11 14.76 13.24 17 16 17C18.76 17 21 14.76 21 12L19.16 12C19.12 13.72 17.73 15.09 16 15.09C14.25 15.09 12.84 13.69 12.84 11.94C12.84 10.19 14.25 8.78 16 8.78L16 11L20.5 8L16 5z"
+ id="path3489" /><path
+ d="m53 37-10 0 0-5 10 0 0 5zm-12 5 14 0 0-12-14 0 0 12z"
+ id="path3491" /><path
+ d="m10 57-2 0 0 9 11 0 0-2-9 0z"
+ id="path3493" /><path
+ d="m13 56 7 0 0 5-7 0zm-2-2 0 9 11 0 0-9z"
+ id="path3495" /><path
+ d="m86 33-8 0 0-2 8 0 0 2z"
+ id="path3497" /><path
+ d="m71.5 31.44 4.2 4.31-4.2 4.31 1.4 1.44 5.6-5.75L72.9 30z"
+ id="path3499" /><path
+ d="m86 37-6 0 0-2 6 0 0 2z"
+ id="path3501" /><path
+ d="m86 41-8 0 0-2 8 0 0 2z"
+ id="path3503" /><path
+ d="m80.44 16.94c-2.48 0-4.5-2.02-4.5-4.5 0-0.88 0.26-1.7 0.69-2.39l6.2 6.2c-0.69 0.44-1.51 0.69-2.39 0.69m4.5-4.5c0 0.88-0.26 1.7-0.69 2.39l-6.2-6.2c0.69-0.44 1.51-0.69 2.39-0.69 2.48 0 4.5 2.02 4.5 4.5M80.5 6c-3.59 0-6.5 2.91-6.5 6.5 0 3.59 2.91 6.5 6.5 6.5 3.59 0 6.5-2.91 6.5-6.5 0-3.59-2.91-6.5-6.5-6.5"
+ id="path3505" /><path
+ d="m117 65-10 0 0-10 10 0 0 10z"
+ id="path3507" /><path
+ d="M149 8.33 147.67 7 144 10.67 140.33 7 139 8.33l3.67 3.67-3.67 3.67 1.33 1.33 3.67-3.67 3.67 3.67L149 15.67 145.33 12 149 8.33z"
+ id="path3509" /><path
+ d="m44 59 2 3 0 4 4 0 0-4 2-3z"
+ fill="#424242"
+ opacity="0.5"
+ id="path3511" /><path
+ d="m46.5 65.23c0.32 0.13 0.84 0.24 1.47 0.24 0.59 0 1.14-0.1 1.53-0.26l0-3.93 4-4.57 0-0.19-11 0 0 0.22 4 4.57 0 3.93zM47.97 67C46.81 66.91 45.82 66.71 45 66.01l0-4.12-4-4.57 0-2.32 14 0 0 2.35-4 4.57 0 4.13c-0.92 0.67-2.1 0.94-3.03 0.95"
+ id="path3513" /><path
+ d="M86 60 76 55 76 65"
+ id="path3515" /><path
+ d="m153 57-11 0 0-2 11 0 0 2z"
+ opacity="0.2"
+ id="path3517" /><path
+ d="m142 57-6 0 0-2 6 0 0 2z"
+ id="path3519" /><path
+ d="m145 60-6 0 0-2 6 0 0 2z"
+ id="path3521" /><path
+ d="m150 63-6 0 0-2 6 0 0 2z"
+ id="path3523" /><path
+ d="m152 66-6 0 0-2 6 0 0 2z"
+ id="path3525" /><path
+ d="m170 67-2 0 0-9 2 0 0 9z"
+ id="path3527" /><path
+ d="m173 67-2 0 0-11 2 0 0 11z"
+ id="path3529" /><path
+ d="m176 67-2 0 0-13 2 0 0 13z"
+ id="path3531" /><path
+ d="m179 67-2 0 0-4 2 0 0 4z"
+ id="path3533" /><path
+ d="m182 67-2 0 0-9 2 0 0 9z"
+ id="path3535" /><path
+ d="m185 67-2 0 0-11 2 0 0 11z"
+ id="path3537" /><path
+ d="m208 57-10 0 0-2 10 0 0 2z"
+ id="path3539" /><path
+ d="m217 57-5 0 0-2 5 0 0 2z"
+ id="path3541" /><path
+ d="m200 61-2 0 0-2 2 0 0 2z"
+ id="path3543" /><path
+ d="m213 61-10 0 0-2 10 0 0 2z"
+ id="path3545" /><path
+ d="m217 61-2 0 0-2 2 0 0 2z"
+ id="path3547" /><path
+ d="m205 65-7 0 0-2 7 0 0 2z"
+ id="path3549" /><path
+ d="m217 65-8 0 0-2 8 0 0 2z"
+ id="path3551" /><path
+ d="m274 64-7 0 0-8 7 0 0 8zm-9 2 14 0 0-12-14 0 0 12z"
+ id="path3553" /><path
+ d="m298 12c0 3.31 2.69 6 6 6 3.31 0 6-2.69 6-6 0-3.31-2.69-6-6-6-3.31 0-6 2.69-6 6"
+ id="path3555" /><path
+ d="m295 36c0 4.97 4.03 9 9 9l0 0c4.97 0 9-4.03 9-9l0 0c0-4.97-4.03-9-9-9l0 0c-4.97 0-9 4.03-9 9"
+ fill="url(#A)"
+ id="path3557" /><path
+ d="m298 36c0 3.31 2.69 6 6 6 3.31 0 6-2.69 6-6 0-3.31-2.69-6-6-6-3.31 0-6 2.69-6 6"
+ id="path3559" /><path
+ d="M239 30C236.24 30 234 32.24 234 35C234 37.76 236.24 40 239 40C240.03 40 240.96 39.69 241.75 39.16L245.56 43L247 41.56L243.19 37.75C243.71 36.96 244 36.02 244 35C244 32.24 241.76 30 239 30zM239 32C240.66 32 242 33.34 242 35C242 36.66 240.66 38 239 38C237.34 38 236 36.66 236 35C236 33.34 237.34 32 239 32z"
+ id="path3561" /><path
+ d="m233.73 63.76 5.25-3.23 5.32 2.23 4.95-4.03"
+ fill="none"
+ stroke="#000"
+ stroke-miterlimit="10"
+ stroke-width="1.48"
+ id="path3563" /><path
+ d="m231 67 0-13-1 0 0 14 21 0 0-1z"
+ id="path3565" /><path
+ d="m237 11-4 0 0-4 4 0 0 4z"
+ id="path3567" /><path
+ d="m247 9-9 0 0-2 9 0 0 2z"
+ id="path3569" /><path
+ d="m247 11-9 0 0-1 9 0 0 1z"
+ id="path3571" /><path
+ d="m247 15-9 0 0-2 9 0 0 2z"
+ id="path3573" /><path
+ d="m237 17-4 0 0-4 4 0 0 4z"
+ id="path3575" /><path
+ d="m247 17-9 0 0-1 9 0 0 1z"
+ id="path3577" /><path
+ d="m176 38.13c-1.18 0-2.13-0.96-2.13-2.13 0-1.18 0.96-2.13 2.13-2.13 1.18 0 2.13 0.96 2.13 2.13 0 1.18-0.96 2.13-2.13 2.13m8-3.73-2.93-0.53 1.72-2.39-2.26-2.26-2.46 1.79-0.47-3-3.2 0-0.4 3.13-2.53-1.92-2.26 2.26 1.99 2.59-3.2 0.33 0 3.2 3.33 0.33-2.12 2.59 2.26 2.26 2.53-2.12 0.4 3.33 3.2 0 0.4-3.2 2.53 1.99 2.26-2.26L181 38.07l3-0.47 0-3.2z"
+ id="path3579" /><path
+ d="m268.01 35.99c0.61 0.28 1.07 0.9 1.07 1.58 0.11 0.85-0.05 1.72 0.12 2.57 0.27 0.54 1 0.28 1.43 0.55 0.49 0.24 0.48 1.01-0.06 1.18-0.56 0.22-1.18 0.08-1.74-0.05-0.71-0.2-1.41-0.72-1.5-1.5-0.18-0.89 0.01-1.8-0.16-2.68-0.22-0.64-0.94-0.9-1.57-0.93-0.58-0.1-0.83-0.94-0.35-1.3 0.51-0.35 1.26-0.14 1.69-0.66 0.44-0.48 0.29-1.18 0.32-1.78 0-0.81-0.02-1.77 0.65-2.34 0.66-0.54 1.58-0.71 2.41-0.63 0.63 0 0.98 0.87 0.4 1.22-0.44 0.37-1.2 0.06-1.51 0.65-0.14 0.56-0.05 1.15-0.07 1.73-0.01 0.75-0.05 1.64-0.72 2.13-0.12 0.1-0.26 0.19-0.4 0.26"
+ id="path3581" /><path
+ d="m276.98 35.99c-0.67-0.3-1.08-1.02-1.08-1.75-0.07-0.76 0.03-1.52-0.06-2.28-0.24-0.58-0.98-0.4-1.46-0.59-0.59-0.24-0.48-1.18 0.14-1.31 0.73-0.15 1.52-0.01 2.18 0.32 0.56 0.28 0.95 0.86 0.99 1.48 0.13 0.83-0.03 1.68 0.13 2.5 0.2 0.68 0.94 0.83 1.54 0.9 0.56 0.07 0.86 0.8 0.46 1.21-0.44 0.46-1.2 0.2-1.65 0.66-0.51 0.46-0.4 1.21-0.4 1.83-0.03 0.78 0.06 1.69-0.52 2.3-0.74 0.65-1.8 0.86-2.75 0.68-0.52-0.16-0.69-1.01-0.15-1.25 0.44-0.23 1.02-0.08 1.41-0.45 0.26-0.45 0.09-0.98 0.14-1.47 0.01-0.76-0.07-1.63 0.43-2.26C276.51 36.3 276.75 36.14 276.99 36"
+ id="path3583" /><path
+ d="m275 15-2 0 0-6 2 0zm-4 0-2 0 0-6 2 0zm4-10-6 0-4 4 0 6 4 4 6 0 4-4.12 0-5.88z"
+ id="path3585" /><path
+ d="m112.03 15.5c-1.93 0-3.5-1.57-3.5-3.5 0-1.93 1.57-3.5 3.5-3.5 1.93 0 3.5 1.57 3.5 3.5 0 1.93-1.57 3.5-3.5 3.5m-0.03-8.5c-2.44 0-4.63 0.83-9 5 4.31 4.17 6.56 5 9 5 2.44 0 4.63-0.83 9-5-4.31-4.17-6.56-5-9-5"
+ id="path3587" /><path
+ d="m110.5 12c0 0.83 0.67 1.5 1.5 1.5 0.83 0 1.5-0.67 1.5-1.5 0-0.83-0.67-1.5-1.5-1.5-0.83 0-1.5 0.67-1.5 1.5"
+ id="path3589" /><path
+ d="m139.5 33 9 0-1.5 10-6 0"
+ id="path3591" /><path
+ d="m147.5 30-2 0 0-1-3 0 0 1-2 0c-0.55 0-1 0.48-1 1l0 1 1 0 7 0 1 0 0-1c0-0.52-0.45-1-1-1"
+ id="path3593" /><path
+ d="m317 69 0-5-5 5 5 0z"
+ id="path3595" /><path
+ d="m23 84-8-5 0 10"
+ id="path3597" /><path
+ d="m13 89-3 0 0-10 3 0 0 10z"
+ id="path3599" /><path
+ d="m47 88-3 0 0-8 3 0 0 8z"
+ id="path3601" /><path
+ d="m53 88-3 0 0-8 3 0 0 8z"
+ id="path3603" /><path
+ d="m78.5 89c0 1.1 0.9 2 2 2 1.1 0 2-0.9 2-2 0-1.1-0.9-2-2-2-1.1 0-2 0.9-2 2"
+ id="path3605" /><path
+ d="M79 78L79 82L76 82L80.5 86L85 82L82 82L82 78L79 78z"
+ id="path3607" /><path
+ d="m110.5 89c0 1.1 0.9 2 2 2 1.1 0 2-0.9 2-2 0-1.1-0.9-2-2-2-1.1 0-2 0.9-2 2"
+ id="path3609" /><path
+ d="M112.5 78L108 82L111 82L111 86L114 86L114 82L117 82L112.5 78z"
+ id="path3611" /><path
+ d="m142 86.5c0 1.1 0.9 2 2 2 1.1 0 2-0.9 2-2 0-1.1-0.9-2-2-2-1.1 0-2 0.9-2 2"
+ id="path3613" /><path
+ d="m137.25 87.03c2.55-8.43 11.4-8.73 13.94 0"
+ fill="none"
+ stroke="#000"
+ stroke-width="2.5"
+ id="path3615" /><path
+ d="m151.68 89-4.54-2.76 6.68-2.1"
+ id="path3617" /><path
+ d="m12 102-7-4 0 8"
+ id="path3619" /><path
+ d="m24 106 4-7-8 0"
+ id="path3621" /><path
+ d="m8 111 4 7-8 0"
+ id="path3623" /><path
+ d="m54 105 0 7-10 0 0-7zm1 8 0-11-12 0 0 11z"
+ id="path3625" /><rect
+ height="3"
+ opacity="0.82"
+ ry="0"
+ width="12"
+ x="73"
+ y="110"
+ id="rect3627" /><rect
+ fill="none"
+ height="12"
+ stroke="#000"
+ width="14"
+ x="168.5"
+ y="78.5"
+ id="rect3629" /><path
+ d="m180 84.5-5-3.25 0 6.5"
+ id="path3631" /><rect
+ height="13"
+ width="1"
+ x="172"
+ y="78"
+ id="rect3633" /><rect
+ fill="none"
+ height="12"
+ stroke="#000"
+ width="14"
+ x="200.5"
+ y="78.5"
+ id="rect3635" /><path
+ d="m207 84.5 5-3.25 0 6.5"
+ id="path3637" /><rect
+ height="13"
+ width="1"
+ x="204"
+ y="78"
+ id="rect3639" /><rect
+ fill="none"
+ height="12"
+ stroke="#000"
+ width="14"
+ x="264.5"
+ y="78.5"
+ id="rect3641" /><path
+ d="m272 84.5-5-3.25 0 6.5"
+ id="path3643" /><rect
+ height="13"
+ width="1"
+ x="274"
+ y="78"
+ id="rect3645" /><rect
+ fill="none"
+ height="12"
+ stroke="#000"
+ width="14"
+ x="296.5"
+ y="78.5"
+ id="rect3647" /><path
+ d="m299 84.5 5-3.25 0 6.5"
+ id="path3649" /><rect
+ height="13"
+ width="1"
+ x="306"
+ y="78"
+ id="rect3651" /><path
+ d="m118 96c-3.87 0-7 3.13-7 7 0 3.87 3.13 7 7 7 3.87 0 7-3.13 7-7 0-3.87-3.13-7-7-7"
+ fill="url(#m)"
+ id="path3653" /><path
+ d="m111.5 103c0 3.59 2.91 6.5 6.5 6.5 3.59 0 6.5-2.91 6.5-6.5 0-3.59-2.91-6.5-6.5-6.5-3.59 0-6.5 2.91-6.5 6.5"
+ fill="#f27d82"
+ id="path3655" /><path
+ d="m121.5 100.93-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57L114.5 106.07 115.43 107 118 104.43 120.57 107 121.5 106.07 118.93 103.5 121.5 100.93z"
+ fill-opacity="0.36"
+ id="path3657" /><path
+ d="m121.5 100.43-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57-2.57 2.57 0.93 0.93 2.57-2.57 2.57 2.57 0.93-0.93-2.57-2.57 2.57-2.57z"
+ fill="#fff"
+ id="path3659" /><path
+ d="m138.5 100.93-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57L131.5 106.07 132.43 107 135 104.43 137.57 107 138.5 106.07 135.93 103.5 138.5 100.93z"
+ fill-opacity="0.24"
+ id="path3661" /><path
+ d="m138.5 100.43-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57-2.57 2.57 0.93 0.93 2.57-2.57 2.57 2.57 0.93-0.93-2.57-2.57 2.57-2.57z"
+ fill="#676767"
+ id="path3663" /><path
+ d="m103 110c3.87 0 7-3.13 7-7 0-3.87-3.13-7-7-7-3.87 0-7 3.13-7 7 0 3.87 3.13 7 7 7"
+ fill="url(#o)"
+ id="path3665" /><path
+ d="m103 96.5c-3.59 0-6.5 2.91-6.5 6.5 0 3.59 2.91 6.5 6.5 6.5 3.59 0 6.5-2.91 6.5-6.5 0-3.59-2.91-6.5-6.5-6.5"
+ fill="url(#n)"
+ id="path3667" /><path
+ d="m106.5 100.93-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57L99.5 106.07 100.43 107 103 104.43 105.57 107 106.5 106.07 103.93 103.5 106.5 100.93z"
+ fill="#993c35"
+ id="path3669" /><path
+ d="m106.5 100.43-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57-2.57 2.57 0.93 0.93 2.57-2.57 2.57 2.57 0.93-0.93-2.57-2.57 2.57-2.57z"
+ fill="#fff"
+ id="path3671" /><path
+ d="m143 102.5c0 3.59 2.91 6.5 6.5 6.5 3.59 0 6.5-2.91 6.5-6.5 0-3.59-2.91-6.5-6.5-6.5-3.59 0-6.5 2.91-6.5 6.5"
+ fill="#bebebe"
+ id="path3673" /><path
+ d="m153 100.43-0.93-0.93-2.57 2.57L146.93 99.5 146 100.43 148.57 103 146 105.57 146.93 106.5 149.5 103.93 152.07 106.5 153 105.57 150.43 103 153 100.43z"
+ fill-opacity="0.37"
+ id="path3675" /><path
+ d="M153 99.93 152.07 99 149.5 101.57 146.93 99 146 99.93 148.57 102.5 146 105.07 146.93 106 149.5 103.43 152.07 106 153 105.07 150.43 102.5 153 99.93z"
+ fill="#fff"
+ id="path3677" /><path
+ d="m160 102.5c0 3.59 2.91 6.5 6.5 6.5 3.59 0 6.5-2.91 6.5-6.5 0-3.59-2.91-6.5-6.5-6.5-3.59 0-6.5 2.91-6.5 6.5"
+ fill="#9f9f9f"
+ id="path3679" /><path
+ d="m170 100.43-0.93-0.93-2.57 2.57L163.93 99.5 163 100.43 165.57 103 163 105.57 163.93 106.5 166.5 103.93 169.07 106.5 170 105.57 167.43 103 170 100.43z"
+ fill-opacity="0.36"
+ id="path3681" /><path
+ d="M170 99.93 169.07 99 166.5 101.57 163.93 99 163 99.93 165.57 102.5 163 105.07 163.93 106 166.5 103.43 169.07 106 170 105.07 167.43 102.5 170 99.93z"
+ fill="#fff"
+ id="path3683" /><path
+ d="m184.5 100.43-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57-2.57 2.57 0.93 0.93 2.57-2.57 2.57 2.57 0.93-0.93-2.57-2.57 2.57-2.57z"
+ fill-opacity="0.24"
+ id="path3685" /><path
+ d="m184.5 99.93-0.93-0.93-2.57 2.57-2.57-2.57-0.93 0.93 2.57 2.57L177.5 105.07 178.43 106 181 103.43 183.57 106 184.5 105.07 181.93 102.5 184.5 99.93z"
+ fill="#676767"
+ id="path3687" /><path
+ d="m131.65 116.21-1.44-2.03-1.21 1.21 2.55 3.61 6.45-7.67-1.12-1.33z"
+ id="path3689" /><path
+ d="m195.75 97.75 3.5 3.25-3.5 3.25"
+ fill="none"
+ stroke="#367cf1"
+ stroke-width="1.5"
+ id="path3691" /><path
+ d="m195.75 108.75 3.5 3.25-3.5 3.25"
+ fill="none"
+ stroke="#939393"
+ stroke-width="1.5"
+ id="path3693" /><path
+ d="m209 101c0 0.55 0.45 1 1 1 0.55 0 1-0.45 1-1 0-0.55-0.45-1-1-1-0.55 0-1 0.45-1 1"
+ fill="#bababa"
+ id="path3695" /><path
+ d="m208.25 97.75-3.5 3.25 3.5 3.25"
+ fill="none"
+ stroke="#bababa"
+ stroke-width="1.5"
+ id="path3697" /><path
+ d="m218 96c-2.76 0-5 2.24-5 5 0 2.76 2.24 5 5 5 2.76 0 5-2.24 5-5 0-2.76-2.24-5-5-5"
+ fill="url(#p)"
+ id="path3699" /><path
+ d="m213.36 101c0 2.56 2.08 4.64 4.64 4.64 2.56 0 4.64-2.08 4.64-4.64 0-2.56-2.08-4.64-4.64-4.64-2.56 0-4.64 2.08-4.64 4.64"
+ fill="#eb3941"
+ id="path3701" /><path
+ d="m216 99 4 4"
+ stroke="#fff"
+ id="path3703" /><path
+ d="m220 99-4 4"
+ stroke="#fff"
+ id="path3705" /><path
+ d="m203 116 4-8 4 8z"
+ stroke="#c19600"
+ stroke-linejoin="round"
+ stroke-width="2"
+ id="path3707" /><path
+ d="m203 116 4-8 4 8z"
+ fill="#f4bd00"
+ stroke="#f5bd00"
+ stroke-linejoin="round"
+ stroke-width="1.5"
+ id="path3709" /><path
+ d="m205.75 109.75 2.5 0 0 2.5-0.5 1.75-1.5 0-0.5-1.75 0-2.5m0 5.25 2.5 0 0 1.25-2.5 0"
+ fill="#ad8601"
+ id="path3711" /><path
+ d="m206 110 2 0 0 2.25-0.5 1.75-1 0-0.5-1.75 0-2.25m0 5 2 0 0 1-2 0"
+ fill="#fff"
+ id="path3713" /><path
+ d="m229 106c-2.76 0-5-2.24-5-5 0-2.76 2.24-5 5-5 2.76 0 5 2.24 5 5 0 2.76-2.24 5-5 5z"
+ fill="url(#r)"
+ id="path3715" /><path
+ d="m233.5 101c0 2.49-2.01 4.5-4.5 4.5-2.49 0-4.5-2.01-4.5-4.5 0-2.49 2.01-4.5 4.5-4.5 2.49 0 4.5 2.01 4.5 4.5z"
+ fill="#d00"
+ id="path3717" /><path
+ d="m229.03 96.53c1.97 0 3.56 1.02 3.56 2.28 0 1.26-1.59 2.28-3.56 2.28-1.97 0-3.56-1.02-3.56-2.28 0-1.26 1.59-2.28 3.56-2.28z"
+ fill="url(#s)"
+ id="path3719" /><path
+ d="m229.03 105.47c1.66 0 3-0.71 3-1.59 0-0.88-1.34-1.59-3-1.59-1.66 0-3 0.71-3 1.59 0 0.88 1.34 1.59 3 1.59z"
+ fill="url(#t)"
+ id="path3721" /><path
+ d="m239.95 106c-2.76-0.03-4.98-2.29-4.95-5.05 0.03-2.76 2.29-4.98 5.05-4.95 2.76 0.03 4.98 2.29 4.95 5.05-0.03 2.76-2.29 4.98-5.05 4.95z"
+ fill="url(#u)"
+ id="path3723" /><path
+ d="m244.5 101.05c-0.03 2.49-2.06 4.48-4.55 4.45-2.49-0.03-4.48-2.06-4.45-4.55 0.03-2.49 2.06-4.48 4.55-4.45 2.49 0.03 4.48 2.06 4.45 4.55z"
+ fill="#00be00"
+ id="path3725" /><path
+ d="m240.08 96.53c1.97 0.02 3.55 1.06 3.54 2.32-0.01 1.26-1.62 2.26-3.59 2.24-1.97-0.02-3.55-1.06-3.54-2.32 0.01-1.26 1.62-2.26 3.59-2.24z"
+ fill="url(#v)"
+ id="path3727" /><path
+ d="m239.98 105.41c1.66 0.02 3.01-0.68 3.02-1.56 0.01-0.88-1.33-1.61-2.98-1.63-1.66-0.02-3.01 0.68-3.02 1.56-0.01 0.88 1.33 1.61 2.98 1.63z"
+ fill="url(#w)"
+ id="path3729" /><path
+ d="m251 106c-2.76 0-5-2.24-5-5 0-2.76 2.24-5 5-5 2.76 0 5 2.24 5 5 0 2.76-2.24 5-5 5z"
+ fill="#e5a600"
+ id="path3731" /><path
+ d="m255.5 101c0 2.49-2.01 4.5-4.5 4.5-2.49 0-4.5-2.01-4.5-4.5 0-2.49 2.01-4.5 4.5-4.5 2.49 0 4.5 2.01 4.5 4.5z"
+ fill="#ffbd00"
+ id="path3733" /><path
+ d="m251.03 96.53c1.97 0 3.56 1.02 3.56 2.28 0 1.26-1.59 2.28-3.56 2.28-1.97 0-3.56-1.02-3.56-2.28 0-1.26 1.59-2.28 3.56-2.28z"
+ fill="url(#x)"
+ id="path3735" /><path
+ d="m250.99 105.42c1.66 0 3-0.71 3-1.59 0-0.88-1.34-1.59-3-1.59-1.66 0-3 0.71-3 1.59 0 0.88 1.34 1.59 3 1.59z"
+ fill="url(#y)"
+ id="path3737" /><rect
+ height="12"
+ rx="0.25"
+ ry="0.25"
+ style="fill-opacity:0.38;stroke-linejoin:round;stroke-miterlimit:0;stroke-width:2;stroke:#000"
+ width="8"
+ x="268"
+ y="102"
+ id="rect3739" /><path
+ d="m218 107c-2.76 0-5 2.24-5 5 0 2.76 2.24 5 5 5 2.76 0 5-2.24 5-5 0-2.76-2.24-5-5-5"
+ fill="url(#q)"
+ id="path3741" /><path
+ d="m213.36 112c0 2.56 2.08 4.64 4.64 4.64 2.56 0 4.64-2.08 4.64-4.64 0-2.56-2.08-4.64-4.64-4.64-2.56 0-4.64 2.08-4.64 4.64"
+ fill="#2a53cd"
+ id="path3743" /><path
+ d="m216.93 109.14c-0.03-0.53 0.55-0.97 1.06-0.83 0.5 0.12 0.79 0.73 0.56 1.18-0.2 0.44-0.79 0.61-1.2 0.36C217.09 109.71 216.93 109.43 216.93 109.14zm1.7 5.46c0.22 0 0.45 0 0.67 0 0 0.18 0 0.35 0 0.53-0.96 0-1.93 0-2.89 0 0-0.18 0-0.35 0-0.53 0.22 0 0.44 0 0.66 0 0-1.2 0-2.41 0-3.61-0.22 0-0.44 0-0.66 0 0-0.18 0-0.35 0-0.53 0.74 0 1.48 0 2.22 0 0 1.38 0 2.76 0 4.14z"
+ fill="#fff"
+ id="path3745" /><rect
+ height="8"
+ rx="0.25"
+ ry="0.25"
+ style="fill-opacity:0.38;stroke-linejoin:round;stroke-miterlimit:0;stroke-width:2;stroke:#000"
+ width="12"
+ x="298"
+ y="104"
+ id="rect3747" /><path
+ d="m12.25 125c-0.68 0-1.25 0.57-1.25 1.25l0 9.69 2-3.31 0-5.63 3.38 0 1.19-2-5.31 0zm8.75 3.06-2 3.31 0 5.63-3.38 0-1.19 2 5.31 0c0.68 0 1.25-0.57 1.25-1.25l0-9.69z"
+ stroke-width="2"
+ id="path3749" /><path
+ d="m10.75 140.75 10.5-17.5"
+ fill="none"
+ stroke="#000"
+ stroke-width="2"
+ id="path3751" /><path
+ d="m46 128 7 0 0 8-7 0 0-8zm9-2-14 0 0 12 14 0 0-12z"
+ id="path3753" /><rect
+ height="6"
+ width="3"
+ x="73"
+ y="129"
+ id="rect3755" /><rect
+ height="6"
+ width="3"
+ x="77"
+ y="129"
+ id="rect3757" /><rect
+ height="6"
+ width="3"
+ x="81"
+ y="129"
+ id="rect3759" /><rect
+ fill="none"
+ height="10"
+ rx="1"
+ ry="1"
+ stroke="#000"
+ stroke-linejoin="round"
+ stroke-width="2"
+ width="15"
+ x="71"
+ y="127"
+ id="rect3761" /><path
+ d="m86 129c3 0 3 0 3 3 0 3 0 3-3 3"
+ fill="none"
+ stroke="#000"
+ stroke-width="2"
+ id="path3763" /><path
+ d="m227.25 107c-0.7 0-1.25 0.5-1.25 1.25l0 7.5c0 0.7 0.5 1.25 1.25 1.25l3.5 0c0.7 0 1.25-0.5 1.25-1.25l0-7.5c0-0.7-0.5-1.25-1.25-1.25l-3.5 0zm-0.25 1 4 0 0 7-4 0 0-7zm2 7.25c0.4 0 0.75 0.3 0.75 0.75 0 0.4-0.3 0.75-0.75 0.75-0.4 0-0.75-0.3-0.75-0.75 0-0.4 0.3-0.75 0.75-0.75z"
+ id="path3765" /><path
+ d="m 180,6 0,11 -7,0 0,-11 z m 1,12.5 0,-14 c -3.61,-0.97 -5.62,-1.02 -9,0 l 0,14 c 3.41,0.68 5.43,0.9 9,0 z"
+ id="path3767"
inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3118"
- d="m 22,178 -6,0 0,-20 6,0 0,20 z" /></g><g
- id="g4303"
- transform="matrix(0.5,0,0,0.5,1,-1)"><path
- d="m 92,178 -6,0 0,-16 6,0 0,16 z"
- id="path3127"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3129"
- d="m 104,178 -6,0 0,-16 6,0 0,16 z" /></g><g
- id="g4323"
- transform="scale(0.5,0.5)"><g
- transform="matrix(0.33333333,0,0,-0.33333333,157,178)"
- id="g3310">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3312"
- d="m 0,0 c 0,-6.627 5.372,-12 12,-12 6.628,0 12,5.373 12,12 C 24,6.627 18.628,12 12,12 5.372,12 0,6.627 0,0" />
- </g><g
- id="g4318"><g
- id="g3314"
- transform="matrix(0,0.42105263,0.91047041,0,161,172)">
- <path
- d="m 0,0 -19,9.885 0,-19.77"
- id="path3316"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><path
- d="m 164,164 -6,0 0,-8 6,0 0,8 z"
- id="path3318"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g></g><g
- id="g4363"
- transform="scale(0.5,0.5)"><g
- id="g4333"
- transform="matrix(0.33333333,0,0,-0.33333333,221,178)">
- <path
- d="m 0,0 c 0,-6.627 5.372,-12 12,-12 6.628,0 12,5.373 12,12 C 24,6.627 18.628,12 12,12 5.372,12 0,6.627 0,0"
- id="path4335"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><g
- id="g4339"
- transform="matrix(0,-0.42105263,0.91047041,0,225,156)">
- <path
- d="m 0,0 -19,9.885 0,-19.77"
- id="path4341"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4351"
- d="m 0,0 -19,9.885 0,-19.77" /></g><path
- d="m 228,164 -6,0 0,8 6,0 0,-8 z"
- id="path4343"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><g
- id="g4371"
- transform="matrix(0.5,0,0,0.5,-0.371325,0.98892)"><g
- transform="matrix(0.33333333,0,0,-0.33333333,285.10972,172.09028)"
- id="g3386">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3388"
- d="m -9.6000008e-8,3.5999999 c 0,-6.627 5.371999996000008,-12 12.000000096000007,-12 6.628,0 12,5.373 12,12 C 24,10.227 18.628,15.6 12,15.6 5.3719999,15.6 -9.6000008e-8,10.227 -9.6000008e-8,3.5999999" />
- </g><path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path3400"
- d="m 275.24265,172.08579 c 5.10629,-16.86347 22.80573,-17.45673 27.87622,0"
- style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><g
- inkscape:transform-center-y="4.8667427"
- inkscape:transform-center-x="31.812074"
- transform="matrix(0.12650103,0.40160031,-0.67542793,0.21275463,304.09531,176.02216)"
- id="g4357">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4359"
- d="m 0,0 -19,9.885 0,-19.77" />
- <path
- d="m 0,0 -19,9.885 0,-19.77"
- id="path4361"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g></g><g
- id="g4389"
- transform="matrix(0.36842106,0,0,-0.40465352,12,102)">
- <path
- d="m 0,0 -19,9.885 0,-19.77"
- id="path4391"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><g
- transform="matrix(0,0.36842106,0.40465352,0,24,106)"
- id="g4393">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4395"
- d="m 0,0 -19,9.885 0,-19.77" />
- </g><g
- id="g4397"
- transform="matrix(0,-0.36842106,0.40465352,0,8,111)">
- <path
- d="m 0,0 -19,9.885 0,-19.77"
- id="path4399"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><path
- d="m 54,105 0,7 -10.000005,0 0,-7 z m 1,8 0,-11 -12,0 0,11 z"
- id="path4987"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc" /><rect
- style="opacity:0.81893005;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4991"
- width="12"
- height="3"
- x="73"
- y="110"
- ry="0" /><g
- id="g6865"
- transform="matrix(1,0,0,1.0833067,0,-7.5809332)"><g
- transform="matrix(0.9994799,0,0,0.99934297,0.09079898,0.05570112)"
- id="g6857"><g
- id="g6850"><g
- transform="matrix(0.49680733,0,0,0.49594275,1.1210985,0.73973011)"
- id="g6083"><rect
- y="158.80269"
- x="336.90268"
- height="22.194668"
- width="28.194668"
- id="rect4212"
- style="fill:none;stroke:#000000;stroke-width:1.93673468;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><g
- transform="matrix(-0.52631579,0,0,-0.60698027,349.99999,169.90003)"
- id="g4216">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4218"
- d="M -19.118894,9.0253678e-4 0.01315753,9.9733228 l 0,-19.9448405" />
- </g></g><rect
- y="78.996201"
- x="171.99866"
- height="12.00789"
- width="1.0005203"
- id="rect6836"
- style="fill:#000000;fill-opacity:1;stroke:none" /></g></g></g><g
- id="g6963"
- transform="matrix(1,0,0,1.0833067,0,-7.5809087)"><g
- transform="translate(32.000017,-2.9395427e-4)"
- id="g6874"><g
- transform="matrix(0.9994799,0,0,0.99934297,0.09079898,0.05570112)"
- id="g6876"><g
- id="g6878"><g
- transform="matrix(0.49680733,0,0,0.49594275,1.1210985,0.73973011)"
- id="g6880"><rect
- y="158.80269"
- x="336.90268"
- height="22.194668"
- width="28.194668"
- id="rect6882"
- style="fill:none;stroke:#000000;stroke-width:1.93673468;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><g
- transform="matrix(-0.52631579,0,0,-0.60698027,349.99999,169.90003)"
- id="g6884">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path6886"
- d="M 0.01315753,9.0253678e-4 -19.118894,9.9733228 l 0,-19.9448405" />
- </g></g><rect
- y="78.996201"
- x="171.99866"
- height="12.00789"
- width="1.0005203"
- id="rect6888"
- style="fill:#000000;fill-opacity:1;stroke:none" /></g></g></g></g><g
- id="g6954"
- transform="matrix(1,0,0,1.0833067,0,-7.5809087)"><g
- id="g6890"
- transform="translate(64.000017,-2.9395427e-4)"><g
- id="g6892"
- transform="matrix(0.9994799,0,0,0.99934297,0.09079898,0.05570112)"><g
- id="g6894"><g
- id="g6896"
- transform="matrix(0.49680733,0,0,0.49594275,1.1210985,0.73973011)"><rect
- style="fill:none;stroke:#000000;stroke-width:1.93673468;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect6898"
- width="28.194668"
- height="22.194668"
- x="336.90268"
- y="158.80269" /><g
- id="g6900"
- transform="matrix(-0.52631579,0,0,-0.60698027,349.99999,169.90003)">
-
- </g></g><rect
- style="fill:#000000;fill-opacity:1;stroke:none"
- id="rect6904"
- width="1.0005203"
- height="12.00789"
- x="171.99866"
- y="78.996201" /></g></g></g></g><g
- transform="matrix(-1,0,0,1.0833067,448.00002,-7.5812271)"
- id="g6906"><g
- transform="matrix(0.9994799,0,0,0.99934297,0.09079898,0.05570112)"
- id="g6908"><g
- id="g6910"><g
- transform="matrix(0.49680733,0,0,0.49594275,1.1210985,0.73973011)"
- id="g6912"><rect
- y="158.80269"
- x="336.90268"
- height="22.194668"
- width="28.194668"
- id="rect6914"
- style="fill:none;stroke:#000000;stroke-width:1.93673468;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><g
- transform="matrix(-0.52631579,0,0,-0.60698027,349.99999,169.90003)"
- id="g6916">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path6918"
- d="M 0.01315753,9.0253678e-4 -19.118894,9.9733228 l 0,-19.9448405" />
- </g></g><rect
- y="78.996201"
- x="171.99866"
- height="12.00789"
- width="1.0005203"
- id="rect6920"
- style="fill:#000000;fill-opacity:1;stroke:none" /></g></g></g><g
- id="g6938"
- transform="matrix(-1,0,0,1.0833067,479.00002,-7.5812271)"><g
- id="g6940"
- transform="matrix(0.9994799,0,0,0.99934297,0.09079898,0.05570112)"><g
- id="g6942"><g
- id="g6944"
- transform="matrix(0.49680733,0,0,0.49594275,1.1210985,0.73973011)"><rect
- style="fill:none;stroke:#000000;stroke-width:1.93673468;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect6946"
- width="28.194668"
- height="22.194668"
- x="336.90268"
- y="158.80269" /><g
- id="g6948"
- transform="matrix(-0.52631579,0,0,-0.60698027,349.99999,169.90003)">
- <path
- d="M -19.118894,9.0253678e-4 0.01315753,9.9733228 l 0,-19.9448405"
- id="path6950"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g></g><rect
- style="fill:#000000;fill-opacity:1;stroke:none"
- id="rect6952"
- width="1.0005203"
- height="12.00789"
- x="171.99866"
- y="78.996201" /></g></g></g><g
- id="g5024"
- transform="translate(-2,-1)"><g
- id="g4933"><path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient5103);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4791"
- d="m 120,97 c -3.86575,0 -7,3.13367 -7,7 0,3.86633 3.13425,7 7,7 3.86575,0 7,-3.13367 7,-7 0,-3.86633 -3.13425,-7 -7,-7" /></g><path
- inkscape:connector-curvature="0"
- style="fill:#f27d82;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4795"
- d="m 113.5,104 c 0,3.58963 2.90983,6.5 6.5,6.5 3.59017,0 6.5,-2.91037 6.5,-6.5 0,-3.58963 -2.90983,-6.5 -6.5,-6.5 -3.59017,0 -6.5,2.91037 -6.5,6.5" /><g
- style="fill:#000000;fill-opacity:0.36444451;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,123.5,101.9332)"
- id="g4797">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:0.36444451;fill-rule:nonzero;stroke:none"
- id="path4799"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g><g
- id="g4801"
- transform="matrix(0.32998633,0,0,-0.32998633,123.5,101.4332)"
- style="fill:#ffffff;fill-opacity:1;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path4803"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g></g><g
- id="g5105"
- transform="translate(-0.99999998,-0.99999868)"><g
- id="g4875"
- transform="matrix(0.32998633,0,0,-0.32998633,139.5,101.9332)"
- style="fill:#000000;fill-opacity:0.24444442;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path4877"
- style="fill:#000000;fill-opacity:0.24444442;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><g
- style="fill:#676767;fill-opacity:1;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,139.5,101.4332)"
- id="g4879">
- <path
- inkscape:connector-curvature="0"
- style="fill:#676767;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4881"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g></g><g
- id="g4951"
- transform="matrix(-1,0,0,-1,223,207)"
- style="fill:url(#linearGradient5356);fill-opacity:1;fill-rule:nonzero"><path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient5354);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4953"
- d="m 120,97 c -3.86575,0 -7,3.13367 -7,7 0,3.86633 3.13425,7 7,7 3.86575,0 7,-3.13367 7,-7 0,-3.86633 -3.13425,-7 -7,-7" /></g><path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient5365);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4955"
- d="m 103,96.5 c -3.58963,0 -6.5,2.90983 -6.5,6.5 0,3.59017 2.91037,6.5 6.5,6.5 3.58963,0 6.5,-2.90983 6.5,-6.5 0,-3.59017 -2.91037,-6.5 -6.5,-6.5" /><g
- style="fill:#993c35;fill-opacity:1;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,106.5,100.9332)"
- id="g4957">
- <path
- inkscape:connector-curvature="0"
- style="fill:#993c35;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4959"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g><g
- id="g4961"
- transform="matrix(0.32998633,0,0,-0.32998633,106.5,100.4332)"
- style="fill:#ffffff;fill-opacity:1;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path4963"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><g
- id="g5129"
- transform="translate(-2.5,-1.5)"><path
- inkscape:connector-curvature="0"
- style="fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path4998"
- d="m 145.5,104 c 0,3.58963 2.90983,6.5 6.5,6.5 3.59017,0 6.5,-2.91037 6.5,-6.5 0,-3.58963 -2.90983,-6.5 -6.5,-6.5 -3.59017,0 -6.5,2.91037 -6.5,6.5" /><g
- style="fill:#000000;fill-opacity:0.37333332;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,155.5,101.9332)"
- id="g5000">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:0.37333332;fill-rule:nonzero;stroke:none"
- id="path5002"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g><g
- id="g5004"
- transform="matrix(0.32998633,0,0,-0.32998633,155.5,101.4332)"
- style="fill:#ffffff;fill-opacity:1;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path5006"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g></g><g
- id="g5136"
- transform="translate(-1.5,-1.5)"><path
- d="m 161.5,104 c 0,3.58963 2.90983,6.5 6.5,6.5 3.59017,0 6.5,-2.91037 6.5,-6.5 0,-3.58963 -2.90983,-6.5 -6.5,-6.5 -3.59017,0 -6.5,2.91037 -6.5,6.5"
- id="path5039"
- style="fill:#9f9f9f;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><g
- id="g5041"
- transform="matrix(0.32998633,0,0,-0.32998633,171.5,101.9332)"
- style="fill:#000000;fill-opacity:0.36444475;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path5043"
- style="fill:#000000;fill-opacity:0.36444475;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><g
- style="fill:#ffffff;fill-opacity:1;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,171.5,101.4332)"
- id="g5045">
- <path
- inkscape:connector-curvature="0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5047"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g></g><g
- transform="translate(45,-1.4999987)"
- id="g5143"><g
- style="fill:#000000;fill-opacity:0.24444442;stroke:none"
- transform="matrix(0.32998633,0,0,-0.32998633,139.5,101.9332)"
- id="g5145">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:0.24444442;fill-rule:nonzero;stroke:none"
- id="path5147"
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z" />
- </g><g
- id="g5149"
- transform="matrix(0.32998633,0,0,-0.32998633,139.5,101.4332)"
- style="fill:#676767;fill-opacity:1;stroke:none">
- <path
- d="M 0,0 -2.828,2.828 -10.606,-4.95 -18.385,2.828 -21.213,0 l 7.778,-7.778 -7.778,-7.779 2.828,-2.828 7.779,7.779 7.778,-7.779 L 0,-15.557 -7.778,-7.778 0,0 z"
- id="path5151"
- style="fill:#676767;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g></g><g
- id="g5165"
- transform="matrix(0.396371,0,0,-0.47078517,131.64855,116.21248)">
- <path
- d="m 0,0 -3.618,4.311 -3.064,-2.572 6.428,-7.66 2.835,2.845 13.443,13.443 -2.828,2.829 L 0,0 z"
- id="path5167"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g><path
- style="fill:none;stroke:#367cf1;stroke-width:1.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 195.75,97.750005 3.5,3.249985 -3.5,3.25001"
- id="path5212"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" /><path
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0"
- id="path5214"
- d="m 195.75,108.75001 3.5,3.24998 -3.5,3.25001"
- style="fill:none;stroke:#939393;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><g
- id="g5222"
- transform="translate(-2,0)"><g
- style="fill:#bababa;fill-opacity:1"
- transform="matrix(0.08333333,0,0,-0.08333333,211,101)"
- id="g5202">
- <path
- inkscape:connector-curvature="0"
- style="fill:#bababa;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5204"
- d="m 0,0 c 0,-6.627 5.372,-12 12,-12 6.628,0 12,5.373 12,12 C 24,6.627 18.628,12 12,12 5.372,12 0,6.627 0,0" />
- </g><path
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0"
- id="path5216"
- d="m 210.25,97.750006 -3.5,3.249984 3.5,3.25001"
- style="fill:none;stroke:#bababa;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g><g
- id="error-message"
- transform="translate(11.000005,-9.9999998)"><g
- transform="matrix(0.71428571,0,0,0.71428571,121.28571,36.714286)"
- id="g5241"><path
- d="m 120,97 c -3.86575,0 -7,3.13367 -7,7 0,3.86633 3.13425,7 7,7 3.86575,0 7,-3.13367 7,-7 0,-3.86633 -3.13425,-7 -7,-7"
- id="path5243"
- style="fill:url(#linearGradient5281);fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><path
- d="m 202.35714,111 c 0,2.56402 2.07845,4.64286 4.64286,4.64286 2.5644,0 4.64285,-2.07884 4.64285,-4.64286 0,-2.56402 -2.07845,-4.64286 -4.64285,-4.64286 -2.56441,0 -4.64286,2.07884 -4.64286,4.64286"
- id="path5245"
- style="fill:#eb3941;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><path
- inkscape:connector-curvature="0"
- id="path5264"
- d="m 205,109 c 4,4 4,4 4,4"
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /><path
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 209,109 c -4,4 -4,4 -4,4"
- id="path5266"
- inkscape:connector-curvature="0" /><path
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 205,109 c 4,4 4,4 4,4"
- id="path5268"
- inkscape:connector-curvature="0" /><path
- inkscape:connector-curvature="0"
- id="path5270"
- d="m 209,109 c -4,4 -4,4 -4,4"
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g><path
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0"
- id="path5289"
- d="m 203,116 4,-7.77778 4,7.77778 z"
- style="fill:none;stroke:#c19600;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><path
- style="fill:#f4bd00;fill-opacity:1;stroke:#f5be00;stroke-width:1.49999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 203.01662,116 4,-7.77778 4,7.77778 z"
- id="path5283"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" /><text
- sodipodi:linespacing="125%"
- id="text5301"
- y="146.8199"
- x="161.33199"
- style="font-size:11.26096152999999944px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ad8601;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Times Bold"
- xml:space="preserve"
- transform="scale(1.2629669,0.79178638)"><tspan
- y="146.8199"
- x="161.33199"
- id="tspan5303"
- sodipodi:role="line">!</tspan></text>
-
-
-
-
-
-<path
- style="font-size:9.67697048px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Times Bold"
- sodipodi:nodetypes="cccccccccccc"
- inkscape:connector-curvature="0"
- id="path5364"
- d="m 206,110 2,0 0,2.30275 -0.28334,1.67983 -1.43333,0 L 206,112.30275 206,110 m 0,4.56933 2,0 0,1.43067 -2,0 0,-1" /><text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="217.42622"
- y="110.74906"
- id="text5307"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan5309"
- x="217.42622"
- y="110.74906" /></text>
-
-
-
-
-
-<g
- id="g5771"><path
- sodipodi:type="arc"
- style="fill:url(#linearGradient5737);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5449"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(4.4216629e-4,1.3793103,-1.3008129,4.1702167e-4,363.08462,-218.35335)" /><path
- transform="matrix(1.2413792,-3.9796805e-4,3.7530216e-4,1.1707316,-58.418,-19.676152)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5451"
- style="fill:#dd0000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /><path
- sodipodi:type="arc"
- style="fill:url(#linearGradient5767);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5453"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(-2.0173838e-4,-0.62931035,0.92682926,-2.9712795e-4,133.46895,244.52849)" /><path
- transform="matrix(1.4094051e-4,0.43965518,0.78048781,-2.5021302e-4,148.48744,2.1206306)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5455"
- style="fill:url(#linearGradient5769);fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /></g><g
- id="g5757"><path
- sodipodi:type="arc"
- style="fill:url(#linearGradient5743);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5513"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(-0.01506784,1.3792098,-1.3007182,-0.01421029,377.66542,-216.8212)" /><path
- transform="matrix(1.2413037,0.01356118,-0.01278943,1.1706604,-46.042497,-22.900348)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5515"
- style="fill:#00be00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /><path
- sodipodi:type="arc"
- style="fill:url(#linearGradient5753);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5517"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(0.00687469,-0.62926454,0.92676181,0.01012483,142.86511,243.44332)" /><path
- transform="matrix(-0.00480288,0.43962318,0.780431,0.00852617,160.60265,1.1603243)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5519"
- style="fill:url(#linearGradient5755);fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /></g><path
- sodipodi:type="arc"
- style="fill:#e5a600;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5588"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(4.4216629e-4,1.3793103,-1.3008129,4.1702167e-4,385.08462,-218.35335)" /><path
- transform="matrix(1.2413792,-3.9796805e-4,3.7530216e-4,1.1707316,-36.418,-19.676152)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5590"
- style="fill:#ffbd00;fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /><path
- sodipodi:type="arc"
- style="fill:url(#linearGradient5835);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path5592"
- sodipodi:cx="231.5"
- sodipodi:cy="103.15625"
- sodipodi:rx="3.625"
- sodipodi:ry="3.84375"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- transform="matrix(-2.0173838e-4,-0.62931035,0.92682926,-2.9712795e-4,155.46895,244.52849)" /><path
- transform="matrix(1.4094051e-4,0.43965518,0.78048781,-2.5021302e-4,170.44325,2.0764364)"
- d="m 235.125,103.15625 a 3.625,3.84375 0 1 1 -7.25,0 3.625,3.84375 0 1 1 7.25,0 z"
- sodipodi:ry="3.84375"
- sodipodi:rx="3.625"
- sodipodi:cy="103.15625"
- sodipodi:cx="231.5"
- id="path5594"
- style="fill:url(#linearGradient5837);fill-opacity:1;fill-rule:nonzero;stroke:none"
- sodipodi:type="arc" /><rect
- style="fill:#000000;fill-opacity:0.38222225;fill-rule:nonzero;stroke:#000000;stroke-width:1.99999988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none"
- id="rect4542"
- width="8"
- height="12"
- x="268"
- y="102"
- ry="1.6104031"
- rx="0" /><g
- id="info-message"
- transform="translate(11.000005,1.0000002)"><g
- transform="matrix(0.71428571,0,0,0.71428571,121.28571,36.714286)"
- id="g5241-7"
- style="fill:url(#linearGradient5635);fill-opacity:1.0"><path
- d="m 120,97 c -3.86575,0 -7,3.13367 -7,7 0,3.86633 3.13425,7 7,7 3.86575,0 7,-3.13367 7,-7 0,-3.86633 -3.13425,-7 -7,-7"
- id="path5243-8"
- style="fill:url(#linearGradient5635);fill-opacity:1.0;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /></g><path
- d="m 202.35714,111 c 0,2.56402 2.07845,4.64286 4.64286,4.64286 2.5644,0 4.64285,-2.07884 4.64285,-4.64286 0,-2.56402 -2.07845,-4.64286 -4.64285,-4.64286 -2.56441,0 -4.64286,2.07884 -4.64286,4.64286"
- id="path5245-1"
- style="fill:#2a53cd;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" /><text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="217.52373"
- y="112.00085"
- id="text4177"
- sodipodi:linespacing="125%"
- transform="translate(-11.000005,-1.0000002)"><tspan
- sodipodi:role="line"
- id="tspan4179" /></text>
-
-
-<text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient5627);fill-opacity:1;stroke:none;font-family:Sans"
- x="206.81799"
- y="114.13864"
- id="text4181"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan4183"
- x="206.81799"
- y="114.13864"
- style="font-size:9px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr;text-anchor:middle;fill:#ffffff;fill-opacity:1;font-family:Serif;-inkscape-font-specification:Serif Bold">i</tspan></text>
-
-
-</g></svg> \ No newline at end of file
+ sodipodi:nodetypes="cccccccccc" /><rect
+ fill-opacity="0.49"
+ height="7"
+ transform="matrix(0.82509248,0.5649977,-0.5649977,0.82509248,0,0)"
+ width="1"
+ x="150.2782"
+ y="-94.72863"
+ id="rect3769" /><rect
+ fill-opacity="0.49"
+ height="3"
+ transform="matrix(0.82909395,0.55910931,-0.55910931,0.82909395,0,0)"
+ width="1"
+ x="148.78542"
+ y="-92.539734"
+ id="rect3771" /></svg> \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
new file mode 100644
index 00000000000..272e8468bf9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -0,0 +1,7 @@
+{
+ "statusbarButtonGlyphs.svg": "3f642dca97434b4cbb6491e2854dc69f",
+ "breakpoint.svg": "69cd92d807259c022791112809b97799",
+ "responsiveDesign.svg": "bc00a0a7fb0a47453929f94c9a4e003c",
+ "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485",
+ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28"
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs.png
index c58a9c5c84c..5472776255d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs.png
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs2x.png
deleted file mode 100644
index ad4a5b28ea8..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs2x.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs_2x.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs_2x.png
new file mode 100644
index 00000000000..ede1c30bd00
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Images/statusbarButtonGlyphs_2x.png
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillBlue.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillBlue.png
deleted file mode 100644
index ed68e459bf4..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillBlue.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGray.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGray.png
deleted file mode 100644
index 12a66620463..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGray.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGreen.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGreen.png
deleted file mode 100644
index 7b31b9e30c9..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillGreen.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillOrange.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillOrange.png
deleted file mode 100644
index b76928edea3..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillOrange.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillPurple.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillPurple.png
deleted file mode 100644
index ce564009619..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillPurple.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillRed.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillRed.png
deleted file mode 100644
index 5cc45b802bb..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillRed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillYellow.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillYellow.png
deleted file mode 100644
index b62f774e956..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelineHollowPillYellow.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillBlue.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillBlue.png
deleted file mode 100644
index ad4821d333a..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillBlue.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGray.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGray.png
deleted file mode 100644
index 4b4d1825479..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGray.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGreen.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGreen.png
deleted file mode 100644
index e6a62a862ed..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillGreen.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillOrange.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillOrange.png
deleted file mode 100644
index 76c9f56de57..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillOrange.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillPurple.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillPurple.png
deleted file mode 100644
index b82cbd8b3b0..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillPurple.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillRed.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillRed.png
deleted file mode 100644
index d8359fd6d28..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillRed.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillYellow.png b/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillYellow.png
deleted file mode 100644
index a5e0d8f9bfb..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Images/timelinePillYellow.png
+++ /dev/null
Binary files differ
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorBackend.js b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorBackend.js
deleted file mode 100644
index 98f24b933fb..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorBackend.js
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- */
-function InspectorBackendClass()
-{
- this._lastCallbackId = 1;
- this._pendingResponsesCount = 0;
- this._callbacks = {};
- this._domainDispatchers = {};
- this._eventArgs = {};
- this._replyArgs = {};
- this._hasErrorData = {};
-
- this.dumpInspectorTimeStats = false;
- this.dumpInspectorProtocolMessages = false;
- this._initialized = false;
-}
-
-InspectorBackendClass.prototype = {
- /**
- * @return {number}
- */
- nextCallbackId: function()
- {
- return this._lastCallbackId++;
- },
-
- _wrap: function(callback, method)
- {
- var callbackId = this.nextCallbackId();
- if (!callback)
- callback = function() {};
-
- this._callbacks[callbackId] = callback;
- callback.methodName = method;
- if (this.dumpInspectorTimeStats)
- callback.sendRequestTime = Date.now();
-
- return callbackId;
- },
-
- _getAgent: function(domain)
- {
- var agentName = domain + "Agent";
- if (!window[agentName])
- window[agentName] = {};
- return window[agentName];
- },
-
- registerCommand: function(method, signature, replyArgs, hasErrorData)
- {
- var domainAndMethod = method.split(".");
- var agent = this._getAgent(domainAndMethod[0]);
-
- agent[domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
- agent[domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
- this._replyArgs[method] = replyArgs;
- if (hasErrorData)
- this._hasErrorData[method] = true;
-
- this._initialized = true;
- },
-
- registerEnum: function(type, values)
- {
- var domainAndMethod = type.split(".");
- var agent = this._getAgent(domainAndMethod[0]);
-
- agent[domainAndMethod[1]] = values;
-
- this._initialized = true;
- },
-
- registerEvent: function(eventName, params)
- {
- this._eventArgs[eventName] = params;
-
- this._initialized = true;
- },
-
- _invoke: function(method, signature, args, callback)
- {
- this._wrapCallbackAndSendMessageObject(method, args, callback);
- },
-
- _sendMessageToBackend: function(method, signature, vararg)
- {
- var args = Array.prototype.slice.call(arguments, 2);
- var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;
-
- var params = {};
- var hasParams = false;
- for (var i = 0; i < signature.length; ++i) {
- var param = signature[i];
- var paramName = param["name"];
- var typeName = param["type"];
- var optionalFlag = param["optional"];
-
- if (!args.length && !optionalFlag) {
- console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
- return;
- }
-
- var value = args.shift();
- if (optionalFlag && typeof value === "undefined") {
- continue;
- }
-
- if (typeof value !== typeName) {
- console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
- return;
- }
-
- params[paramName] = value;
- hasParams = true;
- }
-
- if (args.length === 1 && !callback) {
- if (typeof args[0] !== "undefined") {
- console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
- return;
- }
- }
-
- this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
- },
-
- _wrapCallbackAndSendMessageObject: function(method, params, callback)
- {
- var messageObject = {};
- messageObject.method = method;
- if (params)
- messageObject.params = params;
- messageObject.id = this._wrap(callback, method);
-
- if (this.dumpInspectorProtocolMessages)
- console.log("frontend: " + JSON.stringify(messageObject));
-
- ++this._pendingResponsesCount;
- this.sendMessageObjectToBackend(messageObject);
- },
-
- sendMessageObjectToBackend: function(messageObject)
- {
- var message = JSON.stringify(messageObject);
- InspectorFrontendHost.sendMessageToBackend(message);
- },
-
- registerDomainDispatcher: function(domain, dispatcher)
- {
- this._domainDispatchers[domain] = dispatcher;
- },
-
- dispatch: function(message)
- {
- if (this.dumpInspectorProtocolMessages)
- console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
-
- var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
-
- if ("id" in messageObject) { // just a response for some request
- if (messageObject.error) {
- if (messageObject.error.code !== -32000)
- this.reportProtocolError(messageObject);
- }
-
- var callback = this._callbacks[messageObject.id];
- if (callback) {
- var argumentsArray = [ null ];
- if (messageObject.error) {
- argumentsArray[0] = messageObject.error.message;
- }
- if (this._hasErrorData[callback.methodName]) {
- argumentsArray.push(null);
- if (messageObject.error)
- argumentsArray[1] = messageObject.error.data;
- }
- if (messageObject.result) {
- var paramNames = this._replyArgs[callback.methodName];
- if (paramNames) {
- for (var i = 0; i < paramNames.length; ++i)
- argumentsArray.push(messageObject.result[paramNames[i]]);
- }
- }
-
- var processingStartTime;
- if (this.dumpInspectorTimeStats && callback.methodName)
- processingStartTime = Date.now();
-
- callback.apply(null, argumentsArray);
- --this._pendingResponsesCount;
- delete this._callbacks[messageObject.id];
-
- if (this.dumpInspectorTimeStats && callback.methodName)
- console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
- }
-
- if (this._scripts && !this._pendingResponsesCount)
- this.runAfterPendingDispatches();
-
- return;
- } else {
- var method = messageObject.method.split(".");
- var domainName = method[0];
- var functionName = method[1];
- if (!(domainName in this._domainDispatchers)) {
- console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
- return;
- }
- var dispatcher = this._domainDispatchers[domainName];
- if (!(functionName in dispatcher)) {
- console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
- return;
- }
-
- if (!this._eventArgs[messageObject.method]) {
- console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
- return;
- }
-
- var params = [];
- if (messageObject.params) {
- var paramNames = this._eventArgs[messageObject.method];
- for (var i = 0; i < paramNames.length; ++i)
- params.push(messageObject.params[paramNames[i]]);
- }
-
- var processingStartTime;
- if (this.dumpInspectorTimeStats)
- processingStartTime = Date.now();
-
- dispatcher[functionName].apply(dispatcher, params);
-
- if (this.dumpInspectorTimeStats)
- console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
- }
- },
-
- reportProtocolError: function(messageObject)
- {
- console.error("Request with id = " + messageObject.id + " failed. " + JSON.stringify(messageObject.error));
- },
-
- /**
- * @param {string=} script
- */
- runAfterPendingDispatches: function(script)
- {
- if (!this._scripts)
- this._scripts = [];
-
- if (script)
- this._scripts.push(script);
-
- if (!this._pendingResponsesCount) {
- var scripts = this._scripts;
- this._scripts = []
- for (var id = 0; id < scripts.length; ++id)
- scripts[id].call(this);
- }
- },
-
- loadFromJSONIfNeeded: function(jsonUrl)
- {
- if (this._initialized)
- return;
-
- var xhr = new XMLHttpRequest();
- xhr.open("GET", jsonUrl, false);
- xhr.send(null);
-
- var schema = JSON.parse(xhr.responseText);
- var code = InspectorBackendClass._generateCommands(schema);
- eval(code);
- }
-}
-
-/**
- * @param {*} schema
- * @return {string}
- */
-InspectorBackendClass._generateCommands = function(schema) {
- var jsTypes = { integer: "number", array: "object" };
- var rawTypes = {};
- var result = [];
-
- var domains = schema["domains"] || [];
- for (var i = 0; i < domains.length; ++i) {
- var domain = domains[i];
- for (var j = 0; domain.types && j < domain.types.length; ++j) {
- var type = domain.types[j];
- rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
- }
- }
-
- function toUpperCase(groupIndex, group0, group1)
- {
- return [group0, group1][groupIndex].toUpperCase();
- }
- function generateEnum(enumName, items)
- {
- var members = []
- for (var m = 0; m < items.length; ++m) {
- var value = items[m];
- var name = value.replace(/-(\w)/g, toUpperCase.bind(null, 1)).toTitleCase();
- name = name.replace(/HTML|XML|WML|API/ig, toUpperCase.bind(null, 0));
- members.push(name + ": \"" + value +"\"");
- }
- return "InspectorBackend.registerEnum(\"" + enumName + "\", {" + members.join(", ") + "});";
- }
-
- for (var i = 0; i < domains.length; ++i) {
- var domain = domains[i];
-
- var types = domain["types"] || [];
- for (var j = 0; j < types.length; ++j) {
- var type = types[j];
- if ((type["type"] === "string") && type["enum"])
- result.push(generateEnum(domain.domain + "." + type.id, type["enum"]));
- else if (type["type"] === "object") {
- var properties = type["properties"] || [];
- for (var k = 0; k < properties.length; ++k) {
- var property = properties[k];
- if ((property["type"] === "string") && property["enum"])
- result.push(generateEnum(domain.domain + "." + type.id + property["name"].toTitleCase(), property["enum"]));
- }
- }
- }
-
- var commands = domain["commands"] || [];
- for (var j = 0; j < commands.length; ++j) {
- var command = commands[j];
- var parameters = command["parameters"];
- var paramsText = [];
- for (var k = 0; parameters && k < parameters.length; ++k) {
- var parameter = parameters[k];
-
- var type;
- if (parameter.type)
- type = jsTypes[parameter.type] || parameter.type;
- else {
- var ref = parameter["$ref"];
- if (ref.indexOf(".") !== -1)
- type = rawTypes[ref];
- else
- type = rawTypes[domain.domain + "." + ref];
- }
-
- var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
- paramsText.push(text);
- }
-
- var returnsText = [];
- var returns = command["returns"] || [];
- for (var k = 0; k < returns.length; ++k) {
- var parameter = returns[k];
- returnsText.push("\"" + parameter.name + "\"");
- }
- var hasErrorData = String(Boolean(command.error));
- result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "], " + hasErrorData + ");");
- }
-
- for (var j = 0; domain.events && j < domain.events.length; ++j) {
- var event = domain.events[j];
- var paramsText = [];
- for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
- var parameter = event.parameters[k];
- paramsText.push("\"" + parameter.name + "\"");
- }
- result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
- }
-
- result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
- }
- return result.join("\n");
-}
-
-InspectorBackend = new InspectorBackendClass();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendAPI.js b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendAPI.js
index cecb3aeb3e2..28cc52455ed 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendAPI.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendAPI.js
@@ -37,14 +37,14 @@ var InspectorFrontendAPI = {
showConsole: function()
{
InspectorFrontendAPI._runOnceLoaded(function() {
- WebInspector.showPanel("console");
+ WebInspector.inspectorView.showPanel("console");
});
},
enterInspectElementMode: function()
{
InspectorFrontendAPI._runOnceLoaded(function() {
- WebInspector.showPanel("elements");
+ WebInspector.inspectorView.showPanel("elements");
if (WebInspector.inspectElementModeController)
WebInspector.inspectElementModeController.toggleSearch();
});
@@ -61,7 +61,7 @@ var InspectorFrontendAPI = {
InspectorFrontendAPI._runOnceLoaded(function() {
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
if (uiSourceCode) {
- WebInspector.showPanel("sources").showUISourceCode(uiSourceCode, lineNumber, columnNumber);
+ WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
return;
}
@@ -72,7 +72,7 @@ var InspectorFrontendAPI = {
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
if (uiSourceCode.url === url) {
- WebInspector.showPanel("sources").showUISourceCode(uiSourceCode, lineNumber, columnNumber);
+ WebInspector.Revealer.reveal(uiSourceCode.uiLocation(lineNumber, columnNumber));
WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, listener);
}
}
@@ -96,7 +96,7 @@ var InspectorFrontendAPI = {
loadTimelineFromURL: function(url)
{
InspectorFrontendAPI._runOnceLoaded(function() {
- /** @type {!WebInspector.TimelinePanel} */ (WebInspector.showPanel("timeline")).loadFromURL(url);
+ /** @type {!WebInspector.TimelinePanel} */ (WebInspector.inspectorView.showPanel("timeline")).loadFromURL(url);
});
},
@@ -108,20 +108,9 @@ var InspectorFrontendAPI = {
WebInspector.ContextMenu.setUseSoftMenu(useSoftMenu);
},
- // FIXME: remove this legacy support.
- setAttachedWindow: function(side)
- {
- },
-
- // FIXME: remove this legacy support.
- setDockSide: function(side)
- {
- WebInspector.dockController.setDockSide(side);
- },
-
dispatchMessage: function(messageObject)
{
- InspectorBackend.dispatch(messageObject);
+ InspectorBackend.connection().dispatch(messageObject);
},
// Callbacks to the methods called from within initialized front-end.
@@ -152,28 +141,63 @@ var InspectorFrontendAPI = {
WebInspector.isolatedFileSystemDispatcher.fileSystemAdded(errorMessage, fileSystem);
},
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {number} totalWork
+ */
indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork)
{
- var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
- projectDelegate.indexingTotalWorkCalculated(requestId, totalWork);
+ WebInspector.fileSystemWorkspaceBinding.indexingTotalWorkCalculated(requestId, fileSystemPath, totalWork);
},
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {number} worked
+ */
indexingWorked: function(requestId, fileSystemPath, worked)
{
- var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
- projectDelegate.indexingWorked(requestId, worked);
+ WebInspector.fileSystemWorkspaceBinding.indexingWorked(requestId, fileSystemPath, worked);
},
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ */
indexingDone: function(requestId, fileSystemPath)
{
- var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
- projectDelegate.indexingDone(requestId);
+ WebInspector.fileSystemWorkspaceBinding.indexingDone(requestId, fileSystemPath);
},
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {!Array.<string>} files
+ */
searchCompleted: function(requestId, fileSystemPath, files)
{
- var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
- projectDelegate.searchCompleted(requestId, files);
+ WebInspector.fileSystemWorkspaceBinding.searchCompleted(requestId, fileSystemPath, files);
+ },
+
+ /**
+ * @param {!InspectorFrontendAPI.ForwardedKeyboardEvent} event
+ */
+ keyEventUnhandled: function(event)
+ {
+ InspectorFrontendAPI._runOnceLoaded(function() {
+ WebInspector.forwardedEventHandler.keyEventReceived(event.type, event.keyIdentifier, event.keyCode, event.modifiers);
+ });
+ },
+
+ /**
+ * @param {string} eventType
+ * @param {*=} eventData
+ * @return {boolean}
+ */
+ dispatchEventToListeners: function(eventType, eventData)
+ {
+ return WebInspector.inspectorFrontendEventSink.dispatchEventToListeners(eventType, eventData);
},
/**
@@ -222,39 +246,9 @@ var InspectorFrontendAPI = {
window.opener.postMessage(["loadCompleted"], "*");
},
- /**
- * @param {!Object} queryParamsObject
- */
- dispatchQueryParameters: function(queryParamsObject)
- {
- if ("dispatch" in queryParamsObject)
- InspectorFrontendAPI._dispatch(JSON.parse(window.decodeURI(queryParamsObject["dispatch"])));
- },
-
- // Testing harness support
- //////////////////////////
-
- evaluateForTest: function(callId, script)
- {
- WebInspector.evaluateForTestInFrontend(callId, script);
- },
-
- dispatchMessageAsync: function(messageObject)
- {
- WebInspector.dispatch(messageObject);
- },
-
// Implementation details
/////////////////////////
- _dispatch: function(signature)
- {
- InspectorFrontendAPI._runOnceLoaded(function() {
- var methodName = signature.shift();
- return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
- });
- },
-
/**
* @param {function()} command
*/
@@ -268,11 +262,5 @@ var InspectorFrontendAPI = {
}
}
-function onMessageFromOpener(event)
-{
- if (event.source === window.opener)
- InspectorFrontendAPI._dispatch(event.data);
-}
-
-if (window.opener && window.dispatchStandaloneTestRunnerMessages)
- window.addEventListener("message", onMessageFromOpener, true);
+/** @typedef {!Object.<{type: string, keyCode: (number|undefined), keyIdentifier: (string|undefined), modifiers: (number|undefined)}>} */
+InspectorFrontendAPI.ForwardedKeyboardEvent;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendEventSink.js b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendEventSink.js
new file mode 100644
index 00000000000..ccea57dcfb3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendEventSink.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.InspectorFrontendEventSink = function() {
+}
+
+WebInspector.InspectorFrontendEventSink.prototype = {
+ /**
+ * @param {string} eventType
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ addEventListener: function(eventType, listener, thisObject)
+ {
+ if (!this.hasEventListeners(eventType))
+ InspectorFrontendHost.subscribe(eventType);
+
+ WebInspector.Object.prototype.addEventListener.call(this, eventType, listener, thisObject);
+ },
+
+ /**
+ * @param {string} eventType
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ removeEventListener: function(eventType, listener, thisObject)
+ {
+ WebInspector.Object.prototype.removeEventListener.call(this, eventType, listener, thisObject);
+
+ if (!this.hasEventListeners(eventType))
+ InspectorFrontendHost.unsubscribe(eventType);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}; \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendHostStub.js b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendHostStub.js
index 5d1fe38f531..eae1418bff2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendHostStub.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/InspectorFrontendHostStub.js
@@ -29,27 +29,6 @@
*/
/**
- * @param {string} methodName
- */
-function dispatchMethodByName(methodName)
-{
- var callId = ++lastCallId;
- var argsArray = Array.prototype.slice.call(arguments, 1);
- var callback = argsArray[argsArray.length - 1];
- if (typeof callback === "function") {
- argsArray.pop();
- InspectorFrontendHost._callbacks[callId] = callback;
- }
-
- var message = { "id": callId, "method": methodName };
- if (argsArray.length)
- message.params = argsArray;
- InspectorFrontendHost.sendMessageToEmbedder(JSON.stringify(message));
-}
-
-if (!window.InspectorFrontendHost) {
-
-/**
* @constructor
* @implements {InspectorFrontendHostAPI}
*/
@@ -59,16 +38,25 @@ WebInspector.InspectorFrontendHostStub = function()
}
WebInspector.InspectorFrontendHostStub.prototype = {
+ /**
+ * @return {string}
+ */
getSelectionBackgroundColor: function()
{
return "#6e86ff";
},
+ /**
+ * @return {string}
+ */
getSelectionForegroundColor: function()
{
return "#ffffff";
},
+ /**
+ * @return {string}
+ */
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
@@ -80,6 +68,9 @@ WebInspector.InspectorFrontendHostStub.prototype = {
return "linux";
},
+ /**
+ * @return {string}
+ */
port: function()
{
return "unknown";
@@ -95,47 +86,48 @@ WebInspector.InspectorFrontendHostStub.prototype = {
this._windowVisible = false;
},
- requestSetDockSide: function(side)
+ setIsDocked: function(isDocked, callback)
{
- InspectorFrontendAPI.setDockSide(side);
},
/**
- * Requests inspected page to be placed atop of the inspector frontend
- * with passed insets from the frontend sides.
- * @param {number} top
- * @param {number} left
- * @param {number} bottom
- * @param {number} right
+ * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
+ * @param {{x: number, y: number, width: number, height: number}} bounds
*/
- setContentsInsets: function(top, left, bottom, right)
+ setInspectedPageBounds: function(bounds)
{
},
- moveWindowBy: function(x, y)
+ /**
+ * Requests inspected page to be placed atop of the inspector frontend
+ * with passed insets from the frontend sides, respecting minimum size passed.
+ * @param {{top: number, left: number, right: number, bottom: number}} insets
+ * @param {{width: number, height: number}} minSize
+ */
+ setContentsResizingStrategy: function(insets, minSize)
{
},
- setInjectedScriptForOrigin: function(origin, script)
+ inspectElementCompleted: function()
{
},
- loaded: function()
+ moveWindowBy: function(x, y)
{
},
- localizedStringsURL: function()
+ setInjectedScriptForOrigin: function(origin, script)
{
},
inspectedURLChanged: function(url)
{
- document.title = WebInspector.UIString(Preferences.applicationTitle, url);
+ document.title = WebInspector.UIString("Developer Tools - %s", url);
},
copyText: function(text)
{
- WebInspector.log("Clipboard is not enabled in hosted mode. Please inspect using chrome://inspect", WebInspector.ConsoleMessage.MessageLevel.Error, true);
+ WebInspector.messageSink.addErrorMessage("Clipboard is not enabled in hosted mode. Please inspect using chrome://inspect", true);
},
openInNewTab: function(url)
@@ -145,17 +137,13 @@ WebInspector.InspectorFrontendHostStub.prototype = {
save: function(url, content, forceSaveAs)
{
- WebInspector.log("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect", WebInspector.ConsoleMessage.MessageLevel.Error, true);
+ WebInspector.messageSink.addErrorMessage("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect", true);
WebInspector.fileManager.canceledSaveURL(url);
},
append: function(url, content)
{
- WebInspector.log("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect", WebInspector.ConsoleMessage.MessageLevel.Error, true);
- },
-
- close: function(url)
- {
+ WebInspector.messageSink.addErrorMessage("Saving files is not enabled in hosted mode. Please inspect using chrome://inspect", true);
},
sendMessageToBackend: function(message)
@@ -174,15 +162,6 @@ WebInspector.InspectorFrontendHostStub.prototype = {
{
},
- recordSettingChanged: function(settingCode)
- {
- },
-
- supportsFileSystems: function()
- {
- return false;
- },
-
requestFileSystems: function()
{
},
@@ -195,6 +174,11 @@ WebInspector.InspectorFrontendHostStub.prototype = {
{
},
+ /**
+ * @param {string} fileSystemId
+ * @param {string} registeredName
+ * @return {?WebInspector.IsolatedFileSystem}
+ */
isolatedFileSystem: function(fileSystemId, registeredName)
{
return null;
@@ -220,67 +204,74 @@ WebInspector.InspectorFrontendHostStub.prototype = {
{
},
+ /**
+ * @return {number}
+ */
+ zoomFactor: function()
+ {
+ return 1;
+ },
+
+ zoomIn: function()
+ {
+ },
+
+ zoomOut: function()
+ {
+ },
+
+ resetZoom: function()
+ {
+ },
+
+ setWhitelistedShortcuts: function(shortcuts)
+ {
+ },
+
+ /**
+ * @return {boolean}
+ */
isUnderTest: function()
{
return false;
- }
-}
+ },
-InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
+ /**
+ * @param {string} browserId
+ * @param {string} url
+ */
+ openUrlOnRemoteDeviceAndInspect: function(browserId, url)
+ {
+ },
-} else if (InspectorFrontendHost.sendMessageToEmbedder) {
- // Install message-based handlers with callbacks.
- var lastCallId = 0;
- InspectorFrontendHost._callbacks = [];
+ /**
+ * @param {string} eventType
+ */
+ subscribe: function(eventType)
+ {
+ },
/**
- * @param {number} id
- * @param {?string} error
+ * @param {string} eventType
*/
- InspectorFrontendHost.embedderMessageAck = function(id, error)
+ unsubscribe: function(eventType)
{
- var callback = InspectorFrontendHost._callbacks[id];
- delete InspectorFrontendHost._callbacks[id];
- if (callback)
- callback(error);
}
-
- var methodList = [
- "addFileSystem",
- "append",
- "bringToFront",
- "closeWindow",
- "indexPath",
- "moveWindowBy",
- "openInNewTab",
- "removeFileSystem",
- "requestFileSystems",
- "requestSetDockSide",
- "save",
- "searchInPath",
- "setContentsInsets",
- "stopIndexing"
- ];
-
- for (var i = 0; i < methodList.length; ++i)
- InspectorFrontendHost[methodList[i]] = dispatchMethodByName.bind(null, methodList[i]);
}
-/**
- * @constructor
- * @extends {WebInspector.HelpScreen}
- */
-WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
-{
- WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target"));
- var p = this.contentElement.createChild("p");
- p.classList.add("help-section");
- p.createChild("span").textContent = "Remote debugging has been terminated with reason: ";
- p.createChild("span", "error-message").textContent = reason;
- p.createChild("br");
- p.createChild("span").textContent = "Please re-attach to the new target.";
-}
-
-WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
- __proto__: WebInspector.HelpScreen.prototype
+if (!window.InspectorFrontendHost) {
+ InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
+} else {
+ var proto = WebInspector.InspectorFrontendHostStub.prototype;
+ for (var name in proto) {
+ var value = proto[name];
+ if (typeof value !== "function" || InspectorFrontendHost[name])
+ continue;
+ InspectorFrontendHost[name] = function(name) {
+ var message = "Incompatible embedder: method InspectorFrontendHost." + name + " is missing. Using stub instead.";
+ WebInspector.messageSink.addErrorMessage(message, true);
+ var args = Array.prototype.slice.call(arguments, 1);
+ return proto[name].apply(InspectorFrontendHost, args);
+ }.bind(null, name);
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LayerTreeModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/LayerTreeModel.js
deleted file mode 100644
index f28b7802df7..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LayerTreeModel.js
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.LayerTreeModel = function()
-{
- WebInspector.Object.call(this);
- this._layersById = {};
- // We fetch layer tree lazily and get paint events asynchronously, so keep the last painted
- // rect separate from layer so we can get it after refreshing the tree.
- this._lastPaintRectByLayerId = {};
- InspectorBackend.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._onDocumentUpdated, this);
-}
-
-WebInspector.LayerTreeModel.Events = {
- LayerTreeChanged: "LayerTreeChanged",
- LayerPainted: "LayerPainted",
-}
-
-/**
- * @param {function(T)} clientCallback
- * @param {string} errorPrefix
- * @param {function(new:T,S)=} constructor
- * @param {T=} defaultValue
- * @return {function(?string, S)}
- * @template T,S
- */
-WebInspector.LayerTreeModel._wrapCallback = function(clientCallback, errorPrefix, constructor, defaultValue)
-{
- /**
- * @param {?string} error
- * @param {S} value
- * @template S
- */
- function callbackWrapper(error, value)
- {
- if (error) {
- console.error(errorPrefix + error);
- clientCallback(defaultValue);
- return;
- }
- if (constructor)
- clientCallback(new constructor(value));
- else
- clientCallback(value);
- }
- return callbackWrapper;
-}
-
-WebInspector.LayerTreeModel.prototype = {
- disable: function()
- {
- if (!this._enabled)
- return;
- this._enabled = false;
- LayerTreeAgent.disable();
- },
-
- /**
- * @param {function()=} callback
- */
- enable: function(callback)
- {
- if (this._enabled)
- return;
- this._enabled = true;
- WebInspector.domAgent.requestDocument(onDocumentAvailable.bind(this));
-
- /**
- * @this {WebInspector.LayerTreeModel}
- */
- function onDocumentAvailable()
- {
- // The agent might have been disabled while we were waiting for the document.
- if (!this._enabled)
- return;
- LayerTreeAgent.enable();
- }
- },
-
- /**
- * @return {?WebInspector.Layer}
- */
- root: function()
- {
- return this._root;
- },
-
- /**
- * @return {?WebInspector.Layer}
- */
- contentRoot: function()
- {
- return this._contentRoot;
- },
-
- /**
- * @param {function(!WebInspector.Layer)} callback
- * @param {?WebInspector.Layer} root
- * @return {boolean}
- */
- forEachLayer: function(callback, root)
- {
- if (!root) {
- root = this.root();
- if (!root)
- return false;
- }
- return callback(root) || root.children().some(this.forEachLayer.bind(this, callback));
- },
-
- /**
- * @param {string} id
- * @return {?WebInspector.Layer}
- */
- layerById: function(id)
- {
- return this._layersById[id] || null;
- },
-
- /**
- * @param {!Array.<!LayerTreeAgent.Layer>} payload
- */
- _repopulate: function(payload)
- {
- var oldLayersById = this._layersById;
- this._layersById = {};
- for (var i = 0; i < payload.length; ++i) {
- var layerId = payload[i].layerId;
- var layer = oldLayersById[layerId];
- if (layer)
- layer._reset(payload[i]);
- else
- layer = new WebInspector.Layer(payload[i]);
- this._layersById[layerId] = layer;
- var parentId = layer.parentId();
- if (!this._contentRoot && layer.nodeId())
- this._contentRoot = layer;
- var lastPaintRect = this._lastPaintRectByLayerId[layerId];
- if (lastPaintRect)
- layer._lastPaintRect = lastPaintRect;
- if (parentId) {
- var parent = this._layersById[parentId];
- if (!parent)
- console.assert(parent, "missing parent " + parentId + " for layer " + layerId);
- parent.addChild(layer);
- } else {
- if (this._root)
- console.assert(false, "Multiple root layers");
- this._root = layer;
- }
- }
- this._lastPaintRectByLayerId = {};
- },
-
- /**
- * @param {!Array.<!LayerTreeAgent.Layer>=} payload
- */
- _layerTreeChanged: function(payload)
- {
- this._root = null;
- this._contentRoot = null;
- // Payload will be null when not in the composited mode.
- if (payload)
- this._repopulate(payload);
- this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
- },
-
- /**
- * @param {!LayerTreeAgent.LayerId} layerId
- * @param {!DOMAgent.Rect} clipRect
- */
- _layerPainted: function(layerId, clipRect)
- {
- var layer = this._layersById[layerId];
- if (!layer) {
- this._lastPaintRectByLayerId[layerId] = clipRect;
- return;
- }
- layer._didPaint(clipRect);
- this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted, layer);
- },
-
- _onDocumentUpdated: function()
- {
- this.disable();
- this.enable();
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {!LayerTreeAgent.Layer} layerPayload
- */
-WebInspector.Layer = function(layerPayload)
-{
- this._reset(layerPayload);
-}
-
-WebInspector.Layer.prototype = {
- /**
- * @return {string}
- */
- id: function()
- {
- return this._layerPayload.layerId;
- },
-
- /**
- * @return {string}
- */
- parentId: function()
- {
- return this._layerPayload.parentLayerId;
- },
-
- /**
- * @return {!WebInspector.Layer}
- */
- parent: function()
- {
- return this._parent;
- },
-
- /**
- * @return {boolean}
- */
- isRoot: function()
- {
- return !this.parentId();
- },
-
- /**
- * @return {!Array.<!WebInspector.Layer>}
- */
- children: function()
- {
- return this._children;
- },
-
- /**
- * @param {!WebInspector.Layer} child
- */
- addChild: function(child)
- {
- if (child._parent)
- console.assert(false, "Child already has a parent");
- this._children.push(child);
- child._parent = this;
- },
-
- /**
- * @return {?DOMAgent.NodeId}
- */
- nodeId: function()
- {
- return this._layerPayload.nodeId;
- },
-
- /**
- * @return {?DOMAgent.NodeId}
- */
- nodeIdForSelfOrAncestor: function()
- {
- for (var layer = this; layer; layer = layer._parent) {
- var nodeId = layer._layerPayload.nodeId;
- if (nodeId)
- return nodeId;
- }
- return null;
- },
-
- /**
- * @return {number}
- */
- offsetX: function()
- {
- return this._layerPayload.offsetX;
- },
-
- /**
- * @return {number}
- */
- offsetY: function()
- {
- return this._layerPayload.offsetY;
- },
-
- /**
- * @return {number}
- */
- width: function()
- {
- return this._layerPayload.width;
- },
-
- /**
- * @return {number}
- */
- height: function()
- {
- return this._layerPayload.height;
- },
-
- /**
- * @return {!Array.<number>}
- */
- transform: function()
- {
- return this._layerPayload.transform;
- },
-
- /**
- * @return {!Array.<number>}
- */
- anchorPoint: function()
- {
- return [
- this._layerPayload.anchorX || 0,
- this._layerPayload.anchorY || 0,
- this._layerPayload.anchorZ || 0,
- ];
- },
-
- /**
- * @return {boolean}
- */
- invisible: function()
- {
- return this._layerPayload.invisible;
- },
-
- /**
- * @return {number}
- */
- paintCount: function()
- {
- return this._paintCount || this._layerPayload.paintCount;
- },
-
- /**
- * @return {?DOMAgent.Rect}
- */
- lastPaintRect: function()
- {
- return this._lastPaintRect;
- },
-
- /**
- * @param {function(!Array.<string>)} callback
- */
- requestCompositingReasons: function(callback)
- {
- var wrappedCallback = WebInspector.LayerTreeModel._wrapCallback(callback, "LayerTreeAgent.reasonsForCompositingLayer(): ", undefined, []);
- LayerTreeAgent.compositingReasons(this.id(), wrappedCallback);
- },
-
- /**
- * @param {function(!WebInspector.LayerSnapshot=)} callback
- */
- requestSnapshot: function(callback)
- {
- var wrappedCallback = WebInspector.LayerTreeModel._wrapCallback(callback, "LayerTreeAgent.makeSnapshot(): ", WebInspector.LayerSnapshot.bind(null, this));
- LayerTreeAgent.makeSnapshot(this.id(), wrappedCallback);
- },
-
- /**
- * @param {!DOMAgent.Rect} rect
- */
- _didPaint: function(rect)
- {
- this._lastPaintRect = rect;
- this._paintCount = this.paintCount() + 1;
- this._image = null;
- },
-
- /**
- * @param {!LayerTreeAgent.Layer} layerPayload
- */
- _reset: function(layerPayload)
- {
- this._children = [];
- this._parent = null;
- this._paintCount = 0;
- this._layerPayload = layerPayload;
- this._image = null;
- }
-}
-
-/**
- * @constructor
- * @param {!WebInspector.Layer} layer
- * @param {string} snapshotId
- */
-WebInspector.LayerSnapshot = function(layer, snapshotId)
-{
- this._id = snapshotId;
- this._layer = layer;
-}
-
-WebInspector.LayerSnapshot.prototype = {
- dispose: function()
- {
- LayerTreeAgent.releaseSnapshot(this._id);
- },
-
- /**
- * @param {?number} firstStep
- * @param {?number} lastStep
- * @param {function(string=)} callback
- */
- requestImage: function(firstStep, lastStep, callback)
- {
- var wrappedCallback = WebInspector.LayerTreeModel._wrapCallback(callback, "LayerTreeAgent.replaySnapshot(): ");
- LayerTreeAgent.replaySnapshot(this._id, firstStep || undefined, lastStep || undefined, wrappedCallback);
- },
-
- /**
- * @param {function(!Array.<!LayerTreeAgent.PaintProfile>=)} callback
- */
- profile: function(callback)
- {
- var wrappedCallback = WebInspector.LayerTreeModel._wrapCallback(callback, "LayerTreeAgent.profileSnapshot(): ");
- LayerTreeAgent.profileSnapshot(this._id, 5, 1, wrappedCallback);
- }
-};
-
-/**
- * @constructor
- * @implements {LayerTreeAgent.Dispatcher}
- * @param {!WebInspector.LayerTreeModel} layerTreeModel
- */
-WebInspector.LayerTreeDispatcher = function(layerTreeModel)
-{
- this._layerTreeModel = layerTreeModel;
-}
-
-WebInspector.LayerTreeDispatcher.prototype = {
- /**
- * @param {!Array.<!LayerTreeAgent.Layer>=} payload
- */
- layerTreeDidChange: function(payload)
- {
- this._layerTreeModel._layerTreeChanged(payload);
- },
-
- /**
- * @param {!LayerTreeAgent.LayerId} layerId
- * @param {!DOMAgent.Rect} clipRect
- */
- layerPainted: function(layerId, clipRect)
- {
- this._layerTreeModel._layerPainted(layerId, clipRect);
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Layers3DView.js b/chromium/third_party/WebKit/Source/devtools/front_end/Layers3DView.js
deleted file mode 100644
index 59daf31a709..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Layers3DView.js
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {!WebInspector.LayerTreeModel} model
- */
-WebInspector.Layers3DView = function(model)
-{
- WebInspector.View.call(this);
- this.element.classList.add("fill");
- this.element.classList.add("layers-3d-view");
- this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in the composited mode.\nConsider forcing composited mode in Settings."));
- this._model = model;
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update, this);
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
- this._rotatingContainerElement = this.element.createChild("div", "fill rotating-container");
- this.element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
- this.element.addEventListener("mouseout", this._onMouseMove.bind(this), false);
- this.element.addEventListener("mousedown", this._onMouseDown.bind(this), false);
- this.element.addEventListener("mouseup", this._onMouseUp.bind(this), false);
- this.element.addEventListener("contextmenu", this._onContextMenu.bind(this), false);
- this.element.addEventListener("dblclick", this._onDoubleClick.bind(this), false);
- this.element.addEventListener("click", this._onClick.bind(this), false);
- this._elementsByLayerId = {};
- this._rotateX = 0;
- this._rotateY = 0;
- this._scaleAdjustmentStylesheet = this.element.ownerDocument.head.createChild("style");
- this._scaleAdjustmentStylesheet.disabled = true;
- this._lastOutlinedElement = {};
- this._layerImage = document.createElement("img");
- WebInspector.settings.showPaintRects.addChangeListener(this._update, this);
-}
-
-/**
- * @enum {string}
- */
-WebInspector.Layers3DView.OutlineType = {
- Hovered: "hovered",
- Selected: "selected"
-}
-
-/**
- * @enum {string}
- */
-WebInspector.Layers3DView.Events = {
- LayerHovered: "LayerHovered",
- LayerSelected: "LayerSelected",
- LayerSnapshotRequested: "LayerSnapshotRequested"
-}
-
-WebInspector.Layers3DView.PaintRectColors = [
- WebInspector.Color.fromRGBA([0xFF, 0, 0]),
- WebInspector.Color.fromRGBA([0xFF, 0, 0xFF]),
- WebInspector.Color.fromRGBA([0, 0, 0xFF])
-]
-
-WebInspector.Layers3DView.prototype = {
- onResize: function()
- {
- this._update();
- },
-
- willHide: function()
- {
- this._scaleAdjustmentStylesheet.disabled = true;
- },
-
- wasShown: function()
- {
- this._scaleAdjustmentStylesheet.disabled = false;
- if (this._needsUpdate)
- this._update();
- },
-
- /**
- * @param {!WebInspector.Layers3DView.OutlineType} type
- * @param {?WebInspector.Layer} layer
- */
- _setOutline: function(type, layer)
- {
- var element = layer ? this._elementForLayer(layer) : null;
- var previousElement = this._lastOutlinedElement[type];
- if (previousElement === element)
- return;
- this._lastOutlinedElement[type] = element;
- if (previousElement) {
- previousElement.classList.remove(type);
- this._updateElementColor(previousElement);
- }
- if (element) {
- element.classList.add(type);
- this._updateElementColor(element);
- }
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- hoverLayer: function(layer)
- {
- this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, layer);
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- selectLayer: function(layer)
- {
- this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
- this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, layer);
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @param {string=} imageURL
- */
- showImageForLayer: function(layer, imageURL)
- {
- var element = this._elementForLayer(layer);
- this._layerImage.removeAttribute("src");
- if (imageURL)
- this._layerImage.src = imageURL;
- element.appendChild(this._layerImage);
- },
-
- _scaleToFit: function()
- {
- var root = this._model.contentRoot();
- if (!root)
- return;
- const padding = 40;
- var scaleX = this._clientWidth / (root.width() + 2 * padding);
- var scaleY = this._clientHeight / (root.height() + 2 * padding);
- this._scale = Math.min(scaleX, scaleY);
-
- const screenLayerSpacing = 20;
- this._layerSpacing = Math.ceil(screenLayerSpacing / this._scale) + "px";
- const screenLayerThickness = 4;
- var layerThickness = Math.ceil(screenLayerThickness / this._scale) + "px";
- var stylesheetContent = ".layer-container .side-wall { height: " + layerThickness + "; width: " + layerThickness + "; } " +
- ".layer-container .back-wall { -webkit-transform: translateZ(-" + layerThickness + "); } " +
- ".layer-container { -webkit-transform: translateZ(" + this._layerSpacing + "); }";
- // Workaround for double style recalculation upon assignment to style sheet's text content.
- var stylesheetTextNode = this._scaleAdjustmentStylesheet.firstChild;
- if (!stylesheetTextNode || stylesheetTextNode.nodeType !== Node.TEXT_NODE || stylesheetTextNode.nextSibling)
- this._scaleAdjustmentStylesheet.textContent = stylesheetContent;
- else
- stylesheetTextNode.nodeValue = stylesheetContent;
- var element = this._elementForLayer(root);
- element.style.webkitTransform = "scale3d(" + this._scale + "," + this._scale + "," + this._scale + ")";
- element.style.webkitTransformOrigin = "";
- element.style.left = ((this._clientWidth - root.width() * this._scale) >> 1) + "px";
- element.style.top = ((this._clientHeight - root.height() * this._scale) >> 1) + "px";
- },
-
- _update: function()
- {
- if (!this.isShowing()) {
- this._needsUpdate = true;
- return;
- }
- if (!this._model.contentRoot()) {
- this._emptyView.show(this.element);
- this._rotatingContainerElement.removeChildren();
- return;
- }
- this._emptyView.detach();
-
- /**
- * @this {WebInspector.Layers3DView}
- */
- function updateLayer(layer)
- {
- this._updateLayerElement(this._elementForLayer(layer));
- }
- this._clientWidth = this.element.clientWidth;
- this._clientHeight = this.element.clientHeight;
- for (var layerId in this._elementsByLayerId) {
- if (this._model.layerById(layerId))
- continue;
- this._elementsByLayerId[layerId].remove();
- delete this._elementsByLayerId[layerId];
- }
- this._scaleToFit();
- this._model.forEachLayer(updateLayer.bind(this), this._model.contentRoot());
- this._needsUpdate = false;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onLayerPainted: function(event)
- {
- var layer = /** @type {!WebInspector.Layer} */ (event.data);
- this._updatePaintRect(this._elementForLayer(layer));
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @return {!Element}
- */
- _elementForLayer: function(layer)
- {
- var element = this._elementsByLayerId[layer.id()];
- if (element) {
- // We might have missed an update were a layer with given id was gone and re-created,
- // so update reference to point to proper layer object.
- element.__layerDetails.layer = layer;
- return element;
- }
- element = document.createElement("div");
- element.className = "layer-container";
- ["fill back-wall", "side-wall top", "side-wall right", "side-wall bottom", "side-wall left"].forEach(element.createChild.bind(element, "div"));
- element.__layerDetails = new WebInspector.LayerDetails(layer, element.createChild("div", "paint-rect"));
- this._elementsByLayerId[layer.id()] = element;
- return element;
- },
-
- /**
- * @param {!Element} element
- */
- _updateLayerElement: function(element)
- {
- var layer = element.__layerDetails.layer;
- var style = element.style;
- var isContentRoot = layer === this._model.contentRoot();
- var parentElement = isContentRoot ? this._rotatingContainerElement : this._elementForLayer(layer.parent());
- element.__layerDetails.depth = parentElement.__layerDetails ? parentElement.__layerDetails.depth + 1 : 0;
- element.enableStyleClass("invisible", layer.invisible());
- this._updateElementColor(element);
- if (parentElement !== element.parentElement)
- parentElement.appendChild(element);
-
- style.width = layer.width() + "px";
- style.height = layer.height() + "px";
- this._updatePaintRect(element);
- if (isContentRoot)
- return;
-
- style.left = layer.offsetX() + "px";
- style.top = layer.offsetY() + "px";
- var transform = layer.transform();
- if (transform) {
- // Avoid exponential notation in CSS.
- style.webkitTransform = "matrix3d(" + transform.map(toFixed5).join(",") + ") translateZ(" + this._layerSpacing + ")";
- var anchor = layer.anchorPoint();
- style.webkitTransformOrigin = Math.round(anchor[0] * 100) + "% " + Math.round(anchor[1] * 100) + "% " + anchor[2];
- } else {
- style.webkitTransform = "";
- style.webkitTransformOrigin = "";
- }
-
- function toFixed5(x)
- {
- return x.toFixed(5);
- }
- },
-
- _updatePaintRect: function(element)
- {
- var details = element.__layerDetails;
- var paintRect = details.layer.lastPaintRect();
- var paintRectElement = details.paintRectElement;
- if (!paintRect || !WebInspector.settings.showPaintRects.get()) {
- paintRectElement.classList.add("hidden");
- return;
- }
- paintRectElement.classList.remove("hidden");
- if (details.paintCount === details.layer.paintCount())
- return;
- details.paintCount = details.layer.paintCount();
- var style = paintRectElement.style;
- style.left = paintRect.x + "px";
- style.top = paintRect.y + "px";
- style.width = paintRect.width + "px";
- style.height = paintRect.height + "px";
- var color = WebInspector.Layers3DView.PaintRectColors[details.paintCount % WebInspector.Layers3DView.PaintRectColors.length];
- style.borderWidth = Math.ceil(1 / this._scale) + "px";
- style.borderColor = color.toString(WebInspector.Color.Format.RGBA);
- },
-
- /**
- * @param {!Element} element
- */
- _updateElementColor: function(element)
- {
- var color;
- if (element === this._lastOutlinedElement[WebInspector.Layers3DView.OutlineType.Selected])
- color = WebInspector.Color.PageHighlight.Content.toString(WebInspector.Color.Format.RGBA) || "";
- else {
- const base = 144;
- var component = base + 20 * ((element.__layerDetails.depth - 1) % 5);
- color = "rgba(" + component + "," + component + "," + component + ", 0.8)";
- }
- element.style.backgroundColor = color;
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseDown: function(event)
- {
- if (event.which !== 1)
- return;
- this._setReferencePoint(event);
- },
-
- /**
- * @param {?Event} event
- */
- _setReferencePoint: function(event)
- {
- this._originX = event.clientX;
- this._originY = event.clientY;
- this._oldRotateX = this._rotateX;
- this._oldRotateY = this._rotateY;
- },
-
- _resetReferencePoint: function()
- {
- delete this._originX;
- delete this._originY;
- delete this._oldRotateX;
- delete this._oldRotateY;
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseUp: function(event)
- {
- if (event.which !== 1)
- return;
- this._resetReferencePoint();
- },
-
- /**
- * @param {?Event} event
- * @return {?WebInspector.Layer}
- */
- _layerFromEventPoint: function(event)
- {
- var element = this.element.ownerDocument.elementFromPoint(event.pageX, event.pageY);
- if (!element)
- return null;
- element = element.enclosingNodeOrSelfWithClass("layer-container");
- return element && element.__layerDetails && element.__layerDetails.layer;
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseMove: function(event)
- {
- if (!event.which) {
- this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerHovered, this._layerFromEventPoint(event));
- return;
- }
- if (event.which === 1) {
- // Set reference point if we missed mousedown.
- if (typeof this._originX !== "number")
- this._setReferencePoint(event);
- this._rotateX = this._oldRotateX + (this._originY - event.clientY) / 2;
- this._rotateY = this._oldRotateY - (this._originX - event.clientX) / 4;
- // Translate well to front so that no matter how we turn the plane, no parts of it goes below parent.
- // This makes sure mouse events go to proper layers, not straight to the parent.
- this._rotatingContainerElement.style.webkitTransform = "translateZ(10000px) rotateX(" + this._rotateX + "deg) rotateY(" + this._rotateY + "deg)";
- }
- },
-
- /**
- * @param {?Event} event
- */
- _onContextMenu: function(event)
- {
- var layer = this._layerFromEventPoint(event);
- var nodeId = layer && layer.nodeId();
- if (!nodeId)
- return;
- var domNode = WebInspector.domAgent.nodeForId(nodeId);
- if (!domNode)
- return;
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendApplicableItems(domNode);
- contextMenu.show();
- },
-
- /**
- * @param {?Event} event
- */
- _onClick: function(event)
- {
- this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSelected, this._layerFromEventPoint(event));
- },
-
- /**
- * @param {?Event} event
- */
- _onDoubleClick: function(event)
- {
- var layer = this._layerFromEventPoint(event);
- if (layer)
- this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSnapshotRequested, layer);
- event.stopPropagation();
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @constructor
- * @param {!WebInspector.Layer} layer
- * @param {!Element} paintRectElement
- */
-WebInspector.LayerDetails = function(layer, paintRectElement)
-{
- this.layer = layer;
- this.depth = 0;
- this.paintRectElement = paintRectElement;
- this.paintCount = 0;
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LayersPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/LayersPanel.js
deleted file mode 100644
index 51ac096009d..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LayersPanel.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-importScript("LayerTreeModel.js");
-importScript("LayerTree.js");
-importScript("Layers3DView.js");
-importScript("LayerDetailsView.js");
-importScript("PaintProfilerView.js");
-
-/**
- * @constructor
- * @extends {WebInspector.Panel}
- */
-WebInspector.LayersPanel = function()
-{
- WebInspector.Panel.call(this, "layers");
- this.registerRequiredCSS("layersPanel.css");
-
- const initialLayerTreeSidebarWidth = 225;
- const minimumMainWidthPercent = 0.5;
- this.createSidebarViewWithTree();
- this.sidebarElement.classList.add("outline-disclosure");
- this.sidebarTreeElement.classList.remove("sidebar-tree");
-
- this._model = new WebInspector.LayerTreeModel();
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
- this._currentlySelectedLayer = null;
- this._currentlyHoveredLayer = null;
-
- this._layerTree = new WebInspector.LayerTree(this._model, this.sidebarTree);
- this._layerTree.addEventListener(WebInspector.LayerTree.Events.LayerSelected, this._onLayerSelected, this);
- this._layerTree.addEventListener(WebInspector.LayerTree.Events.LayerHovered, this._onLayerHovered, this);
-
- this._rightSplitView = new WebInspector.SplitView(false, "layerDetailsSplitView");
- this._rightSplitView.show(this.splitView.mainElement);
-
- this._layers3DView = new WebInspector.Layers3DView(this._model);
- this._layers3DView.show(this._rightSplitView.firstElement());
- this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerSelected, this._onLayerSelected, this);
- this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerHovered, this._onLayerHovered, this);
- this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerSnapshotRequested, this._onSnapshotRequested, this);
-
- this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.element.classList.add("fill");
- this._tabbedPane.show(this._rightSplitView.secondElement());
-
- this._layerDetailsView = new WebInspector.LayerDetailsView(this._model);
- this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Details, WebInspector.UIString("Details"), this._layerDetailsView);
- this._paintProfilerView = new WebInspector.PaintProfilerView(this._model, this._layers3DView);
- this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler, WebInspector.UIString("Profiler"), this._paintProfilerView);
-}
-
-WebInspector.LayersPanel.DetailsViewTabs = {
- Details: "details",
- Profiler: "profiler"
-};
-
-WebInspector.LayersPanel.prototype = {
- wasShown: function()
- {
- WebInspector.Panel.prototype.wasShown.call(this);
- this.sidebarTreeElement.focus();
- this._model.enable();
- },
-
- willHide: function()
- {
- this._model.disable();
- WebInspector.Panel.prototype.willHide.call(this);
- },
-
- _onLayerTreeUpdated: function()
- {
- if (this._currentlySelectedLayer && !this._model.layerById(this._currentlySelectedLayer.id()))
- this._selectLayer(null);
- if (this._currentlyHoveredLayer && !this._model.layerById(this._currentlyHoveredLayer.id()))
- this._hoverLayer(null);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onLayerSelected: function(event)
- {
- var layer = /** @type {!WebInspector.Layer} */ (event.data);
- this._selectLayer(layer);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onLayerHovered: function(event)
- {
- var layer = /** @type WebInspector.Layer */ (event.data);
- this._hoverLayer(layer);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onSnapshotRequested: function(event)
- {
- var layer = /** @type {!WebInspector.Layer} */ (event.data);
- this._tabbedPane.selectTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler);
- this._paintProfilerView.profile(layer);
- },
-
- /**
- * @param {?WebInspector.Layer} layer
- */
- _selectLayer: function(layer)
- {
- if (this._currentlySelectedLayer === layer)
- return;
- this._currentlySelectedLayer = layer;
- var nodeId = layer && layer.nodeIdForSelfOrAncestor();
- if (nodeId)
- WebInspector.domAgent.highlightDOMNodeForTwoSeconds(nodeId);
- else
- WebInspector.domAgent.hideDOMNodeHighlight();
- this._layerTree.selectLayer(layer);
- this._layers3DView.selectLayer(layer);
- this._layerDetailsView.setLayer(layer);
- },
-
- /**
- * @param {?WebInspector.Layer} layer
- */
- _hoverLayer: function(layer)
- {
- if (this._currentlyHoveredLayer === layer)
- return;
- this._currentlyHoveredLayer = layer;
- var nodeId = layer && layer.nodeIdForSelfOrAncestor();
- if (nodeId)
- WebInspector.domAgent.highlightDOMNode(nodeId);
- else
- WebInspector.domAgent.hideDOMNodeHighlight();
- this._layerTree.hoverLayer(layer);
- this._layers3DView.hoverLayer(layer);
- },
-
- __proto__: WebInspector.Panel.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/MediaQueryInspector.js b/chromium/third_party/WebKit/Source/devtools/front_end/MediaQueryInspector.js
new file mode 100644
index 00000000000..bee25ee5c12
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/MediaQueryInspector.js
@@ -0,0 +1,371 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ */
+WebInspector.MediaQueryInspector = function()
+{
+ WebInspector.View.call(this);
+ this.element.classList.add("media-inspector-view");
+ this.element.addEventListener("click", this._onMediaQueryClicked.bind(this), false);
+ this.element.addEventListener("contextmenu", this._onContextMenu.bind(this), false);
+ this._mediaThrottler = new WebInspector.Throttler(100);
+ this._zeroOffset = 0;
+
+ this._rulerDecorationLayer = document.createElementWithClass("div", "fill");
+ this._rulerDecorationLayer.classList.add("media-inspector-ruler-decoration");
+ this._rulerDecorationLayer.addEventListener("click", this._onRulerDecorationClicked.bind(this), false);
+
+ WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._scheduleMediaQueriesUpdate, this);
+ WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._scheduleMediaQueriesUpdate, this);
+ WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._scheduleMediaQueriesUpdate, this);
+ WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._scheduleMediaQueriesUpdate, this);
+ WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._renderMediaQueries.bind(this), this);
+ this._scheduleMediaQueriesUpdate();
+}
+
+WebInspector.MediaQueryInspector.Events = {
+ HeightUpdated: "HeightUpdated"
+}
+
+WebInspector.MediaQueryInspector._ThresholdPadding = 1;
+
+WebInspector.MediaQueryInspector.prototype = {
+ /**
+ * @return {!Element}
+ */
+ rulerDecorationLayer: function()
+ {
+ return this._rulerDecorationLayer;
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ _mediaQueryThresholds: function()
+ {
+ if (!this._cachedQueryModels)
+ return [];
+ var thresholds = [];
+ for (var i = 0; i < this._cachedQueryModels.length; ++i) {
+ var model = this._cachedQueryModels[i];
+ if (model.minWidthExpression)
+ thresholds.push(model.minWidthExpression.computedLength());
+ if (model.maxWidthExpression)
+ thresholds.push(model.maxWidthExpression.computedLength());
+ }
+ thresholds.sortNumbers();
+ var filtered = [];
+ for (var i = 0; i < thresholds.length; ++i) {
+ if (i == 0 || thresholds[i] - filtered.peekLast() > WebInspector.MediaQueryInspector._ThresholdPadding)
+ filtered.push(thresholds[i]);
+ }
+ return filtered;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onRulerDecorationClicked: function(event)
+ {
+ var thresholdElement = event.target.enclosingNodeOrSelfWithClass("media-inspector-threshold-serif");
+ if (!thresholdElement)
+ return;
+ WebInspector.settings.showMediaQueryInspector.set(true);
+ var revealValue = thresholdElement._value;
+ for (var mediaQueryContainer = this.element.firstChild; mediaQueryContainer; mediaQueryContainer = mediaQueryContainer.nextSibling) {
+ var model = mediaQueryContainer._model;
+ if ((model.minWidthExpression && Math.abs(model.minWidthExpression.computedLength() - revealValue) <= WebInspector.MediaQueryInspector._ThresholdPadding)
+ || (model.maxWidthExpression && Math.abs(model.maxWidthExpression.computedLength() - revealValue) <= WebInspector.MediaQueryInspector._ThresholdPadding)) {
+ mediaQueryContainer.scrollIntoViewIfNeeded(false);
+ return;
+ }
+ }
+ },
+
+ /**
+ * @param {number} offset
+ */
+ translateZero: function(offset)
+ {
+ this._zeroOffset = offset;
+ this._renderMediaQueries();
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled)
+ {
+ this._enabled = enabled;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMediaQueryClicked: function(event)
+ {
+ var mediaQueryMarkerContainer = event.target.enclosingNodeOrSelfWithClass("media-inspector-marker-container");
+ if (!mediaQueryMarkerContainer)
+ return;
+ var model = mediaQueryMarkerContainer._model;
+ if (model.sectionNumber === 0) {
+ WebInspector.overridesSupport.settings.deviceWidth.set(model.maxWidthExpression.computedLength());
+ return;
+ }
+ if (model.sectionNumber === 2) {
+ WebInspector.overridesSupport.settings.deviceWidth.set(model.minWidthExpression.computedLength());
+ return;
+ }
+ var currentWidth = WebInspector.overridesSupport.settings.deviceWidth.get();
+ if (currentWidth !== model.minWidthExpression.computedLength())
+ WebInspector.overridesSupport.settings.deviceWidth.set(model.minWidthExpression.computedLength());
+ else
+ WebInspector.overridesSupport.settings.deviceWidth.set(model.maxWidthExpression.computedLength());
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onContextMenu: function(event)
+ {
+ var mediaQueryMarkerContainer = event.target.enclosingNodeOrSelfWithClass("media-inspector-marker-container");
+ if (!mediaQueryMarkerContainer)
+ return;
+
+ var model = mediaQueryMarkerContainer._model;
+ var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(model.sourceURL);
+ if (!uiSourceCode || typeof model.lineNumber !== "number" || typeof model.columnNumber !== "number")
+ return;
+
+ var contextMenu = new WebInspector.ContextMenu(event);
+ var location = uiSourceCode.uiLocation(model.lineNumber, model.columnNumber);
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in source code" : "Reveal In Source Code"), this._revealSourceLocation.bind(this, location));
+ contextMenu.show();
+ },
+
+ /**
+ * @param {!WebInspector.UILocation} location
+ */
+ _revealSourceLocation: function(location)
+ {
+ WebInspector.Revealer.reveal(location);
+ },
+
+ _scheduleMediaQueriesUpdate: function()
+ {
+ if (!this._enabled)
+ return;
+ this._mediaThrottler.schedule(this._refetchMediaQueries.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
+ */
+ _refetchMediaQueries: function(finishCallback)
+ {
+ if (!this._enabled) {
+ finishCallback();
+ return;
+ }
+
+ /**
+ * @param {!Array.<!WebInspector.CSSMedia>} cssMedias
+ * @this {!WebInspector.MediaQueryInspector}
+ */
+ function callback(cssMedias)
+ {
+ this._rebuildMediaQueries(cssMedias);
+ finishCallback();
+ }
+ WebInspector.cssModel.getMediaQueries(callback.bind(this));
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.CSSMedia>} cssMedias
+ */
+ _rebuildMediaQueries: function(cssMedias)
+ {
+ var queryModels = [];
+ for (var i = 0; i < cssMedias.length; ++i) {
+ var cssMedia = cssMedias[i];
+ if (!cssMedia.mediaList)
+ continue;
+ for (var j = 0; j < cssMedia.mediaList.length; ++j) {
+ var mediaQueryExpressions = cssMedia.mediaList[j];
+ var queryModel = this._mediaQueryToUIModel(cssMedia, mediaQueryExpressions);
+ if (queryModel)
+ queryModels.push(queryModel);
+ }
+ }
+ queryModels.sort(queryModelComparator);
+ this._cachedQueryModels = queryModels;
+ this._renderMediaQueries();
+
+ /**
+ * @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model1
+ * @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model2
+ * @return {number}
+ */
+ function queryModelComparator(model1, model2)
+ {
+ if (model1.sectionNumber !== model2.sectionNumber)
+ return model1.sectionNumber - model2.sectionNumber;
+ if (model1.sectionNumber === 0)
+ return model1.maxWidthExpression.computedLength() - model2.maxWidthExpression.computedLength();
+ if (model1.sectionNumber === 2)
+ return model1.minWidthExpression.computedLength() - model2.minWidthExpression.computedLength();
+ return model1.minWidthExpression.computedLength() - model2.minWidthExpression.computedLength() || model1.maxWidthExpression.computedLength() - model2.maxWidthExpression.computedLength();
+ }
+ },
+
+ _renderMediaQueries: function()
+ {
+ if (!this._cachedQueryModels)
+ return;
+ this._renderRulerDecorations();
+ if (!this.isShowing())
+ return;
+ var scrollTop = this.element.scrollTop;
+ var heightChanges = this.element.children.length !== this._cachedQueryModels.length;
+ this.element.removeChildren();
+ for (var i = 0; i < this._cachedQueryModels.length; ++i) {
+ var model = this._cachedQueryModels[i];
+ var bar = this._createElementFromMediaQueryModel(model);
+ bar._model = model;
+ this.element.appendChild(bar);
+ }
+ this.element.scrollTop = scrollTop;
+ this.element.classList.toggle("media-inspector-view-fixed-height", this._cachedQueryModels.length > 5);
+ if (heightChanges)
+ this.dispatchEventToListeners(WebInspector.MediaQueryInspector.Events.HeightUpdated);
+ },
+
+ _renderRulerDecorations: function()
+ {
+ this._rulerDecorationLayer.removeChildren();
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+
+ var thresholds = this._mediaQueryThresholds();
+ for (var i = 0; i < thresholds.length; ++i) {
+ var thresholdElement = this._rulerDecorationLayer.createChild("div", "media-inspector-threshold-serif");
+ thresholdElement._value = thresholds[i];
+ thresholdElement.style.left = thresholds[i] / zoomFactor + "px";
+ }
+ },
+
+ wasShown: function()
+ {
+ this._renderMediaQueries();
+ },
+
+ /**
+ * @param {!WebInspector.MediaQueryInspector.MediaQueryUIModel} model
+ * @return {!Element}
+ */
+ _createElementFromMediaQueryModel: function(model)
+ {
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var minWidthValue = model.minWidthExpression ? model.minWidthExpression.computedLength() : 0;
+
+ var container = document.createElementWithClass("div", "media-inspector-marker-container");
+ // Enforce container height if it does not have any children in normal flow.
+ if (model.sectionNumber === 0)
+ container.textContent = ".";
+ var markerElement = container.createChild("div", "media-inspector-marker");
+ const styleClassPerSection = [
+ "media-inspector-marker-max-width",
+ "media-inspector-marker-min-max-width",
+ "media-inspector-marker-min-width"
+ ];
+ markerElement.classList.add(styleClassPerSection[model.sectionNumber]);
+ markerElement.style.left = (minWidthValue ? minWidthValue / zoomFactor + this._zeroOffset : 0) + "px";
+ if (model.maxWidthExpression && model.minWidthExpression)
+ markerElement.style.width = (model.maxWidthExpression.computedLength() - minWidthValue) / zoomFactor + "px";
+ else if (model.maxWidthExpression)
+ markerElement.style.width = model.maxWidthExpression.computedLength() / zoomFactor + this._zeroOffset + "px";
+ else
+ markerElement.style.right = "0";
+
+ const minLabelOverlapMarkerValue = 4;
+ if (model.minWidthExpression) {
+ var minLabelContainer = container.createChild("div", "media-inspector-min-width-label-container");
+ minLabelContainer.style.maxWidth = markerElement.style.left;
+ minLabelContainer.textContent = ".";
+ var label = document.createElementWithClass("span", "media-inspector-marker-label");
+ label.classList.add("media-inspector-min-label");
+ label.textContent = model.minWidthExpression.computedLength() + "px";
+ label.style.right = -minLabelOverlapMarkerValue + "px";
+ minLabelContainer.appendChild(label);
+ }
+ // Image might not be loaded on the moment of label measuring. To avoid
+ // incorrect rendering, image size is hardcoded and label is measured without image.
+ const arrowImageWidth = 13;
+ const maxLabelOverlapMarkerValue = 2 / zoomFactor;
+ if (model.maxWidthExpression) {
+ var label = document.createElementWithClass("span", "media-inspector-marker-label");
+ label.textContent = model.maxWidthExpression.computedLength() + "px";
+ var labelSize = label.measurePreferredSize(this.element);
+ // Append arrow image to label.
+ label.classList.add("media-inspector-max-label");
+ label.style.right = -labelSize.width - arrowImageWidth - maxLabelOverlapMarkerValue + "px";
+ markerElement.appendChild(label);
+ }
+ return container;
+ },
+
+ /**
+ * @param {!WebInspector.CSSMedia} parentCSSMedia
+ * @param {!Array.<!WebInspector.CSSMediaQueryExpression>} mediaQueryExpressions
+ * @return {?WebInspector.MediaQueryInspector.MediaQueryUIModel}
+ */
+ _mediaQueryToUIModel: function(parentCSSMedia, mediaQueryExpressions)
+ {
+ var maxWidthExpression = null;
+ var maxWidthPixels = Number.MAX_VALUE;
+ var minWidthExpression = null;
+ var minWidthPixels = Number.MIN_VALUE;
+ for (var i = 0; i < mediaQueryExpressions.length; ++i) {
+ var expression = mediaQueryExpressions[i];
+ var feature = expression.feature();
+ if (feature.indexOf("width") === -1)
+ continue;
+ var pixels = expression.computedLength();
+ if (feature.startsWith("max-") && pixels < maxWidthPixels) {
+ maxWidthExpression = expression;
+ maxWidthPixels = pixels;
+ } else if (feature.startsWith("min-") && pixels > minWidthPixels) {
+ minWidthExpression = expression;
+ minWidthPixels = pixels;
+ }
+ }
+ if (minWidthPixels > maxWidthPixels || (!maxWidthExpression && !minWidthExpression))
+ return null;
+
+ var sectionNumber;
+ if (maxWidthExpression && !minWidthExpression)
+ sectionNumber = 0;
+ else if (minWidthExpression && maxWidthExpression)
+ sectionNumber = 1;
+ else
+ sectionNumber = 2;
+
+ return {
+ sectionNumber: sectionNumber,
+ mediaText: parentCSSMedia.text,
+ sourceURL: parentCSSMedia.sourceURL,
+ lineNumber: parentCSSMedia.lineNumberInSource(),
+ columnNumber: parentCSSMedia.columnNumberInSource(),
+ minWidthExpression: minWidthExpression,
+ maxWidthExpression: maxWidthExpression
+ };
+ },
+
+ __proto__: WebInspector.View.prototype
+};
+
+/** @typedef {{sectionNumber: number, mediaText: string, sourceURL: string, lineNumber: (?number|undefined), columnNumber: (?number|undefined), minWidthExpression: ?WebInspector.CSSMediaQueryExpression, maxWidthExpression: ?WebInspector.CSSMediaQueryExpression}} */
+WebInspector.MediaQueryInspector.MediaQueryUIModel;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/MemoryStatistics.js b/chromium/third_party/WebKit/Source/devtools/front_end/MemoryStatistics.js
deleted file mode 100644
index 439ebcf509e..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/MemoryStatistics.js
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @param {!WebInspector.TimelinePanel} timelinePanel
- * @param {!WebInspector.TimelineModel} model
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.MemoryStatistics = function(timelinePanel, model)
-{
- WebInspector.View.call(this);
- this._timelinePanel = timelinePanel;
-
- this.element.classList.add("fill");
- this._counters = [];
-
- model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
- model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
-
- this._memorySidebarView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, undefined);
- this._memorySidebarView.element.id = "memory-graphs-container";
-
- this._memorySidebarView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._sidebarResized.bind(this));
-
- this._canvasContainer = this._memorySidebarView.mainElement;
- this._canvasContainer.id = "memory-graphs-canvas-container";
- this._createCurrentValuesBar();
- this._canvas = this._canvasContainer.createChild("canvas", "fill");
- this._canvas.id = "memory-counters-graph";
- this._lastMarkerXPosition = 0;
-
- this._canvas.addEventListener("mouseover", this._onMouseOver.bind(this), true);
- this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), true);
- this._canvas.addEventListener("mouseout", this._onMouseOut.bind(this), true);
- this._canvas.addEventListener("click", this._onClick.bind(this), true);
- // We create extra timeline grid here to reuse its event dividers.
- this._timelineGrid = new WebInspector.TimelineGrid();
- this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
-
- // Populate sidebar
- this._memorySidebarView.sidebarElement.createChild("div", "sidebar-tree sidebar-tree-section").textContent = WebInspector.UIString("COUNTERS");
- this._counterUI = this._createCounterUIList();
- this._memorySidebarView.show(this.element);
-}
-
-/**
- * @constructor
- * @param {number} time
- */
-WebInspector.MemoryStatistics.Counter = function(time)
-{
- this.time = time;
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.SwatchCheckbox = function(title, color)
-{
- this.element = document.createElement("div");
- this._swatch = this.element.createChild("div", "swatch");
- this.element.createChild("span", "title").textContent = title;
- this._color = color;
- this.checked = true;
-
- this.element.addEventListener("click", this._toggleCheckbox.bind(this), true);
-}
-
-WebInspector.SwatchCheckbox.Events = {
- Changed: "Changed"
-}
-
-WebInspector.SwatchCheckbox.prototype = {
- get checked()
- {
- return this._checked;
- },
-
- set checked(v)
- {
- this._checked = v;
- if (this._checked)
- this._swatch.style.backgroundColor = this._color;
- else
- this._swatch.style.backgroundColor = "";
- },
-
- _toggleCheckbox: function(event)
- {
- this.checked = !this.checked;
- this.dispatchEventToListeners(WebInspector.SwatchCheckbox.Events.Changed);
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- */
-WebInspector.CounterUIBase = function(memoryCountersPane, title, graphColor, valueGetter)
-{
- this._memoryCountersPane = memoryCountersPane;
- this.valueGetter = valueGetter;
- var container = memoryCountersPane._memorySidebarView.sidebarElement.createChild("div", "memory-counter-sidebar-info");
- var swatchColor = graphColor;
- this._swatch = new WebInspector.SwatchCheckbox(WebInspector.UIString(title), swatchColor);
- this._swatch.addEventListener(WebInspector.SwatchCheckbox.Events.Changed, this._toggleCounterGraph.bind(this));
- container.appendChild(this._swatch.element);
-
- this._value = null;
- this.graphColor =graphColor;
- this.strokeColor = graphColor;
- this.graphYValues = [];
-}
-
-WebInspector.CounterUIBase.prototype = {
- _toggleCounterGraph: function(event)
- {
- if (this._swatch.checked)
- this._value.classList.remove("hidden");
- else
- this._value.classList.add("hidden");
- this._memoryCountersPane.refresh();
- },
-
- updateCurrentValue: function(countersEntry)
- {
- this._value.textContent = Number.bytesToString(this.valueGetter(countersEntry));
- },
-
- clearCurrentValueAndMarker: function(ctx)
- {
- this._value.textContent = "";
- },
-
- get visible()
- {
- return this._swatch.checked;
- },
-}
-
-WebInspector.MemoryStatistics.prototype = {
- _createCurrentValuesBar: function()
- {
- throw new Error("Not implemented");
- },
-
- _createCounterUIList: function()
- {
- throw new Error("Not implemented");
- },
-
- _onRecordsCleared: function()
- {
- this._counters = [];
- },
-
- /**
- * @param {!WebInspector.TimelineGrid} timelineGrid
- */
- setMainTimelineGrid: function(timelineGrid)
- {
- this._mainTimelineGrid = timelineGrid;
- },
-
- /**
- * @return {number}
- */
- height: function()
- {
- return this._memorySidebarView.element.offsetHeight;
- },
-
- /**
- * @param {number} width
- */
- setSidebarWidth: function(width)
- {
- if (this._ignoreSidebarResize)
- return;
- this._ignoreSidebarResize = true;
- this._memorySidebarView.setSidebarWidth(width);
- this._ignoreSidebarResize = false;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _sidebarResized: function(event)
- {
- if (this._ignoreSidebarResize)
- return;
- this._ignoreSidebarResize = true;
- this._timelinePanel.setSidebarWidth(/** @type {number} */(event.data));
- this._ignoreSidebarResize = false;
- },
-
- _canvasHeight: function()
- {
- throw new Error("Not implemented");
- },
-
- onResize: function()
- {
- var width = this._mainTimelineGrid.dividersElement.offsetWidth + 1;
-
- this._canvas.style.width = width + "px";
- this._timelineGrid.dividersElement.style.width = width + "px";
- var parentElement = this._canvas.parentElement;
-
- this._canvas.width = width;
- this._canvas.height = parentElement.clientHeight - 15;
- this.draw();
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onRecordAdded: function(event)
- {
- throw new Error("Not implemented");
- },
-
- draw: function()
- {
- this._calculateVisibleIndexes();
- this._calculateXValues();
- this._clear();
-
- this._setVerticalClip(10, this._canvas.height - 20);
- },
-
- _calculateVisibleIndexes: function()
- {
- var calculator = this._timelinePanel.calculator;
- var start = calculator.minimumBoundary() * 1000;
- var end = calculator.maximumBoundary() * 1000;
- function comparator(value, sample)
- {
- return value - sample.time;
- }
-
- // Maximum index of element whose time <= start.
- this._minimumIndex = Number.constrain(this._counters.upperBound(start, comparator) - 1, 0, this._counters.length - 1);
-
- // Minimum index of element whose time >= end.
- this._maximumIndex = Number.constrain(this._counters.lowerBound(end, comparator), 0, this._counters.length - 1);
-
- // Current window bounds.
- this._minTime = start;
- this._maxTime = end;
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _onClick: function(event)
- {
- var x = event.x - event.target.offsetParent.offsetLeft;
- var i = this._recordIndexAt(x);
- var counter = this._counters[i];
- if (counter)
- this._timelinePanel.revealRecordAt(counter.time / 1000);
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _onMouseOut: function(event)
- {
- delete this._markerXPosition;
-
- var ctx = this._canvas.getContext("2d");
- this._clearCurrentValueAndMarker(ctx);
- },
-
- /**
- * @param {!CanvasRenderingContext2D} ctx
- */
- _clearCurrentValueAndMarker: function(ctx)
- {
- for (var i = 0; i < this._counterUI.length; i++)
- this._counterUI[i].clearCurrentValueAndMarker(ctx);
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _onMouseOver: function(event)
- {
- this._onMouseMove(event);
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _onMouseMove: function(event)
- {
- var x = event.x - event.target.offsetParent.offsetLeft
- this._markerXPosition = x;
- this._refreshCurrentValues();
- },
-
- _refreshCurrentValues: function()
- {
- if (!this._counters.length)
- return;
- if (this._markerXPosition === undefined)
- return;
- if (this._maximumIndex === -1)
- return;
- var i = this._recordIndexAt(this._markerXPosition);
-
- this._updateCurrentValue(this._counters[i]);
-
- this._highlightCurrentPositionOnGraphs(this._markerXPosition, i);
- },
-
- _updateCurrentValue: function(counterEntry)
- {
- for (var j = 0; j < this._counterUI.length; j++)
- this._counterUI[j].updateCurrentValue(counterEntry);
- },
-
- _recordIndexAt: function(x)
- {
- var i;
- for (i = this._minimumIndex + 1; i <= this._maximumIndex; i++) {
- var statX = this._counters[i].x;
- if (x < statX)
- break;
- }
- i--;
- return i;
- },
-
- _highlightCurrentPositionOnGraphs: function(x, index)
- {
- var ctx = this._canvas.getContext("2d");
- this._restoreImageUnderMarker(ctx);
- this._drawMarker(ctx, x, index);
- },
-
- _restoreImageUnderMarker: function(ctx)
- {
- throw new Error("Not implemented");
- },
-
- _drawMarker: function(ctx, x, index)
- {
- throw new Error("Not implemented");
- },
-
- refresh: function()
- {
- this._refreshDividers();
- this.draw();
- this._refreshCurrentValues();
- },
-
- _refreshDividers: function()
- {
- this._timelineGrid.updateDividers(this._timelinePanel.calculator);
- },
-
- _setVerticalClip: function(originY, height)
- {
- this._originY = originY;
- this._clippedHeight = height;
- },
-
- _calculateXValues: function()
- {
- if (!this._counters.length)
- return;
-
- var width = this._canvas.width;
- var xFactor = width / (this._maxTime - this._minTime);
-
- this._counters[this._minimumIndex].x = 0;
- for (var i = this._minimumIndex + 1; i < this._maximumIndex; i++)
- this._counters[i].x = xFactor * (this._counters[i].time - this._minTime);
- this._counters[this._maximumIndex].x = width;
- },
-
- _clear: function()
- {
- var ctx = this._canvas.getContext("2d");
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- this._discardImageUnderMarker();
- },
-
- _discardImageUnderMarker: function()
- {
- throw new Error("Not implemented");
- },
-
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NavigatorOverlayController.js b/chromium/third_party/WebKit/Source/devtools/front_end/NavigatorOverlayController.js
deleted file mode 100644
index cdc17b85696..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NavigatorOverlayController.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @param {!WebInspector.SidebarView} parentSidebarView
- * @param {!WebInspector.View} navigatorView
- * @param {!WebInspector.View} editorView
- */
-WebInspector.NavigatorOverlayController = function(parentSidebarView, navigatorView, editorView)
-{
- this._parentSidebarView = parentSidebarView;
- this._navigatorView = navigatorView;
- this._editorView = editorView;
-
- this._navigatorSidebarResizeWidgetElement = this._navigatorView.element.createChild("div", "resizer-widget");
- this._parentSidebarView.installResizer(this._navigatorSidebarResizeWidgetElement);
-
- this._navigatorShowHideButton = new WebInspector.StatusBarButton(WebInspector.UIString("Hide navigator"), "left-sidebar-show-hide-button scripts-navigator-show-hide-button", 3);
- this._navigatorShowHideButton.state = "left";
- this._navigatorShowHideButton.addEventListener("click", this._toggleNavigator, this);
- parentSidebarView.mainElement.appendChild(this._navigatorShowHideButton.element);
-
- WebInspector.settings.navigatorHidden = WebInspector.settings.createSetting("navigatorHidden", true);
- if (WebInspector.settings.navigatorHidden.get())
- this._toggleNavigator();
-}
-
-WebInspector.NavigatorOverlayController.prototype = {
- wasShown: function()
- {
- window.setTimeout(this._maybeShowNavigatorOverlay.bind(this), 0);
- },
-
- _maybeShowNavigatorOverlay: function()
- {
- if (WebInspector.settings.navigatorHidden.get() && !WebInspector.settings.navigatorWasOnceHidden.get())
- this.showNavigatorOverlay();
- },
-
- _toggleNavigator: function()
- {
- if (this._navigatorShowHideButton.state === "overlay")
- this._pinNavigator();
- else if (this._navigatorShowHideButton.state === "right")
- this.showNavigatorOverlay();
- else
- this._hidePinnedNavigator();
- },
-
- _hidePinnedNavigator: function()
- {
- this._navigatorShowHideButton.state = "right";
- this._navigatorShowHideButton.title = WebInspector.UIString("Show navigator");
- this._parentSidebarView.element.appendChild(this._navigatorShowHideButton.element);
-
- this._editorView.element.classList.add("navigator-hidden");
- this._navigatorSidebarResizeWidgetElement.classList.add("hidden");
-
- this._parentSidebarView.hideSidebarElement();
- this._navigatorView.detach();
- this._editorView.focus();
-
- WebInspector.settings.navigatorWasOnceHidden.set(true);
- WebInspector.settings.navigatorHidden.set(true);
- },
-
- _pinNavigator: function()
- {
- this._navigatorShowHideButton.state = "left";
- this._navigatorShowHideButton.title = WebInspector.UIString("Hide navigator");
-
- this._editorView.element.classList.remove("navigator-hidden");
- this._navigatorSidebarResizeWidgetElement.classList.remove("hidden");
- this._editorView.element.appendChild(this._navigatorShowHideButton.element);
-
- this._innerHideNavigatorOverlay();
- this._parentSidebarView.showSidebarElement();
- this._navigatorView.show(this._parentSidebarView.sidebarElement);
- this._navigatorView.focus();
- WebInspector.settings.navigatorHidden.set(false);
- },
-
- showNavigatorOverlay: function()
- {
- if (this._navigatorShowHideButton.state === "overlay")
- return;
-
- this._navigatorShowHideButton.state = "overlay";
- this._navigatorShowHideButton.title = WebInspector.UIString("Pin navigator");
-
- this._sidebarOverlay = new WebInspector.SidebarOverlay(this._navigatorView, "scriptsPanelNavigatorOverlayWidth", Preferences.minScriptsSidebarWidth);
- this._boundKeyDown = this._keyDown.bind(this);
- this._sidebarOverlay.element.addEventListener("keydown", this._boundKeyDown, false);
-
- var navigatorOverlayResizeWidgetElement = document.createElement("div");
- navigatorOverlayResizeWidgetElement.classList.add("resizer-widget");
- this._sidebarOverlay.resizerWidgetElement = navigatorOverlayResizeWidgetElement;
-
- this._navigatorView.element.appendChild(this._navigatorShowHideButton.element);
- this._boundContainingElementFocused = this._containingElementFocused.bind(this);
- this._parentSidebarView.element.addEventListener("mousedown", this._boundContainingElementFocused, false);
-
- this._sidebarOverlay.show(this._parentSidebarView.element);
- this._navigatorView.focus();
- },
-
- _keyDown: function(event)
- {
- if (event.handled)
- return;
-
- if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
- this.hideNavigatorOverlay();
- event.consume(true);
- }
- },
-
- hideNavigatorOverlay: function()
- {
- if (this._navigatorShowHideButton.state !== "overlay")
- return;
-
- this._navigatorShowHideButton.state = "right";
- this._navigatorShowHideButton.title = WebInspector.UIString("Show navigator");
- this._parentSidebarView.element.appendChild(this._navigatorShowHideButton.element);
-
- this._innerHideNavigatorOverlay();
- this._editorView.focus();
- },
-
- _innerHideNavigatorOverlay: function()
- {
- this._parentSidebarView.element.removeEventListener("mousedown", this._boundContainingElementFocused, false);
- this._sidebarOverlay.element.removeEventListener("keydown", this._boundKeyDown, false);
- this._sidebarOverlay.hide();
- },
-
- _containingElementFocused: function(event)
- {
- if (!event.target.isSelfOrDescendant(this._sidebarOverlay.element))
- this.hideNavigatorOverlay();
- },
-
- isNavigatorPinned: function()
- {
- return this._navigatorShowHideButton.state === "left";
- },
-
- isNavigatorHidden: function()
- {
- return this._navigatorShowHideButton.state === "right";
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkUISourceCodeProvider.js b/chromium/third_party/WebKit/Source/devtools/front_end/NetworkUISourceCodeProvider.js
deleted file mode 100644
index 7e9903039af..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkUISourceCodeProvider.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @param {!WebInspector.SimpleWorkspaceProvider} networkWorkspaceProvider
- * @param {!WebInspector.Workspace} workspace
- */
-WebInspector.NetworkUISourceCodeProvider = function(networkWorkspaceProvider, workspace)
-{
- this._networkWorkspaceProvider = networkWorkspaceProvider;
- this._workspace = workspace;
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
-
- this._processedURLs = {};
-}
-
-WebInspector.NetworkUISourceCodeProvider.prototype = {
- _populate: function()
- {
- /**
- * @param {!WebInspector.ResourceTreeFrame} frame
- * @this {WebInspector.NetworkUISourceCodeProvider}
- */
- function populateFrame(frame)
- {
- for (var i = 0; i < frame.childFrames.length; ++i)
- populateFrame.call(this, frame.childFrames[i]);
-
- var resources = frame.resources();
- for (var i = 0; i < resources.length; ++i)
- this._resourceAdded({data:resources[i]});
- }
-
- populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _parsedScriptSource: function(event)
- {
- var script = /** @type {!WebInspector.Script} */ (event.data);
- if (!script.sourceURL || script.isInlineScript() || script.isSnippet())
- return;
- // Filter out embedder injected content scripts.
- if (script.isContentScript && !script.hasSourceURL) {
- var parsedURL = new WebInspector.ParsedURL(script.sourceURL);
- if (!parsedURL.isValid)
- return;
- }
- this._addFile(script.sourceURL, script, script.isContentScript);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _styleSheetAdded: function(event)
- {
- var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
- if ((!header.hasSourceURL || header.isInline) && header.origin !== "inspector")
- return;
-
- this._addFile(header.resourceURL(), header, false);
- },
-
- /**
- * @param {!WebInspector.Event|{data: !WebInspector.Resource}} event
- */
- _resourceAdded: function(event)
- {
- var resource = /** @type {!WebInspector.Resource} */ (event.data);
- this._addFile(resource.url, resource);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _mainFrameNavigated: function(event)
- {
- this._reset();
- },
-
- /**
- * @param {string} url
- * @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean=} isContentScript
- */
- _addFile: function(url, contentProvider, isContentScript)
- {
- if (this._workspace.hasMappingForURL(url))
- return;
-
- var type = contentProvider.contentType();
- if (type !== WebInspector.resourceTypes.Stylesheet && type !== WebInspector.resourceTypes.Document && type !== WebInspector.resourceTypes.Script)
- return;
- if (this._processedURLs[url])
- return;
- this._processedURLs[url] = true;
- var isEditable = type !== WebInspector.resourceTypes.Document;
- this._networkWorkspaceProvider.addFileForURL(url, contentProvider, isEditable, isContentScript);
- },
-
- _reset: function()
- {
- this._processedURLs = {};
- this._networkWorkspaceProvider.reset();
- this._populate();
- }
-}
-
-/**
- * @type {!WebInspector.SimpleWorkspaceProvider}
- */
-WebInspector.networkWorkspaceProvider;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/OWNERS b/chromium/third_party/WebKit/Source/devtools/front_end/OWNERS
index a91bd6ea237..9917e82c65b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/OWNERS
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/OWNERS
@@ -1,6 +1,7 @@
aandrey@chromium.org
apavlov@chromium.org
caseq@chromium.org
+dgozman@chromium.org
loislo@chromium.org
pfeldman@chromium.org
vsevik@chromium.org
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/OverridesSupport.js b/chromium/third_party/WebKit/Source/devtools/front_end/OverridesSupport.js
deleted file mode 100644
index 6bcd91e3458..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/OverridesSupport.js
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.OverridesSupport = function()
-{
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._deviceMetricsChanged.bind(this), this);
- this._deviceMetricsOverrideEnabled = false;
- this._emulateViewportEnabled = false;
-
- WebInspector.settings.overrideUserAgent.addChangeListener(this._userAgentChanged, this);
- WebInspector.settings.userAgent.addChangeListener(this._userAgentChanged, this);
-
- WebInspector.settings.overrideDeviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
- WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
- WebInspector.settings.emulateViewport.addChangeListener(this._deviceMetricsChanged, this);
- WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
-
- WebInspector.settings.overrideGeolocation.addChangeListener(this._geolocationPositionChanged, this);
- WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
-
- WebInspector.settings.overrideDeviceOrientation.addChangeListener(this._deviceOrientationChanged, this);
- WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
-
- WebInspector.settings.emulateTouchEvents.addChangeListener(this._emulateTouchEventsChanged, this);
-
- WebInspector.settings.overrideCSSMedia.addChangeListener(this._cssMediaChanged, this);
- WebInspector.settings.emulatedCSSMedia.addChangeListener(this._cssMediaChanged, this);
-}
-
-WebInspector.OverridesSupport.Events = {
- OverridesWarningUpdated: "OverridesWarningUpdated",
-}
-
-/**
- * @constructor
- * @param {number} width
- * @param {number} height
- * @param {number} deviceScaleFactor
- * @param {boolean} textAutosizing
- */
-WebInspector.OverridesSupport.DeviceMetrics = function(width, height, deviceScaleFactor, textAutosizing)
-{
- this.width = width;
- this.height = height;
- this.deviceScaleFactor = deviceScaleFactor;
- this.textAutosizing = textAutosizing;
-}
-
-/**
- * @return {!WebInspector.OverridesSupport.DeviceMetrics}
- */
-WebInspector.OverridesSupport.DeviceMetrics.parseSetting = function(value)
-{
- var width = 0;
- var height = 0;
- var deviceScaleFactor = 1;
- var textAutosizing = true;
- if (value) {
- var splitMetrics = value.split("x");
- if (splitMetrics.length >= 3) {
- width = parseInt(splitMetrics[0], 10);
- height = parseInt(splitMetrics[1], 10);
- deviceScaleFactor = parseFloat(splitMetrics[2]);
- if (splitMetrics.length == 4)
- textAutosizing = splitMetrics[3] == 1;
- }
- }
- return new WebInspector.OverridesSupport.DeviceMetrics(width, height, deviceScaleFactor, textAutosizing);
-}
-
-/**
- * @return {?WebInspector.OverridesSupport.DeviceMetrics}
- */
-WebInspector.OverridesSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, deviceScaleFactorString, textAutosizing)
-{
- function isUserInputValid(value, isInteger)
- {
- if (!value)
- return true;
- return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value);
- }
-
- if (!widthString ^ !heightString)
- return null;
-
- var isWidthValid = isUserInputValid(widthString, true);
- var isHeightValid = isUserInputValid(heightString, true);
- var isDeviceScaleFactorValid = isUserInputValid(deviceScaleFactorString, false);
-
- if (!isWidthValid && !isHeightValid && !isDeviceScaleFactorValid)
- return null;
-
- var width = isWidthValid ? parseInt(widthString || "0", 10) : -1;
- var height = isHeightValid ? parseInt(heightString || "0", 10) : -1;
- var deviceScaleFactor = isDeviceScaleFactorValid ? parseFloat(deviceScaleFactorString) : -1;
-
- return new WebInspector.OverridesSupport.DeviceMetrics(width, height, deviceScaleFactor, textAutosizing);
-}
-
-WebInspector.OverridesSupport.DeviceMetrics.prototype = {
- /**
- * @return {boolean}
- */
- isValid: function()
- {
- return this.isWidthValid() && this.isHeightValid() && this.isDeviceScaleFactorValid();
- },
-
- /**
- * @return {boolean}
- */
- isWidthValid: function()
- {
- return this.width >= 0;
- },
-
- /**
- * @return {boolean}
- */
- isHeightValid: function()
- {
- return this.height >= 0;
- },
-
- /**
- * @return {boolean}
- */
- isDeviceScaleFactorValid: function()
- {
- return this.deviceScaleFactor > 0;
- },
-
- /**
- * @return {string}
- */
- toSetting: function()
- {
- if (!this.isValid())
- return "";
-
- return this.width && this.height ? this.width + "x" + this.height + "x" + this.deviceScaleFactor + "x" + (this.textAutosizing ? "1" : "0") : "";
- },
-
- /**
- * @return {string}
- */
- widthToInput: function()
- {
- return this.isWidthValid() && this.width ? String(this.width) : "";
- },
-
- /**
- * @return {string}
- */
- heightToInput: function()
- {
- return this.isHeightValid() && this.height ? String(this.height) : "";
- },
-
- /**
- * @return {string}
- */
- deviceScaleFactorToInput: function()
- {
- return this.isDeviceScaleFactorValid() && this.deviceScaleFactor ? String(this.deviceScaleFactor) : "";
- },
-
- /**
- * Compute the font scale factor.
- *
- * Chromium on Android uses a device scale adjustment for fonts used in text autosizing for
- * improved legibility. This function computes this adjusted value for text autosizing.
- *
- * For a description of the Android device scale adjustment algorithm, see:
- * chrome/browser/chrome_content_browser_client.cc, GetFontScaleMultiplier(...)
- *
- * @return {number} font scale factor.
- */
- fontScaleFactor: function()
- {
- if (this.isValid()) {
- var minWidth = Math.min(this.width, this.height) / this.deviceScaleFactor;
-
- var kMinFSM = 1.05;
- var kWidthForMinFSM = 320;
- var kMaxFSM = 1.3;
- var kWidthForMaxFSM = 800;
-
- if (minWidth <= kWidthForMinFSM)
- return kMinFSM;
- if (minWidth >= kWidthForMaxFSM)
- return kMaxFSM;
-
- // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
- var ratio = (minWidth - kWidthForMinFSM) / (kWidthForMaxFSM - kWidthForMinFSM);
-
- return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
- }
-
- return 1;
- }
-}
-
-/**
- * @constructor
- * @param {number} latitude
- * @param {number} longitude
- */
-WebInspector.OverridesSupport.GeolocationPosition = function(latitude, longitude, error)
-{
- this.latitude = latitude;
- this.longitude = longitude;
- this.error = error;
-}
-
-WebInspector.OverridesSupport.GeolocationPosition.prototype = {
- /**
- * @return {string}
- */
- toSetting: function()
- {
- return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
- }
-}
-
-/**
- * @return {!WebInspector.OverridesSupport.GeolocationPosition}
- */
-WebInspector.OverridesSupport.GeolocationPosition.parseSetting = function(value)
-{
- if (value) {
- var splitError = value.split(":");
- if (splitError.length === 2) {
- var splitPosition = splitError[0].split("@")
- if (splitPosition.length === 2)
- return new WebInspector.OverridesSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
- }
- }
- return new WebInspector.OverridesSupport.GeolocationPosition(0, 0, "");
-}
-
-/**
- * @return {?WebInspector.OverridesSupport.GeolocationPosition}
- */
-WebInspector.OverridesSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
-{
- function isUserInputValid(value)
- {
- if (!value)
- return true;
- return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
- }
-
- if (!latitudeString ^ !latitudeString)
- return null;
-
- var isLatitudeValid = isUserInputValid(latitudeString);
- var isLongitudeValid = isUserInputValid(longitudeString);
-
- if (!isLatitudeValid && !isLongitudeValid)
- return null;
-
- var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
- var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
-
- return new WebInspector.OverridesSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
-}
-
-WebInspector.OverridesSupport.GeolocationPosition.clearGeolocationOverride = function()
-{
- PageAgent.clearGeolocationOverride();
-}
-
-/**
- * @constructor
- * @param {number} alpha
- * @param {number} beta
- * @param {number} gamma
- */
-WebInspector.OverridesSupport.DeviceOrientation = function(alpha, beta, gamma)
-{
- this.alpha = alpha;
- this.beta = beta;
- this.gamma = gamma;
-}
-
-WebInspector.OverridesSupport.DeviceOrientation.prototype = {
- /**
- * @return {string}
- */
- toSetting: function()
- {
- return JSON.stringify(this);
- }
-}
-
-/**
- * @return {!WebInspector.OverridesSupport.DeviceOrientation}
- */
-WebInspector.OverridesSupport.DeviceOrientation.parseSetting = function(value)
-{
- if (value) {
- var jsonObject = JSON.parse(value);
- return new WebInspector.OverridesSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
- }
- return new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0);
-}
-
-/**
- * @return {?WebInspector.OverridesSupport.DeviceOrientation}
- */
-WebInspector.OverridesSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
-{
- function isUserInputValid(value)
- {
- if (!value)
- return true;
- return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
- }
-
- if (!alphaString ^ !betaString ^ !gammaString)
- return null;
-
- var isAlphaValid = isUserInputValid(alphaString);
- var isBetaValid = isUserInputValid(betaString);
- var isGammaValid = isUserInputValid(gammaString);
-
- if (!isAlphaValid && !isBetaValid && !isGammaValid)
- return null;
-
- var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
- var beta = isBetaValid ? parseFloat(betaString) : -1;
- var gamma = isGammaValid ? parseFloat(gammaString) : -1;
-
- return new WebInspector.OverridesSupport.DeviceOrientation(alpha, beta, gamma);
-}
-
-WebInspector.OverridesSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
-{
- PageAgent.clearDeviceOrientationOverride();
-}
-
-WebInspector.OverridesSupport.prototype = {
- /**
- * @param {string} deviceMetrics
- * @param {string} userAgent
- */
- emulateDevice: function(deviceMetrics, userAgent)
- {
- this._deviceMetricsChangedListenerMuted = true;
- WebInspector.settings.deviceMetrics.set(deviceMetrics);
- WebInspector.settings.userAgent.set(userAgent);
- WebInspector.settings.overrideDeviceMetrics.set(true);
- WebInspector.settings.overrideUserAgent.set(true);
- WebInspector.settings.emulateTouchEvents.set(true);
- WebInspector.settings.emulateViewport.set(true);
- delete this._deviceMetricsChangedListenerMuted;
- this._deviceMetricsChanged();
- },
-
- reset: function()
- {
- this._deviceMetricsChangedListenerMuted = true;
- WebInspector.settings.overrideDeviceMetrics.set(false);
- WebInspector.settings.overrideUserAgent.set(false);
- WebInspector.settings.emulateTouchEvents.set(false);
- WebInspector.settings.overrideDeviceOrientation.set(false);
- WebInspector.settings.overrideGeolocation.set(false);
- WebInspector.settings.overrideCSSMedia.set(false);
- WebInspector.settings.emulateViewport.set(false);
- WebInspector.settings.deviceMetrics.set("");
- delete this._deviceMetricsChangedListenerMuted;
- this._deviceMetricsChanged();
- },
-
- applyInitialOverrides: function()
- {
- this._deviceMetricsChangedListenerMuted = true;
- this._userAgentChanged();
- this._deviceMetricsChanged();
- this._deviceOrientationChanged();
- this._geolocationPositionChanged();
- this._emulateTouchEventsChanged();
- this._cssMediaChanged();
- delete this._deviceMetricsChangedListenerMuted;
- this._deviceMetricsChanged();
- this._revealOverridesTabIfNeeded();
- },
-
- _userAgentChanged: function()
- {
- if (WebInspector.isInspectingDevice())
- return;
- NetworkAgent.setUserAgentOverride(WebInspector.settings.overrideUserAgent.get() ? WebInspector.settings.userAgent.get() : "");
- },
-
- _deviceMetricsChanged: function()
- {
- if (this._deviceMetricsChangedListenerMuted)
- return;
- var metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(WebInspector.settings.overrideDeviceMetrics.get() ? WebInspector.settings.deviceMetrics.get() : "");
- if (!metrics.isValid())
- return;
-
- var dipWidth = Math.round(metrics.width / metrics.deviceScaleFactor);
- var dipHeight = Math.round(metrics.height / metrics.deviceScaleFactor);
-
- // Disable override without checks.
- if (dipWidth && dipHeight && WebInspector.isInspectingDevice()) {
- this._updateWarningMessage(WebInspector.UIString("Screen emulation on the device is not available."));
- return;
- }
-
- PageAgent.setDeviceMetricsOverride(dipWidth, dipHeight, metrics.deviceScaleFactor, WebInspector.settings.emulateViewport.get(), WebInspector.settings.deviceFitWindow.get(), metrics.textAutosizing, metrics.fontScaleFactor(), apiCallback.bind(this));
-
- /**
- * @param {?Protocol.Error} error
- * @this {WebInspector.OverridesSupport}
- */
- function apiCallback(error)
- {
- if (error) {
- this._updateWarningMessage(WebInspector.UIString("Screen emulation is not available on this page."));
- return;
- }
-
- var metricsOverrideEnabled = !!(dipWidth && dipHeight);
- var viewportEnabled = WebInspector.settings.emulateViewport.get();
- this._updateWarningMessage(this._deviceMetricsOverrideEnabled !== metricsOverrideEnabled || (metricsOverrideEnabled && this._emulateViewportEnabled != viewportEnabled) ?
- WebInspector.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering.") : "");
- this._deviceMetricsOverrideEnabled = metricsOverrideEnabled;
- this._emulateViewportEnabled = viewportEnabled;
- }
- },
-
- _geolocationPositionChanged: function()
- {
- if (!WebInspector.settings.overrideGeolocation.get()) {
- PageAgent.clearGeolocationOverride();
- return;
- }
- var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
- if (geolocation.error)
- PageAgent.setGeolocationOverride();
- else
- PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
- },
-
- _deviceOrientationChanged: function()
- {
- if (!WebInspector.settings.overrideDeviceOrientation.get()) {
- PageAgent.clearDeviceOrientationOverride();
- return;
- }
- if (WebInspector.isInspectingDevice())
- return;
-
- var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
- PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
- },
-
- _emulateTouchEventsChanged: function()
- {
- if (WebInspector.isInspectingDevice() && WebInspector.settings.emulateTouchEvents.get())
- return;
-
- WebInspector.domAgent.emulateTouchEventObjects(WebInspector.settings.emulateTouchEvents.get());
- },
-
- _cssMediaChanged: function()
- {
- PageAgent.setEmulatedMedia(WebInspector.settings.overrideCSSMedia.get() ? WebInspector.settings.emulatedCSSMedia.get() : "");
- WebInspector.cssModel.mediaQueryResultChanged();
- },
-
- _anyOverrideIsEnabled: function()
- {
- return WebInspector.settings.overrideUserAgent.get() || WebInspector.settings.overrideDeviceMetrics.get() ||
- WebInspector.settings.overrideGeolocation.get() || WebInspector.settings.overrideDeviceOrientation.get() ||
- WebInspector.settings.emulateTouchEvents.get() || WebInspector.settings.overrideCSSMedia.get();
- },
-
- _revealOverridesTabIfNeeded: function()
- {
- if (this._anyOverrideIsEnabled()) {
- if (!WebInspector.settings.showEmulationViewInDrawer.get())
- WebInspector.settings.showEmulationViewInDrawer.set(true);
- WebInspector.inspectorView.showViewInDrawer("emulation");
- }
- },
-
- /**
- * @param {string} warningMessage
- */
- _updateWarningMessage: function(warningMessage)
- {
- this._warningMessage = warningMessage;
- this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.OverridesWarningUpdated);
- },
-
- /**
- * @return {string}
- */
- warningMessage: function()
- {
- return this._warningMessage || "";
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-
-/**
- * @type {!WebInspector.OverridesSupport}
- */
-WebInspector.overridesSupport;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/OverridesView.js b/chromium/third_party/WebKit/Source/devtools/front_end/OverridesView.js
deleted file mode 100644
index ef0fb75d22b..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/OverridesView.js
+++ /dev/null
@@ -1,1089 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.OverridesView = function()
-{
- WebInspector.View.call(this);
- this.registerRequiredCSS("overrides.css");
- this.registerRequiredCSS("helpScreen.css");
- this.element.classList.add("overrides-view", "fill", "vbox");
-
- this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.shrinkableTabs = false;
- this._tabbedPane.verticalTabLayout = true;
-
- new WebInspector.OverridesView.DeviceTab().appendAsTab(this._tabbedPane);
- new WebInspector.OverridesView.ViewportTab().appendAsTab(this._tabbedPane);
- new WebInspector.OverridesView.UserAgentTab().appendAsTab(this._tabbedPane);
- new WebInspector.OverridesView.SensorsTab().appendAsTab(this._tabbedPane);
-
- this._lastSelectedTabSetting = WebInspector.settings.createSetting("lastSelectedEmulateTab", "device");
- this._tabbedPane.selectTab(this._lastSelectedTabSetting.get());
- this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
- this._tabbedPane.show(this.element);
-
- this._warningFooter = this.element.createChild("div", "overrides-footer");
- this._overridesWarningUpdated();
- WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.OverridesWarningUpdated, this._overridesWarningUpdated, this);
-}
-
-WebInspector.OverridesView.prototype = {
- /**
- * @param {!WebInspector.Event} event
- */
- _tabSelected: function(event)
- {
- this._lastSelectedTabSetting.set(this._tabbedPane.selectedTabId);
- },
-
- _overridesWarningUpdated: function()
- {
- var message = WebInspector.overridesSupport.warningMessage();
- this._warningFooter.enableStyleClass("hidden", !message);
- this._warningFooter.textContent = message;
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {string} id
- * @param {string} name
- * @param {!Array.<!WebInspector.Setting>} settings
- */
-WebInspector.OverridesView.Tab = function(id, name, settings)
-{
- WebInspector.View.call(this);
- this._id = id;
- this._name = name;
- this._settings = settings;
- for (var i = 0; i < settings.length; ++i)
- settings[i].addChangeListener(this._updateActiveState, this);
-}
-
-WebInspector.OverridesView.Tab.prototype = {
- /**
- * @param {!WebInspector.TabbedPane} tabbedPane
- */
- appendAsTab: function(tabbedPane)
- {
- this._tabbedPane = tabbedPane;
- tabbedPane.appendTab(this._id, this._name, this);
- this._updateActiveState();
- },
-
- _updateActiveState: function()
- {
- var active = false;
- for (var i = 0; !active && i < this._settings.length; ++i)
- active = this._settings[i].get();
- this._tabbedPane.element.enableStyleClass("overrides-activate-" + this._id, active);
- this._tabbedPane.changeTabTitle(this._id, active ? this._name + " \u2713" : this._name);
- },
-
- /**
- * Creates an input element under the parentElement with the given id and defaultText.
- * It also sets an onblur event listener.
- * @param {!Element} parentElement
- * @param {string} id
- * @param {string} defaultText
- * @param {function(*)} eventListener
- * @param {boolean=} numeric
- * @return {!Element} element
- */
- _createInput: function(parentElement, id, defaultText, eventListener, numeric)
- {
- var element = parentElement.createChild("input");
- element.id = id;
- element.type = "text";
- element.maxLength = 12;
- element.style.width = "80px";
- element.value = defaultText;
- element.align = "right";
- if (numeric)
- element.className = "numeric";
- element.addEventListener("input", eventListener, false);
- element.addEventListener("keydown", keyDownListener, false);
- function keyDownListener(event)
- {
- if (isEnterKey(event))
- eventListener(event);
- }
- return element;
- },
-
- /**
- * @param {string} title
- * @param {function(boolean)} callback
- */
- _createNonPersistedCheckbox: function(title, callback)
- {
- var labelElement = document.createElement("label");
- var checkboxElement = labelElement.createChild("input");
- checkboxElement.type = "checkbox";
- checkboxElement.checked = false;
- checkboxElement.addEventListener("click", onclick, false);
- labelElement.appendChild(document.createTextNode(title));
- return labelElement;
-
- function onclick()
- {
- callback(checkboxElement.checked);
- }
- },
-
- /**
- * @param {string} name
- * @param {!WebInspector.Setting} setting
- * @param {function(boolean)=} callback
- */
- _createSettingCheckbox: function(name, setting, callback)
- {
- var checkbox = WebInspector.SettingsTab.createCheckbox(name, setting.get.bind(setting), listener, true);
-
- function listener(value)
- {
- if (setting.get() === value)
- return;
-
- setting.set(value);
- if (callback)
- callback(value);
- }
-
- setting.addChangeListener(changeListener);
-
- function changeListener()
- {
- if (checkbox.firstChild.checked !== setting.get())
- checkbox.firstChild.checked = setting.get();
- }
- return checkbox;
- }
-}
-
-WebInspector.OverridesView.Tab.prototype.__proto__ = WebInspector.View.prototype;
-
-/**
- * @constructor
- * @extends {WebInspector.OverridesView.Tab}
- */
-WebInspector.OverridesView.DeviceTab = function()
-{
- WebInspector.OverridesView.Tab.call(this, "device", WebInspector.UIString("Device"), []);
- this.element.classList.add("overrides-device");
-
- this._emulatedDeviceSetting = WebInspector.settings.createSetting("emulatedDevice", "Google Nexus 4");
- this._emulateDeviceViewportSetting = WebInspector.settings.overrideDeviceMetrics;
- this._emulateDeviceUserAgentSetting = WebInspector.settings.overrideUserAgent;
-
- this._deviceSelectElement = this.element.createChild("select");
-
- var devices = WebInspector.OverridesView.DeviceTab._phones.concat(WebInspector.OverridesView.DeviceTab._tablets);
- devices.sort();
- var selectionRestored = false;
- for (var i = 0; i < devices.length; ++i) {
- var device = devices[i];
- var option = new Option(device[0], device[0]);
- option._userAgent = device[1];
- option._metrics = device[2];
- this._deviceSelectElement.add(option);
- if (this._emulatedDeviceSetting.get() === device[0]) {
- this._deviceSelectElement.selectedIndex = i;
- selectionRestored = true;
- }
- }
-
- if (!selectionRestored)
- this._deviceSelectElement.selectedIndex = devices.length - 1;
-
- this._deviceSelectElement.addEventListener("change", this._deviceSelected.bind(this), false);
- this._deviceSelectElement.addEventListener("dblclick", this._emulateButtonClicked.bind(this), false);
- this._deviceSelectElement.addEventListener("keypress", this._keyPressed.bind(this), false);
- this._deviceSelectElement.disabled = WebInspector.isInspectingDevice();
-
- var buttonsBar = this.element.createChild("div");
- var emulateButton = buttonsBar.createChild("button", "settings-tab-text-button");
- emulateButton.textContent = WebInspector.UIString("Emulate");
- emulateButton.addEventListener("click", this._emulateButtonClicked.bind(this), false);
- emulateButton.disabled = WebInspector.isInspectingDevice();
- this._emulateButton = emulateButton;
-
- var resetButton = buttonsBar.createChild("button", "settings-tab-text-button");
- resetButton.textContent = WebInspector.UIString("Reset");
- resetButton.addEventListener("click", this._resetButtonClicked.bind(this), false);
-
- this._viewportValueLabel = this.element.createChild("div", "overrides-device-value-label");
- this._viewportValueLabel.textContent = WebInspector.UIString("Viewport:");
- this._viewportValueElement = this._viewportValueLabel.createChild("span", "overrides-device-value");
-
- this._userAgentLabel = this.element.createChild("div", "overrides-device-value-label");
- this._userAgentLabel.textContent = WebInspector.UIString("User agent:");
- this._userAgentValueElement = this._userAgentLabel.createChild("span", "overrides-device-value");
-
- this._updateValueLabels();
-}
-
-// Third element lists device metrics separated by 'x':
-// - screen width,
-// - screen height,
-// - device scale factor,
-// - use text autosizing.
-WebInspector.OverridesView.DeviceTab._phones = [
- ["Apple iPhone 3GS",
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
- "320x480x1"],
- ["Apple iPhone 4",
- "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
- "640x960x2"],
- ["Apple iPhone 5",
- "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
- "640x1136x2"],
- ["BlackBerry Z10",
- "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
- "768x1280x2"],
- ["BlackBerry Z30",
- "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
- "720x1280x2"],
- ["Google Nexus 4",
- "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
- "768x1280x2"],
- ["Google Nexus 5",
- "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
- "1080x1920x3"],
- ["Google Nexus S",
- "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "480x800x1.5"],
- ["HTC Evo, Touch HD, Desire HD, Desire",
- "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "480x800x1.5"],
- ["HTC One X, EVO LTE",
- "Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
- "720x1280x2"],
- ["HTC Sensation, Evo 3D",
- "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "540x960x1.5"],
- ["LG Optimus 2X, Optimus 3D, Optimus Black",
- "Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2",
- "480x800x1.5"],
- ["LG Optimus G",
- "Mozilla/5.0 (Linux; Android 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
- "768x1280x2"],
- ["LG Optimus LTE, Optimus 4X HD",
- "Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "720x1280x1.7"],
- ["LG Optimus One",
- "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "320x480x1.5"],
- ["Motorola Defy, Droid, Droid X, Milestone",
- "Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
- "480x854x1.5"],
- ["Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2",
- "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "540x960x1"],
- ["Motorola Droid Razr HD",
- "Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "720x1280x1"],
- ["Nokia C5, C6, C7, N97, N8, X7",
- "NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) BrowserNG/7.1.4",
- "360x640x1"],
- ["Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900",
- "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)",
- "480x800x1.5"],
- ["Samsung Galaxy Note 3",
- "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "1080x1920x2"],
- ["Samsung Galaxy Note II",
- "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "720x1280x2"],
- ["Samsung Galaxy Note",
- "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "800x1280x2"],
- ["Samsung Galaxy S III, Galaxy Nexus",
- "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "720x1280x2"],
- ["Samsung Galaxy S, S II, W",
- "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
- "480x800x1.5"],
- ["Samsung Galaxy S4",
- "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
- "1080x1920x3"],
- ["Sony Xperia S, Ion",
- "Mozilla/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "720x1280x2"],
- ["Sony Xperia Sola, U",
- "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "480x854x1"],
- ["Sony Xperia Z, Z1",
- "Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
- "1080x1920x3"],
-];
-
-WebInspector.OverridesView.DeviceTab._tablets = [
- ["Amazon Amazon Kindle Fire HD 7\"",
- "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire HD Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "1280x800x1.5"],
- ["Amazon Amazon Kindle Fire HD 8.9\"",
- "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire HD Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "1920x1200x1.5"],
- ["Amazon Amazon Kindle Fire",
- "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "1024x600x1"],
- ["Apple iPad 1 / 2 / iPad Mini",
- "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
- "1024x768x1"],
- ["Apple iPad 3 / 4",
- "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
- "2048x1536x2"],
- ["BlackBerry PlayBook",
- "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+",
- "1024x600x1"],
- ["Google Nexus 10",
- "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
- "2560x1600x2"],
- ["Google Nexus 7 2",
- "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
- "1920x1200x2"],
- ["Google Nexus 7",
- "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
- "1280x800x1.325"],
- ["Motorola Xoom, Xyboard",
- "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
- "1280x800x1"],
- ["Samsung Galaxy Tab 7.7, 8.9, 10.1",
- "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "1280x800x1"],
- ["Samsung Galaxy Tab",
- "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
- "1024x600x1"],
-];
-
-WebInspector.OverridesView.DeviceTab.prototype = {
- /**
- * @param {!Event} e
- */
- _keyPressed: function(e)
- {
- if (e.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code)
- this._emulateButtonClicked();
- },
-
- _emulateButtonClicked: function()
- {
- var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
- WebInspector.overridesSupport.emulateDevice(option._metrics, option._userAgent);
- },
-
- _resetButtonClicked: function()
- {
- WebInspector.overridesSupport.reset();
- },
-
- _deviceSelected: function()
- {
- var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
- this._emulatedDeviceSetting.set(option.value);
- this._updateValueLabels();
- },
-
- _updateValueLabels: function()
- {
- var option = this._deviceSelectElement.options[this._deviceSelectElement.selectedIndex];
- var metrics;
- if (option._metrics && (metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(option._metrics)))
- this._viewportValueElement.textContent = WebInspector.UIString("%s \u00D7 %s, devicePixelRatio = %s", metrics.width, metrics.height, metrics.deviceScaleFactor);
- else
- this._viewportValueElement.textContent = "";
- this._userAgentValueElement.textContent = option._userAgent || "";
- }
-}
-
-WebInspector.OverridesView.DeviceTab.prototype.__proto__ = WebInspector.OverridesView.Tab.prototype;
-
-
-/**
- * @constructor
- * @extends {WebInspector.OverridesView.Tab}
- */
-WebInspector.OverridesView.ViewportTab = function()
-{
- WebInspector.OverridesView.Tab.call(this, "viewport", WebInspector.UIString("Screen"), [WebInspector.settings.overrideDeviceMetrics, WebInspector.settings.overrideCSSMedia]);
- this.element.classList.add("overrides-viewport");
-
- const metricsSetting = WebInspector.settings.deviceMetrics.get();
- var metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(metricsSetting);
- var checkbox = this._createSettingCheckbox(WebInspector.UIString("Emulate screen"), WebInspector.settings.overrideDeviceMetrics, this._onMetricsCheckboxClicked.bind(this));
- checkbox.firstChild.disabled = WebInspector.isInspectingDevice();
- WebInspector.settings.deviceMetrics.addChangeListener(this._updateDeviceMetricsElement, this);
-
- this.element.appendChild(checkbox);
- this.element.appendChild(this._createDeviceMetricsElement(metrics));
- this.element.appendChild(this._createMediaEmulationElement());
-
- var footnote = this.element.createChild("p", "help-footnote");
- var footnoteLink = footnote.createChild("a");
- footnoteLink.href = "https://developers.google.com/chrome-developer-tools/docs/mobile-emulation";
- footnoteLink.target = "_blank";
- footnoteLink.createTextChild(WebInspector.UIString("More information about screen emulation"));
-
- this._onMetricsCheckboxClicked(WebInspector.settings.overrideDeviceMetrics.get());
-}
-
-WebInspector.OverridesView.ViewportTab.prototype = {
- /**
- * @param {boolean} enabled
- */
- _onMetricsCheckboxClicked: function(enabled)
- {
- if (enabled && !this._widthOverrideElement.value)
- this._widthOverrideElement.focus();
- this._applyDeviceMetricsUserInput();
- },
-
- _applyDeviceMetricsUserInput: function()
- {
- this._muteRangeListener = true;
- this._widthRangeInput.value = this._widthOverrideElement.value;
- delete this._muteRangeListener;
- if (this._applyDeviceMetricsTimer)
- clearTimeout(this._applyDeviceMetricsTimer);
- this._applyDeviceMetricsTimer = setTimeout(this._doApplyDeviceMetricsUserInput.bind(this), 50);
- },
-
- _doApplyDeviceMetricsUserInput: function()
- {
- delete this._applyDeviceMetricsTimer;
- this._setDeviceMetricsOverride(WebInspector.OverridesSupport.DeviceMetrics.parseUserInput(this._widthOverrideElement.value.trim(), this._heightOverrideElement.value.trim(), this._deviceScaleFactorOverrideElement.value.trim(), this._textAutosizingOverrideCheckbox.checked), true);
- },
-
- /**
- * @param {?WebInspector.OverridesSupport.DeviceMetrics} metrics
- * @param {boolean} userInputModified
- */
- _setDeviceMetricsOverride: function(metrics, userInputModified)
- {
- function setValid(condition, element)
- {
- if (condition)
- element.classList.remove("error-input");
- else
- element.classList.add("error-input");
- }
-
- setValid(metrics && metrics.isWidthValid(), this._widthOverrideElement);
- setValid(metrics && metrics.isHeightValid(), this._heightOverrideElement);
- setValid(metrics && metrics.isDeviceScaleFactorValid(), this._deviceScaleFactorOverrideElement);
-
- if (!metrics)
- return;
-
- if (!userInputModified) {
- this._widthOverrideElement.value = metrics.widthToInput();
- this._heightOverrideElement.value = metrics.heightToInput();
- this._deviceScaleFactorOverrideElement.value = metrics.deviceScaleFactorToInput();
- this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing;
- }
-
- if (metrics.isValid()) {
- var value = metrics.toSetting();
- if (value !== WebInspector.settings.deviceMetrics.get())
- WebInspector.settings.deviceMetrics.set(value);
- }
- },
-
- /**
- * @param {!WebInspector.OverridesSupport.DeviceMetrics} metrics
- */
- _createDeviceMetricsElement: function(metrics)
- {
- var fieldsetElement = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.overrideDeviceMetrics);
- if (WebInspector.isInspectingDevice())
- fieldsetElement.disabled = true;
- fieldsetElement.id = "metrics-override-section";
-
- /**
- * @this {WebInspector.OverridesView.ViewportTab}
- */
- function swapDimensionsClicked()
- {
- var widthValue = this._widthOverrideElement.value;
- this._widthOverrideElement.value = this._heightOverrideElement.value;
- this._heightOverrideElement.value = widthValue;
- this._applyDeviceMetricsUserInput();
- }
-
- var tableElement = fieldsetElement.createChild("table", "nowrap");
-
- var rowElement = tableElement.createChild("tr");
- var cellElement = rowElement.createChild("td");
- cellElement.appendChild(document.createTextNode(WebInspector.UIString("Resolution:")));
- cellElement = rowElement.createChild("td");
- this._widthOverrideElement = this._createInput(cellElement, "metrics-override-width", String(metrics.width || screen.width), this._applyDeviceMetricsUserInput.bind(this), true);
- this._swapDimensionsElement = cellElement.createChild("button", "overrides-swap");
- this._swapDimensionsElement.appendChild(document.createTextNode(" \u21C4 ")); // RIGHTWARDS ARROW OVER LEFTWARDS ARROW.
- this._swapDimensionsElement.title = WebInspector.UIString("Swap dimensions");
- this._swapDimensionsElement.addEventListener("click", swapDimensionsClicked.bind(this), false);
- this._swapDimensionsElement.tabIndex = -1;
- this._heightOverrideElement = this._createInput(cellElement, "metrics-override-height", String(metrics.height || screen.height), this._applyDeviceMetricsUserInput.bind(this), true);
-
- rowElement = tableElement.createChild("tr");
- cellElement = rowElement.createChild("td");
- cellElement.colSpan = 4;
- this._widthRangeInput = cellElement.createChild("input");
- this._widthRangeInput.type = "range";
- this._widthRangeInput.min = 100;
- this._widthRangeInput.max = 2000;
- this._widthRangeInput.addEventListener("change", this._rangeValueChanged.bind(this), false);
- this._widthRangeInput.value = this._widthOverrideElement.value;
-
- rowElement = tableElement.createChild("tr");
- rowElement.title = WebInspector.UIString("Ratio between a device's physical pixels and device-independent pixels.");
- cellElement = rowElement.createChild("td");
- cellElement.appendChild(document.createTextNode(WebInspector.UIString("Device pixel ratio:")));
- cellElement = rowElement.createChild("td");
- this._deviceScaleFactorOverrideElement = this._createInput(cellElement, "metrics-override-device-scale", String(metrics.deviceScaleFactor || 1), this._applyDeviceMetricsUserInput.bind(this), true);
-
- var textAutosizingOverrideElement = this._createNonPersistedCheckbox(WebInspector.UIString("Enable text autosizing "), this._applyDeviceMetricsUserInput.bind(this));
- textAutosizingOverrideElement.title = WebInspector.UIString("Text autosizing is the feature that boosts font sizes on mobile devices.");
- this._textAutosizingOverrideCheckbox = textAutosizingOverrideElement.firstChild;
- this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing;
- fieldsetElement.appendChild(textAutosizingOverrideElement);
-
- var checkbox = this._createSettingCheckbox(WebInspector.UIString("Emulate viewport"), WebInspector.settings.emulateViewport);
- fieldsetElement.appendChild(checkbox);
-
- checkbox = this._createSettingCheckbox(WebInspector.UIString("Shrink to fit"), WebInspector.settings.deviceFitWindow);
- fieldsetElement.appendChild(checkbox);
-
- return fieldsetElement;
- },
-
- _updateDeviceMetricsElement: function()
- {
- const metricsSetting = WebInspector.settings.deviceMetrics.get();
- var metrics = WebInspector.OverridesSupport.DeviceMetrics.parseSetting(metricsSetting);
-
- if (this._widthOverrideElement.value !== metrics.width)
- this._widthOverrideElement.value = metrics.width || screen.width;
- this._muteRangeListener = true;
- if (this._widthRangeInput.value != metrics.width)
- this._widthRangeInput.value = metrics.width || screen.width;
- delete this._muteRangeListener;
- if (this._heightOverrideElement.value !== metrics.height)
- this._heightOverrideElement.value = metrics.height || screen.height;
- if (this._deviceScaleFactorOverrideElement.value !== metrics.deviceScaleFactor)
- this._deviceScaleFactorOverrideElement.value = metrics.deviceScaleFactor || 1;
- if (this._textAutosizingOverrideCheckbox.checked !== metrics.textAutosizing)
- this._textAutosizingOverrideCheckbox.checked = metrics.textAutosizing || false;
- },
-
- _createMediaEmulationElement: function()
- {
- var checkbox = WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("CSS media"), WebInspector.settings.overrideCSSMedia, true);
- var fieldsetElement = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.overrideCSSMedia);
- if (WebInspector.isInspectingDevice())
- fieldsetElement.disabled = true;
- checkbox.appendChild(fieldsetElement);
-
- var mediaSelectElement = fieldsetElement.createChild("select");
- var mediaTypes = WebInspector.CSSStyleModel.MediaTypes;
- var defaultMedia = WebInspector.settings.emulatedCSSMedia.get();
- for (var i = 0; i < mediaTypes.length; ++i) {
- var mediaType = mediaTypes[i];
- if (mediaType === "all") {
- // "all" is not a device-specific media type.
- continue;
- }
- var option = document.createElement("option");
- option.text = mediaType;
- option.value = mediaType;
- mediaSelectElement.add(option);
- if (mediaType === defaultMedia)
- mediaSelectElement.selectedIndex = mediaSelectElement.options.length - 1;
- }
-
- mediaSelectElement.addEventListener("change", this._emulateMediaChanged.bind(this, mediaSelectElement), false);
- return checkbox;
- },
-
- _emulateMediaChanged: function(select)
- {
- var media = select.options[select.selectedIndex].value;
- WebInspector.settings.emulatedCSSMedia.set(media);
- },
-
- _rangeValueChanged: function()
- {
- if (this._muteRangeListener)
- return;
- this._widthOverrideElement.value = this._widthRangeInput.value;
- this._applyDeviceMetricsUserInput();
- }
-}
-
-WebInspector.OverridesView.ViewportTab.prototype.__proto__ = WebInspector.OverridesView.Tab.prototype;
-
-
-/**
- * @constructor
- * @extends {WebInspector.OverridesView.Tab}
- */
-WebInspector.OverridesView.UserAgentTab = function()
-{
- WebInspector.OverridesView.Tab.call(this, "user-agent", WebInspector.UIString("User Agent"), [WebInspector.settings.overrideUserAgent]);
- this.element.classList.add("overrides-user-agent");
- var checkbox = this._createSettingCheckbox(WebInspector.UIString("Spoof user agent"), WebInspector.settings.overrideUserAgent);
- checkbox.firstChild.disabled = WebInspector.isInspectingDevice();
- this.element.appendChild(checkbox);
- this.element.appendChild(this._createUserAgentSelectRowElement());
-}
-
-WebInspector.OverridesView.UserAgentTab._userAgents = [
- ["Internet Explorer 10", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"],
- ["Internet Explorer 9", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"],
- ["Internet Explorer 8", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"],
- ["Internet Explorer 7", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"],
-
- ["Firefox 7 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
- ["Firefox 7 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"],
- ["Firefox 4 \u2014 Windows", "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
- ["Firefox 4 \u2014 Mac", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"],
- ["Firefox 14 \u2014 Android Mobile", "Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0"],
- ["Firefox 14 \u2014 Android Tablet", "Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0"],
-
- ["Chrome \u2014 Android Mobile", "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19"],
- ["Chrome \u2014 Android Tablet", "Mozilla/5.0 (Linux; Android 4.1.2; Nexus 7 Build/JZ054K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19"],
-
- ["iPhone \u2014 iOS 7", "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A4449d Safari/9537.53"],
- ["iPhone \u2014 iOS 6", "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"],
- ["iPad \u2014 iOS 7", "Mozilla/5.0 (iPad; CPU OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53"],
- ["iPad \u2014 iOS 6", "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25"],
-
- ["Android 2.3 \u2014 Nexus S", "Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"],
- ["Android 4.0.2 \u2014 Galaxy Nexus", "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"],
-
- ["BlackBerry \u2014 PlayBook 2.1", "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+"],
- ["BlackBerry \u2014 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.187 Mobile Safari/534.11+"],
- ["BlackBerry \u2014 BB10", "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.1+ (KHTML, like Gecko) Version/10.0.0.1337 Mobile Safari/537.1+"],
-
- ["MeeGo \u2014 Nokia N9", "Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13"],
-];
-
-WebInspector.OverridesView.UserAgentTab.prototype = {
- /**
- * @return {!Element}
- */
- _createUserAgentSelectRowElement: function()
- {
- var userAgent = WebInspector.settings.userAgent.get();
- var userAgents = WebInspector.OverridesView.UserAgentTab._userAgents.concat([[WebInspector.UIString("Other"), "Other"]]);
-
- var fieldsetElement = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.overrideUserAgent);
- if (WebInspector.isInspectingDevice())
- fieldsetElement.disabled = true;
-
- this._selectElement = fieldsetElement.createChild("select");
- fieldsetElement.createChild("br");
- this._otherUserAgentElement = fieldsetElement.createChild("input");
- this._otherUserAgentElement.type = "text";
- this._otherUserAgentElement.value = userAgent;
- this._otherUserAgentElement.title = userAgent;
-
- var selectionRestored = false;
- for (var i = 0; i < userAgents.length; ++i) {
- var agent = userAgents[i];
- var option = new Option(agent[0], agent[1]);
- option._metrics = agent[2] ? agent[2] : "";
- this._selectElement.add(option);
- if (userAgent === agent[1]) {
- this._selectElement.selectedIndex = i;
- selectionRestored = true;
- }
- }
-
- if (!selectionRestored) {
- if (!userAgent)
- this._selectElement.selectedIndex = 0;
- else
- this._selectElement.selectedIndex = userAgents.length - 1;
- }
-
- this._selectElement.addEventListener("change", this._userAgentChanged.bind(this, true), false);
- WebInspector.settings.userAgent.addChangeListener(this._userAgentSettingChanged, this);
-
- fieldsetElement.addEventListener("dblclick", textDoubleClicked.bind(this), false);
- this._otherUserAgentElement.addEventListener("blur", textChanged.bind(this), false);
-
- /**
- * @this {WebInspector.OverridesView.UserAgentTab}
- */
- function textDoubleClicked()
- {
- this._selectElement.selectedIndex = userAgents.length - 1;
- this._userAgentChanged();
- }
-
- /**
- * @this {WebInspector.OverridesView.UserAgentTab}
- */
- function textChanged()
- {
- if (WebInspector.settings.userAgent.get() !== this._otherUserAgentElement.value)
- WebInspector.settings.userAgent.set(this._otherUserAgentElement.value);
- }
-
- return fieldsetElement;
- },
-
- /**
- * @param {boolean=} isUserGesture
- */
- _userAgentChanged: function(isUserGesture)
- {
- var value = this._selectElement.options[this._selectElement.selectedIndex].value;
- if (value !== "Other") {
- WebInspector.settings.userAgent.set(value);
- this._otherUserAgentElement.value = value;
- this._otherUserAgentElement.title = value;
- this._otherUserAgentElement.disabled = true;
- } else {
- this._otherUserAgentElement.disabled = false;
- this._otherUserAgentElement.focus();
- }
- },
-
- _userAgentSettingChanged: function()
- {
- var value = WebInspector.settings.userAgent.get();
- var options = this._selectElement.options;
- var foundMatch = false;
- for (var i = 0; i < options.length; ++i) {
- if (options[i].value === value) {
- if (this._selectElement.selectedIndex !== i)
- this._selectElement.selectedIndex = i;
- foundMatch = true;
- break;
- }
- }
-
- this._otherUserAgentElement.disabled = foundMatch;
- if (!foundMatch)
- this._selectElement.selectedIndex = options.length - 1;
-
- if (this._otherUserAgentElement.value !== value) {
- this._otherUserAgentElement.value = value;
- this._otherUserAgentElement.title = value;
- }
- }
-}
-
-WebInspector.OverridesView.UserAgentTab.prototype.__proto__ = WebInspector.OverridesView.Tab.prototype;
-
-
-/**
- * @constructor
- * @extends {WebInspector.OverridesView.Tab}
- */
-WebInspector.OverridesView.SensorsTab = function()
-{
- WebInspector.OverridesView.Tab.call(this, "sensors", WebInspector.UIString("Sensors"), [WebInspector.settings.emulateTouchEvents, WebInspector.settings.overrideGeolocation, WebInspector.settings.overrideDeviceOrientation]);
- this.element.classList.add("overrides-sensors");
- this.registerRequiredCSS("accelerometer.css");
- if (!WebInspector.isInspectingDevice())
- this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate touch screen"), WebInspector.settings.emulateTouchEvents));
- this._appendGeolocationOverrideControl();
- if (!WebInspector.isInspectingDevice())
- this._apendDeviceOrientationOverrideControl();
-}
-
-WebInspector.OverridesView.SensorsTab.prototype = {
- _appendGeolocationOverrideControl: function()
- {
- const geolocationSetting = WebInspector.settings.geolocationOverride.get();
- var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(geolocationSetting);
- this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate geolocation coordinates"), WebInspector.settings.overrideGeolocation, this._geolocationOverrideCheckboxClicked.bind(this)));
- this.element.appendChild(this._createGeolocationOverrideElement(geolocation));
- this._geolocationOverrideCheckboxClicked(WebInspector.settings.overrideGeolocation.get());
- },
-
- /**
- * @param {boolean} enabled
- */
- _geolocationOverrideCheckboxClicked: function(enabled)
- {
- if (enabled && !this._latitudeElement.value)
- this._latitudeElement.focus();
- },
-
- _applyGeolocationUserInput: function()
- {
- this._setGeolocationPosition(WebInspector.OverridesSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked), true);
- },
-
- /**
- * @param {?WebInspector.OverridesSupport.GeolocationPosition} geolocation
- * @param {boolean} userInputModified
- */
- _setGeolocationPosition: function(geolocation, userInputModified)
- {
- if (!geolocation)
- return;
-
- if (!userInputModified) {
- this._latitudeElement.value = geolocation.latitude;
- this._longitudeElement.value = geolocation.longitude;
- }
-
- var value = geolocation.toSetting();
- WebInspector.settings.geolocationOverride.set(value);
- },
-
- /**
- * @param {!WebInspector.OverridesSupport.GeolocationPosition} geolocation
- * @return {!Element}
- */
- _createGeolocationOverrideElement: function(geolocation)
- {
- var fieldsetElement = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.overrideGeolocation);
- fieldsetElement.id = "geolocation-override-section";
-
- var tableElement = fieldsetElement.createChild("table");
- var rowElement = tableElement.createChild("tr");
- var cellElement = rowElement.createChild("td");
- cellElement = rowElement.createChild("td");
- cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lat = ")));
- this._latitudeElement = this._createInput(cellElement, "geolocation-override-latitude", String(geolocation.latitude), this._applyGeolocationUserInput.bind(this), true);
- cellElement.appendChild(document.createTextNode(" , "));
- cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lon = ")));
- this._longitudeElement = this._createInput(cellElement, "geolocation-override-longitude", String(geolocation.longitude), this._applyGeolocationUserInput.bind(this), true);
- rowElement = tableElement.createChild("tr");
- cellElement = rowElement.createChild("td");
- cellElement.colSpan = 2;
- var geolocationErrorLabelElement = document.createElement("label");
- var geolocationErrorCheckboxElement = geolocationErrorLabelElement.createChild("input");
- geolocationErrorCheckboxElement.id = "geolocation-error";
- geolocationErrorCheckboxElement.type = "checkbox";
- geolocationErrorCheckboxElement.checked = !geolocation || geolocation.error;
- geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
- geolocationErrorLabelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate position unavailable")));
- this._geolocationErrorElement = geolocationErrorCheckboxElement;
- cellElement.appendChild(geolocationErrorLabelElement);
-
- return fieldsetElement;
- },
-
- _apendDeviceOrientationOverrideControl: function()
- {
- const deviceOrientationSetting = WebInspector.settings.deviceOrientationOverride.get();
- var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(deviceOrientationSetting);
- this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Accelerometer"), WebInspector.settings.overrideDeviceOrientation, this._deviceOrientationOverrideCheckboxClicked.bind(this)));
- this.element.appendChild(this._createDeviceOrientationOverrideElement(deviceOrientation));
- this._deviceOrientationOverrideCheckboxClicked(WebInspector.settings.overrideDeviceOrientation.get());
- },
-
- /**
- * @param {boolean} enabled
- */
- _deviceOrientationOverrideCheckboxClicked: function(enabled)
- {
- if (enabled && !this._alphaElement.value)
- this._alphaElement.focus();
- },
-
- _applyDeviceOrientationUserInput: function()
- {
- this._setDeviceOrientation(WebInspector.OverridesSupport.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput);
- },
-
- _resetDeviceOrientation: function()
- {
- this._setDeviceOrientation(new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.ResetButton);
- },
-
- /**
- * @param {?WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
- * @param {!WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource} modificationSource
- */
- _setDeviceOrientation: function(deviceOrientation, modificationSource)
- {
- if (!deviceOrientation)
- return;
-
- if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput) {
- this._alphaElement.value = deviceOrientation.alpha;
- this._betaElement.value = deviceOrientation.beta;
- this._gammaElement.value = deviceOrientation.gamma;
- }
-
- if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag)
- this._setBoxOrientation(deviceOrientation);
-
- var value = deviceOrientation.toSetting();
- WebInspector.settings.deviceOrientationOverride.set(value);
- },
-
- /**
- * @param {!Element} parentElement
- * @param {string} id
- * @param {string} label
- * @param {string} defaultText
- * @return {!Element}
- */
- _createAxisInput: function(parentElement, id, label, defaultText)
- {
- var div = parentElement.createChild("div", "accelerometer-axis-input-container");
- div.appendChild(document.createTextNode(label));
- return this._createInput(div, id, defaultText, this._applyDeviceOrientationUserInput.bind(this), true);
- },
-
- /**
- * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
- */
- _createDeviceOrientationOverrideElement: function(deviceOrientation)
- {
- var fieldsetElement = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.overrideDeviceOrientation);
- fieldsetElement.id = "device-orientation-override-section";
- var tableElement = fieldsetElement.createChild("table");
- var rowElement = tableElement.createChild("tr");
- var cellElement = rowElement.createChild("td", "accelerometer-inputs-cell");
-
- this._alphaElement = this._createAxisInput(cellElement, "device-orientation-override-alpha", "\u03B1: ", String(deviceOrientation.alpha));
- this._betaElement = this._createAxisInput(cellElement, "device-orientation-override-beta", "\u03B2: ", String(deviceOrientation.beta));
- this._gammaElement = this._createAxisInput(cellElement, "device-orientation-override-gamma", "\u03B3: ", String(deviceOrientation.gamma));
-
- var resetButton = cellElement.createChild("button", "settings-tab-text-button accelerometer-reset-button");
- resetButton.textContent = WebInspector.UIString("Reset");
- resetButton.addEventListener("click", this._resetDeviceOrientation.bind(this), false);
-
- this._stageElement = rowElement.createChild("td","accelerometer-stage");
- this._boxElement = this._stageElement.createChild("section", "accelerometer-box");
-
- this._boxElement.createChild("section", "front");
- this._boxElement.createChild("section", "top");
- this._boxElement.createChild("section", "back");
- this._boxElement.createChild("section", "left");
- this._boxElement.createChild("section", "right");
- this._boxElement.createChild("section", "bottom");
-
- WebInspector.installDragHandle(this._stageElement, this._onBoxDragStart.bind(this), this._onBoxDrag.bind(this), this._onBoxDragEnd.bind(this), "move");
- this._setBoxOrientation(deviceOrientation);
- return fieldsetElement;
- },
-
- /**
- * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
- */
- _setBoxOrientation: function(deviceOrientation)
- {
- var matrix = new WebKitCSSMatrix();
- this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
- this._boxElement.style.webkitTransform = this._boxMatrix.toString();
- },
-
- /**
- * @param {!MouseEvent} event
- * @return {boolean}
- */
- _onBoxDrag: function(event)
- {
- var mouseMoveVector = this._calculateRadiusVector(event.x, event.y);
- if (!mouseMoveVector)
- return true;
-
- event.consume(true);
- var axis = WebInspector.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
- axis.normalize();
- var angle = WebInspector.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
- var matrix = new WebKitCSSMatrix();
- var rotationMatrix = matrix.rotateAxisAngle(axis.x, axis.y, axis.z, angle);
- this._currentMatrix = rotationMatrix.multiply(this._boxMatrix)
- this._boxElement.style.webkitTransform = this._currentMatrix;
- var eulerAngles = WebInspector.Geometry.EulerAngles.fromRotationMatrix(this._currentMatrix);
- var newOrientation = new WebInspector.OverridesSupport.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
- this._setDeviceOrientation(newOrientation, WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag);
- return false;
- },
-
- /**
- * @param {!MouseEvent} event
- * @return {boolean}
- */
- _onBoxDragStart: function(event)
- {
- if (!WebInspector.settings.overrideDeviceOrientation.get())
- return false;
-
- this._mouseDownVector = this._calculateRadiusVector(event.x, event.y);
-
- if (!this._mouseDownVector)
- return false;
-
- event.consume(true);
- return true;
- },
-
- _onBoxDragEnd: function()
- {
- this._boxMatrix = this._currentMatrix;
- },
-
- /**
- * @param {number} x
- * @param {number} y
- * @return {?WebInspector.Geometry.Vector}
- */
- _calculateRadiusVector: function(x, y)
- {
- var rect = this._stageElement.getBoundingClientRect();
- var radius = Math.max(rect.width, rect.height) / 2;
- var sphereX = (x - rect.left - rect.width / 2) / radius;
- var sphereY = (y - rect.top - rect.height / 2) / radius;
- var sqrSum = sphereX * sphereX + sphereY * sphereY;
- if (sqrSum > 0.5)
- return new WebInspector.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
-
- return new WebInspector.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
- },
-
- __proto__ : WebInspector.OverridesView.Tab.prototype
-}
-
-/** @enum {string} */
-WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource = {
- UserInput: "userInput",
- UserDrag: "userDrag",
- ResetButton: "resetButton"
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RawSourceCode.js b/chromium/third_party/WebKit/Source/devtools/front_end/RawSourceCode.js
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RawSourceCode.js
+++ /dev/null
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResponsiveDesignView.js b/chromium/third_party/WebKit/Source/devtools/front_end/ResponsiveDesignView.js
new file mode 100644
index 00000000000..d5d333d02f7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ResponsiveDesignView.js
@@ -0,0 +1,518 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @implements {WebInspector.OverridesSupport.PageResizer}
+ * @param {!WebInspector.InspectedPagePlaceholder} inspectedPagePlaceholder
+ */
+WebInspector.ResponsiveDesignView = function(inspectedPagePlaceholder)
+{
+ WebInspector.VBox.call(this);
+ this.setMinimumSize(150, 150);
+ this.registerRequiredCSS("responsiveDesignView.css");
+ this.element.classList.add("overflow-hidden");
+
+ this._responsiveDesignContainer = new WebInspector.VBox();
+
+ this._createToolbar();
+
+ this._mediaInspector = new WebInspector.MediaQueryInspector();
+ this._mediaInspectorContainer = this._responsiveDesignContainer.element.createChild("div");
+ this._updateMediaQueryInspector();
+
+ this._canvasContainer = new WebInspector.View();
+ this._canvasContainer.element.classList.add("responsive-design");
+ this._canvasContainer.show(this._responsiveDesignContainer.element);
+
+ this._canvas = this._canvasContainer.element.createChild("canvas", "fill");
+
+ this._rulerGlasspane = this._canvasContainer.element.createChild("div", "responsive-design-ruler-glasspane");
+ this._rulerGlasspane.appendChild(this._mediaInspector.rulerDecorationLayer());
+
+ this._warningMessage = this._canvasContainer.element.createChild("div", "responsive-design-warning hidden");
+ this._warningMessage.createChild("div", "warning-icon-small");
+ this._warningMessage.createChild("span");
+ var warningCloseButton = this._warningMessage.createChild("div", "close-button");
+ warningCloseButton.addEventListener("click", WebInspector.overridesSupport.clearWarningMessage.bind(WebInspector.overridesSupport), false);
+ WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.OverridesWarningUpdated, this._overridesWarningUpdated, this);
+
+ this._slidersContainer = this._canvasContainer.element.createChild("div", "vbox responsive-design-sliders-container");
+ var hbox = this._slidersContainer.createChild("div", "hbox flex-auto");
+ this._heightSliderContainer = this._slidersContainer.createChild("div", "hbox responsive-design-slider-height");
+ this._pageContainer = hbox.createChild("div", "vbox flex-auto");
+ this._widthSliderContainer = hbox.createChild("div", "vbox responsive-design-slider-width");
+
+ this._widthSlider = this._widthSliderContainer.createChild("div", "responsive-design-slider-thumb");
+ this._widthSlider.createChild("div", "responsive-design-thumb-handle");
+ this._createResizer(this._widthSlider, false);
+ this._heightSlider = this._heightSliderContainer.createChild("div", "responsive-design-slider-thumb");
+ this._heightSlider.createChild("div", "responsive-design-thumb-handle");
+ this._createResizer(this._heightSlider, true);
+
+ this._inspectedPagePlaceholder = inspectedPagePlaceholder;
+ inspectedPagePlaceholder.show(this.element);
+
+ this._enabled = false;
+
+ WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
+ WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.EmulationStateChanged, this._emulationEnabledChanged, this);
+ this._mediaInspector.addEventListener(WebInspector.MediaQueryInspector.Events.HeightUpdated, this.onResize, this);
+ this._emulationEnabledChanged();
+ this._overridesWarningUpdated();
+};
+
+// Measured in DIP.
+WebInspector.ResponsiveDesignView.SliderWidth = 19;
+WebInspector.ResponsiveDesignView.RulerWidth = 22;
+
+WebInspector.ResponsiveDesignView.prototype = {
+ _invalidateCache: function()
+ {
+ delete this._cachedScale;
+ delete this._cachedCssCanvasWidth;
+ delete this._cachedCssCanvasHeight;
+ delete this._cachedCssHeight;
+ delete this._cachedCssWidth;
+ delete this._cachedZoomFactor;
+ delete this._availableSize;
+ },
+
+ _emulationEnabledChanged: function()
+ {
+ var enabled = WebInspector.overridesSupport.emulationEnabled();
+ this._mediaInspector.setEnabled(enabled);
+ if (enabled && !this._enabled) {
+ this._invalidateCache();
+ this._ignoreResize = true;
+ this._enabled = true;
+ this._inspectedPagePlaceholder.clearMinimumSizeAndMargins();
+ this._inspectedPagePlaceholder.show(this._pageContainer);
+ this._responsiveDesignContainer.show(this.element);
+ delete this._ignoreResize;
+ this.onResize();
+ } else if (!enabled && this._enabled) {
+ this._invalidateCache();
+ this._ignoreResize = true;
+ this._enabled = false;
+ this._scale = 1;
+ this._inspectedPagePlaceholder.restoreMinimumSizeAndMargins();
+ this._responsiveDesignContainer.detach();
+ this._inspectedPagePlaceholder.show(this.element);
+ delete this._ignoreResize;
+ this.onResize();
+ }
+ },
+
+ /**
+ * WebInspector.OverridesSupport.PageResizer override.
+ * @param {number} dipWidth
+ * @param {number} dipHeight
+ * @param {number} scale
+ */
+ update: function(dipWidth, dipHeight, scale)
+ {
+ this._scale = scale;
+ this._dipWidth = dipWidth;
+ this._dipHeight = dipHeight;
+ this._updateUI();
+ },
+
+ updatePageResizer: function()
+ {
+ WebInspector.overridesSupport.setPageResizer(this, this._availableDipSize());
+ },
+
+ /**
+ * @return {!Size}
+ */
+ _availableDipSize: function()
+ {
+ if (typeof this._availableSize === "undefined") {
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var rect = this._canvasContainer.element.getBoundingClientRect();
+ this._availableSize = new Size(rect.width * zoomFactor - WebInspector.ResponsiveDesignView.RulerWidth,
+ rect.height * zoomFactor - WebInspector.ResponsiveDesignView.RulerWidth);
+ }
+ return this._availableSize;
+ },
+
+ /**
+ * @param {!Element} element
+ * @param {boolean} vertical
+ * @return {!WebInspector.ResizerWidget}
+ */
+ _createResizer: function(element, vertical)
+ {
+ var resizer = new WebInspector.ResizerWidget();
+ resizer.addElement(element);
+ resizer.setVertical(vertical);
+ resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
+ resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate, this);
+ resizer.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
+ return resizer;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeStart: function(event)
+ {
+ var available = this._availableDipSize();
+ this._slowPositionStart = null;
+ this._resizeStartSize = event.target.isVertical() ? (this._dipHeight || available.height) : (this._dipWidth || available.width);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeUpdate: function(event)
+ {
+ if (event.data.shiftKey !== !!this._slowPositionStart)
+ this._slowPositionStart = event.data.shiftKey ? event.data.currentPosition : null;
+ var cssOffset = this._slowPositionStart ? (event.data.currentPosition - this._slowPositionStart) / 10 + this._slowPositionStart - event.data.startPosition : event.data.currentPosition - event.data.startPosition;
+ var dipOffset = Math.round(cssOffset * WebInspector.zoomManager.zoomFactor());
+ var newSize = Math.max(this._resizeStartSize + dipOffset, 1);
+ var requested = {};
+ if (event.target.isVertical())
+ requested.height = newSize;
+ else
+ requested.width = newSize;
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, requested);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeEnd: function(event)
+ {
+ delete this._resizeStartSize;
+ },
+
+ /**
+ * Draws canvas of the specified css size in DevTools page space.
+ * Canvas contains grid and rulers.
+ * @param {number} cssCanvasWidth
+ * @param {number} cssCanvasHeight
+ */
+ _drawCanvas: function(cssCanvasWidth, cssCanvasHeight)
+ {
+ if (!this._enabled)
+ return;
+
+ var canvas = this._canvas;
+ var context = canvas.getContext("2d");
+ canvas.style.width = cssCanvasWidth + "px";
+ canvas.style.height = cssCanvasHeight + "px";
+
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var dipCanvasWidth = cssCanvasWidth * zoomFactor;
+ var dipCanvasHeight = cssCanvasHeight * zoomFactor;
+
+ var deviceScaleFactor = window.devicePixelRatio;
+ canvas.width = deviceScaleFactor * cssCanvasWidth;
+ canvas.height = deviceScaleFactor * cssCanvasHeight;
+ context.scale(canvas.width / dipCanvasWidth, canvas.height / dipCanvasHeight);
+ context.font = "11px " + WebInspector.fontFamily();
+
+ const rulerStep = 100;
+ const rulerSubStep = 5;
+ const gridStep = 50;
+ const gridSubStep = 10;
+ const rulerBackgroundColor = "rgb(0, 0, 0)";
+ const backgroundColor = "rgb(102, 102, 102)";
+ const lightLineColor = "rgb(132, 132, 132)";
+ const darkLineColor = "rgb(114, 114, 114)";
+ const rulerColor = "rgb(125, 125, 125)";
+ const textColor = "rgb(186, 186, 186)";
+
+ var scale = this._scale || 1;
+ var rulerWidth = WebInspector.ResponsiveDesignView.RulerWidth;
+ var dipGridWidth = dipCanvasWidth / scale - rulerWidth;
+ var dipGridHeight = dipCanvasHeight / scale - rulerWidth;
+ rulerWidth /= scale;
+ context.scale(scale, scale);
+ context.translate(rulerWidth, rulerWidth);
+
+ context.fillStyle = rulerBackgroundColor;
+ context.fillRect(-rulerWidth, -rulerWidth, dipGridWidth + rulerWidth, rulerWidth);
+ context.fillRect(-rulerWidth, 0, rulerWidth, dipGridHeight);
+
+ context.fillStyle = backgroundColor;
+ context.fillRect(0, 0, dipGridWidth, dipGridHeight);
+
+ context.translate(0.5, 0.5);
+ context.strokeStyle = rulerColor;
+ context.fillStyle = textColor;
+ context.lineWidth = 1;
+
+ // Draw vertical ruler.
+ for (var x = 0; x < dipGridWidth; x += rulerSubStep) {
+ var y = -rulerWidth / 4;
+ if (!(x % (rulerStep / 4)))
+ y = -rulerWidth / 2;
+ if (!(x % (rulerStep / 2)))
+ y = -rulerWidth + 2;
+
+ if (!(x % rulerStep)) {
+ context.save();
+ context.translate(x, 0);
+ context.fillText(x, 2, -rulerWidth / 2);
+ context.restore();
+ y = -rulerWidth;
+ }
+
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(x, 0);
+ context.stroke();
+ }
+
+ // Draw horizontal ruler.
+ for (var y = 0; y < dipGridHeight; y += rulerSubStep) {
+ x = -rulerWidth / 4;
+ if (!(y % (rulerStep / 4)))
+ x = -rulerWidth / 2;
+ if (!(y % (rulerStep / 2)))
+ x = -rulerWidth + 2;
+
+ if (!(y % rulerStep)) {
+ context.save();
+ context.translate(0, y);
+ context.rotate(-Math.PI / 2);
+ context.fillText(y, 2, -rulerWidth / 2);
+ context.restore();
+ x = -rulerWidth;
+ }
+
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(0, y);
+ context.stroke();
+ }
+
+ // Draw grid.
+ drawGrid(darkLineColor, gridSubStep);
+ drawGrid(lightLineColor, gridStep);
+
+ /**
+ * @param {string} color
+ * @param {number} step
+ */
+ function drawGrid(color, step)
+ {
+ context.strokeStyle = color;
+ for (var x = 0; x < dipGridWidth; x += step) {
+ context.beginPath();
+ context.moveTo(x, 0);
+ context.lineTo(x, dipGridHeight);
+ context.stroke();
+ }
+ for (var y = 0; y < dipGridHeight; y += step) {
+ context.beginPath();
+ context.moveTo(0, y);
+ context.lineTo(dipGridWidth, y);
+ context.stroke();
+ }
+ }
+ },
+
+ _updateUI: function()
+ {
+ if (!this._enabled || !this.isShowing())
+ return;
+
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var rect = this._canvas.parentElement.getBoundingClientRect();
+ var availableDip = this._availableDipSize();
+ var cssCanvasWidth = rect.width;
+ var cssCanvasHeight = rect.height;
+
+ this._widthSlider.classList.toggle("hidden", !!this._scale);
+ this._heightSlider.classList.toggle("hidden", !!this._scale);
+ this._widthSlider.classList.toggle("reversed", !this._dipWidth);
+ this._heightSlider.classList.toggle("reversed", !this._dipHeight);
+
+ if (this._cachedZoomFactor !== zoomFactor) {
+ var cssRulerWidth = WebInspector.ResponsiveDesignView.RulerWidth / zoomFactor + "px";
+ this._rulerGlasspane.style.height = cssRulerWidth;
+ this._rulerGlasspane.style.left = cssRulerWidth;
+ this._slidersContainer.style.left = cssRulerWidth;
+ this._mediaInspector.translateZero(WebInspector.ResponsiveDesignView.RulerWidth / zoomFactor);
+ this._slidersContainer.style.top = cssRulerWidth;
+ this._warningMessage.style.height = cssRulerWidth;
+
+ var cssSliderWidth = WebInspector.ResponsiveDesignView.SliderWidth / zoomFactor + "px";
+ this._heightSliderContainer.style.flexBasis = cssSliderWidth;
+ this._heightSliderContainer.style.marginBottom = "-" + cssSliderWidth;
+ this._widthSliderContainer.style.flexBasis = cssSliderWidth;
+ this._widthSliderContainer.style.marginRight = "-" + cssSliderWidth;
+ }
+
+ var cssWidth = this._dipWidth ? (this._dipWidth / zoomFactor + "px") : (availableDip.width / zoomFactor + "px");
+ var cssHeight = this._dipHeight ? (this._dipHeight / zoomFactor + "px") : (availableDip.height / zoomFactor + "px");
+ if (this._cachedCssWidth !== cssWidth || this._cachedCssHeight !== cssHeight) {
+ this._slidersContainer.style.width = cssWidth;
+ this._slidersContainer.style.height = cssHeight;
+ this._inspectedPagePlaceholder.onResize();
+ }
+
+ if (this._cachedScale !== this._scale || this._cachedCssCanvasWidth !== cssCanvasWidth || this._cachedCssCanvasHeight !== cssCanvasHeight || this._cachedZoomFactor !== zoomFactor)
+ this._drawCanvas(cssCanvasWidth, cssCanvasHeight);
+
+ this._cachedScale = this._scale;
+ this._cachedCssCanvasWidth = cssCanvasWidth;
+ this._cachedCssCanvasHeight = cssCanvasHeight;
+ this._cachedCssHeight = cssHeight;
+ this._cachedCssWidth = cssWidth;
+ this._cachedZoomFactor = zoomFactor;
+ },
+
+ onResize: function()
+ {
+ if (!this._enabled || this._ignoreResize)
+ return;
+ var oldSize = this._availableSize;
+ delete this._availableSize;
+ var newSize = this._availableDipSize();
+ if (!newSize.isEqual(oldSize))
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, newSize);
+ this._updateUI();
+ this._inspectedPagePlaceholder.onResize();
+ },
+
+ _onZoomChanged: function()
+ {
+ this._updateUI();
+ },
+
+ _createToolbar: function()
+ {
+ this._toolbarElement = this._responsiveDesignContainer.element.createChild("div", "responsive-design-toolbar");
+ this._createButtonsSection();
+ this._toolbarElement.createChild("div", "responsive-design-separator");
+ this._createDeviceSection();
+ if (WebInspector.experimentsSettings.networkConditions.isEnabled()) {
+ this._toolbarElement.createChild("div", "responsive-design-separator");
+ this._createNetworkSection();
+ }
+ this._toolbarElement.createChild("div", "responsive-design-separator");
+
+ var moreButtonContainer = this._toolbarElement.createChild("div", "responsive-design-more-button-container");
+ var moreButton = moreButtonContainer.createChild("button", "responsive-design-more-button");
+ moreButton.title = WebInspector.UIString("More overrides");
+ moreButton.addEventListener("click", this._showEmulationInDrawer.bind(this), false);
+ moreButton.textContent = "\u2026";
+ },
+
+ _createButtonsSection: function()
+ {
+ var buttonsSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-buttons");
+
+ var resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("Reset all overrides."), "clear-status-bar-item");
+ buttonsSection.appendChild(resetButton.element);
+ resetButton.addEventListener("click", WebInspector.overridesSupport.reset, WebInspector.overridesSupport);
+
+ // Media Query Inspector.
+ this._toggleMediaInspectorButton = new WebInspector.StatusBarButton(WebInspector.UIString("Media queries."), "responsive-design-toggle-media-inspector");
+ this._toggleMediaInspectorButton.toggled = WebInspector.settings.showMediaQueryInspector.get();
+ this._toggleMediaInspectorButton.addEventListener("click", this._onToggleMediaInspectorButtonClick, this);
+ WebInspector.settings.showMediaQueryInspector.addChangeListener(this._updateMediaQueryInspector, this);
+ buttonsSection.appendChild(this._toggleMediaInspectorButton.element);
+ },
+
+ _createDeviceSection: function()
+ {
+ var deviceSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-device");
+
+ // Device.
+ var deviceElement = deviceSection.createChild("div", "responsive-design-suite responsive-design-suite-top").createChild("div");
+ var fieldsetElement = deviceElement.createChild("fieldset");
+ fieldsetElement.createChild("label").textContent = WebInspector.UIString("Device");
+ fieldsetElement.appendChild(WebInspector.overridesSupport.createDeviceSelect(document));
+
+ var separator = deviceSection.createChild("div", "responsive-design-section-separator");
+
+ var detailsElement = deviceSection.createChild("div", "responsive-design-suite");
+
+ // Dimensions.
+ var screenElement = detailsElement.createChild("div", "");
+ fieldsetElement = screenElement.createChild("fieldset");
+ var resolutionButton = new WebInspector.StatusBarButton(WebInspector.UIString("Screen resolution"), "responsive-design-icon responsive-design-icon-resolution");
+ resolutionButton.setEnabled(false);
+ fieldsetElement.appendChild(resolutionButton.element);
+ fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceWidth, true, 4, "3em", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013")));
+ fieldsetElement.appendChild(document.createTextNode(" \u00D7 "));
+ fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceHeight, true, 4, "3em", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013")));
+
+ var swapButton = new WebInspector.StatusBarButton(WebInspector.UIString("Swap dimensions"), "responsive-design-icon responsive-design-icon-swap");
+ swapButton.element.tabIndex = -1;
+ swapButton.addEventListener("click", WebInspector.overridesSupport.swapDimensions, WebInspector.overridesSupport);
+ fieldsetElement.appendChild(swapButton.element);
+
+ // Device pixel ratio.
+ detailsElement.createChild("div", "responsive-design-suite-separator");
+ var dprElement = detailsElement.createChild("div", "");
+ fieldsetElement = dprElement.createChild("fieldset");
+ var dprButton = new WebInspector.StatusBarButton(WebInspector.UIString("Device pixel ratio"), "responsive-design-icon responsive-design-icon-dpr");
+ dprButton.setEnabled(false);
+ fieldsetElement.appendChild(dprButton.element);
+ fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceScaleFactor, true, 4, "2.5em", WebInspector.OverridesSupport.deviceScaleFactorValidator, true, true, WebInspector.UIString("\u2013")));
+ },
+
+ _createNetworkSection: function()
+ {
+ var networkSection = this._toolbarElement.createChild("div", "responsive-design-section responsive-design-section-network");
+
+ // Bandwidth.
+ var bandwidthElement = networkSection.createChild("div", "responsive-design-suite responsive-design-suite-top").createChild("div");
+ var fieldsetElement = bandwidthElement.createChild("fieldset");
+ var networkCheckbox = fieldsetElement.createChild("label");
+ networkCheckbox.textContent = WebInspector.UIString("Network");
+ fieldsetElement.appendChild(WebInspector.overridesSupport.createNetworkThroughputSelect(document));
+
+ var separator = networkSection.createChild("div", "responsive-design-section-separator");
+
+ // User agent.
+ var userAgentElement = networkSection.createChild("div", "responsive-design-suite").createChild("div");
+ fieldsetElement = userAgentElement.createChild("fieldset");
+ fieldsetElement.appendChild(WebInspector.SettingsUI.createSettingInputField("UA", WebInspector.overridesSupport.settings.userAgent, false, 0, "", undefined, false, false, WebInspector.UIString("No override")));
+ },
+
+ _onToggleMediaInspectorButtonClick: function()
+ {
+ WebInspector.settings.showMediaQueryInspector.set(!this._toggleMediaInspectorButton.toggled);
+ },
+
+ _updateMediaQueryInspector: function()
+ {
+ this._toggleMediaInspectorButton.toggled = WebInspector.settings.showMediaQueryInspector.get();
+ if (this._mediaInspector.isShowing() === WebInspector.settings.showMediaQueryInspector.get())
+ return;
+ if (this._mediaInspector.isShowing())
+ this._mediaInspector.detach();
+ else
+ this._mediaInspector.show(this._mediaInspectorContainer);
+ this.onResize();
+ },
+
+ _overridesWarningUpdated: function()
+ {
+ var message = WebInspector.overridesSupport.warningMessage();
+ if (this._warningMessage.querySelector("span").textContent === message)
+ return;
+ this._warningMessage.classList.toggle("hidden", !message);
+ this._warningMessage.querySelector("span").textContent = message;
+ this._invalidateCache();
+ this.onResize();
+ },
+
+ _showEmulationInDrawer: function()
+ {
+ WebInspector.overridesSupport.reveal();
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ScreencastView.js b/chromium/third_party/WebKit/Source/devtools/front_end/ScreencastView.js
index 9eeb24216a9..3344a14fa7a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ScreencastView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ScreencastView.js
@@ -30,74 +30,81 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @implements {WebInspector.DOMNodeHighlighter}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.ScreencastView = function()
+WebInspector.ScreencastView = function(target)
{
- WebInspector.View.call(this);
- this.registerRequiredCSS("screencastView.css");
+ WebInspector.VBox.call(this);
+ this._target = target;
- this.element.classList.add("fill");
- this.element.classList.add("screencast");
-
- this._createNavigationBar();
-
- this._viewportElement = this.element.createChild("div", "screencast-viewport hidden");
- this._glassPaneElement = this.element.createChild("div", "screencast-glasspane hidden");
-
- this._canvasElement = this._viewportElement.createChild("canvas");
- this._canvasElement.tabIndex = 1;
- this._canvasElement.addEventListener("mousedown", this._handleMouseEvent.bind(this), false);
- this._canvasElement.addEventListener("mouseup", this._handleMouseEvent.bind(this), false);
- this._canvasElement.addEventListener("mousemove", this._handleMouseEvent.bind(this), false);
- this._canvasElement.addEventListener("mousewheel", this._handleMouseEvent.bind(this), false);
- this._canvasElement.addEventListener("click", this._handleMouseEvent.bind(this), false);
- this._canvasElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
- this._canvasElement.addEventListener("keydown", this._handleKeyEvent.bind(this), false);
- this._canvasElement.addEventListener("keyup", this._handleKeyEvent.bind(this), false);
- this._canvasElement.addEventListener("keypress", this._handleKeyEvent.bind(this), false);
-
- this._titleElement = this._viewportElement.createChild("div", "screencast-element-title monospace hidden");
- this._tagNameElement = this._titleElement.createChild("span", "screencast-tag-name");
- this._nodeIdElement = this._titleElement.createChild("span", "screencast-node-id");
- this._classNameElement = this._titleElement.createChild("span", "screencast-class-name");
- this._titleElement.appendChild(document.createTextNode(" "));
- this._nodeWidthElement = this._titleElement.createChild("span");
- this._titleElement.createChild("span", "screencast-px").textContent = "px";
- this._titleElement.appendChild(document.createTextNode(" \u00D7 "));
- this._nodeHeightElement = this._titleElement.createChild("span");
- this._titleElement.createChild("span", "screencast-px").textContent = "px";
-
- this._imageElement = new Image();
- this._isCasting = false;
- this._context = this._canvasElement.getContext("2d");
- this._checkerboardPattern = this._createCheckerboardPattern(this._context);
-
- this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
- this._shortcuts[WebInspector.KeyboardShortcut.makeKey("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl)] = this._focusNavigationBar.bind(this);
-
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, this._screencastFrame, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, this._screencastVisibilityChanged, this);
-
- WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onTimeline.bind(this, true), this);
- WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onTimeline.bind(this, false), this);
- this._timelineActive = WebInspector.timelineManager.isStarted();
-
- WebInspector.cpuProfilerModel.addEventListener(WebInspector.CPUProfilerModel.EventTypes.ProfileStarted, this._onProfiler.bind(this, true), this);
- WebInspector.cpuProfilerModel.addEventListener(WebInspector.CPUProfilerModel.EventTypes.ProfileStopped, this._onProfiler.bind(this, false), this);
- this._profilerActive = WebInspector.cpuProfilerModel.isRecordingProfile();
-
- this._updateGlasspane();
-}
+ this.setMinimumSize(150, 150);
+ this.registerRequiredCSS("screencastView.css");
+};
-WebInspector.ScreencastView._bordersSize = 40;
+WebInspector.ScreencastView._bordersSize = 44;
WebInspector.ScreencastView._navBarHeight = 29;
WebInspector.ScreencastView._HttpRegex = /^https?:\/\/(.+)/;
WebInspector.ScreencastView.prototype = {
+ initialize: function()
+ {
+ this.element.classList.add("screencast");
+
+ this._createNavigationBar();
+
+ this._viewportElement = this.element.createChild("div", "screencast-viewport hidden");
+ this._canvasContainerElement = this._viewportElement.createChild("div", "screencast-canvas-container");
+ this._glassPaneElement = this._canvasContainerElement.createChild("div", "screencast-glasspane hidden");
+
+ this._canvasElement = this._canvasContainerElement.createChild("canvas");
+ this._canvasElement.tabIndex = 1;
+ this._canvasElement.addEventListener("mousedown", this._handleMouseEvent.bind(this), false);
+ this._canvasElement.addEventListener("mouseup", this._handleMouseEvent.bind(this), false);
+ this._canvasElement.addEventListener("mousemove", this._handleMouseEvent.bind(this), false);
+ this._canvasElement.addEventListener("mousewheel", this._handleMouseEvent.bind(this), false);
+ this._canvasElement.addEventListener("click", this._handleMouseEvent.bind(this), false);
+ this._canvasElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
+ this._canvasElement.addEventListener("keydown", this._handleKeyEvent.bind(this), false);
+ this._canvasElement.addEventListener("keyup", this._handleKeyEvent.bind(this), false);
+ this._canvasElement.addEventListener("keypress", this._handleKeyEvent.bind(this), false);
+
+ this._titleElement = this._canvasContainerElement.createChild("div", "screencast-element-title monospace hidden");
+ this._tagNameElement = this._titleElement.createChild("span", "screencast-tag-name");
+ this._nodeIdElement = this._titleElement.createChild("span", "screencast-node-id");
+ this._classNameElement = this._titleElement.createChild("span", "screencast-class-name");
+ this._titleElement.appendChild(document.createTextNode(" "));
+ this._nodeWidthElement = this._titleElement.createChild("span");
+ this._titleElement.createChild("span", "screencast-px").textContent = "px";
+ this._titleElement.appendChild(document.createTextNode(" \u00D7 "));
+ this._nodeHeightElement = this._titleElement.createChild("span");
+ this._titleElement.createChild("span", "screencast-px").textContent = "px";
+
+ this._imageElement = new Image();
+ this._isCasting = false;
+ this._context = this._canvasElement.getContext("2d");
+ this._checkerboardPattern = this._createCheckerboardPattern(this._context);
+
+ this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
+ this._shortcuts[WebInspector.KeyboardShortcut.makeKey("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl)] = this._focusNavigationBar.bind(this);
+
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, this._screencastFrame, this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, this._screencastVisibilityChanged, this);
+
+ WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onTimeline.bind(this, true), this);
+ WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onTimeline.bind(this, false), this);
+ this._timelineActive = WebInspector.timelineManager.isStarted();
+
+ WebInspector.cpuProfilerModel.addEventListener(WebInspector.CPUProfilerModel.EventTypes.ProfileStarted, this._onProfiler.bind(this, true), this);
+ WebInspector.cpuProfilerModel.addEventListener(WebInspector.CPUProfilerModel.EventTypes.ProfileStopped, this._onProfiler.bind(this, false), this);
+ this._profilerActive = WebInspector.cpuProfilerModel.isRecordingProfile();
+
+ this._updateGlasspane();
+ },
+
wasShown: function()
{
this._startCasting();
@@ -122,10 +129,10 @@ WebInspector.ScreencastView.prototype = {
this._isCasting = false;
return;
}
- dimensions.width *= WebInspector.zoomFactor();
- dimensions.height *= WebInspector.zoomFactor();
- PageAgent.startScreencast("jpeg", 80, Math.min(maxImageDimension, dimensions.width), Math.min(maxImageDimension, dimensions.height));
- WebInspector.domAgent.setHighlighter(this);
+ dimensions.width *= WebInspector.zoomManager.zoomFactor();
+ dimensions.height *= WebInspector.zoomManager.zoomFactor();
+ this._target.pageAgent().startScreencast("jpeg", 80, Math.min(maxImageDimension, dimensions.width), Math.min(maxImageDimension, dimensions.height));
+ this._target.domModel.setHighlighter(this);
},
_stopCasting: function()
@@ -133,8 +140,8 @@ WebInspector.ScreencastView.prototype = {
if (!this._isCasting)
return;
this._isCasting = false;
- PageAgent.stopScreencast();
- WebInspector.domAgent.setHighlighter(null);
+ this._target.pageAgent().stopScreencast();
+ this._target.domModel.setHighlighter(null);
},
/**
@@ -165,7 +172,7 @@ WebInspector.ScreencastView.prototype = {
this._resizeViewport(screenWidthDIP, screenHeightDIP);
this._imageZoom = this._imageElement.naturalWidth ? this._canvasElement.offsetWidth / this._imageElement.naturalWidth : 1;
- this.highlightDOMNode(this._highlightNodeId, this._highlightConfig);
+ this.highlightDOMNode(this._highlightNode, this._highlightConfig);
},
_isGlassPaneActive: function()
@@ -198,6 +205,7 @@ WebInspector.ScreencastView.prototype = {
/**
* @param {boolean} on
+ * @param {!WebInspector.Event} event
* @private
*/
_onProfiler: function(on, event) {
@@ -241,7 +249,7 @@ WebInspector.ScreencastView.prototype = {
},
/**
- * @param {!Event} event
+ * @param {?Event} event
*/
_handleMouseEvent: function(event)
{
@@ -262,26 +270,25 @@ WebInspector.ScreencastView.prototype = {
}
var position = this._convertIntoScreenSpace(event);
- DOMAgent.getNodeForLocation(position.x / this._pageScaleFactor, position.y / this._pageScaleFactor, callback.bind(this));
+ this._target.domModel.nodeForLocation(position.x / this._pageScaleFactor, position.y / this._pageScaleFactor, callback.bind(this));
/**
- * @param {?Protocol.Error} error
- * @param {number} nodeId
+ * @param {?WebInspector.DOMNode} node
* @this {WebInspector.ScreencastView}
*/
- function callback(error, nodeId)
+ function callback(node)
{
- if (error)
+ if (!node)
return;
if (event.type === "mousemove")
- this.highlightDOMNode(nodeId, this._inspectModeConfig);
+ this.highlightDOMNode(node, this._inspectModeConfig);
else if (event.type === "click")
- WebInspector.domAgent.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectNodeRequested, nodeId);
+ node.reveal();
}
},
/**
- * @param {!KeyboardEvent} event
+ * @param {?Event} event
*/
_handleKeyEvent: function(event)
{
@@ -290,7 +297,7 @@ WebInspector.ScreencastView.prototype = {
return;
}
- var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(/** @type {!KeyboardEvent} */ (event));
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event)) {
event.consume();
@@ -307,13 +314,13 @@ WebInspector.ScreencastView.prototype = {
var text = event.type === "keypress" ? String.fromCharCode(event.charCode) : undefined;
InputAgent.dispatchKeyEvent(type, this._modifiersForEvent(event), event.timeStamp / 1000, text, text ? text.toLowerCase() : undefined,
- event.keyIdentifier, event.keyCode /* windowsVirtualKeyCode */, event.keyCode /* nativeVirtualKeyCode */, undefined /* macCharCode */, false, false, false);
+ event.keyIdentifier, event.keyCode /* windowsVirtualKeyCode */, event.keyCode /* nativeVirtualKeyCode */, false, false, false);
event.consume();
this._canvasElement.focus();
},
/**
- * @param {!Event} event
+ * @param {?Event} event
*/
_handleContextMenuEvent: function(event)
{
@@ -321,92 +328,193 @@ WebInspector.ScreencastView.prototype = {
},
/**
- * @param {!Event} event
+ * @param {?Event} event
*/
_simulateTouchGestureForMouseEvent: function(event)
{
- var position = this._convertIntoScreenSpace(event);
+ var convertedPosition = this._convertIntoScreenSpace(event);
+ var zoomedPosition = this._zoomIntoScreenSpace(event);
var timeStamp = event.timeStamp / 1000;
- var x = position.x;
- var y = position.y;
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function clearPinch()
+ {
+ delete this._lastPinchAnchor;
+ delete this._lastPinchZoomedY;
+ delete this._lastPinchScale;
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function clearScroll()
+ {
+ delete this._lastScrollZoomedPosition;
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function scrollBegin()
+ {
+ InputAgent.dispatchGestureEvent("scrollBegin", convertedPosition.x, convertedPosition.y, timeStamp);
+ this._lastScrollZoomedPosition = zoomedPosition;
+ clearPinch.call(this);
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function scrollUpdate()
+ {
+ var dx = this._lastScrollZoomedPosition ? zoomedPosition.x - this._lastScrollZoomedPosition.x : 0;
+ var dy = this._lastScrollZoomedPosition ? zoomedPosition.y - this._lastScrollZoomedPosition.y : 0;
+ if (dx || dy) {
+ InputAgent.dispatchGestureEvent("scrollUpdate", convertedPosition.x, convertedPosition.y, timeStamp, dx, dy);
+ this._lastScrollZoomedPosition = zoomedPosition;
+ }
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function scrollEnd()
+ {
+ if (this._lastScrollZoomedPosition) {
+ InputAgent.dispatchGestureEvent("scrollEnd", convertedPosition.x, convertedPosition.y, timeStamp);
+ clearScroll.call(this);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function pinchBegin()
+ {
+ InputAgent.dispatchGestureEvent("pinchBegin", convertedPosition.x, convertedPosition.y, timeStamp);
+ this._lastPinchAnchor = convertedPosition;
+ this._lastPinchZoomedY = zoomedPosition.y;
+ this._lastPinchScale = 1;
+ clearScroll.call(this);
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function pinchUpdate()
+ {
+ var dy = this._lastPinchZoomedY ? this._lastPinchZoomedY - zoomedPosition.y : 0;
+ if (dy) {
+ var scale = Math.exp(dy * 0.002);
+ InputAgent.dispatchGestureEvent("pinchUpdate", this._lastPinchAnchor.x, this._lastPinchAnchor.y, timeStamp, 0, 0, scale / this._lastPinchScale);
+ this._lastPinchScale = scale;
+ }
+ }
+
+ /**
+ * @this {!WebInspector.ScreencastView}
+ */
+ function pinchEnd()
+ {
+ if (this._lastPinchAnchor) {
+ InputAgent.dispatchGestureEvent("pinchEnd", this._lastPinchAnchor.x, this._lastPinchAnchor.y, timeStamp);
+ clearPinch.call(this);
+ return true;
+ }
+ return false;
+ }
switch (event.which) {
case 1: // Left
if (event.type === "mousedown") {
- InputAgent.dispatchGestureEvent("scrollBegin", x, y, timeStamp);
+ if (event.shiftKey) {
+ pinchBegin.call(this);
+ } else {
+ scrollBegin.call(this);
+ }
} else if (event.type === "mousemove") {
- var dx = this._lastScrollPosition ? position.x - this._lastScrollPosition.x : 0;
- var dy = this._lastScrollPosition ? position.y - this._lastScrollPosition.y : 0;
- if (dx || dy)
- InputAgent.dispatchGestureEvent("scrollUpdate", x, y, timeStamp, dx, dy);
+ if (event.shiftKey) {
+ if (scrollEnd.call(this))
+ pinchBegin.call(this);
+ pinchUpdate.call(this);
+ } else {
+ if (pinchEnd.call(this))
+ scrollBegin.call(this);
+ scrollUpdate.call(this);
+ }
} else if (event.type === "mouseup") {
- InputAgent.dispatchGestureEvent("scrollEnd", x, y, timeStamp);
+ pinchEnd.call(this);
+ scrollEnd.call(this);
} else if (event.type === "mousewheel") {
- if (event.altKey) {
- var factor = 1.1;
- var scale = event.wheelDeltaY < 0 ? 1 / factor : factor;
- InputAgent.dispatchGestureEvent("pinchBegin", x, y, timeStamp);
- InputAgent.dispatchGestureEvent("pinchUpdate", x, y, timeStamp, 0, 0, scale);
- InputAgent.dispatchGestureEvent("pinchEnd", x, y, timeStamp);
- } else {
- InputAgent.dispatchGestureEvent("scrollBegin", x, y, timeStamp);
- InputAgent.dispatchGestureEvent("scrollUpdate", x, y, timeStamp, event.wheelDeltaX, event.wheelDeltaY);
- InputAgent.dispatchGestureEvent("scrollEnd", x, y, timeStamp);
+ if (!this._lastPinchAnchor && !this._lastScrollZoomedPosition) {
+ if (event.shiftKey) {
+ var factor = 1.1;
+ var scale = event.wheelDeltaY < 0 ? 1 / factor : factor;
+ InputAgent.dispatchGestureEvent("pinchBegin", convertedPosition.x, convertedPosition.y, timeStamp);
+ InputAgent.dispatchGestureEvent("pinchUpdate", convertedPosition.x, convertedPosition.y, timeStamp, 0, 0, scale);
+ InputAgent.dispatchGestureEvent("pinchEnd", convertedPosition.x, convertedPosition.y, timeStamp);
+ } else {
+ InputAgent.dispatchGestureEvent("scrollBegin", convertedPosition.x, convertedPosition.y, timeStamp);
+ InputAgent.dispatchGestureEvent("scrollUpdate", convertedPosition.x, convertedPosition.y, timeStamp, event.wheelDeltaX, event.wheelDeltaY);
+ InputAgent.dispatchGestureEvent("scrollEnd", convertedPosition.x, convertedPosition.y, timeStamp);
+ }
}
} else if (event.type === "click") {
- InputAgent.dispatchMouseEvent("mousePressed", x, y, 0, timeStamp, "left", 1, true);
- InputAgent.dispatchMouseEvent("mouseReleased", x, y, 0, timeStamp, "left", 1, true);
- // FIXME: migrate to tap once it dispatches clicks again.
- // InputAgent.dispatchGestureEvent("tapDown", x, y, timeStamp);
- // InputAgent.dispatchGestureEvent("tap", x, y, timeStamp);
+ if (!event.shiftKey) {
+ InputAgent.dispatchMouseEvent("mousePressed", convertedPosition.x, convertedPosition.y, 0, timeStamp, "left", 1, true);
+ InputAgent.dispatchMouseEvent("mouseReleased", convertedPosition.x, convertedPosition.y, 0, timeStamp, "left", 1, true);
+ // FIXME: migrate to tap once it dispatches clicks again.
+ // InputAgent.dispatchGestureEvent("tapDown", x, y, timeStamp);
+ // InputAgent.dispatchGestureEvent("tap", x, y, timeStamp);
+ }
}
- this._lastScrollPosition = position;
break;
case 2: // Middle
if (event.type === "mousedown") {
- InputAgent.dispatchGestureEvent("tapDown", x, y, timeStamp);
+ InputAgent.dispatchGestureEvent("tapDown", convertedPosition.x, convertedPosition.y, timeStamp);
} else if (event.type === "mouseup") {
- InputAgent.dispatchGestureEvent("tap", x, y, timeStamp);
+ InputAgent.dispatchGestureEvent("tap", convertedPosition.x, convertedPosition.y, timeStamp);
}
break;
case 3: // Right
- if (event.type === "mousedown") {
- this._pinchStart = position;
- InputAgent.dispatchGestureEvent("pinchBegin", x, y, timeStamp);
- } else if (event.type === "mousemove") {
- var dx = this._pinchStart ? position.x - this._pinchStart.x : 0;
- var dy = this._pinchStart ? position.y - this._pinchStart.y : 0;
- if (dx || dy) {
- var scale = Math.pow(dy < 0 ? 0.999 : 1.001, Math.abs(dy));
- InputAgent.dispatchGestureEvent("pinchUpdate", this._pinchStart.x, this._pinchStart.y, timeStamp, 0, 0, scale);
- }
- } else if (event.type === "mouseup") {
- InputAgent.dispatchGestureEvent("pinchEnd", x, y, timeStamp);
- }
- break;
case 0: // None
default:
}
},
/**
- * @param {!Event} event
+ * @param {?Event} event
* @return {!{x: number, y: number}}
*/
- _convertIntoScreenSpace: function(event)
+ _zoomIntoScreenSpace: function(event)
{
var zoom = this._canvasElement.offsetWidth / this._viewport.width / this._pageScaleFactor;
var position = {};
position.x = Math.round(event.offsetX / zoom);
- position.y = Math.round(event.offsetY / zoom - this._screenOffsetTop);
+ position.y = Math.round(event.offsetY / zoom);
+ return position;
+ },
+
+ /**
+ * @param {?Event} event
+ * @return {!{x: number, y: number}}
+ */
+ _convertIntoScreenSpace: function(event)
+ {
+ var position = this._zoomIntoScreenSpace(event);
+ position.y = Math.round(position.y - this._screenOffsetTop);
return position;
},
/**
- * @param {!Event} event
- * @return number
+ * @param {?Event} event
+ * @return {number}
*/
_modifiersForEvent: function(event)
{
@@ -434,15 +542,15 @@ WebInspector.ScreencastView.prototype = {
},
/**
- * @param {!DOMAgent.NodeId} nodeId
+ * @param {?WebInspector.DOMNode} node
* @param {?DOMAgent.HighlightConfig} config
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
- highlightDOMNode: function(nodeId, config, objectId)
+ highlightDOMNode: function(node, config, objectId)
{
- this._highlightNodeId = nodeId;
+ this._highlightNode = node;
this._highlightConfig = config;
- if (!nodeId) {
+ if (!node) {
this._model = null;
this._config = null;
this._node = null;
@@ -451,17 +559,16 @@ WebInspector.ScreencastView.prototype = {
return;
}
- this._node = WebInspector.domAgent.nodeForId(nodeId);
- DOMAgent.getBoxModel(nodeId, callback.bind(this));
+ this._node = node;
+ node.boxModel(callback.bind(this));
/**
- * @param {?Protocol.Error} error
- * @param {!DOMAgent.BoxModel} model
+ * @param {?DOMAgent.BoxModel} model
* @this {WebInspector.ScreencastView}
*/
- function callback(error, model)
+ function callback(model)
{
- if (error) {
+ if (!model) {
this._repaint();
return;
}
@@ -716,11 +823,11 @@ WebInspector.ScreencastView.prototype = {
/**
* @param {boolean} enabled
- * @param {boolean} inspectShadowDOM
+ * @param {boolean} inspectUAShadowDOM
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
- setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback)
+ setInspectModeEnabled: function(enabled, inspectUAShadowDOM, config, callback)
{
this._inspectModeConfig = enabled ? config : null;
if (callback)
@@ -750,6 +857,8 @@ WebInspector.ScreencastView.prototype = {
_createNavigationBar: function()
{
this._navigationBar = this.element.createChild("div", "toolbar-background screencast-navigation");
+ if (WebInspector.queryParam("hideNavigation"))
+ this._navigationBar.classList.add("hidden");
this._navigationBack = this._navigationBar.createChild("button", "back");
this._navigationBack.disabled = true;
@@ -819,6 +928,7 @@ WebInspector.ScreencastView.prototype = {
var match = url.match(WebInspector.ScreencastView._HttpRegex);
if (match)
url = match[1];
+ InspectorFrontendHost.inspectedURLChanged(url);
this._navigationUrl.value = url;
},
@@ -829,11 +939,11 @@ WebInspector.ScreencastView.prototype = {
return true;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
- * @param {!HTMLElement} element
+ * @param {!Element} element
* @constructor
*/
WebInspector.ScreencastView.ProgressTracker = function(element) {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ShortcutsScreen.js b/chromium/third_party/WebKit/Source/devtools/front_end/ShortcutsScreen.js
deleted file mode 100644
index a555423d811..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ShortcutsScreen.js
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- */
-WebInspector.ShortcutsScreen = function()
-{
- /** @type {!Object.<string, !WebInspector.ShortcutsSection>} */
- this._sections = {};
-}
-
-WebInspector.ShortcutsScreen.prototype = {
- /**
- * @param {string} name
- * @return {!WebInspector.ShortcutsSection}
- */
- section: function(name)
- {
- var section = this._sections[name];
- if (!section)
- this._sections[name] = section = new WebInspector.ShortcutsSection(name);
- return section;
- },
-
- /**
- * @return {!WebInspector.View}
- */
- createShortcutsTabView: function()
- {
- var orderedSections = [];
- for (var section in this._sections)
- orderedSections.push(this._sections[section]);
- function compareSections(a, b)
- {
- return a.order - b.order;
- }
- orderedSections.sort(compareSections);
-
- var view = new WebInspector.View();
-
- view.element.className = "settings-tab-container";
- view.element.createChild("header").createChild("h3").appendChild(document.createTextNode(WebInspector.UIString("Shortcuts")));
- var scrollPane = view.element.createChild("div", "help-container-wrapper");
- var container = scrollPane.createChild("div");
- container.className = "help-content help-container";
- for (var i = 0; i < orderedSections.length; ++i)
- orderedSections[i].renderSection(container);
-
- var note = scrollPane.createChild("p", "help-footnote");
- var noteLink = note.createChild("a");
- noteLink.href = "https://developers.google.com/chrome-developer-tools/docs/shortcuts";
- noteLink.target = "_blank";
- noteLink.createTextChild(WebInspector.UIString("Full list of keyboard shortcuts and gestures"));
-
- return view;
- }
-}
-
-/**
- * We cannot initialize it here as localized strings are not loaded yet.
- * @type {!WebInspector.ShortcutsScreen}
- */
-WebInspector.shortcutsScreen;
-
-/**
- * @constructor
- * @param {string} name
- */
-WebInspector.ShortcutsSection = function(name)
-{
- this.name = name;
- this._lines = /** @type {!Array.<{key: !Node, text: string}>} */ ([]);
- this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
-};
-
-WebInspector.ShortcutsSection._sequenceNumber = 0;
-
-WebInspector.ShortcutsSection.prototype = {
- /**
- * @param {!WebInspector.KeyboardShortcut.Descriptor} key
- * @param {string} description
- */
- addKey: function(key, description)
- {
- this._addLine(this._renderKey(key), description);
- },
-
- /**
- * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
- * @param {string} description
- */
- addRelatedKeys: function(keys, description)
- {
- this._addLine(this._renderSequence(keys, "/"), description);
- },
-
- /**
- * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
- * @param {string} description
- */
- addAlternateKeys: function(keys, description)
- {
- this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description);
- },
-
- /**
- * @param {!Node} keyElement
- * @param {string} description
- */
- _addLine: function(keyElement, description)
- {
- this._lines.push({ key: keyElement, text: description })
- },
-
- /**
- * @param {!Element} container
- */
- renderSection: function(container)
- {
- var parent = container.createChild("div", "help-block");
-
- var headLine = parent.createChild("div", "help-line");
- headLine.createChild("div", "help-key-cell");
- headLine.createChild("div", "help-section-title help-cell").textContent = this.name;
-
- for (var i = 0; i < this._lines.length; ++i) {
- var line = parent.createChild("div", "help-line");
- var keyCell = line.createChild("div", "help-key-cell");
- keyCell.appendChild(this._lines[i].key);
- keyCell.appendChild(this._createSpan("help-key-delimiter", ":"));
- line.createChild("div", "help-cell").textContent = this._lines[i].text;
- }
- },
-
- /**
- * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} sequence
- * @param {string} delimiter
- * @return {!Node}
- */
- _renderSequence: function(sequence, delimiter)
- {
- var delimiterSpan = this._createSpan("help-key-delimiter", delimiter);
- return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
- },
-
- /**
- * @param {!WebInspector.KeyboardShortcut.Descriptor} key
- * @return {!Node}
- */
- _renderKey: function(key)
- {
- var keyName = key.name;
- var plus = this._createSpan("help-combine-keys", "+");
- return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this, "help-key")), plus);
- },
-
- /**
- * @param {string} className
- * @param {string} textContent
- * @return {!Element}
- */
- _createSpan: function(className, textContent)
- {
- var node = document.createElement("span");
- node.className = className;
- node.textContent = textContent;
- return node;
- },
-
- /**
- * @param {!Array.<!Element>} nodes
- * @param {!Element} delimiter
- * @return {!Node}
- */
- _joinNodes: function(nodes, delimiter)
- {
- var result = document.createDocumentFragment();
- for (var i = 0; i < nodes.length; ++i) {
- if (i > 0)
- result.appendChild(delimiter.cloneNode(true));
- result.appendChild(nodes[i]);
- }
- return result;
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarOverlay.js b/chromium/third_party/WebKit/Source/devtools/front_end/SidebarOverlay.js
deleted file mode 100644
index 9ee6df57464..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarOverlay.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @param {!WebInspector.View} view
- * @param {string} widthSettingName
- * @param {number} minimalWidth
- */
-WebInspector.SidebarOverlay = function(view, widthSettingName, minimalWidth)
-{
- this.element = document.createElement("div");
- this.element.className = "sidebar-overlay";
-
- this._view = view;
- this._widthSettingName = widthSettingName;
- this._minimalWidth = minimalWidth;
- this._savedWidth = minimalWidth || 300;
-
- if (this._widthSettingName)
- WebInspector.settings[this._widthSettingName] = WebInspector.settings.createSetting(this._widthSettingName, undefined);
-
- this._resizerElement = document.createElement("div");
- this._resizerElement.className = "sidebar-overlay-resizer";
- this._installResizer(this._resizerElement);
-}
-
-WebInspector.SidebarOverlay.prototype = {
- /**
- * @param {!Element} relativeToElement
- */
- show: function(relativeToElement)
- {
- relativeToElement.appendChild(this.element);
- relativeToElement.classList.add("sidebar-overlay-shown");
- this._view.show(this.element);
- this.element.appendChild(this._resizerElement);
- if (this._resizerWidgetElement)
- this.element.appendChild(this._resizerWidgetElement);
- this.position(relativeToElement);
- },
-
- /**
- * @param {!Element} relativeToElement
- */
- position: function(relativeToElement)
- {
- this._totalWidth = relativeToElement.offsetWidth;
- this._setWidth(this._preferredWidth());
- },
-
- focus: function()
- {
- WebInspector.setCurrentFocusElement(this._view.element);
- },
-
- hide: function()
- {
- var element = this.element.parentElement;
- if (!element)
- return;
-
- this._view.detach();
- element.removeChild(this.element);
- element.classList.remove("sidebar-overlay-shown");
- this.element.removeChild(this._resizerElement);
- if (this._resizerWidgetElement)
- this.element.removeChild(this._resizerWidgetElement);
- },
-
- /**
- * @param {number} newWidth
- */
- _setWidth: function(newWidth)
- {
- var width = Number.constrain(newWidth, this._minimalWidth, this._totalWidth);
-
- if (this._width === width)
- return;
-
- this.element.style.width = width + "px";
- this._resizerElement.style.left = (width - 3) + "px";
- this._width = width;
- this._view.doResize();
- this._saveWidth();
- },
-
- /**
- * @return {number}
- */
- _preferredWidth: function()
- {
- if (!this._widthSettingName)
- return this._savedWidth;
-
- return WebInspector.settings[this._widthSettingName].get() || this._savedWidth;
- },
-
- _saveWidth: function()
- {
- this._savedWidth = this._width;
- if (!this._widthSettingName)
- return;
-
- WebInspector.settings[this._widthSettingName].set(this._width);
- },
-
- /**
- * @param {!Event} event
- * @return {boolean}
- */
- _startResizerDragging: function(event)
- {
- var width = this._width;
- this._dragOffset = width - event.pageX;
- return true;
- },
-
- /**
- * @param {!Event} event
- */
- _resizerDragging: function(event)
- {
- var width = event.pageX + this._dragOffset;
- this._setWidth(width);
- event.preventDefault();
- },
-
- /**
- * @param {!Event} event
- */
- _endResizerDragging: function(event)
- {
- delete this._dragOffset;
- },
-
- /**
- * @param {!Element} resizerElement
- */
- _installResizer: function(resizerElement)
- {
- WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "ew-resize");
- },
-
- /**
- * @param {!Element} resizerWidgetElement
- */
- set resizerWidgetElement(resizerWidgetElement)
- {
- this._resizerWidgetElement = resizerWidgetElement;
- this._installResizer(resizerWidgetElement);
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarView.js b/chromium/third_party/WebKit/Source/devtools/front_end/SidebarView.js
deleted file mode 100644
index e6cdff1bb08..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarView.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.SplitView}
- * @param {string=} sidebarPosition
- * @param {string=} sidebarWidthSettingName
- * @param {number=} defaultSidebarWidth
- * @param {number=} defaultSidebarHeight
- */
-WebInspector.SidebarView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth, defaultSidebarHeight)
-{
- WebInspector.SplitView.call(this, true, sidebarWidthSettingName, defaultSidebarWidth, defaultSidebarHeight);
-
- this.setSidebarElementConstraints(Preferences.minSidebarWidth, Preferences.minSidebarHeight);
- this.setMainElementConstraints(0.5, 0.5);
-
- this.setSecondIsSidebar(sidebarPosition === WebInspector.SidebarView.SidebarPosition.End);
-}
-
-WebInspector.SidebarView.EventTypes = {
- Resized: "Resized"
-}
-
-/**
- * @enum {string}
- */
-WebInspector.SidebarView.SidebarPosition = {
- Start: "Start",
- End: "End"
-}
-
-WebInspector.SidebarView.prototype = {
- /**
- * @param {number} width
- */
- setSidebarWidth: function(width)
- {
- this.setSidebarSize(width);
- },
-
- /**
- * @return {number}
- */
- sidebarWidth: function()
- {
- return this.sidebarSize();
- },
-
- onResize: function()
- {
- WebInspector.SplitView.prototype.onResize.call(this);
- this.dispatchEventToListeners(WebInspector.SidebarView.EventTypes.Resized, this.sidebarWidth());
- },
-
- hideMainElement: function()
- {
- if (this.isSidebarSecond())
- this.showOnlySecond();
- else
- this.showOnlyFirst();
- },
-
- showMainElement: function()
- {
- this.showBoth();
- },
-
- hideSidebarElement: function()
- {
- if (this.isSidebarSecond())
- this.showOnlyFirst();
- else
- this.showOnlySecond();
- },
-
- showSidebarElement: function()
- {
- this.showBoth();
- },
-
- /**
- * @return {!Array.<!Element>}
- */
- elementsToRestoreScrollPositionsFor: function()
- {
- return [ this.mainElement, this.sidebarElement ];
- },
-
- __proto__: WebInspector.SplitView.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesNavigator.js b/chromium/third_party/WebKit/Source/devtools/front_end/SourcesNavigator.js
deleted file mode 100644
index 4c272b9967a..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesNavigator.js
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @extends {WebInspector.Object}
- * @constructor
- */
-WebInspector.SourcesNavigator = function()
-{
- WebInspector.Object.call(this);
-
- this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.shrinkableTabs = true;
- this._tabbedPane.element.classList.add("navigator-tabbed-pane");
-
- this._sourcesView = new WebInspector.NavigatorView();
- this._sourcesView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected, this._sourceSelected, this);
- this._sourcesView.addEventListener(WebInspector.NavigatorView.Events.ItemSearchStarted, this._itemSearchStarted, this);
- this._sourcesView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
- this._sourcesView.addEventListener(WebInspector.NavigatorView.Events.ItemCreationRequested, this._itemCreationRequested, this);
-
- this._contentScriptsView = new WebInspector.NavigatorView();
- this._contentScriptsView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected, this._sourceSelected, this);
- this._contentScriptsView.addEventListener(WebInspector.NavigatorView.Events.ItemSearchStarted, this._itemSearchStarted, this);
- this._contentScriptsView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
- this._contentScriptsView.addEventListener(WebInspector.NavigatorView.Events.ItemCreationRequested, this._itemCreationRequested, this);
-
- this._snippetsView = new WebInspector.SnippetsNavigatorView();
- this._snippetsView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected, this._sourceSelected, this);
- this._snippetsView.addEventListener(WebInspector.NavigatorView.Events.ItemSearchStarted, this._itemSearchStarted, this);
- this._snippetsView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
- this._snippetsView.addEventListener(WebInspector.NavigatorView.Events.ItemCreationRequested, this._itemCreationRequested, this);
-
- this._tabbedPane.appendTab(WebInspector.SourcesNavigator.SourcesTab, WebInspector.UIString("Sources"), this._sourcesView);
- this._tabbedPane.selectTab(WebInspector.SourcesNavigator.SourcesTab);
- this._tabbedPane.appendTab(WebInspector.SourcesNavigator.ContentScriptsTab, WebInspector.UIString("Content scripts"), this._contentScriptsView);
- this._tabbedPane.appendTab(WebInspector.SourcesNavigator.SnippetsTab, WebInspector.UIString("Snippets"), this._snippetsView);
-}
-
-WebInspector.SourcesNavigator.Events = {
- SourceSelected: "SourceSelected",
- ItemCreationRequested: "ItemCreationRequested",
- ItemRenamingRequested: "ItemRenamingRequested",
- ItemSearchStarted: "ItemSearchStarted",
-}
-
-WebInspector.SourcesNavigator.SourcesTab = "sources";
-WebInspector.SourcesNavigator.ContentScriptsTab = "contentScripts";
-WebInspector.SourcesNavigator.SnippetsTab = "snippets";
-
-WebInspector.SourcesNavigator.prototype = {
- /**
- * @return {!WebInspector.View}
- */
- get view()
- {
- return this._tabbedPane;
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _navigatorViewForUISourceCode: function(uiSourceCode)
- {
- if (uiSourceCode.isContentScript)
- return this._contentScriptsView;
- else if (uiSourceCode.project().type() === WebInspector.projectTypes.Snippets)
- return this._snippetsView;
- else
- return this._sourcesView;
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- addUISourceCode: function(uiSourceCode)
- {
- this._navigatorViewForUISourceCode(uiSourceCode).addUISourceCode(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- removeUISourceCode: function(uiSourceCode)
- {
- this._navigatorViewForUISourceCode(uiSourceCode).removeUISourceCode(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {boolean=} select
- */
- revealUISourceCode: function(uiSourceCode, select)
- {
- this._navigatorViewForUISourceCode(uiSourceCode).revealUISourceCode(uiSourceCode, select);
- if (uiSourceCode.isContentScript)
- this._tabbedPane.selectTab(WebInspector.SourcesNavigator.ContentScriptsTab);
- else if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
- this._tabbedPane.selectTab(WebInspector.SourcesNavigator.SourcesTab);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- updateIcon: function(uiSourceCode)
- {
- this._navigatorViewForUISourceCode(uiSourceCode).updateIcon(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {function(boolean)=} callback
- */
- rename: function(uiSourceCode, callback)
- {
- this._navigatorViewForUISourceCode(uiSourceCode).rename(uiSourceCode, callback);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _sourceSelected: function(event)
- {
- this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceSelected, event.data);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _itemSearchStarted: function(event)
- {
- this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.ItemSearchStarted, event.data);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _itemRenamingRequested: function(event)
- {
- this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.ItemRenamingRequested, event.data);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _itemCreationRequested: function(event)
- {
- this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.ItemCreationRequested, event.data);
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.NavigatorView}
- */
-WebInspector.SnippetsNavigatorView = function()
-{
- WebInspector.NavigatorView.call(this);
-}
-
-WebInspector.SnippetsNavigatorView.prototype = {
- /**
- * @param {!Event} event
- */
- handleContextMenu: function(event)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
- contextMenu.show();
- },
-
- /**
- * @param {!Event} event
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- handleFileContextMenu: function(event, uiSourceCode)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendItem(WebInspector.UIString("Run"), this._handleEvaluateSnippet.bind(this, uiSourceCode));
- contextMenu.appendItem(WebInspector.UIString("Rename"), this.requestRename.bind(this, uiSourceCode));
- contextMenu.appendItem(WebInspector.UIString("Remove"), this._handleRemoveSnippet.bind(this, uiSourceCode));
- contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
- contextMenu.show();
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _handleEvaluateSnippet: function(uiSourceCode)
- {
- if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
- return;
- WebInspector.scriptSnippetModel.evaluateScriptSnippet(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _handleRemoveSnippet: function(uiSourceCode)
- {
- if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
- return;
- uiSourceCode.project().deleteFile(uiSourceCode.path());
- },
-
- _handleCreateSnippet: function()
- {
- var data = {};
- data.project = WebInspector.scriptSnippetModel.project();
- data.path = "";
- this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemCreationRequested, data);
- },
-
- /**
- * @override
- */
- sourceDeleted: function(uiSourceCode)
- {
- this._handleRemoveSnippet(uiSourceCode);
- },
-
- __proto__: WebInspector.NavigatorView.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanel.js
deleted file mode 100644
index b15afd80a4a..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanel.js
+++ /dev/null
@@ -1,1730 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-importScript("BreakpointsSidebarPane.js");
-importScript("CallStackSidebarPane.js");
-importScript("FilePathScoreFunction.js");
-importScript("FilteredItemSelectionDialog.js");
-importScript("UISourceCodeFrame.js");
-importScript("JavaScriptSourceFrame.js");
-importScript("CSSSourceFrame.js");
-importScript("NavigatorOverlayController.js");
-importScript("NavigatorView.js");
-importScript("RevisionHistoryView.js");
-importScript("ScopeChainSidebarPane.js");
-importScript("SourcesNavigator.js");
-importScript("SourcesSearchScope.js");
-importScript("StyleSheetOutlineDialog.js");
-importScript("TabbedEditorContainer.js");
-importScript("WatchExpressionsSidebarPane.js");
-importScript("WorkersSidebarPane.js");
-
-/**
- * @constructor
- * @implements {WebInspector.TabbedEditorContainerDelegate}
- * @implements {WebInspector.ContextMenu.Provider}
- * @implements {WebInspector.Searchable}
- * @extends {WebInspector.Panel}
- * @param {!WebInspector.Workspace=} workspaceForTest
- */
-WebInspector.SourcesPanel = function(workspaceForTest)
-{
- WebInspector.Panel.call(this, "sources");
- this.registerRequiredCSS("sourcesPanel.css");
- this.registerRequiredCSS("textPrompt.css"); // Watch Expressions autocomplete.
-
- WebInspector.settings.navigatorWasOnceHidden = WebInspector.settings.createSetting("navigatorWasOnceHidden", false);
- WebInspector.settings.debuggerSidebarHidden = WebInspector.settings.createSetting("debuggerSidebarHidden", false);
- WebInspector.settings.showEditorInDrawer = WebInspector.settings.createSetting("showEditorInDrawer", true);
-
- this._workspace = workspaceForTest || WebInspector.workspace;
-
- /**
- * @return {!WebInspector.View}
- * @this {WebInspector.SourcesPanel}
- */
- function viewGetter()
- {
- return this.visibleView;
- }
- WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
-
- var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
- this.debugToolbar = this._createDebugToolbar();
-
- const initialDebugSidebarWidth = 225;
- const minimumDebugSidebarWidthPercent = 0.5;
- this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.End, initialDebugSidebarWidth);
- this.splitView.element.id = "scripts-split-view";
- this.splitView.setSidebarElementConstraints(Preferences.minScriptsSidebarWidth);
- this.splitView.setMainElementConstraints(minimumDebugSidebarWidthPercent);
-
- // Create scripts navigator
- const initialNavigatorWidth = 225;
- const minimumViewsContainerWidthPercent = 0.5;
- this.editorView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, "scriptsPanelNavigatorSidebarWidth", initialNavigatorWidth);
- this.editorView.element.id = "scripts-editor-split-view";
- this.editorView.element.tabIndex = 0;
-
- this.editorView.setSidebarElementConstraints(Preferences.minScriptsSidebarWidth);
- this.editorView.setMainElementConstraints(minimumViewsContainerWidthPercent);
- this.editorView.show(this.splitView.mainElement);
-
- this._navigator = new WebInspector.SourcesNavigator();
- this._navigator.view.show(this.editorView.sidebarElement);
-
- var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIString("Hit Cmd+O to open a file") : WebInspector.UIString("Hit Ctrl+O to open a file");
-
- this.editorView.mainElement.classList.add("vbox");
- this.editorView.sidebarElement.classList.add("vbox");
-
- this.sourcesView = new WebInspector.SourcesView();
-
- this._searchableView = new WebInspector.SearchableView(this);
- this._searchableView.setMinimalSearchQuerySize(0);
- this._searchableView.show(this.sourcesView.element);
-
- this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previouslyViewedFiles", tabbedEditorPlaceholderText);
- this._editorContainer.show(this._searchableView.element);
-
- this._navigatorController = new WebInspector.NavigatorOverlayController(this.editorView, this._navigator.view, this._editorContainer.view);
-
- this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected, this._sourceSelected, this);
- this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.ItemSearchStarted, this._itemSearchStarted, this);
- this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.ItemCreationRequested, this._itemCreationRequested, this);
- this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.ItemRenamingRequested, this._itemRenamingRequested, this);
-
- this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
- this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
-
- this._debugSidebarResizeWidgetElement = document.createElementWithClass("div", "resizer-widget");
- this._debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
- this.splitView.installResizer(this._debugSidebarResizeWidgetElement);
-
- this.sidebarPanes = {};
- this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
- this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
- this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this));
- this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameRestarted, this._callFrameRestartedInSidebar.bind(this));
-
- this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
- this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this._showSourceLocation.bind(this));
- this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
- this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
- this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
-
- if (Capabilities.canInspectWorkers && !WebInspector.WorkerManager.isWorkerFrontend()) {
- WorkerAgent.enable();
- this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane(WebInspector.workerManager);
- }
-
- this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
- this.registerShortcuts(WebInspector.SourcesPanelDescriptor.ShortcutKeys.GoToMember, this._showOutlineDialog.bind(this));
- this.registerShortcuts(WebInspector.SourcesPanelDescriptor.ShortcutKeys.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
-
- this._extensionSidebarPanes = [];
-
- this._toggleFormatSourceButton = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "sources-toggle-pretty-print-status-bar-item");
- this._toggleFormatSourceButton.toggled = false;
- this._toggleFormatSourceButton.addEventListener("click", this._toggleFormatSource, this);
-
- this._scriptViewStatusBarItemsContainer = document.createElement("div");
- this._scriptViewStatusBarItemsContainer.className = "inline-block";
-
- this._scriptViewStatusBarTextContainer = document.createElement("div");
- this._scriptViewStatusBarTextContainer.className = "inline-block";
-
- this._statusBarContainerElement = this.sourcesView.element.createChild("div", "sources-status-bar");
- this._statusBarContainerElement.appendChild(this._toggleFormatSourceButton.element);
- this._statusBarContainerElement.appendChild(this._scriptViewStatusBarItemsContainer);
- this._statusBarContainerElement.appendChild(this._scriptViewStatusBarTextContainer);
-
- this._installDebuggerSidebarController();
-
- WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
- WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
- this._dockSideChanged();
-
- /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.SourceFrame>} */
- this._sourceFramesByUISourceCode = new Map();
- this._updateDebuggerButtons();
- this._pauseOnExceptionStateChanged();
- if (WebInspector.debuggerModel.isPaused())
- this._showDebuggerPausedDetails();
-
- WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerWasDisabled, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
-
- WebInspector.startBatchUpdate();
- this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
- WebInspector.endBatchUpdate();
-
- this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
- this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
- this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset.bind(this), this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
-
- WebInspector.advancedSearchController.registerSearchScope(new WebInspector.SourcesSearchScope(this._workspace));
-
- this._boundOnKeyUp = this._onKeyUp.bind(this);
- this._boundOnKeyDown = this._onKeyDown.bind(this);
-
- function handleBeforeUnload(event)
- {
- if (event.returnValue)
- return;
- var unsavedSourceCodes = WebInspector.workspace.unsavedSourceCodes();
- if (!unsavedSourceCodes.length)
- return;
-
- event.returnValue = WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");
- WebInspector.showPanel("sources");
- for (var i = 0; i < unsavedSourceCodes.length; ++i)
- WebInspector.panels.sources.showUISourceCode(unsavedSourceCodes[i]);
- }
- window.addEventListener("beforeunload", handleBeforeUnload.bind(this), true);
-}
-
-WebInspector.SourcesPanel.prototype = {
- defaultFocusedElement: function()
- {
- return this._editorContainer.view.defaultFocusedElement() || this._navigator.view.defaultFocusedElement();
- },
-
- get paused()
- {
- return this._paused;
- },
-
- wasShown: function()
- {
- WebInspector.inspectorView.closeViewInDrawer("editor");
- this.sourcesView.show(this.editorView.mainElement);
- WebInspector.Panel.prototype.wasShown.call(this);
- this._navigatorController.wasShown();
-
- this.element.addEventListener("keydown", this._boundOnKeyDown, false);
- this.element.addEventListener("keyup", this._boundOnKeyUp, false);
- },
-
- willHide: function()
- {
- this.element.removeEventListener("keydown", this._boundOnKeyDown, false);
- this.element.removeEventListener("keyup", this._boundOnKeyUp, false);
-
- WebInspector.Panel.prototype.willHide.call(this);
- },
-
- /**
- * @return {!WebInspector.SearchableView}
- */
- searchableView: function()
- {
- return this._searchableView;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _uiSourceCodeAdded: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
- this._addUISourceCode(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _addUISourceCode: function(uiSourceCode)
- {
- if (this._toggleFormatSourceButton.toggled)
- uiSourceCode.setFormatted(true);
- if (uiSourceCode.project().isServiceProject())
- return;
- this._navigator.addUISourceCode(uiSourceCode);
- this._editorContainer.addUISourceCode(uiSourceCode);
- // Replace debugger script-based uiSourceCode with a network-based one.
- var currentUISourceCode = this._currentUISourceCode;
- if (currentUISourceCode && currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSourceCode.url) {
- this._showFile(uiSourceCode);
- this._editorContainer.removeUISourceCode(currentUISourceCode);
- }
- },
-
- _uiSourceCodeRemoved: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
- this._removeUISourceCodes([uiSourceCode]);
- },
-
- /**
- * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes
- */
- _removeUISourceCodes: function(uiSourceCodes)
- {
- for (var i = 0; i < uiSourceCodes.length; ++i) {
- this._navigator.removeUISourceCode(uiSourceCodes[i]);
- this._removeSourceFrame(uiSourceCodes[i]);
- }
- this._editorContainer.removeUISourceCodes(uiSourceCodes);
- },
-
- _consoleCommandEvaluatedInSelectedCallFrame: function(event)
- {
- this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
- },
-
- _debuggerPaused: function()
- {
- WebInspector.inspectorView.setCurrentPanel(this);
- this._showDebuggerPausedDetails();
- },
-
- _showDebuggerPausedDetails: function()
- {
- var details = WebInspector.debuggerModel.debuggerPausedDetails();
-
- this._paused = true;
- this._waitingToPause = false;
- this._stepping = false;
-
- this._updateDebuggerButtons();
-
- this.sidebarPanes.callstack.update(details.callFrames, details.asyncStackTrace);
-
- /**
- * @param {!Element} element
- * @this {WebInspector.SourcesPanel}
- */
- function didCreateBreakpointHitStatusMessage(element)
- {
- this.sidebarPanes.callstack.setStatus(element);
- }
-
- /**
- * @param {!WebInspector.UILocation} uiLocation
- * @this {WebInspector.SourcesPanel}
- */
- function didGetUILocation(uiLocation)
- {
- var breakpoint = WebInspector.breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber);
- if (!breakpoint)
- return;
- this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
- }
-
- if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
- WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
- WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details.auxData, didCreateBreakpointHitStatusMessage.bind(this));
- } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
- var eventName = details.auxData.eventName;
- this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(details.auxData.eventName);
- var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData);
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
- } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
- this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
- } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData.description));
- else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
- else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
- else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand)
- this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function"));
- else {
- if (details.callFrames.length)
- details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
- else
- console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
- }
-
- this._enableDebuggerSidebar(true);
- this._toggleDebuggerSidebarButton.setEnabled(false);
- window.focus();
- InspectorFrontendHost.bringToFront();
- },
-
- _debuggerResumed: function()
- {
- this._paused = false;
- this._waitingToPause = false;
- this._stepping = false;
-
- this._clearInterface();
- this._toggleDebuggerSidebarButton.setEnabled(true);
- },
-
- _debuggerWasEnabled: function()
- {
- this._updateDebuggerButtons();
- },
-
- _debuggerWasDisabled: function()
- {
- this._debuggerReset();
- },
-
- _debuggerReset: function()
- {
- this._debuggerResumed();
- this.sidebarPanes.watchExpressions.reset();
- delete this._skipExecutionLineRevealing;
- },
-
- _projectWillReset: function(event)
- {
- var project = event.data;
- var uiSourceCodes = project.uiSourceCodes();
- this._removeUISourceCodes(uiSourceCodes);
- if (project.type() === WebInspector.projectTypes.Network)
- this._editorContainer.reset();
- },
-
- get visibleView()
- {
- return this._editorContainer.visibleView;
- },
-
- _updateScriptViewStatusBarItems: function()
- {
- this._scriptViewStatusBarItemsContainer.removeChildren();
- this._scriptViewStatusBarTextContainer.removeChildren();
-
- var sourceFrame = this.visibleView;
- if (sourceFrame) {
- var statusBarItems = sourceFrame.statusBarItems() || [];
- for (var i = 0; i < statusBarItems.length; ++i)
- this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
- var statusBarText = sourceFrame.statusBarText();
- if (statusBarText)
- this._scriptViewStatusBarTextContainer.appendChild(statusBarText);
- }
- },
-
- /**
- * @param {!Element} anchor
- * @return {boolean}
- */
- showAnchorLocation: function(anchor)
- {
- if (!anchor.uiSourceCode) {
- var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
- if (uiSourceCode)
- anchor.uiSourceCode = uiSourceCode;
- }
- if (!anchor.uiSourceCode)
- return false;
-
- this._showSourceLocation(anchor.uiSourceCode, anchor.lineNumber, anchor.columnNumber);
- return true;
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {number=} lineNumber
- * @param {number=} columnNumber
- * @param {boolean=} forceShowInPanel
- */
- showUISourceCode: function(uiSourceCode, lineNumber, columnNumber, forceShowInPanel)
- {
- this._showSourceLocation(uiSourceCode, lineNumber, columnNumber, forceShowInPanel);
- },
-
- /**
- * @param {boolean=} forceShowInPanel
- */
- _showEditor: function(forceShowInPanel)
- {
- if (this.sourcesView.isShowing())
- return;
- if (this._canShowEditorInDrawer() && !forceShowInPanel) {
- var drawerEditorView = new WebInspector.DrawerEditorView();
- this.sourcesView.show(drawerEditorView.element);
- WebInspector.inspectorView.showCloseableViewInDrawer("editor", WebInspector.UIString("Editor"), drawerEditorView);
- } else {
- WebInspector.showPanel("sources");
- }
- },
-
- /**
- * @return {?WebInspector.UISourceCode}
- */
- currentUISourceCode: function()
- {
- return this._currentUISourceCode;
- },
-
- /**
- * @param {!WebInspector.UILocation} uiLocation
- * @param {boolean=} forceShowInPanel
- */
- showUILocation: function(uiLocation, forceShowInPanel)
- {
- this._showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, forceShowInPanel);
- },
-
- /**
- * @return {boolean}
- */
- _canShowEditorInDrawer: function()
- {
- return WebInspector.experimentsSettings.showEditorInDrawer.isEnabled() && WebInspector.settings.showEditorInDrawer.get();
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {number=} lineNumber
- * @param {number=} columnNumber
- * @param {boolean=} forceShowInPanel
- */
- _showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, forceShowInPanel)
- {
- this._showEditor(forceShowInPanel);
- var sourceFrame = this._showFile(uiSourceCode);
- if (typeof lineNumber === "number")
- sourceFrame.highlightPosition(lineNumber, columnNumber);
- sourceFrame.focus();
-
- WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
- action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
- url: uiSourceCode.originURL(),
- lineNumber: lineNumber
- });
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!WebInspector.SourceFrame}
- */
- _showFile: function(uiSourceCode)
- {
- var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
- if (this._currentUISourceCode === uiSourceCode)
- return sourceFrame;
- this._currentUISourceCode = uiSourceCode;
- if (!uiSourceCode.project().isServiceProject())
- this._navigator.revealUISourceCode(uiSourceCode, true);
- this._editorContainer.showFile(uiSourceCode);
- this._updateScriptViewStatusBarItems();
-
- if (this._currentUISourceCode.project().type() === WebInspector.projectTypes.Snippets)
- this._runSnippetButton.element.classList.remove("hidden");
- else
- this._runSnippetButton.element.classList.add("hidden");
-
- return sourceFrame;
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!WebInspector.SourceFrame}
- */
- _createSourceFrame: function(uiSourceCode)
- {
- var sourceFrame;
- switch (uiSourceCode.contentType()) {
- case WebInspector.resourceTypes.Script:
- sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
- break;
- case WebInspector.resourceTypes.Document:
- sourceFrame = new WebInspector.JavaScriptSourceFrame(this, uiSourceCode);
- break;
- case WebInspector.resourceTypes.Stylesheet:
- sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode);
- break;
- default:
- sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
- break;
- }
- sourceFrame.setHighlighterType(uiSourceCode.highlighterType());
- this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
- return sourceFrame;
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!WebInspector.SourceFrame}
- */
- _getOrCreateSourceFrame: function(uiSourceCode)
- {
- return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.SourceFrame} sourceFrame
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {boolean}
- */
- _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode)
- {
- switch (uiSourceCode.contentType()) {
- case WebInspector.resourceTypes.Script:
- case WebInspector.resourceTypes.Document:
- return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;
- case WebInspector.resourceTypes.Stylesheet:
- return sourceFrame instanceof WebInspector.CSSSourceFrame;
- default:
- return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);
- }
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _recreateSourceFrameIfNeeded: function(uiSourceCode)
- {
- var oldSourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
- if (!oldSourceFrame)
- return;
- if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
- oldSourceFrame.setHighlighterType(uiSourceCode.highlighterType());
- } else {
- this._editorContainer.removeUISourceCode(uiSourceCode);
- this._removeSourceFrame(uiSourceCode);
- }
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!WebInspector.SourceFrame}
- */
- viewForFile: function(uiSourceCode)
- {
- return this._getOrCreateSourceFrame(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _removeSourceFrame: function(uiSourceCode)
- {
- var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
- if (!sourceFrame)
- return;
- this._sourceFramesByUISourceCode.remove(uiSourceCode);
- sourceFrame.dispose();
- },
-
- _clearCurrentExecutionLine: function()
- {
- if (this._executionSourceFrame)
- this._executionSourceFrame.clearExecutionLine();
- delete this._executionSourceFrame;
- },
-
- _setExecutionLine: function(uiLocation)
- {
- var callFrame = WebInspector.debuggerModel.selectedCallFrame()
- var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
- sourceFrame.setExecutionLine(uiLocation.lineNumber, callFrame);
- this._executionSourceFrame = sourceFrame;
- },
-
- _executionLineChanged: function(uiLocation)
- {
- this._clearCurrentExecutionLine();
- this._setExecutionLine(uiLocation);
-
- var uiSourceCode = uiLocation.uiSourceCode;
- var scriptFile = this._currentUISourceCode ? this._currentUISourceCode.scriptFile() : null;
- if (this._skipExecutionLineRevealing)
- return;
- this._skipExecutionLineRevealing = true;
- var sourceFrame = this._showFile(uiSourceCode);
- sourceFrame.revealLine(uiLocation.lineNumber);
- if (sourceFrame.canEditSource())
- sourceFrame.setSelection(WebInspector.TextRange.createFromLocation(uiLocation.lineNumber, 0));
- sourceFrame.focus();
- },
-
- _callFrameSelected: function(event)
- {
- var callFrame = event.data;
-
- if (!callFrame)
- return;
-
- this.sidebarPanes.scopechain.update(callFrame);
- this.sidebarPanes.watchExpressions.refreshExpressions();
- this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
- callFrame.createLiveLocation(this._executionLineChanged.bind(this));
- },
-
- _editorClosed: function(event)
- {
- this._navigatorController.hideNavigatorOverlay();
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
-
- if (this._currentUISourceCode === uiSourceCode)
- delete this._currentUISourceCode;
-
- // SourcesNavigator does not need to update on EditorClosed.
- this._updateScriptViewStatusBarItems();
- this._searchableView.resetSearch();
- },
-
- _editorSelected: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
- var sourceFrame = this._showFile(uiSourceCode);
- this._navigatorController.hideNavigatorOverlay();
- if (!this._navigatorController.isNavigatorPinned())
- sourceFrame.focus();
- this._searchableView.setCanReplace(!!sourceFrame && sourceFrame.canEditSource());
- this._searchableView.resetSearch();
- },
-
- _sourceSelected: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
- var sourceFrame = this._showFile(uiSourceCode);
- this._navigatorController.hideNavigatorOverlay();
- if (sourceFrame && (!this._navigatorController.isNavigatorPinned() || event.data.focusSource))
- sourceFrame.focus();
- },
-
- _itemSearchStarted: function(event)
- {
- var searchText = /** @type {string} */ (event.data);
- WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement, searchText);
- },
-
- _pauseOnExceptionStateChanged: function()
- {
- var pauseOnExceptionsState = WebInspector.settings.pauseOnExceptionStateString.get();
- switch (pauseOnExceptionsState) {
- case WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions:
- this._pauseOnExceptionButton.title = WebInspector.UIString("Don't pause on exceptions.\nClick to Pause on all exceptions.");
- break;
- case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions:
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on all exceptions.\nClick to Pause on uncaught exceptions.");
- break;
- case WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions:
- this._pauseOnExceptionButton.title = WebInspector.UIString("Pause on uncaught exceptions.\nClick to Not pause on exceptions.");
- break;
- }
- this._pauseOnExceptionButton.state = pauseOnExceptionsState;
- },
-
- _updateDebuggerButtons: function()
- {
- if (this._paused) {
- this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Resume script execution (%s)."))
- this._pauseButton.state = true;
- this._pauseButton.setLongClickOptionsEnabled((function() { return [ this._longResumeButton ] }).bind(this));
-
- this._pauseButton.setEnabled(true);
- this._stepOverButton.setEnabled(true);
- this._stepIntoButton.setEnabled(true);
- this._stepOutButton.setEnabled(true);
- } else {
- this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Pause script execution (%s)."))
- this._pauseButton.state = false;
- this._pauseButton.setLongClickOptionsEnabled(null);
-
- this._pauseButton.setEnabled(!this._waitingToPause);
- this._stepOverButton.setEnabled(false);
- this._stepIntoButton.setEnabled(false);
- this._stepOutButton.setEnabled(false);
- }
- },
-
- _clearInterface: function()
- {
- this.sidebarPanes.callstack.update(null, null);
- this.sidebarPanes.scopechain.update(null);
- this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
- WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
- this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
- this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
-
- this._clearCurrentExecutionLine();
- this._updateDebuggerButtons();
- },
-
- _togglePauseOnExceptions: function()
- {
- var nextStateMap = {};
- var stateEnum = WebInspector.DebuggerModel.PauseOnExceptionsState;
- nextStateMap[stateEnum.DontPauseOnExceptions] = stateEnum.PauseOnAllExceptions;
- nextStateMap[stateEnum.PauseOnAllExceptions] = stateEnum.PauseOnUncaughtExceptions;
- nextStateMap[stateEnum.PauseOnUncaughtExceptions] = stateEnum.DontPauseOnExceptions;
- WebInspector.settings.pauseOnExceptionStateString.set(nextStateMap[this._pauseOnExceptionButton.state]);
- },
-
- /**
- * @return {boolean}
- */
- _runSnippet: function()
- {
- if (this._currentUISourceCode.project().type() !== WebInspector.projectTypes.Snippets)
- return false;
- WebInspector.scriptSnippetModel.evaluateScriptSnippet(this._currentUISourceCode);
- return true;
- },
-
- /**
- * @return {boolean}
- */
- _togglePause: function()
- {
- if (this._paused) {
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._waitingToPause = false;
- WebInspector.debuggerModel.resume();
- } else {
- this._stepping = false;
- this._waitingToPause = true;
- // Make sure pauses didn't stick skipped.
- WebInspector.debuggerModel.skipAllPauses(false);
- DebuggerAgent.pause();
- }
-
- this._clearInterface();
- return true;
- },
-
- /**
- * @return {boolean}
- */
- _longResume: function()
- {
- if (!this._paused)
- return true;
-
- this._paused = false;
- this._waitingToPause = false;
- WebInspector.debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
- WebInspector.debuggerModel.resume();
-
- this._clearInterface();
- return true;
- },
-
- /**
- * @return {boolean}
- */
- _stepOverClicked: function()
- {
- if (!this._paused)
- return true;
-
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._stepping = true;
-
- this._clearInterface();
-
- WebInspector.debuggerModel.stepOver();
- return true;
- },
-
- /**
- * @return {boolean}
- */
- _stepIntoClicked: function()
- {
- if (!this._paused)
- return true;
-
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._stepping = true;
-
- this._clearInterface();
-
- WebInspector.debuggerModel.stepInto();
- return true;
- },
-
- /**
- * @param {?Event=} event
- * @return {boolean}
- */
- _stepIntoSelectionClicked: function(event)
- {
- if (!this._paused)
- return true;
-
- if (this._executionSourceFrame) {
- var stepIntoMarkup = this._executionSourceFrame.stepIntoMarkup();
- if (stepIntoMarkup)
- stepIntoMarkup.iterateSelection(event.shiftKey);
- }
- return true;
- },
-
- doStepIntoSelection: function(rawLocation)
- {
- if (!this._paused)
- return;
-
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._stepping = true;
- this._clearInterface();
- WebInspector.debuggerModel.stepIntoSelection(rawLocation);
- },
-
- /**
- * @return {boolean}
- */
- _stepOutClicked: function()
- {
- if (!this._paused)
- return true;
-
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._stepping = true;
-
- this._clearInterface();
-
- WebInspector.debuggerModel.stepOut();
- return true;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _callFrameSelectedInSidebar: function(event)
- {
- var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data);
- delete this._skipExecutionLineRevealing;
- WebInspector.debuggerModel.setSelectedCallFrame(callFrame);
- },
-
- _callFrameRestartedInSidebar: function()
- {
- delete this._skipExecutionLineRevealing;
- },
-
- continueToLocation: function(rawLocation)
- {
- if (!this._paused)
- return;
-
- delete this._skipExecutionLineRevealing;
- this._paused = false;
- this._stepping = true;
- this._clearInterface();
- WebInspector.debuggerModel.continueToLocation(rawLocation);
- },
-
- _toggleBreakpointsClicked: function(event)
- {
- WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
- },
-
- _breakpointsActiveStateChanged: function(event)
- {
- var active = event.data;
- this._toggleBreakpointsButton.toggled = !active;
- if (active) {
- this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
- this._editorContainer.view.element.classList.remove("breakpoints-deactivated");
- this.sidebarPanes.jsBreakpoints.listElement.classList.remove("breakpoints-list-deactivated");
- } else {
- this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
- this._editorContainer.view.element.classList.add("breakpoints-deactivated");
- this.sidebarPanes.jsBreakpoints.listElement.classList.add("breakpoints-list-deactivated");
- }
- },
-
- _createDebugToolbar: function()
- {
- var debugToolbar = document.createElement("div");
- debugToolbar.className = "status-bar";
- debugToolbar.id = "scripts-debug-toolbar";
-
- var title, handler;
- var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
-
- // Run snippet.
- title = WebInspector.UIString("Run snippet (%s).");
- handler = this._runSnippet.bind(this);
- this._runSnippetButton = this._createButtonAndRegisterShortcuts("scripts-run-snippet", title, handler, WebInspector.SourcesPanelDescriptor.ShortcutKeys.RunSnippet);
- debugToolbar.appendChild(this._runSnippetButton.element);
- this._runSnippetButton.element.classList.add("hidden");
-
- // Continue.
- handler = this._togglePause.bind(this);
- this._pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, WebInspector.SourcesPanelDescriptor.ShortcutKeys.PauseContinue);
- debugToolbar.appendChild(this._pauseButton.element);
-
- // Long resume.
- title = WebInspector.UIString("Resume with all pauses blocked for 500 ms");
- this._longResumeButton = new WebInspector.StatusBarButton(title, "scripts-long-resume");
- this._longResumeButton.addEventListener("click", this._longResume.bind(this), this);
-
- // Step over.
- title = WebInspector.UIString("Step over next function call (%s).");
- handler = this._stepOverClicked.bind(this);
- this._stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepOver);
- debugToolbar.appendChild(this._stepOverButton.element);
-
- // Step into.
- title = WebInspector.UIString("Step into next function call (%s).");
- handler = this._stepIntoClicked.bind(this);
- this._stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepInto);
- debugToolbar.appendChild(this._stepIntoButton.element);
-
- // Step into selection (keyboard shortcut only).
- this.registerShortcuts(WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepIntoSelection, this._stepIntoSelectionClicked.bind(this))
-
- // Step out.
- title = WebInspector.UIString("Step out of current function (%s).");
- handler = this._stepOutClicked.bind(this);
- this._stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepOut);
- debugToolbar.appendChild(this._stepOutButton.element);
-
- // Toggle Breakpoints
- this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "scripts-toggle-breakpoints");
- this._toggleBreakpointsButton.toggled = false;
- this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
- debugToolbar.appendChild(this._toggleBreakpointsButton.element);
-
- // Pause on Exception
- this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item", 3);
- this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
- debugToolbar.appendChild(this._pauseOnExceptionButton.element);
-
- return debugToolbar;
- },
-
- /**
- * @param {!WebInspector.StatusBarButton} button
- * @param {string} buttonTitle
- */
- _updateButtonTitle: function(button, buttonTitle)
- {
- var hasShortcuts = button.shortcuts && button.shortcuts.length;
- if (hasShortcuts)
- button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
- else
- button.title = buttonTitle;
- },
-
- /**
- * @param {string} buttonId
- * @param {string} buttonTitle
- * @param {function(?Event=):boolean} handler
- * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
- * @return {!WebInspector.StatusBarButton}
- */
- _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
- {
- var button = new WebInspector.StatusBarButton(buttonTitle, buttonId);
- button.element.addEventListener("click", handler, false);
- button.shortcuts = shortcuts;
- this._updateButtonTitle(button, buttonTitle);
- this.registerShortcuts(shortcuts, handler);
- return button;
- },
-
- searchCanceled: function()
- {
- if (this._searchView)
- this._searchView.searchCanceled();
-
- delete this._searchView;
- delete this._searchQuery;
- },
-
- /**
- * @param {string} query
- * @param {boolean} shouldJump
- */
- performSearch: function(query, shouldJump)
- {
- this._searchableView.updateSearchMatchesCount(0);
-
- if (!this.visibleView)
- return;
-
- this._searchView = this.visibleView;
- this._searchQuery = query;
-
- /**
- * @param {!WebInspector.View} view
- * @param {number} searchMatches
- * @this {WebInspector.SourcesPanel}
- */
- function finishedCallback(view, searchMatches)
- {
- if (!searchMatches)
- return;
-
- this._searchableView.updateSearchMatchesCount(searchMatches);
- }
-
- /**
- * @param {number} currentMatchIndex
- * @this {WebInspector.SourcesPanel}
- */
- function currentMatchChanged(currentMatchIndex)
- {
- this._searchableView.updateCurrentMatchIndex(currentMatchIndex);
- }
-
- /**
- * @this {WebInspector.SourcesPanel}
- */
- function searchResultsChanged()
- {
- this._searchableView.cancelSearch();
- }
-
- this._searchView.performSearch(query, shouldJump, finishedCallback.bind(this), currentMatchChanged.bind(this), searchResultsChanged.bind(this));
- },
-
- jumpToNextSearchResult: function()
- {
- if (!this._searchView)
- return;
-
- if (this._searchView !== this.visibleView) {
- this.performSearch(this._searchQuery, true);
- return;
- }
-
- this._searchView.jumpToNextSearchResult();
- return true;
- },
-
- jumpToPreviousSearchResult: function()
- {
- if (!this._searchView)
- return;
-
- if (this._searchView !== this.visibleView) {
- this.performSearch(this._searchQuery, true);
- if (this._searchView)
- this._searchView.jumpToLastSearchResult();
- return;
- }
-
- this._searchView.jumpToPreviousSearchResult();
- },
-
- /**
- * @param {string} text
- */
- replaceSelectionWith: function(text)
- {
- var view = /** @type {!WebInspector.SourceFrame} */ (this.visibleView);
- view.replaceSearchMatchWith(text);
- },
-
- /**
- * @param {string} query
- * @param {string} text
- */
- replaceAllWith: function(query, text)
- {
- var view = /** @type {!WebInspector.SourceFrame} */ (this.visibleView);
- view.replaceAllWith(query, text);
- },
-
- _onKeyDown: function(event)
- {
- if (event.keyCode !== WebInspector.KeyboardShortcut.Keys.CtrlOrMeta.code)
- return;
- if (!this._paused || !this._executionSourceFrame)
- return;
- var stepIntoMarkup = this._executionSourceFrame.stepIntoMarkup();
- if (stepIntoMarkup)
- stepIntoMarkup.startIteratingSelection();
- },
-
- _onKeyUp: function(event)
- {
- if (event.keyCode !== WebInspector.KeyboardShortcut.Keys.CtrlOrMeta.code)
- return;
- if (!this._paused || !this._executionSourceFrame)
- return;
- var stepIntoMarkup = this._executionSourceFrame.stepIntoMarkup();
- if (!stepIntoMarkup)
- return;
- var currentPosition = stepIntoMarkup.getSelectedItemIndex();
- if (typeof currentPosition === "undefined") {
- stepIntoMarkup.stopIteratingSelection();
- } else {
- var rawLocation = stepIntoMarkup.getRawPosition(currentPosition);
- this.doStepIntoSelection(rawLocation);
- }
- },
-
- _toggleFormatSource: function()
- {
- delete this._skipExecutionLineRevealing;
- this._toggleFormatSourceButton.toggled = !this._toggleFormatSourceButton.toggled;
- var uiSourceCodes = this._workspace.uiSourceCodes();
- for (var i = 0; i < uiSourceCodes.length; ++i)
- uiSourceCodes[i].setFormatted(this._toggleFormatSourceButton.toggled);
-
- var currentFile = this._editorContainer.currentFile();
-
- WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
- action: WebInspector.UserMetrics.UserActionNames.TogglePrettyPrint,
- enabled: this._toggleFormatSourceButton.toggled,
- url: currentFile ? currentFile.originURL() : null
- });
- },
-
- addToWatch: function(expression)
- {
- this.sidebarPanes.watchExpressions.addExpression(expression);
- },
-
- /**
- * @return {boolean}
- */
- _toggleBreakpoint: function()
- {
- var sourceFrame = this.visibleView;
- if (!sourceFrame)
- return false;
-
- if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
- var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
- javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
- return true;
- }
- return false;
- },
-
- /**
- * @param {?Event=} event
- * @return {boolean}
- */
- _showOutlineDialog: function(event)
- {
- var uiSourceCode = this._editorContainer.currentFile();
- if (!uiSourceCode)
- return false;
-
- switch (uiSourceCode.contentType()) {
- case WebInspector.resourceTypes.Document:
- case WebInspector.resourceTypes.Script:
- WebInspector.JavaScriptOutlineDialog.show(this.visibleView, uiSourceCode, this.highlightPosition.bind(this));
- return true;
- case WebInspector.resourceTypes.Stylesheet:
- WebInspector.StyleSheetOutlineDialog.show(this.visibleView, uiSourceCode, this.highlightPosition.bind(this));
- return true;
- }
- return false;
- },
-
- _installDebuggerSidebarController: function()
- {
- this._toggleDebuggerSidebarButton = new WebInspector.StatusBarButton("", "right-sidebar-show-hide-button scripts-debugger-show-hide-button", 3);
- this._toggleDebuggerSidebarButton.addEventListener("click", clickHandler, this);
-
- if (this.splitView.isVertical()) {
- this.editorView.element.appendChild(this._toggleDebuggerSidebarButton.element);
- this.splitView.mainElement.appendChild(this._debugSidebarResizeWidgetElement);
- } else {
- this._statusBarContainerElement.appendChild(this._debugSidebarResizeWidgetElement);
- this._statusBarContainerElement.appendChild(this._toggleDebuggerSidebarButton.element);
- }
-
- this._enableDebuggerSidebar(!WebInspector.settings.debuggerSidebarHidden.get());
-
- /**
- * @this {WebInspector.SourcesPanel}
- */
- function clickHandler()
- {
- this._enableDebuggerSidebar(this._toggleDebuggerSidebarButton.state === "left");
- }
- },
-
- /**
- * @param {boolean} show
- */
- _enableDebuggerSidebar: function(show)
- {
- this._toggleDebuggerSidebarButton.state = show ? "right" : "left";
- this._toggleDebuggerSidebarButton.title = show ? WebInspector.UIString("Hide debugger") : WebInspector.UIString("Show debugger");
- if (show)
- this.splitView.showSidebarElement();
- else
- this.splitView.hideSidebarElement();
- this._debugSidebarResizeWidgetElement.enableStyleClass("hidden", !show);
- WebInspector.settings.debuggerSidebarHidden.set(!show);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _itemCreationRequested: function(event)
- {
- var project = event.data.project;
- var path = event.data.path;
- var uiSourceCodeToCopy = event.data.uiSourceCode;
- var filePath;
- var shouldHideNavigator;
- var uiSourceCode;
-
- /**
- * @param {?string} content
- * @this {WebInspector.SourcesPanel}
- */
- function contentLoaded(content)
- {
- createFile.call(this, content || "");
- }
-
- if (uiSourceCodeToCopy)
- uiSourceCodeToCopy.requestContent(contentLoaded.bind(this));
- else
- createFile.call(this);
-
- /**
- * @param {string=} content
- * @this {WebInspector.SourcesPanel}
- */
- function createFile(content)
- {
- project.createFile(path, null, content || "", fileCreated.bind(this));
- }
-
- /**
- * @param {?string} path
- * @this {WebInspector.SourcesPanel}
- */
- function fileCreated(path)
- {
- if (!path)
- return;
- filePath = path;
- uiSourceCode = project.uiSourceCode(filePath);
- this._showSourceLocation(uiSourceCode);
-
- shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
- if (this._navigatorController.isNavigatorHidden())
- this._navigatorController.showNavigatorOverlay();
- this._navigator.rename(uiSourceCode, callback.bind(this));
- }
-
- /**
- * @param {boolean} committed
- * @this {WebInspector.SourcesPanel}
- */
- function callback(committed)
- {
- if (shouldHideNavigator)
- this._navigatorController.hideNavigatorOverlay();
-
- if (!committed) {
- project.deleteFile(uiSourceCode);
- return;
- }
-
- this._recreateSourceFrameIfNeeded(uiSourceCode);
- this._navigator.updateIcon(uiSourceCode);
- this._showSourceLocation(uiSourceCode);
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _itemRenamingRequested: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
-
- var shouldHideNavigator = !this._navigatorController.isNavigatorPinned();
- if (this._navigatorController.isNavigatorHidden())
- this._navigatorController.showNavigatorOverlay();
- this._navigator.rename(uiSourceCode, callback.bind(this));
-
- /**
- * @param {boolean} committed
- * @this {WebInspector.SourcesPanel}
- */
- function callback(committed)
- {
- if (shouldHideNavigator && committed)
- this._navigatorController.hideNavigatorOverlay();
- this._recreateSourceFrameIfNeeded(uiSourceCode);
- this._navigator.updateIcon(uiSourceCode);
- this._showSourceLocation(uiSourceCode);
- }
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _showLocalHistory: function(uiSourceCode)
- {
- WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
- */
- appendApplicableItems: function(event, contextMenu, target)
- {
- this._appendUISourceCodeItems(contextMenu, target);
- this._appendFunctionItems(contextMenu, target);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _mapFileSystemToNetwork: function(uiSourceCode)
- {
- WebInspector.SelectUISourceCodeForProjectTypeDialog.show(uiSourceCode.name(), WebInspector.projectTypes.Network, mapFileSystemToNetwork.bind(this), this.editorView.mainElement)
-
- /**
- * @param {!WebInspector.UISourceCode} networkUISourceCode
- * @this {WebInspector.SourcesPanel}
- */
- function mapFileSystemToNetwork(networkUISourceCode)
- {
- this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
- }
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _removeNetworkMapping: function(uiSourceCode)
- {
- if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?")))
- this._workspace.removeMapping(uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} networkUISourceCode
- */
- _mapNetworkToFileSystem: function(networkUISourceCode)
- {
- WebInspector.SelectUISourceCodeForProjectTypeDialog.show(networkUISourceCode.name(), WebInspector.projectTypes.FileSystem, mapNetworkToFileSystem.bind(this), this.editorView.mainElement)
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @this {WebInspector.SourcesPanel}
- */
- function mapNetworkToFileSystem(uiSourceCode)
- {
- this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceProvider);
- }
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
- {
- if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
- var hasMappings = !!uiSourceCode.url;
- if (!hasMappings)
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode));
- else
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
- }
-
- /**
- * @param {!WebInspector.Project} project
- */
- function filterProject(project)
- {
- return project.type() === WebInspector.projectTypes.FileSystem;
- }
-
- if (uiSourceCode.project().type() === WebInspector.projectTypes.Network) {
- if (!this._workspace.projects().filter(filterProject).length)
- return;
- if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode));
- }
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
- */
- _appendUISourceCodeItems: function(contextMenu, target)
- {
- if (!(target instanceof WebInspector.UISourceCode))
- return;
-
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target);
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
-
- if (WebInspector.isolatedFileSystemManager.supportsFileSystems())
- this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
- */
- _appendFunctionItems: function(contextMenu, target)
- {
- if (!(target instanceof WebInspector.RemoteObject))
- return;
- var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
- if (remoteObject.type !== "function")
- return;
-
- /**
- * @param {?Protocol.Error} error
- * @param {!DebuggerAgent.FunctionDetails} response
- * @this {WebInspector.SourcesPanel}
- */
- function didGetDetails(error, response)
- {
- if (error) {
- console.error(error);
- return;
- }
-
- var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
- if (!uiLocation)
- return;
-
- this.showUILocation(uiLocation, true);
- }
-
- /**
- * @this {WebInspector.SourcesPanel}
- */
- function revealFunction()
- {
- DebuggerAgent.getFunctionDetails(remoteObject.objectId, didGetDetails.bind(this));
- }
-
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), revealFunction.bind(this));
- },
-
- showGoToSourceDialog: function()
- {
- var uiSourceCodes = this._editorContainer.historyUISourceCodes();
- /** @type {!Map.<!WebInspector.UISourceCode, number>} */
- var defaultScores = new Map();
- for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
- defaultScores.put(uiSourceCodes[i], uiSourceCodes.length - i);
- WebInspector.OpenResourceDialog.show(this, this.editorView.mainElement, undefined, defaultScores);
- },
-
- _dockSideChanged: function()
- {
- var dockSide = WebInspector.dockController.dockSide();
- var vertically = dockSide === WebInspector.DockController.State.DockedToRight && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
- this._splitVertically(vertically);
- },
-
- /**
- * @param {boolean} vertically
- */
- _splitVertically: function(vertically)
- {
- if (this.sidebarPaneView && vertically === !this.splitView.isVertical())
- return;
-
- if (this.sidebarPaneView)
- this.sidebarPaneView.detach();
-
- this.splitView.setVertical(!vertically);
-
- if (!vertically) {
- this.splitView.uninstallResizer(this._statusBarContainerElement);
- this.sidebarPaneView = new WebInspector.SidebarPaneStack();
- for (var pane in this.sidebarPanes)
- this.sidebarPaneView.addPane(this.sidebarPanes[pane]);
- this._extensionSidebarPanesContainer = this.sidebarPaneView;
- this.sidebarElement.appendChild(this.debugToolbar);
- this.editorView.element.appendChild(this._toggleDebuggerSidebarButton.element);
- this.splitView.mainElement.appendChild(this._debugSidebarResizeWidgetElement);
- } else {
- this.splitView.installResizer(this._statusBarContainerElement);
- this.sidebarPaneView = new WebInspector.SplitView(true, this.name + "PanelSplitSidebarRatio", 0.5);
-
- var group1 = new WebInspector.SidebarPaneStack();
- group1.show(this.sidebarPaneView.firstElement());
- group1.element.id = "scripts-sidebar-stack-pane";
- group1.addPane(this.sidebarPanes.callstack);
- group1.addPane(this.sidebarPanes.jsBreakpoints);
- group1.addPane(this.sidebarPanes.domBreakpoints);
- group1.addPane(this.sidebarPanes.xhrBreakpoints);
- group1.addPane(this.sidebarPanes.eventListenerBreakpoints);
- if (this.sidebarPanes.workerList)
- group1.addPane(this.sidebarPanes.workerList);
-
- var group2 = new WebInspector.SidebarTabbedPane();
- group2.show(this.sidebarPaneView.secondElement());
- group2.addPane(this.sidebarPanes.scopechain);
- group2.addPane(this.sidebarPanes.watchExpressions);
- this._extensionSidebarPanesContainer = group2;
- this.sidebarPaneView.firstElement().appendChild(this.debugToolbar);
- this._statusBarContainerElement.appendChild(this._debugSidebarResizeWidgetElement);
- this._statusBarContainerElement.appendChild(this._toggleDebuggerSidebarButton.element)
- }
- for (var i = 0; i < this._extensionSidebarPanes.length; ++i)
- this._extensionSidebarPanesContainer.addPane(this._extensionSidebarPanes[i]);
-
- this.sidebarPaneView.element.id = "scripts-debug-sidebar-contents";
- this.sidebarPaneView.show(this.splitView.sidebarElement);
-
- this.sidebarPanes.scopechain.expand();
- this.sidebarPanes.jsBreakpoints.expand();
- this.sidebarPanes.callstack.expand();
-
- if (WebInspector.settings.watchExpressions.get().length > 0)
- this.sidebarPanes.watchExpressions.expand();
- },
-
- canHighlightPosition: function()
- {
- return this.visibleView && this.visibleView.canHighlightPosition();
- },
-
- /**
- * @param {number} line
- * @param {number=} column
- */
- highlightPosition: function(line, column)
- {
- if (!this.canHighlightPosition())
- return;
- this.visibleView.highlightPosition(line, column);
- },
-
- /**
- * @param {string} id
- * @param {!WebInspector.SidebarPane} pane
- */
- addExtensionSidebarPane: function(id, pane)
- {
- this._extensionSidebarPanes.push(pane);
- this._extensionSidebarPanesContainer.addPane(pane);
- this.setHideOnDetach();
- },
-
- /**
- * @return {!WebInspector.TabbedEditorContainer}
- */
- get tabbedEditorContainer()
- {
- return this._editorContainer;
- },
-
- __proto__: WebInspector.Panel.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.SourcesView = function()
-{
- WebInspector.View.call(this);
- this.registerRequiredCSS("sourcesView.css");
- this.element.id = "sources-panel-sources-view";
- this.element.classList.add("vbox");
- this.element.addEventListener("dragenter", this._onDragEnter.bind(this), true);
- this.element.addEventListener("dragover", this._onDragOver.bind(this), true);
-}
-
-WebInspector.SourcesView.dragAndDropFilesType = "Files";
-
-WebInspector.SourcesView.prototype = {
- _onDragEnter: function (event)
- {
- if (event.dataTransfer.types.indexOf(WebInspector.SourcesView.dragAndDropFilesType) === -1)
- return;
- event.consume(true);
- },
-
- _onDragOver: function (event)
- {
- if (event.dataTransfer.types.indexOf(WebInspector.SourcesView.dragAndDropFilesType) === -1)
- return;
- event.consume(true);
- if (this._dragMaskElement)
- return;
- this._dragMaskElement = this.element.createChild("div", "fill drag-mask");
- this._dragMaskElement.addEventListener("drop", this._onDrop.bind(this), true);
- this._dragMaskElement.addEventListener("dragleave", this._onDragLeave.bind(this), true);
- },
-
- _onDrop: function (event)
- {
- event.consume(true);
- this._removeMask();
- var items = /** @type {!Array.<!DataTransferItem>} */ (event.dataTransfer.items);
- if (!items.length)
- return;
- var entry = items[0].webkitGetAsEntry();
- if (!entry.isDirectory)
- return;
- InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);
- },
-
- _onDragLeave: function (event)
- {
- event.consume(true);
- this._removeMask();
- },
-
- _removeMask: function ()
- {
- this._dragMaskElement.remove();
- delete this._dragMaskElement;
- },
-
- __proto__: WebInspector.View.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.DrawerEditorView = function()
-{
- WebInspector.View.call(this);
- this.element.id = "drawer-editor-view";
- this.element.classList.add("vbox");
-}
-
-WebInspector.DrawerEditorView.prototype = {
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanelDescriptor.js
deleted file mode 100644
index b1bd0dc7367..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesPanelDescriptor.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.PanelDescriptor}
- * @implements {WebInspector.ContextMenu.Provider}
- */
-WebInspector.SourcesPanelDescriptor = function()
-{
- WebInspector.PanelDescriptor.call(this, "sources", WebInspector.UIString("Sources"), "SourcesPanel", "SourcesPanel.js");
- WebInspector.ContextMenu.registerProvider(this);
-}
-
-WebInspector.SourcesPanelDescriptor.prototype = {
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
- */
- appendApplicableItems: function(event, contextMenu, target)
- {
- var hasApplicableItems = target instanceof WebInspector.UISourceCode;
-
- if (!hasApplicableItems && target instanceof WebInspector.RemoteObject) {
- var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
- if (remoteObject.type !== "function")
- return;
- }
-
- this.panel().appendApplicableItems(event, contextMenu, target);
- },
-
- registerShortcuts: function()
- {
- var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
-
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.PauseContinue, WebInspector.UIString("Pause/Continue"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepOver, WebInspector.UIString("Step over"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepInto, WebInspector.UIString("Step into"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepIntoSelection, WebInspector.UIString("Step into selection"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.StepOut, WebInspector.UIString("Step out"));
-
- var nextAndPrevFrameKeys = WebInspector.SourcesPanelDescriptor.ShortcutKeys.NextCallFrame.concat(WebInspector.SourcesPanelDescriptor.ShortcutKeys.PrevCallFrame);
- section.addRelatedKeys(nextAndPrevFrameKeys, WebInspector.UIString("Next/previous call frame"));
-
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.EvaluateSelectionInConsole, WebInspector.UIString("Evaluate selection in console"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.AddSelectionToWatch, WebInspector.UIString("Add selection to watch"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.GoToMember, WebInspector.UIString("Go to member"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.ToggleBreakpoint, WebInspector.UIString("Toggle breakpoint"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.ToggleComment, WebInspector.UIString("Toggle comment"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.IncreaseCSSUnitByOne, WebInspector.UIString("Increment CSS unit by 1"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.DecreaseCSSUnitByOne, WebInspector.UIString("Decrement CSS unit by 1"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.IncreaseCSSUnitByTen, WebInspector.UIString("Increment CSS unit by 10"));
- section.addAlternateKeys(WebInspector.SourcesPanelDescriptor.ShortcutKeys.DecreaseCSSUnitByTen, WebInspector.UIString("Decrement CSS unit by 10"));
- },
-
- __proto__: WebInspector.PanelDescriptor.prototype
-}
-
-WebInspector.SourcesPanelDescriptor.ShortcutKeys = {
- IncreaseCSSUnitByOne: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ],
-
- DecreaseCSSUnitByOne: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ],
-
- IncreaseCSSUnitByTen: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ],
-
- DecreaseCSSUnitByTen: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt)
- ],
-
- RunSnippet: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- PauseContinue: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Backslash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- StepOver: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- StepInto: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- StepIntoSelection: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- StepOut: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift),
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- EvaluateSelectionInConsole: [
- WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl)
- ],
-
- AddSelectionToWatch: [
- WebInspector.KeyboardShortcut.makeDescriptor("a", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl)
- ],
-
- GoToMember: [
- WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift)
- ],
-
- ToggleBreakpoint: [
- WebInspector.KeyboardShortcut.makeDescriptor("b", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- NextCallFrame: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
- ],
-
- PrevCallFrame: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
- ],
-
- ToggleComment: [
- WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
-
- ]
-};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SplitView.js b/chromium/third_party/WebKit/Source/devtools/front_end/SplitView.js
deleted file mode 100644
index f81d98d80d9..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SplitView.js
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- * @param {boolean} isVertical
- * @param {string=} sidebarSizeSettingName
- * @param {number=} defaultSidebarWidth
- * @param {number=} defaultSidebarHeight
- */
-WebInspector.SplitView = function(isVertical, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight)
-{
- WebInspector.View.call(this);
-
- this.registerRequiredCSS("splitView.css");
-
- this.element.classList.add("split-view");
- this.element.classList.add("fill");
-
- this._firstElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-first");
- this._secondElement = this.element.createChild("div", "split-view-contents scroll-target split-view-contents-second");
-
- this._resizerElement = this.element.createChild("div", "split-view-resizer");
- this._onDragStartBound = this._onDragStart.bind(this);
- this._resizerElements = [];
-
- this._resizable = true;
-
- this._savedSidebarWidth = defaultSidebarWidth || 200;
- this._savedSidebarHeight = defaultSidebarHeight || this._savedSidebarWidth;
-
- if (0 < this._savedSidebarWidth && this._savedSidebarWidth < 1 &&
- 0 < this._savedSidebarHeight && this._savedSidebarHeight < 1)
- this._useFraction = true;
-
- this._sidebarSizeSettingName = sidebarSizeSettingName;
-
- this.setSecondIsSidebar(true);
-
- this._innerSetVertical(isVertical);
-
- // Should be called after isVertical has the right value.
- this.installResizer(this._resizerElement);
-}
-
-WebInspector.SplitView.prototype = {
- /**
- * @return {boolean}
- */
- isVertical: function()
- {
- return this._isVertical;
- },
-
- /**
- * @param {boolean} isVertical
- */
- setVertical: function(isVertical)
- {
- if (this._isVertical === isVertical)
- return;
-
- this._innerSetVertical(isVertical);
-
- if (this.isShowing())
- this._updateLayout();
-
- for (var i = 0; i < this._resizerElements.length; ++i)
- this._resizerElements[i].style.setProperty("cursor", this._isVertical ? "ew-resize" : "ns-resize");
- },
-
- /**
- * @param {boolean} isVertical
- */
- _innerSetVertical: function(isVertical)
- {
- this.element.classList.remove(this._isVertical ? "hbox" : "vbox");
- this._isVertical = isVertical;
- this.element.classList.add(this._isVertical ? "hbox" : "vbox");
- delete this._resizerElementSize;
- this._sidebarSize = -1;
- },
-
- _updateLayout: function()
- {
- delete this._totalSize; // Lazy update.
- this._innerSetSidebarSize(this._lastSidebarSize());
- },
-
- /**
- * @return {!Element}
- */
- firstElement: function()
- {
- return this._firstElement;
- },
-
- /**
- * @return {!Element}
- */
- secondElement: function()
- {
- return this._secondElement;
- },
-
- /**
- * @return {!Element}
- */
- get mainElement()
- {
- return this.isSidebarSecond() ? this.firstElement() : this.secondElement();
- },
-
- /**
- * @return {!Element}
- */
- get sidebarElement()
- {
- return this.isSidebarSecond() ? this.secondElement() : this.firstElement();
- },
-
- /**
- * @return {boolean}
- */
- isSidebarSecond: function()
- {
- return this._secondIsSidebar;
- },
-
- /**
- * @param {boolean} secondIsSidebar
- */
- setSecondIsSidebar: function(secondIsSidebar)
- {
- this.sidebarElement.classList.remove("split-view-sidebar");
- this.mainElement.classList.remove("split-view-main");
- this._secondIsSidebar = secondIsSidebar;
- this.sidebarElement.classList.add("split-view-sidebar");
- this.mainElement.classList.add("split-view-main");
- },
-
- /**
- * @return {!Element}
- */
- resizerElement: function()
- {
- return this._resizerElement;
- },
-
- showOnlyFirst: function()
- {
- this._showOnly(this._firstElement, this._secondElement);
- },
-
- showOnlySecond: function()
- {
- this._showOnly(this._secondElement, this._firstElement);
- },
-
- /**
- * @param {!Element} sideA
- * @param {!Element} sideB
- */
- _showOnly: function(sideA, sideB)
- {
- sideA.classList.remove("hidden");
- sideA.classList.add("maximized");
- sideB.classList.add("hidden");
- sideB.classList.remove("maximized");
- this._removeAllLayoutProperties();
-
- this._isShowingOne = true;
- this._sidebarSize = -1;
- this.setResizable(false);
- this.doResize();
- },
-
- _removeAllLayoutProperties: function()
- {
- this.sidebarElement.style.removeProperty("flexBasis");
-
- this._resizerElement.style.removeProperty("left");
- this._resizerElement.style.removeProperty("right");
- this._resizerElement.style.removeProperty("top");
- this._resizerElement.style.removeProperty("bottom");
-
- this._resizerElement.style.removeProperty("margin-left");
- this._resizerElement.style.removeProperty("margin-right");
- this._resizerElement.style.removeProperty("margin-top");
- this._resizerElement.style.removeProperty("margin-bottom");
- },
-
- showBoth: function()
- {
- this._firstElement.classList.remove("hidden");
- this._firstElement.classList.remove("maximized");
- this._secondElement.classList.remove("hidden");
- this._secondElement.classList.remove("maximized");
-
- this._isShowingOne = false;
- this._sidebarSize = -1;
- this.setResizable(true);
- this.doResize();
- },
-
- /**
- * @param {boolean} resizable
- */
- setResizable: function(resizable)
- {
- this._resizable = resizable;
- this._resizerElement.enableStyleClass("hidden", !resizable);
- },
-
- /**
- * @param {number} size
- */
- setSidebarSize: function(size)
- {
- this._innerSetSidebarSize(size);
- this._saveSidebarSize();
- },
-
- /**
- * @return {number}
- */
- sidebarSize: function()
- {
- return Math.max(0, this._sidebarSize);
- },
-
- /**
- * @return {number}
- */
- totalSize: function()
- {
- if (!this._totalSize)
- this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
- return this._totalSize;
- },
-
- /**
- * @param {number} size
- */
- _innerSetSidebarSize: function(size)
- {
- if (this._isShowingOne) {
- this._sidebarSize = size;
- return;
- }
-
- size = this._applyConstraints(size);
- if (this._sidebarSize === size)
- return;
-
- if (size < 0) {
- // Never apply bad values, fix it upon onResize instead.
- return;
- }
-
- this._removeAllLayoutProperties();
-
- var sizeValue;
- if (this._useFraction)
- sizeValue = (size / this.totalSize()) * 100 + "%";
- else
- sizeValue = size + "px";
-
- if (!this._resizerElementSize)
- this._resizerElementSize = this._isVertical ? this._resizerElement.offsetWidth : this._resizerElement.offsetHeight;
-
- this.sidebarElement.style.flexBasis = sizeValue;
- if (this._isVertical) {
- if (this._secondIsSidebar) {
- this._resizerElement.style.right = sizeValue;
- this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + "px";
- } else {
- this._resizerElement.style.left = sizeValue;
- this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + "px";
- }
- } else {
- if (this._secondIsSidebar) {
- this._resizerElement.style.bottom = sizeValue;
- this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + "px";
- } else {
- this._resizerElement.style.top = sizeValue;
- this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + "px";
- }
- }
-
- this._sidebarSize = size;
-
- // No need to recalculate this._sidebarSize and this._totalSize again.
- this._muteOnResize = true;
- this.doResize();
- delete this._muteOnResize;
- },
-
- /**
- * @param {number=} minWidth
- * @param {number=} minHeight
- */
- setSidebarElementConstraints: function(minWidth, minHeight)
- {
- if (typeof minWidth === "number")
- this._minimumSidebarWidth = minWidth;
- if (typeof minHeight === "number")
- this._minimumSidebarHeight = minHeight;
- },
-
- /**
- * @param {number=} minWidth
- * @param {number=} minHeight
- */
- setMainElementConstraints: function(minWidth, minHeight)
- {
- if (typeof minWidth === "number")
- this._minimumMainWidth = minWidth;
- if (typeof minHeight === "number")
- this._minimumMainHeight = minHeight;
- },
-
- /**
- * @param {number} sidebarSize
- * @return {number}
- */
- _applyConstraints: function(sidebarSize)
- {
- const minPadding = 20;
- var totalSize = this.totalSize();
- var from = (this.isVertical() ? this._minimumSidebarWidth : this._minimumSidebarHeight) || 0;
- var fromInPercents = false;
- if (from && from < 1) {
- fromInPercents = true;
- from = Math.round(totalSize * from);
- }
- from = Math.max(from, minPadding);
-
- var minMainSize = (this.isVertical() ? this._minimumMainWidth : this._minimumMainHeight) || 0;
- var toInPercents = false;
- if (minMainSize && minMainSize < 1) {
- toInPercents = true;
- minMainSize = Math.round(totalSize * minMainSize);
- }
- minMainSize = Math.max(minMainSize, minPadding);
-
- var to = totalSize - minMainSize;
- if (from <= to)
- return Number.constrain(sidebarSize, from, to);
-
- // Respect fixed constraints over percents. This will, for example, shrink
- // the sidebar to its minimum size when possible.
- if (!fromInPercents && !toInPercents)
- return -1;
- if (toInPercents && sidebarSize >= from && from < totalSize)
- return from;
- if (fromInPercents && sidebarSize <= to && to < totalSize)
- return to;
-
- return -1;
- },
-
- wasShown: function()
- {
- this._updateLayout();
- },
-
- onResize: function()
- {
- if (this._muteOnResize)
- return;
- this._updateLayout();
- },
-
- /**
- * @param {!MouseEvent} event
- * @return {boolean}
- */
- _startResizerDragging: function(event)
- {
- if (!this._resizable)
- return false;
-
- this._saveSidebarSizeRecursively();
- this._dragOffset = (this._secondIsSidebar ? this.totalSize() - this._sidebarSize : this._sidebarSize) - (this._isVertical ? event.pageX : event.pageY);
- return true;
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _resizerDragging: function(event)
- {
- var newOffset = (this._isVertical ? event.pageX : event.pageY) + this._dragOffset;
- var newSize = (this._secondIsSidebar ? this.totalSize() - newOffset : newOffset);
- this.setSidebarSize(newSize);
- event.preventDefault();
- },
-
- /**
- * @param {!MouseEvent} event
- */
- _endResizerDragging: function(event)
- {
- delete this._dragOffset;
- this._saveSidebarSizeRecursively();
- },
-
- _saveSidebarSizeRecursively: function()
- {
- /** @this {WebInspector.View} */
- function doSaveSidebarSizeRecursively()
- {
- if (this._saveSidebarSize)
- this._saveSidebarSize();
- this._callOnVisibleChildren(doSaveSidebarSizeRecursively);
- }
- this._saveSidebarSize();
- this._callOnVisibleChildren(doSaveSidebarSizeRecursively);
- },
-
- /**
- * @param {!Element} resizerElement
- */
- installResizer: function(resizerElement)
- {
- resizerElement.addEventListener("mousedown", this._onDragStartBound, false);
- resizerElement.style.setProperty("cursor", this._isVertical ? "ew-resize" : "ns-resize");
- this._resizerElements.push(resizerElement);
- },
-
- /**
- * @param {!Element} resizerElement
- */
- uninstallResizer: function(resizerElement)
- {
- resizerElement.removeEventListener("mousedown", this._onDragStartBound, false);
- resizerElement.style.removeProperty("cursor");
- this._resizerElements.remove(resizerElement);
- },
-
- /**
- * @param {?Event} event
- */
- _onDragStart: function(event)
- {
- WebInspector.elementDragStart(this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), this._isVertical ? "ew-resize" : "ns-resize", event);
- },
-
- /**
- * @return {?WebInspector.Setting}
- */
- _sizeSetting: function()
- {
- if (!this._sidebarSizeSettingName)
- return null;
-
- var settingName = this._sidebarSizeSettingName + (this._isVertical ? "" : "H");
- if (!WebInspector.settings[settingName])
- WebInspector.settings[settingName] = WebInspector.settings.createSetting(settingName, undefined);
-
- return WebInspector.settings[settingName];
- },
-
- /**
- * @return {number}
- */
- _lastSidebarSize: function()
- {
- var sizeSetting = this._sizeSetting();
- var size = sizeSetting ? sizeSetting.get() : 0;
- if (!size)
- size = this._isVertical ? this._savedSidebarWidth : this._savedSidebarHeight;
- if (this._useFraction)
- size *= this.totalSize();
- return size;
- },
-
- _saveSidebarSize: function()
- {
- var size = this._sidebarSize;
- if (size < 0)
- return;
-
- if (this._useFraction)
- size /= this.totalSize();
-
- if (this._isVertical)
- this._savedSidebarWidth = size;
- else
- this._savedSidebarHeight = size;
-
- var sizeSetting = this._sizeSetting();
- if (sizeSetting)
- sizeSetting.set(size);
- },
-
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TempFile.js b/chromium/third_party/WebKit/Source/devtools/front_end/TempFile.js
deleted file mode 100644
index 66f60386db5..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TempFile.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
-
-/**
- * @constructor
- * @param {!string} dirPath
- * @param {!string} name
- * @param {!function(?WebInspector.TempFile)} callback
- */
-WebInspector.TempFile = function(dirPath, name, callback)
-{
- this._fileEntry = null;
- this._writer = null;
-
- /**
- * @param {!FileSystem} fs
- * @this {WebInspector.TempFile}
- */
- function didInitFs(fs)
- {
- fs.root.getDirectory(dirPath, { create: true }, didGetDir.bind(this), boundErrorHandler);
- }
-
- /**
- * @param {!DirectoryEntry} dir
- * @this {WebInspector.TempFile}
- */
- function didGetDir(dir)
- {
- dir.getFile(name, { create: true }, didCreateFile.bind(this), boundErrorHandler);
- }
-
- /**
- * @param {!FileEntry} fileEntry
- * @this {WebInspector.TempFile}
- */
- function didCreateFile(fileEntry)
- {
- this._fileEntry = fileEntry;
- fileEntry.createWriter(didCreateWriter.bind(this), boundErrorHandler);
- }
-
- /**
- * @param {!FileWriter} writer
- * @this {WebInspector.TempFile}
- */
- function didCreateWriter(writer)
- {
- /**
- * @this {WebInspector.TempFile}
- */
- function didTruncate(e)
- {
- this._writer = writer;
- writer.onwrite = null;
- writer.onerror = null;
- callback(this);
- }
- function onTruncateError(e)
- {
- WebInspector.log("Failed to truncate temp file " + e.code + " : " + e.message,
- WebInspector.ConsoleMessage.MessageLevel.Error);
- callback(null);
- }
- if (writer.length) {
- writer.onwrite = didTruncate.bind(this);
- writer.onerror = onTruncateError.bind(this);
- writer.truncate(0);
- } else {
- this._writer = writer;
- callback(this);
- }
- }
-
- function errorHandler(e)
- {
- WebInspector.log("Failed to create temp file " + e.code + " : " + e.message,
- WebInspector.ConsoleMessage.MessageLevel.Error);
- callback(null);
- }
- var boundErrorHandler = errorHandler.bind(this)
- window.requestFileSystem(window.TEMPORARY, 10, didInitFs.bind(this), errorHandler.bind(this));
-}
-
-WebInspector.TempFile.prototype = {
- /**
- * @param {!string} data
- */
- write: function(data)
- {
- var blob = new Blob([data], {type: 'text/plain'});
- this._writer.onerror = function(e)
- {
- WebInspector.log("Failed to write into a temp file: " + e.message,
- WebInspector.ConsoleMessage.MessageLevel.Error);
- }
- this._writer.write(blob);
- this._writer = null;
- },
-
- /**
- * @param {function(?string)} callback
- */
- read: function(callback)
- {
- /**
- * @param {!File} file
- * @this {WebInspector.TempFile}
- */
- function didGetFile(file)
- {
- var reader = new FileReader();
-
- /**
- * @this {FileReader}
- */
- reader.onloadend = function(e)
- {
- callback(/** @type {string} */ (this.result));
- }
- reader.onerror = function(error)
- {
- WebInspector.log("Failed to read from temp file: " + error.message,
- WebInspector.ConsoleMessage.MessageLevel.Error);
- callback(null);
- }
- reader.readAsText(file);
- }
- function didFailToGetFile(error)
- {
- WebInspector.log("Failed to load temp file: " + error.message,
- WebInspector.ConsoleMessage.MessageLevel.Error);
- }
- this._fileEntry.file(didGetFile.bind(this), didFailToGetFile.bind(this));
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TestController.js b/chromium/third_party/WebKit/Source/devtools/front_end/TestController.js
index ffb023804f8..04ad6d9b90a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TestController.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/TestController.js
@@ -45,5 +45,5 @@ WebInspector.evaluateForTestInFrontend = function(callId, script)
}
RuntimeAgent.evaluate("didEvaluateForTestInFrontend(" + callId + ", " + message + ")", "test");
}
- InspectorBackend.runAfterPendingDispatches(invokeMethod);
+ InspectorBackend.connection().runAfterPendingDispatches(invokeMethod);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Tests.js b/chromium/third_party/WebKit/Source/devtools/front_end/Tests.js
index 745c6cc4ab0..09603cf3c91 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Tests.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -54,7 +54,7 @@ TestSuite = function()
/**
* Reports test failure.
- * @param {string} message !Failure description.
+ * @param {string} message Failure description.
*/
TestSuite.prototype.fail = function(message)
{
@@ -67,9 +67,9 @@ TestSuite.prototype.fail = function(message)
/**
* Equals assertion tests that expected === actual.
- * @param {!Object} expected !Expected object.
- * @param {!Object} actual !Actual object.
- * @param {string} opt_message !User message to print if the test fails.
+ * @param {!Object} expected Expected object.
+ * @param {!Object} actual Actual object.
+ * @param {string} opt_message User message to print if the test fails.
*/
TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
{
@@ -83,8 +83,8 @@ TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
/**
* True assertion tests that value == true.
- * @param {!Object} value !Actual object.
- * @param {string} opt_message !User message to print if the test fails.
+ * @param {!Object} value Actual object.
+ * @param {string} opt_message User message to print if the test fails.
*/
TestSuite.prototype.assertTrue = function(value, opt_message)
{
@@ -106,8 +106,8 @@ TestSuite.prototype.assertHasKey = function(object, key)
/**
* Contains assertion tests that string contains substring.
- * @param {string} string !Outer.
- * @param {string} substring !Inner.
+ * @param {string} string Outer.
+ * @param {string} substring Inner.
*/
TestSuite.prototype.assertContains = function(string, substring)
{
@@ -181,7 +181,7 @@ TestSuite.prototype.runTest = function(testName)
/**
- * @param {string} panelName !Name of the panel to show.
+ * @param {string} panelName Name of the panel to show.
*/
TestSuite.prototype.showPanel = function(panelName)
{
@@ -194,11 +194,11 @@ TestSuite.prototype.showPanel = function(panelName)
/**
* Overrides the method with specified name until it's called first time.
- * @param {!Object} receiver !An object whose method to override.
- * @param {string} methodName !Name of the method to override.
- * @param {!Function} override !A function that should be called right after the
- * overriden method returns.
- * @param {boolean} opt_sticky !Whether restore original method after first run
+ * @param {!Object} receiver An object whose method to override.
+ * @param {string} methodName Name of the method to override.
+ * @param {!Function} override A function that should be called right after the
+ * overridden method returns.
+ * @param {boolean} opt_sticky Whether restore original method after first run
* or not.
*/
TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky)
@@ -225,16 +225,6 @@ TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_st
};
-TestSuite.prototype.testEnableResourcesTab = function()
-{
- // FIXME once reference is removed downstream.
-}
-
-TestSuite.prototype.testCompletionOnPause = function()
-{
- // FIXME once reference is removed downstream.
-}
-
// UI Tests
@@ -520,7 +510,6 @@ TestSuite.prototype.testConsoleOnNavigateBack = function()
function didClickLink() {
// Check that there are no new messages(command is not a message).
this.assertEquals(3, WebInspector.console.messages.length);
- this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.evaluateInConsole_("history.back();", didNavigateBack.bind(this));
}
@@ -532,18 +521,17 @@ TestSuite.prototype.testConsoleOnNavigateBack = function()
function didCompleteNavigation() {
this.assertEquals(7, WebInspector.console.messages.length);
- this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
this.releaseControl();
}
this.takeControl();
};
-
TestSuite.prototype.testReattachAfterCrash = function()
{
- this.evaluateInConsole_("1+1;", this.releaseControl.bind(this));
- this.takeControl();
+ PageAgent.navigate("about:crash");
+ PageAgent.navigate("about:blank");
+ WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this.releaseControl, this);
};
@@ -586,8 +574,8 @@ TestSuite.prototype.testTimelineFrames = function()
for (var i = 0; i < records.length; ++i) {
var record = records[i];
- if (record.type !== "BeginFrame") {
- recordsInFrame[record.type] = (recordsInFrame[record.type] || 0) + 1;
+ if (record.type() !== "BeginFrame") {
+ recordsInFrame[record.type()] = (recordsInFrame[record.type()] || 0) + 1;
continue;
}
if (!frameCount++)
@@ -607,10 +595,16 @@ TestSuite.prototype.testTimelineFrames = function()
test.takeControl();
}
+TestSuite.prototype.enableTouchEmulation = function()
+{
+ WebInspector.targetManager.activeTarget().domModel.emulateTouchEventObjects(true);
+};
+
// Regression test for http://webk.it/97466
TestSuite.prototype.testPageOverlayUpdate = function()
{
var test = this;
+ WebInspector.inspectorView.panel("elements");
function populatePage()
{
@@ -628,12 +622,12 @@ TestSuite.prototype.testPageOverlayUpdate = function()
{
test.evaluateInConsole_(populatePage.toString() + "; populatePage();" +
"inspect(document.getElementById('div1'))", function() {});
- WebInspector.notifications.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step2);
+ WebInspector.notifications.addEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, step2);
}
function step2()
{
- WebInspector.notifications.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step2);
+ WebInspector.notifications.removeEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, step2);
test.recordTimeline(onTimelineRecorded);
setTimeout(step3, 500);
}
@@ -641,12 +635,12 @@ TestSuite.prototype.testPageOverlayUpdate = function()
function step3()
{
test.evaluateInConsole_("inspect(document.getElementById('div2'))", function() {});
- WebInspector.notifications.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step4);
+ WebInspector.notifications.addEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, step4);
}
function step4()
{
- WebInspector.notifications.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, step4);
+ WebInspector.notifications.removeEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, step4);
test.stopTimeline();
}
@@ -669,8 +663,66 @@ TestSuite.prototype.testPageOverlayUpdate = function()
this.takeControl();
}
+// Regression test for crbug.com/370035.
+TestSuite.prototype.testDeviceMetricsOverrides = function()
+{
+ const dumpPageMetrics = function()
+ {
+ return JSON.stringify({
+ width: window.innerWidth,
+ height: window.innerHeight,
+ deviceScaleFactor: window.devicePixelRatio
+ });
+ };
-/**
+ var test = this;
+
+ function testOverrides(params, metrics, callback)
+ {
+ PageAgent.invoke_setDeviceMetricsOverride(params, getMetrics);
+
+ function getMetrics()
+ {
+ test.evaluateInConsole_("(" + dumpPageMetrics.toString() + ")()", checkMetrics);
+ }
+
+ function checkMetrics(consoleResult)
+ {
+ test.assertEquals('"' + JSON.stringify(metrics) + '"', consoleResult, "Wrong metrics for params: " + JSON.stringify(params));
+ callback();
+ }
+ }
+
+ function step1()
+ {
+ testOverrides({width: 1200, height: 1000, deviceScaleFactor: 1, emulateViewport: false, fitWindow: true}, {width: 1200, height: 1000, deviceScaleFactor: 1}, step2);
+ }
+
+ function step2()
+ {
+ testOverrides({width: 1200, height: 1000, deviceScaleFactor: 1, emulateViewport: false, fitWindow: false}, {width: 1200, height: 1000, deviceScaleFactor: 1}, step3);
+ }
+
+ function step3()
+ {
+ testOverrides({width: 1200, height: 1000, deviceScaleFactor: 3, emulateViewport: false, fitWindow: true}, {width: 1200, height: 1000, deviceScaleFactor: 3}, step4);
+ }
+
+ function step4()
+ {
+ testOverrides({width: 1200, height: 1000, deviceScaleFactor: 3, emulateViewport: false, fitWindow: false}, {width: 1200, height: 1000, deviceScaleFactor: 3}, finish);
+ }
+
+ function finish()
+ {
+ test.releaseControl();
+ }
+
+ step1();
+ test.takeControl();
+};
+
+ /**
* Records timeline till console.timeStamp("ready"), invokes callback with resulting records.
* @param {function(!Array.<!Object>)} callback
*/
@@ -690,11 +742,11 @@ TestSuite.prototype.recordTimeline = function(callback)
function innerAddRecord(record)
{
records.push(record);
- if (record.type === "TimeStamp" && record.data.message === "ready")
+ if (record.type() === "TimeStamp" && record.data().message === "ready")
done();
- if (record.children)
- record.children.forEach(innerAddRecord);
+ if (record.children())
+ record.children().forEach(innerAddRecord);
}
function done()
@@ -715,16 +767,16 @@ TestSuite.prototype.waitForTestResultsInConsole = function()
{
var messages = WebInspector.console.messages;
for (var i = 0; i < messages.length; ++i) {
- var text = messages[i].text;
+ var text = messages[i].messageText;
if (text === "PASS")
return;
else if (/^FAIL/.test(text))
this.fail(text); // This will throw.
}
- // Neitwer PASS nor FAIL, so wait for more messages.
+ // Neither PASS nor FAIL, so wait for more messages.
function onConsoleMessage(event)
{
- var text = event.data.text;
+ var text = event.data.messageText;
if (text === "PASS")
this.releaseControl();
else if (/^FAIL/.test(text))
@@ -824,22 +876,31 @@ TestSuite.prototype.nonAnonymousUISourceCodes_ = function()
*/
TestSuite.prototype.evaluateInConsole_ = function(code, callback)
{
- WebInspector.showConsole();
- WebInspector.consoleView.prompt.text = code;
- WebInspector.consoleView.promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));
+ function innerEvaluate()
+ {
+ WebInspector.console.show();
+ var consoleView = WebInspector.ConsolePanel._view();
+ consoleView._prompt.text = code;
+ consoleView._promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));
+
+ this.addSniffer(WebInspector.ConsoleView.prototype, "_showConsoleMessage",
+ function(viewMessage) {
+ callback(viewMessage.toMessageElement().textContent);
+ }.bind(this));
+ }
- this.addSniffer(WebInspector.ConsoleView.prototype, "_showConsoleMessage",
- function(messageIndex) {
- var commandResult = WebInspector.console.messages[messageIndex];
- callback(commandResult.toMessageElement().textContent);
- });
-};
+ if (!WebInspector.context.flavor(WebInspector.ExecutionContext)) {
+ WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, innerEvaluate, this);
+ return;
+ }
+ innerEvaluate.call(this);
+};
/**
* Checks that all expected scripts are present in the scripts list
* in the Scripts panel.
- * @param {!Array.<string>} expected !Regular expressions describing
+ * @param {!Array.<string>} expected Regular expressions describing
* expected script names.
* @return {boolean} Whether all the scripts are in "scripts-files" select
* box
@@ -908,7 +969,7 @@ TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callb
if (test._scriptsAreParsed(expectedScripts))
callback();
else
- test.addSniffer(WebInspector.panels.sources, "_addUISourceCode", waitForAllScripts);
+ test.addSniffer(WebInspector.panels.sources.sourcesView(), "_addUISourceCode", waitForAllScripts);
}
waitForAllScripts();
@@ -947,7 +1008,7 @@ uiTests.runAllTests = function()
/**
* Run specified test on a fresh instance of the test suite.
- * @param {string} name Name of a test method from !TestSuite class.
+ * @param {string} name Name of a test method from TestSuite class.
*/
uiTests.runTest = function(name)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameController.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameController.js
deleted file mode 100644
index 7baeecad59a..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameController.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @param {!WebInspector.TimelineModel} model
- * @param {!WebInspector.TimelineFrameOverview} frameOverview
- * @param {!WebInspector.TimelinePresentationModel} presentationModel
- */
-WebInspector.TimelineFrameController = function(model, frameOverview, presentationModel)
-{
- this._lastMainThreadFrame = null;
- this._lastBackgroundFrame = null;
- this._model = model;
- this._frameOverview = frameOverview;
- this._presentationModel = presentationModel;
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
-
- this._frameOverview.reset();
- var records = model.records;
- for (var i = 0; i < records.length; ++i)
- this._addRecord(records[i]);
- this._frameOverview.update();
-}
-
-WebInspector.TimelineFrameController.prototype = {
- _onRecordAdded: function(event)
- {
- this._addRecord(event.data);
- },
-
- _onRecordsCleared: function()
- {
- this._lastMainThreadFrame = null;
- this._lastBackgroundFrame = null;
- },
-
- _addRecord: function(record)
- {
- var records;
- var programRecord;
- if (record.type === WebInspector.TimelineModel.RecordType.Program) {
- programRecord = record;
- if (this._lastMainThreadFrame)
- this._lastMainThreadFrame.timeByCategory["other"] += WebInspector.TimelineModel.durationInSeconds(programRecord);
- records = record["children"] || [];
- } else
- records = [record];
- records.forEach(this._innerAddRecord.bind(this, programRecord));
- },
-
- /**
- * @param {!Object} programRecord
- * @param {!Object} record
- */
- _innerAddRecord: function(programRecord, record)
- {
- var isFrameRecord = record.type === WebInspector.TimelineModel.RecordType.BeginFrame;
- var programTimeCarryover = isFrameRecord && programRecord ? WebInspector.TimelineModel.endTimeInSeconds(programRecord) - WebInspector.TimelineModel.startTimeInSeconds(record) : 0;
- var lastFrame = record.thread ? this._lastBackgroundFrame : this._lastMainThreadFrame;
- if (isFrameRecord && lastFrame) {
- this._flushFrame(lastFrame, record, programTimeCarryover);
- lastFrame = this._createFrame(record, programTimeCarryover);
- } else if (record.type === WebInspector.TimelineModel.RecordType.ActivateLayerTree) {
- if (lastFrame)
- lastFrame.mainThreadFrameId = record.data.id;
- } else {
- if (!lastFrame)
- lastFrame = this._createFrame(record, programTimeCarryover);
- if (!record.thread) {
- WebInspector.TimelineModel.aggregateTimeForRecord(lastFrame.timeByCategory, record);
- var duration = WebInspector.TimelineModel.durationInSeconds(record);
- lastFrame.cpuTime += duration;
- lastFrame.timeByCategory["other"] -= duration;
- }
- }
- if (record.thread)
- this._lastBackgroundFrame = lastFrame;
- else
- this._lastMainThreadFrame = lastFrame;
- },
-
- /**
- * @param {!WebInspector.TimelineFrame} frame
- * @param {!Object} record
- * @param {number} programTimeCarryover
- */
- _flushFrame: function(frame, record, programTimeCarryover)
- {
- frame.endTime = WebInspector.TimelineModel.startTimeInSeconds(record);
- frame.duration = frame.endTime - frame.startTime;
- frame.timeByCategory["other"] -= programTimeCarryover;
- // Alternatively, we could compute CPU time as sum of all Program events.
- // This way it's a bit more flexible, as it works in case there's no program events.
- frame.cpuTime += frame.timeByCategory["other"];
- this._frameOverview.addFrame(frame);
- this._presentationModel.addFrame(frame);
- },
-
- /**
- * @param {!Object} record
- * @param {number} programTimeCarryover
- */
- _createFrame: function(record, programTimeCarryover)
- {
- var frame = new WebInspector.TimelineFrame();
- frame.startTime = WebInspector.TimelineModel.startTimeInSeconds(record);
- frame.startTimeOffset = this._model.recordOffsetInSeconds(record);
- frame.timeByCategory["other"] = programTimeCarryover;
- frame.isBackground = !!record.thread;
- frame.id = record.data && record.data["id"];
- return frame;
- },
-
- dispose: function()
- {
- this._model.removeEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
- this._model.removeEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
- }
-}
-
-/**
- * @constructor
- * @param {!Array.<!WebInspector.TimelineFrame>} frames
- */
-WebInspector.FrameStatistics = function(frames)
-{
- this.frameCount = frames.length;
- this.minDuration = Infinity;
- this.maxDuration = 0;
- this.timeByCategory = {};
- this.startOffset = frames[0].startTimeOffset;
- var lastFrame = frames[this.frameCount - 1];
- this.endOffset = lastFrame.startTimeOffset + lastFrame.duration;
-
- var totalDuration = 0;
- var sumOfSquares = 0;
- for (var i = 0; i < this.frameCount; ++i) {
- var duration = frames[i].duration;
- totalDuration += duration;
- sumOfSquares += duration * duration;
- this.minDuration = Math.min(this.minDuration, duration);
- this.maxDuration = Math.max(this.maxDuration, duration);
- WebInspector.TimelineModel.aggregateTimeByCategory(this.timeByCategory, frames[i].timeByCategory);
- }
- this.average = totalDuration / this.frameCount;
- var variance = sumOfSquares / this.frameCount - this.average * this.average;
- this.stddev = Math.sqrt(variance);
-}
-
-/**
- * @constructor
- */
-WebInspector.TimelineFrame = function()
-{
- this.timeByCategory = {};
- this.cpuTime = 0;
- /** @type {string} */
- this.mainThreadFrameId;
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineGrid.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelineGrid.js
deleted file mode 100644
index 1eaf3aecc47..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineGrid.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- */
-WebInspector.TimelineGrid = function()
-{
- this.element = document.createElement("div");
-
- this._itemsGraphsElement = document.createElement("div");
- this._itemsGraphsElement.id = "resources-graphs";
- this.element.appendChild(this._itemsGraphsElement);
-
- this._dividersElement = this.element.createChild("div", "resources-dividers");
-
- this._gridHeaderElement = document.createElement("div");
- this._eventDividersElement = this._gridHeaderElement.createChild("div", "resources-event-dividers");
- this._dividersLabelBarElement = this._gridHeaderElement.createChild("div", "resources-dividers-label-bar");
- this.element.appendChild(this._gridHeaderElement);
-
- this._leftCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-left");
- this._rightCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-right");
-
- this._gridSliceTime = 1;
-}
-
-WebInspector.TimelineGrid.prototype = {
- get itemsGraphsElement()
- {
- return this._itemsGraphsElement;
- },
-
- get dividersElement()
- {
- return this._dividersElement;
- },
-
- get dividersLabelBarElement()
- {
- return this._dividersLabelBarElement;
- },
-
- get gridHeaderElement()
- {
- return this._gridHeaderElement;
- },
-
- get gridSliceTime() {
- return this._gridSliceTime;
- },
-
- removeDividers: function()
- {
- this._dividersElement.removeChildren();
- this._dividersLabelBarElement.removeChildren();
- },
-
- updateDividers: function(calculator)
- {
- const minGridSlicePx = 64; // minimal distance between grid lines.
- const gridFreeZoneAtLeftPx = 50;
-
- var dividersElementClientWidth = this._dividersElement.clientWidth;
- var dividersCount = dividersElementClientWidth / minGridSlicePx;
- var gridSliceTime = calculator.boundarySpan() / dividersCount;
- var pixelsPerTime = dividersElementClientWidth / calculator.boundarySpan();
-
- // Align gridSliceTime to a nearest round value.
- // We allow spans that fit into the formula: span = (1|2|5)x10^n,
- // e.g.: ... .1 .2 .5 1 2 5 10 20 50 ...
- // After a span has been chosen make grid lines at multiples of the span.
-
- var logGridSliceTime = Math.ceil(Math.log(gridSliceTime) / Math.LN10);
- gridSliceTime = Math.pow(10, logGridSliceTime);
- if (gridSliceTime * pixelsPerTime >= 5 * minGridSlicePx)
- gridSliceTime = gridSliceTime / 5;
- if (gridSliceTime * pixelsPerTime >= 2 * minGridSlicePx)
- gridSliceTime = gridSliceTime / 2;
- this._gridSliceTime = gridSliceTime;
-
- var firstDividerTime = Math.ceil((calculator.minimumBoundary() - calculator.zeroTime()) / gridSliceTime) * gridSliceTime + calculator.zeroTime();
- var lastDividerTime = calculator.maximumBoundary();
- // Add some extra space past the right boundary as the rightmost divider label text
- // may be partially shown rather than just pop up when a new rightmost divider gets into the view.
- if (calculator.paddingLeft > 0)
- lastDividerTime = lastDividerTime + minGridSlicePx / pixelsPerTime;
- dividersCount = Math.ceil((lastDividerTime - firstDividerTime) / gridSliceTime);
-
- // Reuse divider elements and labels.
- var divider = this._dividersElement.firstChild;
- var dividerLabelBar = this._dividersLabelBarElement.firstChild;
-
- var skipLeftmostDividers = calculator.paddingLeft === 0;
-
- if (!gridSliceTime)
- dividersCount = 0;
-
- for (var i = 0; i < dividersCount; ++i) {
- var left = calculator.computePosition(firstDividerTime + gridSliceTime * i);
- if (skipLeftmostDividers && left < gridFreeZoneAtLeftPx)
- continue;
-
- if (!divider) {
- divider = document.createElement("div");
- divider.className = "resources-divider";
- this._dividersElement.appendChild(divider);
-
- dividerLabelBar = document.createElement("div");
- dividerLabelBar.className = "resources-divider";
- var label = document.createElement("div");
- label.className = "resources-divider-label";
- dividerLabelBar._labelElement = label;
- dividerLabelBar.appendChild(label);
- this._dividersLabelBarElement.appendChild(dividerLabelBar);
- }
-
- dividerLabelBar._labelElement.textContent = calculator.formatTime(firstDividerTime + gridSliceTime * i - calculator.minimumBoundary());
- var percentLeft = 100 * left / dividersElementClientWidth;
- divider.style.left = percentLeft + "%";
- dividerLabelBar.style.left = percentLeft + "%";
-
- divider = divider.nextSibling;
- dividerLabelBar = dividerLabelBar.nextSibling;
- }
-
- // Remove extras.
- while (divider) {
- var nextDivider = divider.nextSibling;
- this._dividersElement.removeChild(divider);
- divider = nextDivider;
- }
- while (dividerLabelBar) {
- var nextDivider = dividerLabelBar.nextSibling;
- this._dividersLabelBarElement.removeChild(dividerLabelBar);
- dividerLabelBar = nextDivider;
- }
- return true;
- },
-
- addEventDivider: function(divider)
- {
- this._eventDividersElement.appendChild(divider);
- },
-
- addEventDividers: function(dividers)
- {
- this._gridHeaderElement.removeChild(this._eventDividersElement);
- for (var i = 0; i < dividers.length; ++i) {
- if (dividers[i])
- this._eventDividersElement.appendChild(dividers[i]);
- }
- this._gridHeaderElement.appendChild(this._eventDividersElement);
- },
-
- removeEventDividers: function()
- {
- this._eventDividersElement.removeChildren();
- },
-
- hideEventDividers: function()
- {
- this._eventDividersElement.classList.add("hidden");
- },
-
- showEventDividers: function()
- {
- this._eventDividersElement.classList.remove("hidden");
- },
-
- hideCurtains: function()
- {
- this._leftCurtainElement.classList.add("hidden");
- this._rightCurtainElement.classList.add("hidden");
- },
-
- /**
- * @param {number} gapOffset
- * @param {number} gapWidth
- */
- showCurtains: function(gapOffset, gapWidth)
- {
- this._leftCurtainElement.style.width = gapOffset + "px";
- this._leftCurtainElement.classList.remove("hidden");
- this._rightCurtainElement.style.left = (gapOffset + gapWidth) + "px";
- this._rightCurtainElement.classList.remove("hidden");
- },
-
- setScrollAndDividerTop: function(scrollTop, dividersTop)
- {
- this._dividersElement.style.top = scrollTop + "px";
- this._leftCurtainElement.style.top = scrollTop + "px";
- this._rightCurtainElement.style.top = scrollTop + "px";
- }
-}
-
-/**
- * @interface
- */
-WebInspector.TimelineGrid.Calculator = function() { }
-
-WebInspector.TimelineGrid.Calculator.prototype = {
- /**
- * @param {number} time
- * @return {number}
- */
- computePosition: function(time) { return 0; },
-
- /**
- * @param {number} time
- * @param {boolean=} hires
- * @return {string}
- */
- formatTime: function(time, hires) { },
-
- /** @return {number} */
- minimumBoundary: function() { },
-
- /** @return {number} */
- zeroTime: function() { },
-
- /** @return {number} */
- maximumBoundary: function() { },
-
- /** @return {number} */
- boundarySpan: function() { }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelineModel.js
deleted file mode 100644
index d4e3379f15b..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineModel.js
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.TimelineModel = function()
-{
- this._records = [];
- this._stringPool = new StringPool();
- this._minimumRecordTime = -1;
- this._maximumRecordTime = -1;
-
- WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onRecordAdded, this);
- WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onStarted, this);
- WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onStopped, this);
-}
-
-WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000;
-
-WebInspector.TimelineModel.RecordType = {
- Root: "Root",
- Program: "Program",
- EventDispatch: "EventDispatch",
-
- GPUTask: "GPUTask",
-
- BeginFrame: "BeginFrame",
- ActivateLayerTree: "ActivateLayerTree",
- ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
- RecalculateStyles: "RecalculateStyles",
- InvalidateLayout: "InvalidateLayout",
- Layout: "Layout",
- AutosizeText: "AutosizeText",
- PaintSetup: "PaintSetup",
- Paint: "Paint",
- Rasterize: "Rasterize",
- ScrollLayer: "ScrollLayer",
- DecodeImage: "DecodeImage",
- ResizeImage: "ResizeImage",
- CompositeLayers: "CompositeLayers",
-
- ParseHTML: "ParseHTML",
-
- TimerInstall: "TimerInstall",
- TimerRemove: "TimerRemove",
- TimerFire: "TimerFire",
-
- XHRReadyStateChange: "XHRReadyStateChange",
- XHRLoad: "XHRLoad",
- EvaluateScript: "EvaluateScript",
-
- MarkLoad: "MarkLoad",
- MarkDOMContent: "MarkDOMContent",
- MarkFirstPaint: "MarkFirstPaint",
-
- TimeStamp: "TimeStamp",
- Time: "Time",
- TimeEnd: "TimeEnd",
-
- ScheduleResourceRequest: "ScheduleResourceRequest",
- ResourceSendRequest: "ResourceSendRequest",
- ResourceReceiveResponse: "ResourceReceiveResponse",
- ResourceReceivedData: "ResourceReceivedData",
- ResourceFinish: "ResourceFinish",
-
- FunctionCall: "FunctionCall",
- GCEvent: "GCEvent",
-
- RequestAnimationFrame: "RequestAnimationFrame",
- CancelAnimationFrame: "CancelAnimationFrame",
- FireAnimationFrame: "FireAnimationFrame",
-
- WebSocketCreate : "WebSocketCreate",
- WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
- WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
- WebSocketDestroy : "WebSocketDestroy",
-}
-
-WebInspector.TimelineModel.Events = {
- RecordAdded: "RecordAdded",
- RecordsCleared: "RecordsCleared",
- RecordingStarted: "RecordingStarted",
- RecordingStopped: "RecordingStopped"
-}
-
-WebInspector.TimelineModel.startTimeInSeconds = function(record)
-{
- return record.startTime / 1000;
-}
-
-WebInspector.TimelineModel.endTimeInSeconds = function(record)
-{
- return (record.endTime || record.startTime) / 1000;
-}
-
-WebInspector.TimelineModel.durationInSeconds = function(record)
-{
- return WebInspector.TimelineModel.endTimeInSeconds(record) - WebInspector.TimelineModel.startTimeInSeconds(record);
-}
-
-/**
- * @param {!Object} total
- * @param {!Object} rawRecord
- */
-WebInspector.TimelineModel.aggregateTimeForRecord = function(total, rawRecord)
-{
- var childrenTime = 0;
- var children = rawRecord["children"] || [];
- for (var i = 0; i < children.length; ++i) {
- WebInspector.TimelineModel.aggregateTimeForRecord(total, children[i]);
- childrenTime += WebInspector.TimelineModel.durationInSeconds(children[i]);
- }
- var categoryName = WebInspector.TimelinePresentationModel.recordStyle(rawRecord).category.name;
- var ownTime = WebInspector.TimelineModel.durationInSeconds(rawRecord) - childrenTime;
- total[categoryName] = (total[categoryName] || 0) + ownTime;
-}
-
-/**
- * @param {!Object} total
- * @param {!Object} addend
- */
-WebInspector.TimelineModel.aggregateTimeByCategory = function(total, addend)
-{
- for (var category in addend)
- total[category] = (total[category] || 0) + addend[category];
-}
-
-WebInspector.TimelineModel.prototype = {
- /**
- * @param {boolean=} includeDomCounters
- */
- startRecording: function(includeDomCounters)
- {
- this._clientInitiatedRecording = true;
- this.reset();
- var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ? 30 : 0;
- var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEnabled();
- WebInspector.timelineManager.start(maxStackFrames, includeDomCounters, includeGPUEvents, this._fireRecordingStarted.bind(this));
- },
-
- stopRecording: function()
- {
- if (!this._clientInitiatedRecording) {
- WebInspector.timelineManager.start(undefined, undefined, undefined, stopTimeline.bind(this));
- return;
- }
-
- /**
- * Console started this one and we are just sniffing it. Initiate recording so that we
- * could stop it.
- * @this {WebInspector.TimelineModel}
- */
- function stopTimeline()
- {
- WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(this));
- }
-
- this._clientInitiatedRecording = false;
- WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(this));
- },
-
- get records()
- {
- return this._records;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onRecordAdded: function(event)
- {
- if (this._collectionEnabled)
- this._addRecord(/** @type {!TimelineAgent.TimelineEvent} */(event.data));
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onStarted: function(event)
- {
- if (event.data) {
- // Started from console.
- this._fireRecordingStarted();
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _onStopped: function(event)
- {
- if (event.data) {
- // Stopped from console.
- this._fireRecordingStopped();
- }
- },
-
- _fireRecordingStarted: function()
- {
- this._collectionEnabled = true;
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted);
- },
-
- _fireRecordingStopped: function()
- {
- this._collectionEnabled = false;
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- */
- _addRecord: function(record)
- {
- this._stringPool.internObjectStrings(record);
- this._records.push(record);
- this._updateBoundaries(record);
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAdded, record);
- },
-
- /**
- * @param {!Blob} file
- * @param {!WebInspector.Progress} progress
- */
- loadFromFile: function(file, progress)
- {
- var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
- var fileReader = this._createFileReader(file, delegate);
- var loader = new WebInspector.TimelineModelLoader(this, fileReader, progress);
- fileReader.start(loader);
- },
-
- /**
- * @param {string} url
- */
- loadFromURL: function(url, progress)
- {
- var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
- var urlReader = new WebInspector.ChunkedXHRReader(url, delegate);
- var loader = new WebInspector.TimelineModelLoader(this, urlReader, progress);
- urlReader.start(loader);
- },
-
- _createFileReader: function(file, delegate)
- {
- return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModel.TransferChunkLengthBytes, delegate);
- },
-
- _createFileWriter: function()
- {
- return new WebInspector.FileOutputStream();
- },
-
- saveToFile: function()
- {
- var now = new Date();
- var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json";
- var stream = this._createFileWriter();
-
- /**
- * @param {boolean} accepted
- * @this {WebInspector.TimelineModel}
- */
- function callback(accepted)
- {
- if (!accepted)
- return;
- var saver = new WebInspector.TimelineSaver(stream);
- saver.save(this._records, window.navigator.appVersion);
- }
- stream.open(fileName, callback.bind(this));
- },
-
- reset: function()
- {
- this._records = [];
- this._stringPool.reset();
- this._minimumRecordTime = -1;
- this._maximumRecordTime = -1;
- this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsCleared);
- },
-
- minimumRecordTime: function()
- {
- return this._minimumRecordTime;
- },
-
- maximumRecordTime: function()
- {
- return this._maximumRecordTime;
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- */
- _updateBoundaries: function(record)
- {
- var startTime = WebInspector.TimelineModel.startTimeInSeconds(record);
- var endTime = WebInspector.TimelineModel.endTimeInSeconds(record);
-
- if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTime)
- this._minimumRecordTime = startTime;
- if (this._maximumRecordTime === -1 || endTime > this._maximumRecordTime)
- this._maximumRecordTime = endTime;
- },
-
- /**
- * @param {!Object} rawRecord
- */
- recordOffsetInSeconds: function(rawRecord)
- {
- return WebInspector.TimelineModel.startTimeInSeconds(rawRecord) - this._minimumRecordTime;
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @implements {WebInspector.OutputStream}
- * @param {!WebInspector.TimelineModel} model
- * @param {!{cancel: function()}} reader
- * @param {!WebInspector.Progress} progress
- */
-WebInspector.TimelineModelLoader = function(model, reader, progress)
-{
- this._model = model;
- this._reader = reader;
- this._progress = progress;
- this._buffer = "";
- this._firstChunk = true;
-}
-
-WebInspector.TimelineModelLoader.prototype = {
- /**
- * @param {string} chunk
- */
- write: function(chunk)
- {
- var data = this._buffer + chunk;
- var lastIndex = 0;
- var index;
- do {
- index = lastIndex;
- lastIndex = WebInspector.findBalancedCurlyBrackets(data, index);
- } while (lastIndex !== -1)
-
- var json = data.slice(0, index) + "]";
- this._buffer = data.slice(index);
-
- if (!index)
- return;
-
- // Prepending "0" to turn string into valid JSON.
- if (!this._firstChunk)
- json = "[0" + json;
-
- var items;
- try {
- items = /** @type {!Array.<!TimelineAgent.TimelineEvent>} */ (JSON.parse(json));
- } catch (e) {
- WebInspector.showErrorMessage("Malformed timeline data.");
- this._model.reset();
- this._reader.cancel();
- this._progress.done();
- return;
- }
-
- if (this._firstChunk) {
- this._version = items[0];
- this._firstChunk = false;
- this._model.reset();
- }
-
- // Skip 0-th element - it is either version or 0.
- for (var i = 1, size = items.length; i < size; ++i)
- this._model._addRecord(items[i]);
- },
-
- close: function() { }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.OutputStreamDelegate}
- * @param {!WebInspector.TimelineModel} model
- * @param {!WebInspector.Progress} progress
- */
-WebInspector.TimelineModelLoadFromFileDelegate = function(model, progress)
-{
- this._model = model;
- this._progress = progress;
-}
-
-WebInspector.TimelineModelLoadFromFileDelegate.prototype = {
- onTransferStarted: function()
- {
- this._progress.setTitle(WebInspector.UIString("Loading\u2026"));
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- */
- onChunkTransferred: function(reader)
- {
- if (this._progress.isCanceled()) {
- reader.cancel();
- this._progress.done();
- this._model.reset();
- return;
- }
-
- var totalSize = reader.fileSize();
- if (totalSize) {
- this._progress.setTotalWork(totalSize);
- this._progress.setWorked(reader.loadedSize());
- }
- },
-
- onTransferFinished: function()
- {
- this._progress.done();
- },
-
- /**
- * @param {!WebInspector.ChunkedReader} reader
- */
- onError: function(reader, event)
- {
- this._progress.done();
- this._model.reset();
- switch (event.target.error.code) {
- case FileError.NOT_FOUND_ERR:
- WebInspector.showErrorMessage(WebInspector.UIString("File \"%s\" not found.", reader.fileName()));
- break;
- case FileError.NOT_READABLE_ERR:
- WebInspector.showErrorMessage(WebInspector.UIString("File \"%s\" is not readable", reader.fileName()));
- break;
- case FileError.ABORT_ERR:
- break;
- default:
- WebInspector.showErrorMessage(WebInspector.UIString("An error occurred while reading the file \"%s\"", reader.fileName()));
- }
- }
-}
-
-/**
- * @constructor
- */
-WebInspector.TimelineSaver = function(stream)
-{
- this._stream = stream;
-}
-
-WebInspector.TimelineSaver.prototype = {
- /**
- * @param {!Array.<*>} records
- * @param {string} version
- */
- save: function(records, version)
- {
- this._records = records;
- this._recordIndex = 0;
- this._prologue = "[" + JSON.stringify(version);
-
- this._writeNextChunk(this._stream);
- },
-
- _writeNextChunk: function(stream)
- {
- const separator = ",\n";
- var data = [];
- var length = 0;
-
- if (this._prologue) {
- data.push(this._prologue);
- length += this._prologue.length;
- delete this._prologue;
- } else {
- if (this._recordIndex === this._records.length) {
- stream.close();
- return;
- }
- data.push("");
- }
- while (this._recordIndex < this._records.length) {
- var item = JSON.stringify(this._records[this._recordIndex]);
- var itemLength = item.length + separator.length;
- if (length + itemLength > WebInspector.TimelineModel.TransferChunkLengthBytes)
- break;
- length += itemLength;
- data.push(item);
- ++this._recordIndex;
- }
- if (this._recordIndex === this._records.length)
- data.push(data.pop() + "]");
- stream.write(data.join(separator), this._writeNextChunk.bind(this));
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanel.js
deleted file mode 100644
index f39c86f9181..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanel.js
+++ /dev/null
@@ -1,2108 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2012 Intel Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-importScript("MemoryStatistics.js");
-importScript("DOMCountersGraph.js");
-importScript("PieChart.js");
-importScript("TimelineModel.js");
-importScript("TimelineOverviewPane.js");
-importScript("TimelinePresentationModel.js");
-importScript("TimelineFrameController.js");
-importScript("TimelineEventOverview.js");
-importScript("TimelineFrameOverview.js");
-importScript("TimelineMemoryOverview.js");
-
-/**
- * @constructor
- * @implements {WebInspector.Searchable}
- * @extends {WebInspector.Panel}
- */
-WebInspector.TimelinePanel = function()
-{
- WebInspector.Panel.call(this, "timeline");
- this.registerRequiredCSS("timelinePanel.css");
- this.registerRequiredCSS("filter.css");
- this.element.classList.add("vbox");
- this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);
-
- // Create model.
- this._model = new WebInspector.TimelineModel();
- this._calculator = new WebInspector.TimelineCalculator(this._model);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
- this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStopped, this._onRecordingStopped, this);
-
- this._presentationModeSetting = WebInspector.settings.createSetting("timelineOverviewMode", WebInspector.TimelinePanel.Mode.Events);
- this._glueRecordsSetting = WebInspector.settings.createSetting("timelineGlueRecords", false);
-
- this._createStatusBarItems();
-
- this._createPresentationSelector();
-
- // Create top overview component.
- this._overviewPane = new WebInspector.TimelineOverviewPane(this._model);
- this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged, this._windowChanged.bind(this));
- this._overviewPane.show(this._presentationSelector.element);
-
- // Create presentation model.
- this._presentationModel = new WebInspector.TimelinePresentationModel();
- this._presentationModel.addFilter(this._windowFilter);
- this._presentationModel.addFilter(this._categoryFilter);
- this._presentationModel.addFilter(this._durationFilter);
- this._presentationModel.setGlueRecords(this._glueParentButton.toggled);
-
- this._frameMode = false;
- this._boundariesAreValid = true;
- this._scrollTop = 0;
-
- // Create layout componets.
-
- // -------------------------------
- // | Overview |
- // |-------------------------------|
- // | | | |
- // | | Records | |
- // | | | Details |
- // |----------------| |
- // | | Memory | |
- // -------------------------------
-
- // Create top level properties splitter.
- this._detailsSplitView = new WebInspector.SplitView(false, "timeline-details");
- this._detailsSplitView.element.classList.remove("fill");
- this._detailsSplitView.element.classList.add("timeline-details-split");
- this._detailsSplitView.sidebarElement.classList.add("timeline-details");
- this._detailsSplitView.show(this.element);
- this._detailsSplitView.mainElement.classList.add("vbox");
- this._detailsSplitView.setMainElementConstraints(undefined, 40);
- this._detailsView = new WebInspector.TimelineDetailsView();
- this._detailsView.show(this._detailsSplitView.sidebarElement);
- this._detailsSplitView.installResizer(this._detailsView.titleElement());
-
- WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
- WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
- this._dockSideChanged();
-
- // Create memory splitter as a left child of properties.
- this._searchableView = new WebInspector.SearchableView(this);
- this._searchableView.show(this._detailsSplitView.mainElement);
-
- this._timelineMemorySplitter = new WebInspector.SplitView(false, "timeline-memory");
- this._timelineMemorySplitter.element.classList.remove("fill");
- this._timelineMemorySplitter.element.classList.add("timeline-memory-split");
- this._timelineMemorySplitter.show(this._searchableView.element);
- if (this._presentationModeSetting.get() !== WebInspector.TimelinePanel.Mode.Memory)
- this._timelineMemorySplitter.showOnlyFirst();
-
- // Create records sidebar as a top memory splitter child.
- this._sidebarView = new WebInspector.SidebarView(WebInspector.SidebarView.SidebarPosition.Start, "timeline-split");
- this._sidebarView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._sidebarResized, this);
- this._sidebarView.setSecondIsSidebar(false);
- this._sidebarView.show(this._timelineMemorySplitter.mainElement);
- this._containerElement = this._sidebarView.element;
- this._containerElement.tabIndex = 0;
- this._containerElement.id = "timeline-container";
- this._containerElement.addEventListener("scroll", this._onScroll.bind(this), false);
-
- // Create memory statistics as a bottom memory splitter child.
- this._memoryStatistics = new WebInspector.DOMCountersGraph(this, this._model);
- this._memoryStatistics.show(this._timelineMemorySplitter.sidebarElement);
- this._timelineMemorySplitter.installResizer(this._memoryStatistics.resizeElement());
-
- // Create records list in the records sidebar.
- this._sidebarView.sidebarElement.classList.add("vbox");
- this._sidebarView.sidebarElement.createChild("div", "timeline-records-title").textContent = WebInspector.UIString("RECORDS");
- this._sidebarListElement = this._sidebarView.sidebarElement.createChild("div", "timeline-records-list");
-
- // Create grid in the records main area.
- this._gridContainer = new WebInspector.ViewWithResizeCallback(this._onViewportResize.bind(this));
- this._gridContainer.element.classList.add("fill");
- this._gridContainer.element.id = "resources-container-content";
- this._gridContainer.show(this._sidebarView.mainElement);
- this._timelineGrid = new WebInspector.TimelineGrid();
- this._itemsGraphsElement = this._timelineGrid.itemsGraphsElement;
- this._itemsGraphsElement.id = "timeline-graphs";
- this._gridContainer.element.appendChild(this._timelineGrid.element);
- this._timelineGrid.gridHeaderElement.id = "timeline-grid-header";
- this._timelineGrid.gridHeaderElement.classList.add("fill");
- this._memoryStatistics.setMainTimelineGrid(this._timelineGrid);
- this._timelineMemorySplitter.mainElement.appendChild(this._timelineGrid.gridHeaderElement);
-
- // Create gap elements
- this._topGapElement = this._itemsGraphsElement.createChild("div", "timeline-gap");
- this._graphRowsElement = this._itemsGraphsElement.createChild("div");
- this._bottomGapElement = this._itemsGraphsElement.createChild("div", "timeline-gap");
- this._expandElements = this._itemsGraphsElement.createChild("div");
- this._expandElements.id = "orphan-expand-elements";
-
- this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
-
- this.element.addEventListener("mousemove", this._mouseMove.bind(this), false);
- this.element.addEventListener("mouseout", this._mouseOut.bind(this), false);
- this.element.addEventListener("keydown", this._keyDown.bind(this), false);
-
- this._expandOffset = 15;
-
- // Create gpu tasks containers.
- this._mainThreadTasks = /** @type {!Array.<!TimelineAgent.TimelineEvent>} */ ([]);
- this._gpuTasks = /** @type {!Array.<!TimelineAgent.TimelineEvent>} */ ([]);
- var utilizationStripsElement = this._timelineGrid.gridHeaderElement.createChild("div", "timeline-utilization-strips vbox");
- this._cpuBarsElement = utilizationStripsElement.createChild("div", "timeline-utilization-strip");
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
- this._gpuBarsElement = utilizationStripsElement.createChild("div", "timeline-utilization-strip gpu");
-
- this._createFileSelector();
- this._registerShortcuts();
- this._allRecordsCount = 0;
-
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
-
- this._createOverviewControls();
- this._selectPresentationMode(this._presentationModeSetting.get());
-}
-
-WebInspector.TimelinePanel.Mode = {
- Events: "Events",
- Frames: "Frames",
- Memory: "Memory"
-};
-
-// Define row and header height, should be in sync with styles for timeline graphs.
-WebInspector.TimelinePanel.rowHeight = 18;
-WebInspector.TimelinePanel.headerHeight = 20;
-
-WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15];
-
-WebInspector.TimelinePanel.prototype = {
- _createPresentationSelector: function()
- {
- this._presentationSelector = new WebInspector.View();
- this._presentationSelector.element.classList.add("hbox");
- this._presentationSelector.element.id = "timeline-overview-panel";
- this._presentationSelector.show(this.element);
-
- this._topPaneSidebarElement = this._presentationSelector.element.createChild("div");
- this._topPaneSidebarElement.id = "timeline-overview-sidebar";
-
- var overviewTreeElement = this._topPaneSidebarElement.createChild("ol", "sidebar-tree vbox");
- var topPaneSidebarTree = new TreeOutline(overviewTreeElement);
-
- this._overviewItems = {};
- this._overviewItems[WebInspector.TimelinePanel.Mode.Events] = new WebInspector.SidebarTreeElement("timeline-overview-sidebar-events",
- WebInspector.UIString("Events"));
- this._overviewItems[WebInspector.TimelinePanel.Mode.Frames] = new WebInspector.SidebarTreeElement("timeline-overview-sidebar-frames",
- WebInspector.UIString("Frames"));
- this._overviewItems[WebInspector.TimelinePanel.Mode.Memory] = new WebInspector.SidebarTreeElement("timeline-overview-sidebar-memory",
- WebInspector.UIString("Memory"));
-
- for (var mode in this._overviewItems) {
- var item = this._overviewItems[mode];
- item.onselect = this._onModeChanged.bind(this, mode);
- topPaneSidebarTree.appendChild(item);
- }
- },
-
- _createStatusBarItems: function()
- {
- var panelStatusBarElement = this.element.createChild("div", "panel-status-bar");
- this._statusBarButtons = /** @type {!Array.<!WebInspector.StatusBarItem>} */ ([]);
-
- this.toggleTimelineButton = new WebInspector.StatusBarButton(WebInspector.UIString("Record"), "record-profile-status-bar-item");
- this.toggleTimelineButton.addEventListener("click", this._toggleTimelineButtonClicked, this);
- this._statusBarButtons.push(this.toggleTimelineButton);
- panelStatusBarElement.appendChild(this.toggleTimelineButton.element);
-
- this.clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
- this.clearButton.addEventListener("click", this._onClearButtonClick, this);
- this._statusBarButtons.push(this.clearButton);
- panelStatusBarElement.appendChild(this.clearButton.element);
-
- this._filterBar = new WebInspector.FilterBar();
- panelStatusBarElement.appendChild(this._filterBar.filterButton().element);
-
- this.garbageCollectButton = new WebInspector.StatusBarButton(WebInspector.UIString("Collect Garbage"), "garbage-collect-status-bar-item");
- this.garbageCollectButton.addEventListener("click", this._garbageCollectButtonClicked, this);
- this._statusBarButtons.push(this.garbageCollectButton);
- panelStatusBarElement.appendChild(this.garbageCollectButton.element);
-
- this._glueParentButton = new WebInspector.StatusBarButton(WebInspector.UIString("Glue asynchronous events to causes"), "glue-async-status-bar-item");
- this._glueParentButton.toggled = this._glueRecordsSetting.get();
- this._glueParentButton.addEventListener("click", this._glueParentButtonClicked, this);
- this._statusBarButtons.push(this._glueParentButton);
- panelStatusBarElement.appendChild(this._glueParentButton.element);
-
- panelStatusBarElement.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Capture stacks"), WebInspector.settings.timelineCaptureStacks, true, undefined,
- WebInspector.UIString("Capture JavaScript stack on every timeline event")));
-
- this._statusTextContainer = panelStatusBarElement.createChild("div");
- this.recordsCounter = new WebInspector.StatusBarText("", "timeline-records-counter");
- this._statusTextContainer.appendChild(this.recordsCounter.element);
-
- this._miscStatusBarItems = panelStatusBarElement.createChild("div", "status-bar-item");
-
- this._filtersContainer = this.element.createChild("div", "timeline-filters-header hidden");
- this._filtersContainer.appendChild(this._filterBar.filtersElement());
- this._filterBar.addEventListener(WebInspector.FilterBar.Events.FiltersToggled, this._onFiltersToggled, this);
- this._updateFiltersBar();
- },
-
- _updateFiltersBar: function()
- {
- this._filterBar.clear();
- var hasFilters = this._createFilters(this._filterBar);
- this._filterBar.filterButton().setEnabled(hasFilters);
- },
-
- defaultFocusedElement: function()
- {
- return this.element;
- },
-
- /**
- * @return {!WebInspector.SearchableView}
- */
- searchableView: function()
- {
- return this._searchableView;
- },
-
- _onFiltersToggled: function(event)
- {
- var toggled = /** @type {boolean} */ (event.data);
- this._filtersContainer.enableStyleClass("hidden", !toggled);
- this.onResize();
- },
-
- /**
- * @return {?WebInspector.ProgressIndicator}
- */
- _prepareToLoadTimeline: function()
- {
- if (this._operationInProgress)
- return null;
- if (this._recordingInProgress()) {
- this.toggleTimelineButton.toggled = false;
- this._stopRecording();
- }
- var progressIndicator = new WebInspector.ProgressIndicator();
- progressIndicator.addEventListener(WebInspector.ProgressIndicator.Events.Done, this._setOperationInProgress.bind(this, null));
- this._setOperationInProgress(progressIndicator);
- return progressIndicator;
- },
-
- /**
- * @param {?WebInspector.ProgressIndicator} indicator
- */
- _setOperationInProgress: function(indicator)
- {
- this._operationInProgress = !!indicator;
- for (var i = 0; i < this._statusBarButtons.length; ++i)
- this._statusBarButtons[i].setEnabled(!this._operationInProgress);
- this._glueParentButton.setEnabled(!this._operationInProgress && !this._frameController);
- this._statusTextContainer.enableStyleClass("hidden", !!indicator);
- this._miscStatusBarItems.removeChildren();
- if (indicator)
- this._miscStatusBarItems.appendChild(indicator.element);
- },
-
- _registerShortcuts: function()
- {
- this.registerShortcuts(WebInspector.TimelinePanelDescriptor.ShortcutKeys.StartStopRecording, this._toggleTimelineButtonClicked.bind(this));
- this.registerShortcuts(WebInspector.TimelinePanelDescriptor.ShortcutKeys.SaveToFile, this._saveToFile.bind(this));
- this.registerShortcuts(WebInspector.TimelinePanelDescriptor.ShortcutKeys.LoadFromFile, this._selectFileToLoad.bind(this));
- },
-
- _createFileSelector: function()
- {
- if (this._fileSelectorElement)
- this._fileSelectorElement.remove();
-
- this._fileSelectorElement = WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));
- this.element.appendChild(this._fileSelectorElement);
- },
-
- _contextMenu: function(event)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save Timeline data\u2026" : "Save Timeline Data\u2026"), this._saveToFile.bind(this), this._operationInProgress);
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Load Timeline data\u2026" : "Load Timeline Data\u2026"), this._selectFileToLoad.bind(this), this._operationInProgress);
- contextMenu.show();
- },
-
- /**
- * @return {boolean}
- */
- _saveToFile: function()
- {
- if (this._operationInProgress)
- return true;
- this._model.saveToFile();
- return true;
- },
-
- /**
- * @return {boolean}
- */
- _selectFileToLoad: function() {
- this._fileSelectorElement.click();
- return true;
- },
-
- /**
- * @param {!File} file
- */
- _loadFromFile: function(file)
- {
- var progressIndicator = this._prepareToLoadTimeline();
- if (!progressIndicator)
- return;
- this._model.loadFromFile(file, progressIndicator);
- this._createFileSelector();
- },
-
- /**
- * @param {string} url
- */
- loadFromURL: function(url)
- {
- var progressIndicator = this._prepareToLoadTimeline();
- if (!progressIndicator)
- return;
- this._model.loadFromURL(url, progressIndicator);
- },
-
- _createOverviewControls: function()
- {
- this._overviewControls = {};
- this._overviewControls[WebInspector.TimelinePanel.Mode.Events] = new WebInspector.TimelineEventOverview(this._model);
- this._frameOverviewControl = new WebInspector.TimelineFrameOverview(this._model);
- this._overviewControls[WebInspector.TimelinePanel.Mode.Frames] = this._frameOverviewControl;
- this._overviewControls[WebInspector.TimelinePanel.Mode.Memory] = new WebInspector.TimelineMemoryOverview(this._model);
- },
-
- _selectPresentationMode: function(mode)
- {
- if (!this._overviewItems[mode])
- mode = WebInspector.TimelinePanel.Mode.Events;
- this._overviewItems[mode].revealAndSelect(false);
- },
-
- _onModeChanged: function(mode)
- {
- this.element.classList.remove("timeline-" + this._presentationModeSetting.get().toLowerCase() + "-view");
- this._presentationModeSetting.set(mode);
- this.element.classList.add("timeline-" + mode.toLowerCase() + "-view");
-
- this._overviewPane.willSetOverviewControl(this._overviewControls[mode]);
-
- this._timelineViewWasShown(mode);
-
- this.onResize();
- this._overviewPane.didSetOverviewControl();
- },
-
- /**
- * @param {boolean} userInitiated
- */
- _startRecording: function(userInitiated)
- {
- this._userInitiatedRecording = userInitiated;
- this._model.startRecording(true);
- if (userInitiated)
- WebInspector.userMetrics.TimelineStarted.record();
- },
-
- _stopRecording: function()
- {
- this._userInitiatedRecording = false;
- this._model.stopRecording();
- },
-
- /**
- * @return {boolean}
- */
- _toggleTimelineButtonClicked: function()
- {
- if (this._operationInProgress)
- return true;
- if (this._recordingInProgress())
- this._stopRecording();
- else
- this._startRecording(true);
- return true;
- },
-
- _garbageCollectButtonClicked: function()
- {
- HeapProfilerAgent.collectGarbage();
- },
-
- _glueParentButtonClicked: function()
- {
- var newValue = !this._glueParentButton.toggled;
- this._glueParentButton.toggled = newValue;
- this._presentationModel.setGlueRecords(newValue);
- this._glueRecordsSetting.set(newValue);
- this._repopulateRecords();
- },
-
- _onClearButtonClick: function()
- {
- this._model.reset();
- },
-
- _onRecordingStarted: function()
- {
- this.toggleTimelineButton.title = WebInspector.UIString("Stop");
- this.toggleTimelineButton.toggled = true;
- },
-
- _recordingInProgress: function()
- {
- return this.toggleTimelineButton.toggled;
- },
-
- _onRecordingStopped: function()
- {
- this.toggleTimelineButton.title = WebInspector.UIString("Record");
- this.toggleTimelineButton.toggled = false;
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _willReloadPage: function(event)
- {
- if (this._operationInProgress || this._userInitiatedRecording || !this.isShowing())
- return;
- this._startRecording(false);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _loadEventFired: function(event)
- {
- if (!this._recordingInProgress() || this._userInitiatedRecording)
- return;
- this._stopRecording();
- },
-
- // TimelineView.
-
- /**
- * @param {!string} mode
- */
- _timelineViewWasShown: function(mode)
- {
- var frameMode = mode === WebInspector.TimelinePanel.Mode.Frames
- if (frameMode !== this._frameMode) {
- this._frameMode = frameMode;
- this._glueParentButton.setEnabled(!this._frameMode);
- this._presentationModel.setGlueRecords(!this._frameMode && this._glueParentButton.toggled);
- this._repopulateRecords();
-
- if (this._frameMode) {
- this._frameController = new WebInspector.TimelineFrameController(this._model, this._frameOverviewControl, this._presentationModel);
- } else {
- this._frameController.dispose();
- this._frameController = null;
- }
- }
- if (mode === WebInspector.TimelinePanel.Mode.Memory)
- this._timelineMemorySplitter.showBoth();
- else
- this._timelineMemorySplitter.showOnlyFirst();
- this._updateSelectionDetails();
- },
-
- get calculator()
- {
- return this._calculator;
- },
-
- /**
- * @param {!WebInspector.FilterBar} filterBar
- * @return {boolean}
- */
- _createFilters: function(filterBar)
- {
- this._textFilterUI = new WebInspector.TextFilterUI();
- this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._textFilterChanged, this);
- filterBar.addFilter(this._textFilterUI);
-
- var durationOptions = [];
- for (var presetIndex = 0; presetIndex < WebInspector.TimelinePanel.durationFilterPresetsMs.length; ++presetIndex) {
- var durationMs = WebInspector.TimelinePanel.durationFilterPresetsMs[presetIndex];
- var durationOption = {};
- if (!durationMs) {
- durationOption.label = WebInspector.UIString("All");
- durationOption.title = WebInspector.UIString("Show all records");
- } else {
- durationOption.label = WebInspector.UIString("\u2265 %dms", durationMs);
- durationOption.title = WebInspector.UIString("Hide records shorter than %dms", durationMs);
- }
- durationOption.value = durationMs;
- durationOptions.push(durationOption);
- }
- this._durationFilterUI = new WebInspector.ComboBoxFilterUI(durationOptions);
- this._durationFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._durationFilterChanged, this);
- filterBar.addFilter(this._durationFilterUI);
- this._durationFilter = new WebInspector.TimelineIsLongFilter();
-
- this._categoryFiltersUI = {};
- var categoryTypes = [];
- var categories = WebInspector.TimelinePresentationModel.categories();
- for (var categoryName in categories) {
- var category = categories[categoryName];
- if (category.overviewStripGroupIndex < 0)
- continue;
- var filter = new WebInspector.CheckboxFilterUI(category.name, category.title);
- filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._categoriesFilterChanged.bind(this, category.name), this);
- filterBar.addFilter(filter);
- this._categoryFiltersUI[category.name] = filter;
- }
- this._categoryFilter = new WebInspector.TimelineCategoryFilter();
-
- this._windowFilter = new WebInspector.TimelineWindowFilter();
-
- return true;
- },
-
- _textFilterChanged: function(event)
- {
- var searchQuery = this._textFilterUI.value();
- this._presentationModel.setSearchFilter(null);
- delete this._searchFilter;
-
- function cleanRecord(record)
- {
- delete record.clicked;
- }
- WebInspector.TimelinePresentationModel.forAllRecords(this._presentationModel.rootRecord().children, cleanRecord);
-
- this.searchCanceled();
- if (searchQuery) {
- this._searchFilter = new WebInspector.TimelineSearchFilter(createPlainTextSearchRegex(searchQuery, "i"));
- this._presentationModel.setSearchFilter(this._searchFilter);
- }
- this._invalidateAndScheduleRefresh(true, true);
- },
-
- _durationFilterChanged: function()
- {
- var duration = this._durationFilterUI.value();
- var minimumRecordDuration = +duration / 1000.0;
- this._durationFilter.setMinimumRecordDuration(minimumRecordDuration);
- this._invalidateAndScheduleRefresh(true, true);
- },
-
- _categoriesFilterChanged: function(name, event)
- {
- var categories = WebInspector.TimelinePresentationModel.categories();
- categories[name].hidden = !this._categoryFiltersUI[name].checked();
- this._invalidateAndScheduleRefresh(true, true);
- },
-
- _dockSideChanged: function()
- {
- var dockSide = WebInspector.dockController.dockSide();
- var vertically = false;
- if (dockSide === WebInspector.DockController.State.DockedToBottom)
- vertically = true;
- else
- vertically = !WebInspector.settings.splitVerticallyWhenDockedToRight.get();
- this._detailsSplitView.setVertical(vertically);
- this._detailsView.setVertical(vertically);
- },
-
- _rootRecord: function()
- {
- return this._presentationModel.rootRecord();
- },
-
- _updateRecordsCounter: function(recordsInWindowCount)
- {
- this.recordsCounter.setText(WebInspector.UIString("%d of %d records shown", recordsInWindowCount, this._allRecordsCount));
- },
-
- _updateFrameStatistics: function(frames)
- {
- this._lastFrameStatistics = frames.length ? new WebInspector.FrameStatistics(frames) : null;
- },
-
- _updateEventDividers: function()
- {
- this._timelineGrid.removeEventDividers();
- var clientWidth = this._graphRowsElementWidth;
- var dividers = [];
- var eventDividerRecords = this._presentationModel.eventDividerRecords();
-
- for (var i = 0; i < eventDividerRecords.length; ++i) {
- var record = eventDividerRecords[i];
- var positions = this._calculator.computeBarGraphWindowPosition(record);
- var dividerPosition = Math.round(positions.left);
- if (dividerPosition < 0 || dividerPosition >= clientWidth || dividers[dividerPosition])
- continue;
- var divider = WebInspector.TimelinePresentationModel.createEventDivider(record.type, record.title);
- divider.style.left = dividerPosition + "px";
- dividers[dividerPosition] = divider;
- }
- this._timelineGrid.addEventDividers(dividers);
- },
-
- _updateFrameBars: function(frames)
- {
- var clientWidth = this._graphRowsElementWidth;
- if (this._frameContainer)
- this._frameContainer.removeChildren();
- else {
- const frameContainerBorderWidth = 1;
- this._frameContainer = document.createElement("div");
- this._frameContainer.classList.add("fill");
- this._frameContainer.classList.add("timeline-frame-container");
- this._frameContainer.style.height = WebInspector.TimelinePanel.rowHeight + frameContainerBorderWidth + "px";
- this._frameContainer.addEventListener("dblclick", this._onFrameDoubleClicked.bind(this), false);
- }
-
- var dividers = [ this._frameContainer ];
-
- for (var i = 0; i < frames.length; ++i) {
- var frame = frames[i];
- var frameStart = this._calculator.computePosition(frame.startTime);
- var frameEnd = this._calculator.computePosition(frame.endTime);
-
- var frameStrip = document.createElement("div");
- frameStrip.className = "timeline-frame-strip";
- var actualStart = Math.max(frameStart, 0);
- var width = frameEnd - actualStart;
- frameStrip.style.left = actualStart + "px";
- frameStrip.style.width = width + "px";
- frameStrip._frame = frame;
-
- const minWidthForFrameInfo = 60;
- if (width > minWidthForFrameInfo)
- frameStrip.textContent = Number.secondsToString(frame.endTime - frame.startTime, true);
-
- this._frameContainer.appendChild(frameStrip);
-
- if (actualStart > 0) {
- var frameMarker = WebInspector.TimelinePresentationModel.createEventDivider(WebInspector.TimelineModel.RecordType.BeginFrame);
- frameMarker.style.left = frameStart + "px";
- dividers.push(frameMarker);
- }
- }
- this._timelineGrid.addEventDividers(dividers);
- },
-
- _onFrameDoubleClicked: function(event)
- {
- var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip");
- if (!frameBar)
- return;
- this._overviewPane.zoomToFrame(frameBar._frame);
- },
-
- _repopulateRecords: function()
- {
- this._resetPanel();
- this._automaticallySizeWindow = false;
- var records = this._model.records;
- for (var i = 0; i < records.length; ++i)
- this._innerAddRecordToTimeline(records[i]);
- this._invalidateAndScheduleRefresh(false, false);
- },
-
- _onTimelineEventRecorded: function(event)
- {
- if (this._innerAddRecordToTimeline(/** @type {!TimelineAgent.TimelineEvent} */(event.data)))
- this._invalidateAndScheduleRefresh(false, false);
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- * @return {boolean}
- */
- _innerAddRecordToTimeline: function(record)
- {
- if (record.type === WebInspector.TimelineModel.RecordType.Program)
- this._mainThreadTasks.push(record);
-
- if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) {
- this._gpuTasks.push(record);
- return WebInspector.TimelineModel.startTimeInSeconds(record) < this._overviewPane.windowEndTime();
- }
-
- var records = this._presentationModel.addRecord(record);
- this._allRecordsCount += records.length;
- var hasVisibleRecords = false;
- var presentationModel = this._presentationModel;
- function checkVisible(record)
- {
- hasVisibleRecords |= presentationModel.isVisible(record);
- }
- WebInspector.TimelinePresentationModel.forAllRecords(records, checkVisible);
-
- function isAdoptedRecord(record)
- {
- return record.parent !== presentationModel.rootRecord;
- }
- // Tell caller update is necessary either if we added a visible record or if we re-parented a record.
- return hasVisibleRecords || records.some(isAdoptedRecord);
- },
-
- _sidebarResized: function()
- {
- var width = this._sidebarView.sidebarWidth();
- this._topPaneSidebarElement.style.flexBasis = width + "px";
- if (this._presentationModeSetting.get() === WebInspector.TimelinePanel.Mode.Memory)
- this._memoryStatistics.setSidebarWidth(width);
- this._timelineGrid.gridHeaderElement.style.left = width + "px";
- },
-
- /**
- * @param {number} width
- */
- setSidebarWidth: function(width)
- {
- if (this._presentationModeSetting.get() === WebInspector.TimelinePanel.Mode.Memory)
- this._sidebarView.setSidebarWidth(width);
- },
-
- _onViewportResize: function()
- {
- this._resize(this._sidebarView.sidebarWidth());
- },
-
- /**
- * @param {number} sidebarWidth
- */
- _resize: function(sidebarWidth)
- {
- this._closeRecordDetails();
- this._graphRowsElementWidth = this._graphRowsElement.offsetWidth;
- this._containerElementHeight = this._containerElement.clientHeight;
- this._timelineGrid.gridHeaderElement.style.width = this._itemsGraphsElement.offsetWidth + "px";
- this._scheduleRefresh(false, true);
- },
-
- _resetPanel: function()
- {
- this._presentationModel.reset();
- this._boundariesAreValid = false;
- this._adjustScrollPosition(0);
- this._closeRecordDetails();
- this._allRecordsCount = 0;
- this._automaticallySizeWindow = true;
- this._mainThreadTasks = [];
- this._gpuTasks = [];
- },
-
- _onRecordsCleared: function()
- {
- this._resetPanel();
- this._invalidateAndScheduleRefresh(true, true);
- },
-
- elementsToRestoreScrollPositionsFor: function()
- {
- return [this._containerElement];
- },
-
- wasShown: function()
- {
- WebInspector.Panel.prototype.wasShown.call(this);
- if (!WebInspector.TimelinePanel._categoryStylesInitialized) {
- WebInspector.TimelinePanel._categoryStylesInitialized = true;
- this._injectCategoryStyles();
- }
- this._overviewPane.willSetOverviewControl(this._overviewControls[this._presentationModeSetting.get()]);
- this._onViewportResize();
- this._refresh();
- },
-
- willHide: function()
- {
- this._closeRecordDetails();
- WebInspector.Panel.prototype.willHide.call(this);
- },
-
- _onScroll: function(event)
- {
- this._closeRecordDetails();
- this._scrollTop = this._containerElement.scrollTop;
- var dividersTop = Math.max(0, this._scrollTop);
- this._timelineGrid.setScrollAndDividerTop(this._scrollTop, dividersTop);
- this._scheduleRefresh(true, true);
- },
-
- /**
- * @param {boolean} preserveBoundaries
- * @param {boolean} userGesture
- */
- _invalidateAndScheduleRefresh: function(preserveBoundaries, userGesture)
- {
- this._presentationModel.invalidateFilteredRecords();
- delete this._searchResults;
- this._scheduleRefresh(preserveBoundaries, userGesture);
- },
-
- /**
- * @param {?WebInspector.TimelinePresentationModel.Record} record
- */
- _selectRecord: function(record)
- {
- if (record === this._lastSelectedRecord)
- return;
-
- // Remove selection rendering.
- if (this._lastSelectedRecord) {
- var listRow = /** @type {!WebInspector.TimelineRecordListRow} */ (this._lastSelectedRecord.getUserObject("WebInspector.TimelineRecordListRow"));
- if (listRow)
- listRow.renderAsSelected(false);
- var graphRow = /** @type {!WebInspector.TimelineRecordGraphRow} */ (this._lastSelectedRecord.getUserObject("WebInspector.TimelineRecordGraphRow"));
- if (graphRow)
- graphRow.renderAsSelected(false);
- }
-
- if (!record) {
- this._updateSelectionDetails();
- return;
- }
-
- this._lastSelectedRecord = record;
- this._revealRecord(record);
- var listRow = /** @type {!WebInspector.TimelineRecordListRow} */ (record.getUserObject("WebInspector.TimelineRecordListRow"));
- if (listRow)
- listRow.renderAsSelected(true);
- var graphRow = /** @type {!WebInspector.TimelineRecordListRow} */ (record.getUserObject("WebInspector.TimelineRecordGraphRow"));
- if (graphRow)
- graphRow.renderAsSelected(true);
-
- record.generatePopupContent(showCallback.bind(this));
-
- /**
- * @param {!DocumentFragment} element
- * @this {WebInspector.TimelinePanel}
- */
- function showCallback(element)
- {
- this._detailsView.setContent(record.title, element);
- }
- },
-
- _updateSelectionDetails: function()
- {
- var startTime = this._overviewPane.windowStartTime() * 1000;
- var endTime = this._overviewPane.windowEndTime() * 1000;
- // Return early in case 0 selection window.
- if (startTime < 0)
- return;
-
- var aggregatedStats = {};
-
- /**
- * @param {number} value
- * @param {!TimelineAgent.TimelineEvent} task
- * @return {number}
- */
- function compareEndTime(value, task)
- {
- return value < task.endTime ? -1 : 1;
- }
-
- /**
- * @param {!TimelineAgent.TimelineEvent} rawRecord
- */
- function aggregateTimeForRecordWithinWindow(rawRecord)
- {
- if (!rawRecord.endTime || rawRecord.endTime < startTime || rawRecord.startTime > endTime)
- return;
-
- var childrenTime = 0;
- var children = rawRecord.children || [];
- for (var i = 0; i < children.length; ++i) {
- var child = children[i];
- if (!child.endTime || child.endTime < startTime || child.startTime > endTime)
- continue;
- childrenTime += Math.min(endTime, child.endTime) - Math.max(startTime, child.startTime);
- aggregateTimeForRecordWithinWindow(child);
- }
- var categoryName = WebInspector.TimelinePresentationModel.categoryForRecord(rawRecord).name;
- var ownTime = Math.min(endTime, rawRecord.endTime) - Math.max(startTime, rawRecord.startTime) - childrenTime;
- aggregatedStats[categoryName] = (aggregatedStats[categoryName] || 0) + ownTime / 1000;
- }
-
- var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, this._mainThreadTasks, compareEndTime);
- for (; taskIndex < this._mainThreadTasks.length; ++taskIndex) {
- var task = this._mainThreadTasks[taskIndex];
- if (task.startTime > endTime)
- break;
- aggregateTimeForRecordWithinWindow(task);
- }
-
- var aggregatedTotal = 0;
- for (var categoryName in aggregatedStats)
- aggregatedTotal += aggregatedStats[categoryName];
- aggregatedStats["idle"] = Math.max(0, (endTime - startTime) / 1000 - aggregatedTotal);
-
- var fragment = document.createDocumentFragment();
- var pie = WebInspector.TimelinePresentationModel.generatePieChart(aggregatedStats);
- fragment.appendChild(pie.element);
-
- if (this._frameMode && this._lastFrameStatistics) {
- var title = WebInspector.UIString("%s \u2013 %s (%d frames)", Number.secondsToString(this._lastFrameStatistics.startOffset, true), Number.secondsToString(this._lastFrameStatistics.endOffset, true), this._lastFrameStatistics.frameCount);
- fragment.appendChild(WebInspector.TimelinePresentationModel.generatePopupContentForFrameStatistics(this._lastFrameStatistics));
- } else {
- var title = WebInspector.UIString("%s \u2013 %s", this._calculator.formatTime(0, true), this._calculator.formatTime(this._calculator.boundarySpan(), true));
- }
- this._detailsView.setContent(title, fragment);
- },
-
- _windowChanged: function()
- {
- this._windowFilter.setWindowTimes(this._overviewPane.windowStartTime(), this._overviewPane.windowEndTime());
- this._invalidateAndScheduleRefresh(false, true);
- this._selectRecord(null);
- },
-
- /**
- * @param {boolean} preserveBoundaries
- * @param {boolean} userGesture
- */
- _scheduleRefresh: function(preserveBoundaries, userGesture)
- {
- this._closeRecordDetails();
- this._boundariesAreValid &= preserveBoundaries;
-
- if (!this.isShowing())
- return;
-
- if (preserveBoundaries || userGesture)
- this._refresh();
- else {
- if (!this._refreshTimeout)
- this._refreshTimeout = setTimeout(this._refresh.bind(this), 300);
- }
- },
-
- _refresh: function()
- {
- if (this._refreshTimeout) {
- clearTimeout(this._refreshTimeout);
- delete this._refreshTimeout;
- }
-
- this._timelinePaddingLeft = this._expandOffset;
- this._calculator.setWindow(this._overviewPane.windowStartTime(), this._overviewPane.windowEndTime());
- this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth);
-
- var recordsInWindowCount = this._refreshRecords();
- this._updateRecordsCounter(recordsInWindowCount);
- if (!this._boundariesAreValid) {
- this._updateEventDividers();
- var frames = this._frameController && this._presentationModel.filteredFrames(this._overviewPane.windowStartTime(), this._overviewPane.windowEndTime());
- if (frames) {
- this._updateFrameStatistics(frames);
- const maxFramesForFrameBars = 30;
- if (frames.length && frames.length < maxFramesForFrameBars) {
- this._timelineGrid.removeDividers();
- this._updateFrameBars(frames);
- } else
- this._timelineGrid.updateDividers(this._calculator);
- } else
- this._timelineGrid.updateDividers(this._calculator);
- this._refreshAllUtilizationBars();
- }
- if (this._presentationModeSetting.get() === WebInspector.TimelinePanel.Mode.Memory)
- this._memoryStatistics.refresh();
- this._boundariesAreValid = true;
- },
-
- revealRecordAt: function(time)
- {
- var recordToReveal;
- function findRecordToReveal(record)
- {
- if (record.containsTime(time)) {
- recordToReveal = record;
- return true;
- }
- // If there is no record containing the time than use the latest one before that time.
- if (!recordToReveal || record.endTime < time && recordToReveal.endTime < record.endTime)
- recordToReveal = record;
- return false;
- }
- WebInspector.TimelinePresentationModel.forAllRecords(this._presentationModel.rootRecord().children, null, findRecordToReveal);
-
- // The record ends before the window left bound so scroll to the top.
- if (!recordToReveal) {
- this._containerElement.scrollTop = 0;
- return;
- }
-
- this._selectRecord(recordToReveal);
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} recordToReveal
- */
- _revealRecord: function(recordToReveal)
- {
- var needRefresh = false;
- // Expand all ancestors.
- for (var parent = recordToReveal.parent; parent !== this._rootRecord(); parent = parent.parent) {
- if (!parent.collapsed)
- continue;
- this._presentationModel.invalidateFilteredRecords();
- parent.collapsed = false;
- needRefresh = true;
- }
- var recordsInWindow = this._presentationModel.filteredRecords();
- var index = recordsInWindow.indexOf(recordToReveal);
-
- var itemOffset = index * WebInspector.TimelinePanel.rowHeight;
- var visibleTop = this._scrollTop - WebInspector.TimelinePanel.headerHeight;
- var visibleBottom = visibleTop + this._containerElementHeight - WebInspector.TimelinePanel.rowHeight;
- if (itemOffset < visibleTop)
- this._containerElement.scrollTop = itemOffset;
- else if (itemOffset > visibleBottom)
- this._containerElement.scrollTop = itemOffset - this._containerElementHeight + WebInspector.TimelinePanel.headerHeight + WebInspector.TimelinePanel.rowHeight;
- else if (needRefresh)
- this._refreshRecords();
- },
-
- _refreshRecords: function()
- {
- var recordsInWindow = this._presentationModel.filteredRecords();
-
- // Calculate the visible area.
- var visibleTop = this._scrollTop;
- var visibleBottom = visibleTop + this._containerElementHeight;
-
- var rowHeight = WebInspector.TimelinePanel.rowHeight;
- var headerHeight = WebInspector.TimelinePanel.headerHeight;
-
- // Convert visible area to visible indexes. Always include top-level record for a visible nested record.
- var startIndex = Math.max(0, Math.min(Math.floor((visibleTop - headerHeight) / rowHeight), recordsInWindow.length - 1));
- var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight));
- var lastVisibleLine = Math.max(0, Math.floor((visibleBottom - headerHeight) / rowHeight));
- if (this._automaticallySizeWindow && recordsInWindow.length > lastVisibleLine) {
- this._automaticallySizeWindow = false;
- // If we're at the top, always use real timeline start as a left window bound so that expansion arrow padding logic works.
- var windowStartTime = startIndex ? recordsInWindow[startIndex].startTime : this._model.minimumRecordTime();
- this._overviewPane.setWindowTimes(windowStartTime, recordsInWindow[Math.max(0, lastVisibleLine - 1)].endTime);
- recordsInWindow = this._presentationModel.filteredRecords();
- endIndex = Math.min(recordsInWindow.length, lastVisibleLine);
- }
-
- // Resize gaps first.
- this._topGapElement.style.height = (startIndex * rowHeight) + "px";
- this._sidebarView.sidebarElement.firstChild.style.flexBasis = (startIndex * rowHeight + headerHeight) + "px";
- this._bottomGapElement.style.height = (recordsInWindow.length - endIndex) * rowHeight + "px";
- var rowsHeight = headerHeight + recordsInWindow.length * rowHeight;
- var totalHeight = Math.max(this._containerElementHeight, rowsHeight);
-
- this._sidebarView.firstElement().style.height = totalHeight + "px";
- this._sidebarView.secondElement().style.height = totalHeight + "px";
- this._sidebarView.resizerElement().style.height = totalHeight + "px";
-
- // Update visible rows.
- var listRowElement = this._sidebarListElement.firstChild;
- var width = this._graphRowsElementWidth;
- this._itemsGraphsElement.removeChild(this._graphRowsElement);
- var graphRowElement = this._graphRowsElement.firstChild;
- var scheduleRefreshCallback = this._invalidateAndScheduleRefresh.bind(this, true, true);
- var selectRecordCallback = this._selectRecord.bind(this);
- this._itemsGraphsElement.removeChild(this._expandElements);
- this._expandElements.removeChildren();
-
- for (var i = 0; i < endIndex; ++i) {
- var record = recordsInWindow[i];
-
- if (i < startIndex) {
- var lastChildIndex = i + record.visibleChildrenCount;
- if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
- var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
- var positions = this._calculator.computeBarGraphWindowPosition(record);
- expandElement._update(record, i, positions.left - this._expandOffset, positions.width);
- }
- } else {
- if (!listRowElement) {
- listRowElement = new WebInspector.TimelineRecordListRow(selectRecordCallback, scheduleRefreshCallback).element;
- this._sidebarListElement.appendChild(listRowElement);
- }
- if (!graphRowElement) {
- graphRowElement = new WebInspector.TimelineRecordGraphRow(this._itemsGraphsElement, selectRecordCallback, scheduleRefreshCallback).element;
- this._graphRowsElement.appendChild(graphRowElement);
- }
-
- listRowElement.row.update(record, visibleTop);
- graphRowElement.row.update(record, this._calculator, this._expandOffset, i);
- if (this._lastSelectedRecord === record) {
- listRowElement.row.renderAsSelected(true);
- graphRowElement.row.renderAsSelected(true);
- }
-
- listRowElement = listRowElement.nextSibling;
- graphRowElement = graphRowElement.nextSibling;
- }
- }
-
- // Remove extra rows.
- while (listRowElement) {
- var nextElement = listRowElement.nextSibling;
- listRowElement.row.dispose();
- listRowElement = nextElement;
- }
- while (graphRowElement) {
- var nextElement = graphRowElement.nextSibling;
- graphRowElement.row.dispose();
- graphRowElement = nextElement;
- }
-
- this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement);
- this._itemsGraphsElement.appendChild(this._expandElements);
- this._adjustScrollPosition(recordsInWindow.length * rowHeight + headerHeight);
- this._updateSearchHighlight(false, true);
-
- return recordsInWindow.length;
- },
-
- _refreshAllUtilizationBars: function()
- {
- this._refreshUtilizationBars(WebInspector.UIString("CPU"), this._mainThreadTasks, this._cpuBarsElement);
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
- this._refreshUtilizationBars(WebInspector.UIString("GPU"), this._gpuTasks, this._gpuBarsElement);
- },
-
- /**
- * @param {string} name
- * @param {!Array.<!TimelineAgent.TimelineEvent>} tasks
- * @param {?Element} container
- */
- _refreshUtilizationBars: function(name, tasks, container)
- {
- if (!container)
- return;
-
- const barOffset = 3;
- const minGap = 3;
-
- var minWidth = WebInspector.TimelineCalculator._minWidth;
- var widthAdjustment = minWidth / 2;
-
- var width = this._graphRowsElementWidth;
- var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPane.windowStartTime();
- var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft);
- var startTime = (this._overviewPane.windowStartTime() - this._timelinePaddingLeft * scale) * 1000;
- var endTime = startTime + width * scale * 1000;
-
- /**
- * @param {number} value
- * @param {!TimelineAgent.TimelineEvent} task
- * @return {number}
- */
- function compareEndTime(value, task)
- {
- return value < task.endTime ? -1 : 1;
- }
-
- var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
-
- var foreignStyle = "gpu-task-foreign";
- var element = container.firstChild;
- var lastElement;
- var lastLeft;
- var lastRight;
-
- for (; taskIndex < tasks.length; ++taskIndex) {
- var task = tasks[taskIndex];
- if (task.startTime > endTime)
- break;
-
- var left = Math.max(0, this._calculator.computePosition(WebInspector.TimelineModel.startTimeInSeconds(task)) + barOffset - widthAdjustment);
- var right = Math.min(width, this._calculator.computePosition(WebInspector.TimelineModel.endTimeInSeconds(task)) + barOffset + widthAdjustment);
-
- if (lastElement) {
- var gap = Math.floor(left) - Math.ceil(lastRight);
- if (gap < minGap) {
- if (!task.data["foreign"])
- lastElement.classList.remove(foreignStyle);
- lastRight = right;
- lastElement._tasksInfo.lastTaskIndex = taskIndex;
- continue;
- }
- lastElement.style.width = (lastRight - lastLeft) + "px";
- }
-
- if (!element)
- element = container.createChild("div", "timeline-graph-bar");
- element.style.left = left + "px";
- element._tasksInfo = {name: name, tasks: tasks, firstTaskIndex: taskIndex, lastTaskIndex: taskIndex};
- if (task.data["foreign"])
- element.classList.add(foreignStyle);
- lastLeft = left;
- lastRight = right;
- lastElement = element;
- element = element.nextSibling;
- }
-
- if (lastElement)
- lastElement.style.width = (lastRight - lastLeft) + "px";
-
- while (element) {
- var nextElement = element.nextSibling;
- element._tasksInfo = null;
- container.removeChild(element);
- element = nextElement;
- }
- },
-
- _adjustScrollPosition: function(totalHeight)
- {
- // Prevent the container from being scrolled off the end.
- if ((this._scrollTop + this._containerElementHeight) > totalHeight + 1)
- this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
- },
-
- _getPopoverAnchor: function(element)
- {
- var anchor = element.enclosingNodeOrSelfWithClass("timeline-graph-bar");
- if (anchor && anchor._tasksInfo)
- return anchor;
- return element.enclosingNodeOrSelfWithClass("timeline-frame-strip");
- },
-
- _mouseOut: function()
- {
- this._hideQuadHighlight();
- },
-
- /**
- * @param {?Event} e
- */
- _mouseMove: function(e)
- {
- var rowElement = e.target.enclosingNodeOrSelfWithClass("timeline-tree-item");
- if (rowElement && rowElement.row && rowElement.row._record.highlightQuad && !this._recordingInProgress())
- this._highlightQuad(rowElement.row._record.highlightQuad);
- else
- this._hideQuadHighlight();
-
- var taskBarElement = e.target.enclosingNodeOrSelfWithClass("timeline-graph-bar");
- if (taskBarElement && taskBarElement._tasksInfo) {
- var offset = taskBarElement.offsetLeft;
- this._timelineGrid.showCurtains(offset >= 0 ? offset : 0, taskBarElement.offsetWidth);
- } else
- this._timelineGrid.hideCurtains();
- },
-
- /**
- * @param {?Event} event
- */
- _keyDown: function(event)
- {
- if (!this._lastSelectedRecord || event.shiftKey || event.metaKey || event.ctrlKey)
- return;
-
- var record = this._lastSelectedRecord;
- var recordsInWindow = this._presentationModel.filteredRecords();
- var index = recordsInWindow.indexOf(record);
- var recordsInPage = Math.floor(this._containerElementHeight / WebInspector.TimelinePanel.rowHeight);
- var rowHeight = WebInspector.TimelinePanel.rowHeight;
-
- if (index === -1)
- index = 0;
-
- switch (event.keyIdentifier) {
- case "Left":
- if (record.parent) {
- if ((!record.expandable || record.collapsed) && record.parent !== this._presentationModel.rootRecord()) {
- this._selectRecord(record.parent);
- } else {
- record.collapsed = true;
- record.clicked = true;
- this._invalidateAndScheduleRefresh(true, true);
- }
- }
- event.consume(true);
- break;
- case "Up":
- if (--index < 0)
- break;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- case "Right":
- if (record.expandable && record.collapsed) {
- record.collapsed = false;
- record.clicked = true;
- this._invalidateAndScheduleRefresh(true, true);
- } else {
- if (++index >= recordsInWindow.length)
- break;
- this._selectRecord(recordsInWindow[index]);
- }
- event.consume(true);
- break;
- case "Down":
- if (++index >= recordsInWindow.length)
- break;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- case "PageUp":
- index = Math.max(0, index - recordsInPage);
- this._scrollTop = Math.max(0, this._scrollTop - recordsInPage * rowHeight);
- this._containerElement.scrollTop = this._scrollTop;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- case "PageDown":
- index = Math.min(recordsInWindow.length - 1, index + recordsInPage);
- this._scrollTop = Math.min(this._containerElement.scrollHeight - this._containerElementHeight, this._scrollTop + recordsInPage * rowHeight);
- this._containerElement.scrollTop = this._scrollTop;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- case "Home":
- index = 0;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- case "End":
- index = recordsInWindow.length - 1;
- this._selectRecord(recordsInWindow[index]);
- event.consume(true);
- break;
- }
- },
-
- /**
- * @param {!Array.<number>} quad
- */
- _highlightQuad: function(quad)
- {
- if (this._highlightedQuad === quad)
- return;
- this._highlightedQuad = quad;
- DOMAgent.highlightQuad(quad, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
- },
-
- _hideQuadHighlight: function()
- {
- if (this._highlightedQuad) {
- delete this._highlightedQuad;
- DOMAgent.hideHighlight();
- }
- },
-
- /**
- * @param {!Element} anchor
- * @param {!WebInspector.Popover} popover
- */
- _showPopover: function(anchor, popover)
- {
- if (anchor.classList.contains("timeline-frame-strip")) {
- var frame = anchor._frame;
- popover.show(WebInspector.TimelinePresentationModel.generatePopupContentForFrame(frame), anchor);
- } else {
- if (anchor.row && anchor.row._record)
- anchor.row._record.generatePopupContent(showCallback);
- else if (anchor._tasksInfo)
- popover.show(this._presentationModel.generateMainThreadBarPopupContent(anchor._tasksInfo), anchor, null, null, WebInspector.Popover.Orientation.Bottom);
- }
-
- function showCallback(popupContent)
- {
- popover.show(popupContent, anchor);
- }
- },
-
- _closeRecordDetails: function()
- {
- this._popoverHelper.hidePopover();
- },
-
- _injectCategoryStyles: function()
- {
- var style = document.createElement("style");
- var categories = WebInspector.TimelinePresentationModel.categories();
-
- style.textContent = Object.values(categories).map(WebInspector.TimelinePresentationModel.createStyleRuleForCategory).join("\n");
- document.head.appendChild(style);
- },
-
- jumpToNextSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : -1;
- this._jumpToSearchResult(index + 1);
- },
-
- jumpToPreviousSearchResult: function()
- {
- if (!this._searchResults || !this._searchResults.length)
- return;
- var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : 0;
- this._jumpToSearchResult(index - 1);
- },
-
- _jumpToSearchResult: function(index)
- {
- this._selectSearchResult((index + this._searchResults.length) % this._searchResults.length);
- this._highlightSelectedSearchResult(true);
- },
-
- _selectSearchResult: function(index)
- {
- this._selectedSearchResult = this._searchResults[index];
- this._searchableView.updateCurrentMatchIndex(index);
- },
-
- /**
- * @param {boolean} selectRecord
- */
- _highlightSelectedSearchResult: function(selectRecord)
- {
- this._clearHighlight();
- if (this._searchFilter)
- return;
-
- var record = this._selectedSearchResult;
- if (!record)
- return;
-
- if (selectRecord)
- this._selectRecord(record);
-
- for (var element = this._sidebarListElement.firstChild; element; element = element.nextSibling) {
- if (element.row._record === record) {
- element.row.highlight(this._searchRegExp, this._highlightDomChanges);
- break;
- }
- }
- },
-
- _clearHighlight: function()
- {
- if (this._highlightDomChanges)
- WebInspector.revertDomChanges(this._highlightDomChanges);
- this._highlightDomChanges = [];
- },
-
- /**
- * @param {boolean} revealRecord
- * @param {boolean} shouldJump
- */
- _updateSearchHighlight: function(revealRecord, shouldJump)
- {
- if (this._searchFilter || !this._searchRegExp) {
- this._clearHighlight();
- return;
- }
-
- if (!this._searchResults)
- this._updateSearchResults(shouldJump);
- this._highlightSelectedSearchResult(revealRecord);
- },
-
- _updateSearchResults: function(shouldJump)
- {
- var searchRegExp = this._searchRegExp;
- if (!searchRegExp)
- return;
-
- var matches = [];
- var presentationModel = this._presentationModel;
-
- function processRecord(record)
- {
- if (presentationModel.isVisible(record) && WebInspector.TimelineRecordListRow.testContentMatching(record, searchRegExp))
- matches.push(record);
- return false;
- }
- WebInspector.TimelinePresentationModel.forAllRecords(presentationModel.rootRecord().children, processRecord);
-
- var matchesCount = matches.length;
- if (matchesCount) {
- this._searchResults = matches;
- this._searchableView.updateSearchMatchesCount(matchesCount);
-
- var selectedIndex = matches.indexOf(this._selectedSearchResult);
- if (shouldJump && selectedIndex === -1)
- selectedIndex = 0;
- this._selectSearchResult(selectedIndex);
- } else {
- this._searchableView.updateSearchMatchesCount(0);
- delete this._selectedSearchResult;
- }
- },
-
- searchCanceled: function()
- {
- this._clearHighlight();
- delete this._searchResults;
- delete this._selectedSearchResult;
- delete this._searchRegExp;
- },
-
- /**
- * @param {string} query
- * @param {boolean} shouldJump
- */
- performSearch: function(query, shouldJump)
- {
- this._searchRegExp = createPlainTextSearchRegex(query, "i");
- delete this._searchResults;
- this._updateSearchHighlight(true, shouldJump);
- },
-
- __proto__: WebInspector.Panel.prototype
-}
-
-/**
- * @constructor
- * @param {!WebInspector.TimelineModel} model
- * @implements {WebInspector.TimelineGrid.Calculator}
- */
-WebInspector.TimelineCalculator = function(model)
-{
- this._model = model;
-}
-
-WebInspector.TimelineCalculator._minWidth = 5;
-
-WebInspector.TimelineCalculator.prototype = {
- /**
- * @param {number} time
- */
- computePosition: function(time)
- {
- return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this.paddingLeft;
- },
-
- computeBarGraphPercentages: function(record)
- {
- var start = (record.startTime - this._minimumBoundary) / this.boundarySpan() * 100;
- var end = (record.startTime + record.selfTime - this._minimumBoundary) / this.boundarySpan() * 100;
- var endWithChildren = (record.lastChildEndTime - this._minimumBoundary) / this.boundarySpan() * 100;
- var cpuWidth = record.coalesced ? endWithChildren - start : record.cpuTime / this.boundarySpan() * 100;
- return {start: start, end: end, endWithChildren: endWithChildren, cpuWidth: cpuWidth};
- },
-
- computeBarGraphWindowPosition: function(record)
- {
- var percentages = this.computeBarGraphPercentages(record);
- var widthAdjustment = 0;
-
- var left = this.computePosition(record.startTime);
- var width = (percentages.end - percentages.start) / 100 * this._workingArea;
- if (width < WebInspector.TimelineCalculator._minWidth) {
- widthAdjustment = WebInspector.TimelineCalculator._minWidth - width;
- width = WebInspector.TimelineCalculator._minWidth;
- }
- var widthWithChildren = (percentages.endWithChildren - percentages.start) / 100 * this._workingArea + widthAdjustment;
- var cpuWidth = percentages.cpuWidth / 100 * this._workingArea + widthAdjustment;
- if (percentages.endWithChildren > percentages.end)
- widthWithChildren += widthAdjustment;
- return {left: left, width: width, widthWithChildren: widthWithChildren, cpuWidth: cpuWidth};
- },
-
- setWindow: function(minimumBoundary, maximumBoundary)
- {
- this._minimumBoundary = minimumBoundary;
- this._maximumBoundary = maximumBoundary;
- },
-
- /**
- * @param {number} paddingLeft
- * @param {number} clientWidth
- */
- setDisplayWindow: function(paddingLeft, clientWidth)
- {
- this._workingArea = clientWidth - WebInspector.TimelineCalculator._minWidth - paddingLeft;
- this.paddingLeft = paddingLeft;
- },
-
- /**
- * @param {number} value
- * @param {boolean=} hires
- * @return {string}
- */
- formatTime: function(value, hires)
- {
- return Number.secondsToString(value + this._minimumBoundary - this._model.minimumRecordTime(), hires);
- },
-
- maximumBoundary: function()
- {
- return this._maximumBoundary;
- },
-
- minimumBoundary: function()
- {
- return this._minimumBoundary;
- },
-
- zeroTime: function()
- {
- return this._model.minimumRecordTime();
- },
-
- boundarySpan: function()
- {
- return this._maximumBoundary - this._minimumBoundary;
- }
-}
-
-/**
- * @constructor
- * @param {function(!WebInspector.TimelinePresentationModel.Record)} selectRecord
- * @param {function()} scheduleRefresh
- */
-WebInspector.TimelineRecordListRow = function(selectRecord, scheduleRefresh)
-{
- this.element = document.createElement("div");
- this.element.row = this;
- this.element.style.cursor = "pointer";
- this.element.addEventListener("click", this._onClick.bind(this), false);
- this.element.addEventListener("mouseover", this._onMouseOver.bind(this), false);
- this.element.addEventListener("mouseout", this._onMouseOut.bind(this), false);
-
- // Warning is float right block, it goes first.
- this._warningElement = this.element.createChild("div", "timeline-tree-item-warning hidden");
-
- this._expandArrowElement = this.element.createChild("div", "timeline-tree-item-expand-arrow");
- this._expandArrowElement.addEventListener("click", this._onExpandClick.bind(this), false);
- var iconElement = this.element.createChild("span", "timeline-tree-icon");
- this._typeElement = this.element.createChild("span", "type");
-
- this._dataElement = this.element.createChild("span", "data dimmed");
- this._scheduleRefresh = scheduleRefresh;
- this._selectRecord = selectRecord;
-}
-
-WebInspector.TimelineRecordListRow.prototype = {
- update: function(record, offset)
- {
- this._record = record;
- this._offset = offset;
-
- this.element.className = "timeline-tree-item timeline-category-" + record.category.name;
- var paddingLeft = 5;
- var step = -3;
- for (var currentRecord = record.parent ? record.parent.parent : null; currentRecord; currentRecord = currentRecord.parent)
- paddingLeft += 12 / (Math.max(1, step++));
- this.element.style.paddingLeft = paddingLeft + "px";
- if (record.isBackground)
- this.element.classList.add("background");
-
- this._typeElement.textContent = record.title;
-
- if (this._dataElement.firstChild)
- this._dataElement.removeChildren();
-
- this._warningElement.enableStyleClass("hidden", !record.hasWarnings() && !record.childHasWarnings());
- this._warningElement.enableStyleClass("timeline-tree-item-child-warning", record.childHasWarnings() && !record.hasWarnings());
-
- if (record.detailsNode())
- this._dataElement.appendChild(record.detailsNode());
- this._expandArrowElement.enableStyleClass("parent", record.children && record.children.length);
- this._expandArrowElement.enableStyleClass("expanded", record.visibleChildrenCount);
- this._record.setUserObject("WebInspector.TimelineRecordListRow", this);
- },
-
- highlight: function(regExp, domChanges)
- {
- var matchInfo = this.element.textContent.match(regExp);
- if (matchInfo)
- WebInspector.highlightSearchResult(this.element, matchInfo.index, matchInfo[0].length, domChanges);
- },
-
- dispose: function()
- {
- this.element.remove();
- },
-
- /**
- * @param {!Event} event
- */
- _onExpandClick: function(event)
- {
- this._record.collapsed = !this._record.collapsed;
- this._record.clicked = true;
- this._scheduleRefresh();
- event.consume(true);
- },
-
- /**
- * @param {?Event} event
- */
- _onClick: function(event)
- {
- this._selectRecord(this._record);
- },
-
- /**
- * @param {boolean} selected
- */
- renderAsSelected: function(selected)
- {
- this.element.enableStyleClass("selected", selected);
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseOver: function(event)
- {
- this.element.classList.add("hovered");
- var graphRow = /** @type {!WebInspector.TimelineRecordGraphRow} */ (this._record.getUserObject("WebInspector.TimelineRecordGraphRow"));
- graphRow.element.classList.add("hovered");
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseOut: function(event)
- {
- this.element.classList.remove("hovered");
- var graphRow = /** @type {!WebInspector.TimelineRecordGraphRow} */ (this._record.getUserObject("WebInspector.TimelineRecordGraphRow"));
- graphRow.element.classList.remove("hovered");
- }
-}
-
-/**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @param {!RegExp} regExp
- */
-WebInspector.TimelineRecordListRow.testContentMatching = function(record, regExp)
-{
- var toSearchText = record.title;
- if (record.detailsNode())
- toSearchText += " " + record.detailsNode().textContent;
- return regExp.test(toSearchText);
-}
-
-/**
- * @constructor
- * @param {function(!WebInspector.TimelinePresentationModel.Record)} selectRecord
- * @param {function()} scheduleRefresh
- */
-WebInspector.TimelineRecordGraphRow = function(graphContainer, selectRecord, scheduleRefresh)
-{
- this.element = document.createElement("div");
- this.element.row = this;
- this.element.addEventListener("mouseover", this._onMouseOver.bind(this), false);
- this.element.addEventListener("mouseout", this._onMouseOut.bind(this), false);
- this.element.addEventListener("click", this._onClick.bind(this), false);
-
- this._barAreaElement = document.createElement("div");
- this._barAreaElement.className = "timeline-graph-bar-area";
- this.element.appendChild(this._barAreaElement);
-
- this._barWithChildrenElement = document.createElement("div");
- this._barWithChildrenElement.className = "timeline-graph-bar with-children";
- this._barWithChildrenElement.row = this;
- this._barAreaElement.appendChild(this._barWithChildrenElement);
-
- this._barCpuElement = document.createElement("div");
- this._barCpuElement.className = "timeline-graph-bar cpu"
- this._barCpuElement.row = this;
- this._barAreaElement.appendChild(this._barCpuElement);
-
- this._barElement = document.createElement("div");
- this._barElement.className = "timeline-graph-bar";
- this._barElement.row = this;
- this._barAreaElement.appendChild(this._barElement);
-
- this._expandElement = new WebInspector.TimelineExpandableElement(graphContainer);
-
- this._selectRecord = selectRecord;
- this._scheduleRefresh = scheduleRefresh;
-}
-
-WebInspector.TimelineRecordGraphRow.prototype = {
- update: function(record, calculator, expandOffset, index)
- {
- this._record = record;
- this.element.className = "timeline-graph-side timeline-category-" + record.category.name;
- if (record.isBackground)
- this.element.classList.add("background");
-
- var barPosition = calculator.computeBarGraphWindowPosition(record);
- this._barWithChildrenElement.style.left = barPosition.left + "px";
- this._barWithChildrenElement.style.width = barPosition.widthWithChildren + "px";
- this._barElement.style.left = barPosition.left + "px";
- this._barElement.style.width = barPosition.width + "px";
- this._barCpuElement.style.left = barPosition.left + "px";
- this._barCpuElement.style.width = barPosition.cpuWidth + "px";
- this._expandElement._update(record, index, barPosition.left - expandOffset, barPosition.width);
-
- this._record.setUserObject("WebInspector.TimelineRecordGraphRow", this);
- },
-
- /**
- * @param {?Event} event
- */
- _onClick: function(event)
- {
- // check if we click arrow and expand if yes.
- if (this._expandElement._arrow.containsEventPoint(event))
- this._expand();
- this._selectRecord(this._record);
- },
-
- /**
- * @param {boolean} selected
- */
- renderAsSelected: function(selected)
- {
- this.element.enableStyleClass("selected", selected);
- },
-
- _expand: function()
- {
- this._record.collapsed = !this._record.collapsed;
- this._record.clicked = true;
- this._scheduleRefresh();
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseOver: function(event)
- {
- this.element.classList.add("hovered");
- var listRow = /** @type {!WebInspector.TimelineRecordListRow} */ (this._record.getUserObject("WebInspector.TimelineRecordListRow"));
- listRow.element.classList.add("hovered");
- },
-
- /**
- * @param {?Event} event
- */
- _onMouseOut: function(event)
- {
- this.element.classList.remove("hovered");
- var listRow = /** @type {!WebInspector.TimelineRecordListRow} */ (this._record.getUserObject("WebInspector.TimelineRecordListRow"));
- listRow.element.classList.remove("hovered");
- },
-
- dispose: function()
- {
- this.element.remove();
- this._expandElement._dispose();
- }
-}
-
-/**
- * @constructor
- */
-WebInspector.TimelineExpandableElement = function(container)
-{
- this._element = container.createChild("div", "timeline-expandable");
- this._element.createChild("div", "timeline-expandable-left");
- this._arrow = this._element.createChild("div", "timeline-expandable-arrow");
-}
-
-WebInspector.TimelineExpandableElement.prototype = {
- _update: function(record, index, left, width)
- {
- const rowHeight = WebInspector.TimelinePanel.rowHeight;
- if (record.visibleChildrenCount || record.expandable) {
- this._element.style.top = index * rowHeight + "px";
- this._element.style.left = left + "px";
- this._element.style.width = Math.max(12, width + 25) + "px";
- if (!record.collapsed) {
- this._element.style.height = (record.visibleChildrenCount + 1) * rowHeight + "px";
- this._element.classList.add("timeline-expandable-expanded");
- this._element.classList.remove("timeline-expandable-collapsed");
- } else {
- this._element.style.height = rowHeight + "px";
- this._element.classList.add("timeline-expandable-collapsed");
- this._element.classList.remove("timeline-expandable-expanded");
- }
- this._element.classList.remove("hidden");
- } else
- this._element.classList.add("hidden");
- },
-
- _dispose: function()
- {
- this._element.remove();
- }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.TimelinePresentationModel.Filter}
- */
-WebInspector.TimelineCategoryFilter = function()
-{
-}
-
-WebInspector.TimelineCategoryFilter.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record)
- {
- return !record.category.hidden && record.type !== WebInspector.TimelineModel.RecordType.BeginFrame;
- }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.TimelinePresentationModel.Filter}
- */
-WebInspector.TimelineIsLongFilter = function()
-{
- this._minimumRecordDuration = 0;
-}
-
-WebInspector.TimelineIsLongFilter.prototype = {
- /**
- * @param {number} value
- */
- setMinimumRecordDuration: function(value)
- {
- this._minimumRecordDuration = value;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record)
- {
- return this._minimumRecordDuration ? ((record.lastChildEndTime - record.startTime) >= this._minimumRecordDuration) : true;
- }
-}
-
-/**
- * @param {!RegExp} regExp
- * @constructor
- * @implements {WebInspector.TimelinePresentationModel.Filter}
- */
-WebInspector.TimelineSearchFilter = function(regExp)
-{
- this._regExp = regExp;
-}
-
-WebInspector.TimelineSearchFilter.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record)
- {
- return WebInspector.TimelineRecordListRow.testContentMatching(record, this._regExp);
- }
-}
-
-/**
- * @constructor
- * @implements {WebInspector.TimelinePresentationModel.Filter}
- */
-WebInspector.TimelineWindowFilter = function()
-{
- this._windowStartTime = 0;
- this._windowEndTime = Infinity;
-}
-
-WebInspector.TimelineWindowFilter.prototype = {
- setWindowTimes: function(windowStartTime, windowEndTime)
- {
- this._windowStartTime = windowStartTime;
- this._windowEndTime = windowEndTime;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record)
- {
- return record.lastChildEndTime >= this._windowStartTime && record.startTime <= this._windowEndTime;
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.TimelineDetailsView = function()
-{
- WebInspector.View.call(this);
- this.element = document.createElement("div");
- this.element.className = "timeline-details-view fill vbox";
- this._titleElement = this.element.createChild("div", "timeline-details-view-title");
- this._titleElement.textContent = WebInspector.UIString("DETAILS");
- this._contentElement = this.element.createChild("div", "timeline-details-view-body");
-}
-
-WebInspector.TimelineDetailsView.prototype = {
- /**
- * @return {!Element}
- */
- titleElement: function()
- {
- return this._titleElement;
- },
-
- /**
- * @param {string} title
- * @param {!Node} node
- */
- setContent: function(title, node)
- {
- this._titleElement.textContent = WebInspector.UIString("DETAILS: %s", title);
- this._contentElement.removeChildren();
- this._contentElement.appendChild(node);
- },
-
- /**
- * @param {boolean} vertical
- */
- setVertical: function(vertical)
- {
- this._contentElement.enableStyleClass("hbox", !vertical);
- this._contentElement.enableStyleClass("vbox", vertical);
- },
-
- __proto__: WebInspector.View.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanelDescriptor.js
deleted file mode 100644
index 55af813d264..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePanelDescriptor.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.PanelDescriptor}
- */
-WebInspector.TimelinePanelDescriptor = function()
-{
- WebInspector.PanelDescriptor.call(this, "timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js");
-}
-
-WebInspector.TimelinePanelDescriptor.prototype = {
- registerShortcuts: function()
- {
- var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Timeline Panel"));
- section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.StartStopRecording, WebInspector.UIString("Start/stop recording"));
- section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.SaveToFile, WebInspector.UIString("Save timeline data"));
- section.addAlternateKeys(WebInspector.TimelinePanelDescriptor.ShortcutKeys.LoadFromFile, WebInspector.UIString("Load timeline data"));
- },
-
- __proto__: WebInspector.PanelDescriptor.prototype
-}
-
-WebInspector.TimelinePanelDescriptor.ShortcutKeys = {
- StartStopRecording: [
- WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- SaveToFile: [
- WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ],
-
- LoadFromFile: [
- WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ]
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js
deleted file mode 100644
index 95111ea1437..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelinePresentationModel.js
+++ /dev/null
@@ -1,1891 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- * Copyright (C) 2012 Intel Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.TimelinePresentationModel = function()
-{
- this._linkifier = new WebInspector.Linkifier();
- this._glueRecords = false;
- this._filters = [];
- this.reset();
-}
-
-WebInspector.TimelinePresentationModel.categories = function()
-{
- if (WebInspector.TimelinePresentationModel._categories)
- return WebInspector.TimelinePresentationModel._categories;
- WebInspector.TimelinePresentationModel._categories = {
- loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), 0, "#5A8BCC", "#8EB6E9", "#70A2E3"),
- scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), 1, "#D8AA34", "#F3D07A", "#F1C453"),
- rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), 2, "#8266CC", "#AF9AEB", "#9A7EE6"),
- painting: new WebInspector.TimelineCategory("painting", WebInspector.UIString("Painting"), 2, "#5FA050", "#8DC286", "#71B363"),
- other: new WebInspector.TimelineCategory("other", WebInspector.UIString("Other"), -1, "#BBBBBB", "#DDDDDD", "#DDDDDD"),
- idle: new WebInspector.TimelineCategory("idle", WebInspector.UIString("Idle"), -1, "#DDDDDD", "#FFFFFF", "#FFFFFF")
- };
- return WebInspector.TimelinePresentationModel._categories;
-};
-
-/**
- * @return {!Object.<string, {title: string, category: !WebInspector.TimelineCategory}>}
- */
-WebInspector.TimelinePresentationModel._initRecordStyles = function()
-{
- if (WebInspector.TimelinePresentationModel._recordStylesMap)
- return WebInspector.TimelinePresentationModel._recordStylesMap;
-
- var recordTypes = WebInspector.TimelineModel.RecordType;
- var categories = WebInspector.TimelinePresentationModel.categories();
-
- var recordStyles = {};
- recordStyles[recordTypes.Root] = { title: "#root", category: categories["loading"] };
- recordStyles[recordTypes.Program] = { title: WebInspector.UIString("Other"), category: categories["other"] };
- recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: categories["scripting"] };
- recordStyles[recordTypes.BeginFrame] = { title: WebInspector.UIString("Frame Start"), category: categories["rendering"] };
- recordStyles[recordTypes.ScheduleStyleRecalculation] = { title: WebInspector.UIString("Schedule Style Recalculation"), category: categories["rendering"] };
- recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: categories["rendering"] };
- recordStyles[recordTypes.InvalidateLayout] = { title: WebInspector.UIString("Invalidate Layout"), category: categories["rendering"] };
- recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: categories["rendering"] };
- recordStyles[recordTypes.AutosizeText] = { title: WebInspector.UIString("Autosize Text"), category: categories["rendering"] };
- recordStyles[recordTypes.PaintSetup] = { title: WebInspector.UIString("Paint Setup"), category: categories["painting"] };
- recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
- recordStyles[recordTypes.Rasterize] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
- recordStyles[recordTypes.ScrollLayer] = { title: WebInspector.UIString("Scroll"), category: categories["rendering"] };
- recordStyles[recordTypes.DecodeImage] = { title: WebInspector.UIString("Image Decode"), category: categories["painting"] };
- recordStyles[recordTypes.ResizeImage] = { title: WebInspector.UIString("Image Resize"), category: categories["painting"] };
- recordStyles[recordTypes.CompositeLayers] = { title: WebInspector.UIString("Composite Layers"), category: categories["painting"] };
- recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse HTML"), category: categories["loading"] };
- recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: categories["scripting"] };
- recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: categories["scripting"] };
- recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: categories["scripting"] };
- recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: categories["scripting"] };
- recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: categories["scripting"] };
- recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: categories["scripting"] };
- recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: categories["loading"] };
- recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: categories["loading"] };
- recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: categories["loading"] };
- recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: categories["scripting"] };
- recordStyles[recordTypes.ResourceReceivedData] = { title: WebInspector.UIString("Receive Data"), category: categories["loading"] };
- recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("DOMContentLoaded event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load event"), category: categories["scripting"] };
- recordStyles[recordTypes.MarkFirstPaint] = { title: WebInspector.UIString("First paint"), category: categories["painting"] };
- recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Stamp"), category: categories["scripting"] };
- recordStyles[recordTypes.Time] = { title: WebInspector.UIString("Time"), category: categories["scripting"] };
- recordStyles[recordTypes.TimeEnd] = { title: WebInspector.UIString("Time End"), category: categories["scripting"] };
- recordStyles[recordTypes.ScheduleResourceRequest] = { title: WebInspector.UIString("Schedule Request"), category: categories["loading"] };
- recordStyles[recordTypes.RequestAnimationFrame] = { title: WebInspector.UIString("Request Animation Frame"), category: categories["scripting"] };
- recordStyles[recordTypes.CancelAnimationFrame] = { title: WebInspector.UIString("Cancel Animation Frame"), category: categories["scripting"] };
- recordStyles[recordTypes.FireAnimationFrame] = { title: WebInspector.UIString("Animation Frame Fired"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketCreate] = { title: WebInspector.UIString("Create WebSocket"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketSendHandshakeRequest] = { title: WebInspector.UIString("Send WebSocket Handshake"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketReceiveHandshakeResponse] = { title: WebInspector.UIString("Receive WebSocket Handshake"), category: categories["scripting"] };
- recordStyles[recordTypes.WebSocketDestroy] = { title: WebInspector.UIString("Destroy WebSocket"), category: categories["scripting"] };
-
- WebInspector.TimelinePresentationModel._recordStylesMap = recordStyles;
- return recordStyles;
-}
-
-/**
- * @param {!Object} record
- * @return {{title: string, category: !WebInspector.TimelineCategory}}
- */
-WebInspector.TimelinePresentationModel.recordStyle = function(record)
-{
- var recordStyles = WebInspector.TimelinePresentationModel._initRecordStyles();
- var result = recordStyles[record.type];
- if (!result) {
- result = {
- title: WebInspector.UIString("Unknown: %s", record.type),
- category: WebInspector.TimelinePresentationModel.categories()["other"]
- };
- recordStyles[record.type] = result;
- }
- return result;
-}
-
-WebInspector.TimelinePresentationModel.categoryForRecord = function(record)
-{
- return WebInspector.TimelinePresentationModel.recordStyle(record).category;
-}
-
-WebInspector.TimelinePresentationModel.isEventDivider = function(record)
-{
- var recordTypes = WebInspector.TimelineModel.RecordType;
- if (record.type === recordTypes.TimeStamp)
- return true;
- if (record.type === recordTypes.MarkFirstPaint)
- return true;
- if (record.type === recordTypes.MarkDOMContent || record.type === recordTypes.MarkLoad) {
- if (record.data && ((typeof record.data.isMainFrame) === "boolean"))
- return record.data.isMainFrame;
- }
- return false;
-}
-
-/**
- * @param {!Array.<*>} recordsArray
- * @param {?function(*)} preOrderCallback
- * @param {function(*)=} postOrderCallback
- */
-WebInspector.TimelinePresentationModel.forAllRecords = function(recordsArray, preOrderCallback, postOrderCallback)
-{
- if (!recordsArray)
- return;
- var stack = [{array: recordsArray, index: 0}];
- while (stack.length) {
- var entry = stack[stack.length - 1];
- var records = entry.array;
- if (entry.index < records.length) {
- var record = records[entry.index];
- if (preOrderCallback && preOrderCallback(record))
- return;
- if (record.children)
- stack.push({array: record.children, index: 0, record: record});
- else if (postOrderCallback && postOrderCallback(record))
- return;
- ++entry.index;
- } else {
- if (entry.record && postOrderCallback && postOrderCallback(entry.record))
- return;
- stack.pop();
- }
- }
-}
-
-/**
- * @param {string=} recordType
- * @return {boolean}
- */
-WebInspector.TimelinePresentationModel.needsPreviewElement = function(recordType)
-{
- if (!recordType)
- return false;
- const recordTypes = WebInspector.TimelineModel.RecordType;
- switch (recordType) {
- case recordTypes.ScheduleResourceRequest:
- case recordTypes.ResourceSendRequest:
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- return true;
- default:
- return false;
- }
-}
-
-/**
- * @param {string} recordType
- * @param {string=} title
- */
-WebInspector.TimelinePresentationModel.createEventDivider = function(recordType, title)
-{
- var eventDivider = document.createElement("div");
- eventDivider.className = "resources-event-divider";
- var recordTypes = WebInspector.TimelineModel.RecordType;
-
- if (recordType === recordTypes.MarkDOMContent)
- eventDivider.className += " resources-blue-divider";
- else if (recordType === recordTypes.MarkLoad)
- eventDivider.className += " resources-red-divider";
- else if (recordType === recordTypes.MarkFirstPaint)
- eventDivider.className += " resources-green-divider";
- else if (recordType === recordTypes.TimeStamp)
- eventDivider.className += " resources-orange-divider";
- else if (recordType === recordTypes.BeginFrame)
- eventDivider.className += " timeline-frame-divider";
-
- if (title)
- eventDivider.title = title;
-
- return eventDivider;
-}
-
-WebInspector.TimelinePresentationModel._hiddenRecords = { }
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkDOMContent] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkLoad] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkFirstPaint] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.InvalidateLayout] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.GPUTask] = 1;
-WebInspector.TimelinePresentationModel._hiddenRecords[WebInspector.TimelineModel.RecordType.ActivateLayerTree] = 1;
-
-WebInspector.TimelinePresentationModel.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Filter} filter
- */
- addFilter: function(filter)
- {
- this._filters.push(filter);
- },
-
- /**
- * @param {?WebInspector.TimelinePresentationModel.Filter} filter
- */
- setSearchFilter: function(filter)
- {
- this._searchFilter = filter;
- },
-
- rootRecord: function()
- {
- return this._rootRecord;
- },
-
- frames: function()
- {
- return this._frames;
- },
-
- reset: function()
- {
- this._linkifier.reset();
- this._rootRecord = new WebInspector.TimelinePresentationModel.Record(this, { type: WebInspector.TimelineModel.RecordType.Root }, null, null, null, false);
- this._sendRequestRecords = {};
- this._scheduledResourceRequests = {};
- this._timerRecords = {};
- this._requestAnimationFrameRecords = {};
- this._eventDividerRecords = [];
- this._timeRecords = {};
- this._timeRecordStack = [];
- this._frames = [];
- this._minimumRecordTime = -1;
- this._layoutInvalidateStack = {};
- this._lastScheduleStyleRecalculation = {};
- this._webSocketCreateRecords = {};
- this._coalescingBuckets = {};
- },
-
- addFrame: function(frame)
- {
- if (!frame.isBackground)
- this._frames.push(frame);
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} record
- * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
- */
- addRecord: function(record)
- {
- if (this._minimumRecordTime === -1 || record.startTime < this._minimumRecordTime)
- this._minimumRecordTime = WebInspector.TimelineModel.startTimeInSeconds(record);
-
- var records;
- if (record.type === WebInspector.TimelineModel.RecordType.Program)
- records = this._foldSyncTimeRecords(record.children || []);
- else
- records = [record];
- var result = Array(records.length);
- for (var i = 0; i < records.length; ++i)
- result[i] = this._innerAddRecord(this._rootRecord, records[i]);
- return result;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} parentRecord
- * @param {!TimelineAgent.TimelineEvent} record
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- _innerAddRecord: function(parentRecord, record)
- {
- const recordTypes = WebInspector.TimelineModel.RecordType;
- var isHiddenRecord = record.type in WebInspector.TimelinePresentationModel._hiddenRecords;
- var origin;
- var coalescingBucket;
-
- if (!isHiddenRecord) {
- var newParentRecord = this._findParentRecord(record);
- if (newParentRecord) {
- origin = parentRecord;
- parentRecord = newParentRecord;
- }
- // On main thread, only coalesce if the last event is of same type.
- if (parentRecord === this._rootRecord)
- coalescingBucket = record.thread ? record.type : "mainThread";
- var coalescedRecord = this._findCoalescedParent(record, parentRecord, coalescingBucket);
- if (coalescedRecord) {
- if (!origin)
- origin = parentRecord;
- parentRecord = coalescedRecord;
- }
- }
-
- var children = record.children;
- var scriptDetails = null;
- if (record.data && record.data["scriptName"]) {
- scriptDetails = {
- scriptName: record.data["scriptName"],
- scriptLine: record.data["scriptLine"]
- }
- };
-
- if ((record.type === recordTypes.TimerFire || record.type === recordTypes.FireAnimationFrame) && children && children.length) {
- var childRecord = children[0];
- if (childRecord.type === recordTypes.FunctionCall) {
- scriptDetails = {
- scriptName: childRecord.data["scriptName"],
- scriptLine: childRecord.data["scriptLine"]
- };
- children = childRecord.children.concat(children.slice(1));
- }
- }
-
- var formattedRecord = new WebInspector.TimelinePresentationModel.Record(this, record, parentRecord, origin, scriptDetails, isHiddenRecord);
-
- if (WebInspector.TimelinePresentationModel.isEventDivider(formattedRecord))
- this._eventDividerRecords.push(formattedRecord);
-
- if (isHiddenRecord)
- return formattedRecord;
-
- formattedRecord.collapsed = parentRecord === this._rootRecord;
- if (coalescingBucket)
- this._coalescingBuckets[coalescingBucket] = formattedRecord;
-
- if (children) {
- children = this._foldSyncTimeRecords(children);
- for (var i = 0; i < children.length; ++i)
- this._innerAddRecord(formattedRecord, children[i]);
- }
-
- formattedRecord.calculateAggregatedStats();
- if (parentRecord.coalesced)
- this._updateCoalescingParent(formattedRecord);
- else if (origin)
- this._updateAncestorStats(formattedRecord);
-
- origin = formattedRecord.origin();
- if (!origin.isRoot() && !origin.coalesced)
- origin.selfTime -= formattedRecord.endTime - formattedRecord.startTime;
- return formattedRecord;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- */
- _updateAncestorStats: function(record)
- {
- var lastChildEndTime = record.lastChildEndTime;
- var aggregatedStats = record.aggregatedStats;
- for (var currentRecord = record.parent; currentRecord && !currentRecord.isRoot(); currentRecord = currentRecord.parent) {
- currentRecord._cpuTime += record._cpuTime;
- if (currentRecord.lastChildEndTime < lastChildEndTime)
- currentRecord.lastChildEndTime = lastChildEndTime;
- for (var category in aggregatedStats)
- currentRecord.aggregatedStats[category] += aggregatedStats[category];
- }
- },
-
- /**
- * @param {!Object} record
- * @param {!Object} newParent
- * @param {string=} bucket
- * @return {?WebInspector.TimelinePresentationModel.Record}
- */
- _findCoalescedParent: function(record, newParent, bucket)
- {
- const coalescingThresholdSeconds = 0.005;
-
- var lastRecord = bucket ? this._coalescingBuckets[bucket] : newParent.children.peekLast();
- if (lastRecord && lastRecord.coalesced)
- lastRecord = lastRecord.children.peekLast();
- var startTime = WebInspector.TimelineModel.startTimeInSeconds(record);
- var endTime = WebInspector.TimelineModel.endTimeInSeconds(record);
- if (!lastRecord)
- return null;
- if (lastRecord.type !== record.type)
- return null;
- if (lastRecord.endTime + coalescingThresholdSeconds < startTime)
- return null;
- if (endTime + coalescingThresholdSeconds < lastRecord.startTime)
- return null;
- if (WebInspector.TimelinePresentationModel.coalescingKeyForRecord(record) !== WebInspector.TimelinePresentationModel.coalescingKeyForRecord(lastRecord._record))
- return null;
- if (lastRecord.parent.coalesced)
- return lastRecord.parent;
- return this._replaceWithCoalescedRecord(lastRecord);
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- _replaceWithCoalescedRecord: function(record)
- {
- var rawRecord = {
- type: record._record.type,
- startTime: record._record.startTime,
- endTime: record._record.endTime,
- data: { }
- };
- if (record._record.thread)
- rawRecord.thread = "aggregated";
- if (record.type === WebInspector.TimelineModel.RecordType.TimeStamp)
- rawRecord.data.message = record.data.message;
-
- var coalescedRecord = new WebInspector.TimelinePresentationModel.Record(this, rawRecord, null, null, null, false);
- var parent = record.parent;
-
- coalescedRecord.coalesced = true;
- coalescedRecord.collapsed = true;
- coalescedRecord._children.push(record);
- record.parent = coalescedRecord;
- if (record.hasWarnings() || record.childHasWarnings())
- coalescedRecord._childHasWarnings = true;
-
- coalescedRecord.parent = parent;
- parent._children[parent._children.indexOf(record)] = coalescedRecord;
- WebInspector.TimelineModel.aggregateTimeByCategory(coalescedRecord._aggregatedStats, record._aggregatedStats);
-
- return coalescedRecord;
- },
-
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- */
- _updateCoalescingParent: function(record)
- {
- var parentRecord = record.parent;
- WebInspector.TimelineModel.aggregateTimeByCategory(parentRecord._aggregatedStats, record._aggregatedStats);
- if (parentRecord.startTime > record._record.startTime)
- parentRecord._record.startTime = record._record.startTime;
- if (parentRecord.endTime < record._record.endTime) {
- parentRecord._record.endTime = record._record.endTime;
- parentRecord.lastChildEndTime = parentRecord.endTime;
- }
- },
-
- /**
- * @param {!Array.<!TimelineAgent.TimelineEvent>} records
- */
- _foldSyncTimeRecords: function(records)
- {
- var recordTypes = WebInspector.TimelineModel.RecordType;
- // Fast case -- if there are no Time records, return input as is.
- for (var i = 0; i < records.length && records[i].type !== recordTypes.Time; ++i) {}
- if (i === records.length)
- return records;
-
- var result = [];
- var stack = [];
- for (var i = 0; i < records.length; ++i) {
- result.push(records[i]);
- if (records[i].type === recordTypes.Time) {
- stack.push(result.length - 1);
- continue;
- }
- if (records[i].type !== recordTypes.TimeEnd)
- continue;
- while (stack.length) {
- var begin = stack.pop();
- if (result[begin].data.message !== records[i].data.message)
- continue;
- var timeEndRecord = /** @type {!TimelineAgent.TimelineEvent} */ (result.pop());
- var children = result.splice(begin + 1, result.length - begin);
- result[begin] = this._createSynchronousTimeRecord(result[begin], timeEndRecord, children);
- break;
- }
- }
- return result;
- },
-
- /**
- * @param {!TimelineAgent.TimelineEvent} beginRecord
- * @param {!TimelineAgent.TimelineEvent} endRecord
- * @param {!Array.<!TimelineAgent.TimelineEvent>} children
- * @return {!TimelineAgent.TimelineEvent}
- */
- _createSynchronousTimeRecord: function(beginRecord, endRecord, children)
- {
- return {
- type: beginRecord.type,
- startTime: beginRecord.startTime,
- endTime: endRecord.startTime,
- stackTrace: beginRecord.stackTrace,
- children: children,
- data: {
- message: beginRecord.data.message,
- isSynchronous: true
- },
- };
- },
-
- _findParentRecord: function(record)
- {
- if (!this._glueRecords)
- return null;
- var recordTypes = WebInspector.TimelineModel.RecordType;
-
- switch (record.type) {
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceFinish:
- case recordTypes.ResourceReceivedData:
- return this._sendRequestRecords[record.data["requestId"]];
-
- case recordTypes.ResourceSendRequest:
- return this._rootRecord;
-
- case recordTypes.TimerFire:
- return this._timerRecords[record.data["timerId"]];
-
- case recordTypes.ResourceSendRequest:
- return this._scheduledResourceRequests[record.data["url"]];
-
- case recordTypes.FireAnimationFrame:
- return this._requestAnimationFrameRecords[record.data["id"]];
- }
- },
-
- setGlueRecords: function(glue)
- {
- this._glueRecords = glue;
- },
-
- invalidateFilteredRecords: function()
- {
- delete this._filteredRecords;
- },
-
- filteredRecords: function()
- {
- if (this._filteredRecords)
- return this._filteredRecords;
-
- var recordsInWindow = [];
- var stack = [{children: this._rootRecord.children, index: 0, parentIsCollapsed: false, parentRecord: {}}];
- var revealedDepth = 0;
-
- function revealRecordsInStack() {
- for (var depth = revealedDepth + 1; depth < stack.length; ++depth) {
- if (stack[depth - 1].parentIsCollapsed) {
- stack[depth].parentRecord.parent._expandable = true;
- return;
- }
- stack[depth - 1].parentRecord.collapsed = false;
- recordsInWindow.push(stack[depth].parentRecord);
- stack[depth].windowLengthBeforeChildrenTraversal = recordsInWindow.length;
- stack[depth].parentIsRevealed = true;
- revealedDepth = depth;
- }
- }
-
- while (stack.length) {
- var entry = stack[stack.length - 1];
- var records = entry.children;
- if (records && entry.index < records.length) {
- var record = records[entry.index];
- ++entry.index;
-
- if (this.isVisible(record)) {
- record.parent._expandable = true;
- if (this._searchFilter)
- revealRecordsInStack();
- if (!entry.parentIsCollapsed) {
- recordsInWindow.push(record);
- revealedDepth = stack.length;
- entry.parentRecord.collapsed = false;
- }
- }
-
- record._expandable = false;
-
- stack.push({children: record.children,
- index: 0,
- parentIsCollapsed: (entry.parentIsCollapsed || (record.collapsed && (!this._searchFilter || record.clicked))),
- parentRecord: record,
- windowLengthBeforeChildrenTraversal: recordsInWindow.length});
- } else {
- stack.pop();
- revealedDepth = Math.min(revealedDepth, stack.length - 1);
- entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
- }
- }
-
- this._filteredRecords = recordsInWindow;
- return recordsInWindow;
- },
-
- filteredFrames: function(startTime, endTime)
- {
- function compareStartTime(value, object)
- {
- return value - object.startTime;
- }
- function compareEndTime(value, object)
- {
- return value - object.endTime;
- }
- var firstFrame = insertionIndexForObjectInListSortedByFunction(startTime, this._frames, compareStartTime);
- var lastFrame = insertionIndexForObjectInListSortedByFunction(endTime, this._frames, compareEndTime);
- while (lastFrame < this._frames.length && this._frames[lastFrame].endTime <= endTime)
- ++lastFrame;
- return this._frames.slice(firstFrame, lastFrame);
- },
-
- eventDividerRecords: function()
- {
- return this._eventDividerRecords;
- },
-
- isVisible: function(record)
- {
- for (var i = 0; i < this._filters.length; ++i) {
- if (!this._filters[i].accept(record))
- return false;
- }
- return !this._searchFilter || this._searchFilter.accept(record);
- },
-
- /**
- * @param {{tasks: !Array.<{startTime: number, endTime: number}>, firstTaskIndex: number, lastTaskIndex: number}} info
- * @return {!Element}
- */
- generateMainThreadBarPopupContent: function(info)
- {
- var firstTaskIndex = info.firstTaskIndex;
- var lastTaskIndex = info.lastTaskIndex;
- var tasks = info.tasks;
- var messageCount = lastTaskIndex - firstTaskIndex + 1;
- var cpuTime = 0;
-
- for (var i = firstTaskIndex; i <= lastTaskIndex; ++i) {
- var task = tasks[i];
- cpuTime += WebInspector.TimelineModel.endTimeInSeconds(task) - WebInspector.TimelineModel.startTimeInSeconds(task);
- }
- var startTime = WebInspector.TimelineModel.startTimeInSeconds(tasks[firstTaskIndex]);
- var endTime = WebInspector.TimelineModel.endTimeInSeconds(tasks[lastTaskIndex]);
- var duration = endTime - startTime;
- var offset = this._minimumRecordTime;
-
- var contentHelper = new WebInspector.TimelinePopupContentHelper(info.name);
- var durationText = WebInspector.UIString("%s (at %s)", Number.secondsToString(duration, true),
- Number.secondsToString(startTime - offset, true));
- contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
- contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.secondsToString(cpuTime, true));
- contentHelper.appendTextRow(WebInspector.UIString("Message Count"), messageCount);
- return contentHelper.contentTable();
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {!WebInspector.TimelinePresentationModel} presentationModel
- * @param {!Object} record
- * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord
- * @param {?WebInspector.TimelinePresentationModel.Record} origin
- * @param {?Object} scriptDetails
- * @param {boolean} hidden
- */
-WebInspector.TimelinePresentationModel.Record = function(presentationModel, record, parentRecord, origin, scriptDetails, hidden)
-{
- this._linkifier = presentationModel._linkifier;
- this._aggregatedStats = {};
- this._record = record;
- this._children = [];
- if (!hidden && parentRecord) {
- this.parent = parentRecord;
- if (this.isBackground)
- WebInspector.TimelinePresentationModel.insertRetrospectiveRecord(parentRecord, this);
- else
- parentRecord.children.push(this);
- }
- if (origin)
- this._origin = origin;
-
- this._selfTime = this.endTime - this.startTime;
- this._lastChildEndTime = this.endTime;
- this._startTimeOffset = this.startTime - presentationModel._minimumRecordTime;
-
- if (record.data) {
- if (record.data["url"])
- this.url = record.data["url"];
- if (record.data["rootNode"])
- this._relatedBackendNodeId = record.data["rootNode"];
- else if (record.data["elementId"])
- this._relatedBackendNodeId = record.data["elementId"];
- }
- if (scriptDetails) {
- this.scriptName = scriptDetails.scriptName;
- this.scriptLine = scriptDetails.scriptLine;
- }
- if (parentRecord && parentRecord.callSiteStackTrace)
- this.callSiteStackTrace = parentRecord.callSiteStackTrace;
-
- var recordTypes = WebInspector.TimelineModel.RecordType;
- switch (record.type) {
- case recordTypes.ResourceSendRequest:
- // Make resource receive record last since request was sent; make finish record last since response received.
- presentationModel._sendRequestRecords[record.data["requestId"]] = this;
- break;
-
- case recordTypes.ScheduleResourceRequest:
- presentationModel._scheduledResourceRequests[record.data["url"]] = this;
- break;
-
- case recordTypes.ResourceReceiveResponse:
- var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
- if (sendRequestRecord) { // False if we started instrumentation in the middle of request.
- this.url = sendRequestRecord.url;
- // Now that we have resource in the collection, recalculate details in order to display short url.
- sendRequestRecord._refreshDetails();
- if (sendRequestRecord.parent !== presentationModel._rootRecord && sendRequestRecord.parent.type === recordTypes.ScheduleResourceRequest)
- sendRequestRecord.parent._refreshDetails();
- }
- break;
-
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- var sendRequestRecord = presentationModel._sendRequestRecords[record.data["requestId"]];
- if (sendRequestRecord) // False for main resource.
- this.url = sendRequestRecord.url;
- break;
-
- case recordTypes.TimerInstall:
- this.timeout = record.data["timeout"];
- this.singleShot = record.data["singleShot"];
- presentationModel._timerRecords[record.data["timerId"]] = this;
- break;
-
- case recordTypes.TimerFire:
- var timerInstalledRecord = presentationModel._timerRecords[record.data["timerId"]];
- if (timerInstalledRecord) {
- this.callSiteStackTrace = timerInstalledRecord.stackTrace;
- this.timeout = timerInstalledRecord.timeout;
- this.singleShot = timerInstalledRecord.singleShot;
- }
- break;
-
- case recordTypes.RequestAnimationFrame:
- presentationModel._requestAnimationFrameRecords[record.data["id"]] = this;
- break;
-
- case recordTypes.FireAnimationFrame:
- var requestAnimationRecord = presentationModel._requestAnimationFrameRecords[record.data["id"]];
- if (requestAnimationRecord)
- this.callSiteStackTrace = requestAnimationRecord.stackTrace;
- break;
-
- case recordTypes.Time:
- if (record.data.isSynchronous)
- break;
- var message = record.data["message"];
- var oldReference = presentationModel._timeRecords[message];
- if (oldReference)
- break;
- presentationModel._timeRecords[message] = this;
- if (origin)
- presentationModel._timeRecordStack.push(this);
- break;
-
- case recordTypes.TimeEnd:
- var message = record.data["message"];
- var timeRecord = presentationModel._timeRecords[message];
- delete presentationModel._timeRecords[message];
- if (timeRecord) {
- this.timeRecord = timeRecord;
- timeRecord.timeEndRecord = this;
- var intervalDuration = this.startTime - timeRecord.startTime;
- this.intervalDuration = intervalDuration;
- timeRecord.intervalDuration = intervalDuration;
- }
- break;
-
- case recordTypes.ScheduleStyleRecalculation:
- presentationModel._lastScheduleStyleRecalculation[this.frameId] = this;
- break;
-
- case recordTypes.RecalculateStyles:
- var scheduleStyleRecalculationRecord = presentationModel._lastScheduleStyleRecalculation[this.frameId];
- if (!scheduleStyleRecalculationRecord)
- break;
- this.callSiteStackTrace = scheduleStyleRecalculationRecord.stackTrace;
- break;
-
- case recordTypes.InvalidateLayout:
- // Consider style recalculation as a reason for layout invalidation,
- // but only if we had no earlier layout invalidation records.
- var styleRecalcStack;
- if (!presentationModel._layoutInvalidateStack[this.frameId]) {
- for (var outerRecord = parentRecord; outerRecord; outerRecord = record.parent) {
- if (outerRecord.type === recordTypes.RecalculateStyles) {
- styleRecalcStack = outerRecord.callSiteStackTrace;
- break;
- }
- }
- }
- presentationModel._layoutInvalidateStack[this.frameId] = styleRecalcStack || this.stackTrace;
- break;
-
- case recordTypes.Layout:
- var layoutInvalidateStack = presentationModel._layoutInvalidateStack[this.frameId];
- if (layoutInvalidateStack)
- this.callSiteStackTrace = layoutInvalidateStack;
- if (this.stackTrace)
- this.addWarning(WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck."));
-
- presentationModel._layoutInvalidateStack[this.frameId] = null;
- this.highlightQuad = record.data.root || WebInspector.TimelinePresentationModel.quadFromRectData(record.data);
- this._relatedBackendNodeId = record.data["rootNode"];
- break;
-
- case recordTypes.AutosizeText:
- if (record.data.needsRelayout && parentRecord.type === recordTypes.Layout)
- parentRecord.addWarning(WebInspector.UIString("Layout required two passes due to text autosizing, consider setting viewport."));
- break;
-
- case recordTypes.Paint:
- this.highlightQuad = record.data.clip || WebInspector.TimelinePresentationModel.quadFromRectData(record.data);
- break;
-
- case recordTypes.WebSocketCreate:
- this.webSocketURL = record.data["url"];
- if (typeof record.data["webSocketProtocol"] !== "undefined")
- this.webSocketProtocol = record.data["webSocketProtocol"];
- presentationModel._webSocketCreateRecords[record.data["identifier"]] = this;
- break;
-
- case recordTypes.WebSocketSendHandshakeRequest:
- case recordTypes.WebSocketReceiveHandshakeResponse:
- case recordTypes.WebSocketDestroy:
- var webSocketCreateRecord = presentationModel._webSocketCreateRecords[record.data["identifier"]];
- if (webSocketCreateRecord) { // False if we started instrumentation in the middle of request.
- this.webSocketURL = webSocketCreateRecord.webSocketURL;
- if (typeof webSocketCreateRecord.webSocketProtocol !== "undefined")
- this.webSocketProtocol = webSocketCreateRecord.webSocketProtocol;
- }
- break;
- }
-}
-
-WebInspector.TimelinePresentationModel.adoptRecord = function(newParent, record)
-{
- record.parent.children.splice(record.parent.children.indexOf(record));
- WebInspector.TimelinePresentationModel.insertRetrospectiveRecord(newParent, record);
- record.parent = newParent;
-}
-
-WebInspector.TimelinePresentationModel.insertRetrospectiveRecord = function(parent, record)
-{
- function compareStartTime(value, record)
- {
- return value < record.startTime ? -1 : 1;
- }
-
- parent.children.splice(insertionIndexForObjectInListSortedByFunction(record.startTime, parent.children, compareStartTime), 0, record);
-}
-
-WebInspector.TimelinePresentationModel.Record.prototype = {
- get lastChildEndTime()
- {
- return this._lastChildEndTime;
- },
-
- set lastChildEndTime(time)
- {
- this._lastChildEndTime = time;
- },
-
- get selfTime()
- {
- return this.coalesced ? this._lastChildEndTime - this.startTime : this._selfTime;
- },
-
- set selfTime(time)
- {
- this._selfTime = time;
- },
-
- get cpuTime()
- {
- return this._cpuTime;
- },
-
- /**
- * @return {boolean}
- */
- isRoot: function()
- {
- return this.type === WebInspector.TimelineModel.RecordType.Root;
- },
-
- /**
- * @return {!WebInspector.TimelinePresentationModel.Record}
- */
- origin: function()
- {
- return this._origin || this.parent;
- },
-
- /**
- * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
- */
- get children()
- {
- return this._children;
- },
-
- /**
- * @return {number}
- */
- get visibleChildrenCount()
- {
- return this._visibleChildrenCount || 0;
- },
-
- /**
- * @return {boolean}
- */
- get expandable()
- {
- return !!this._expandable;
- },
-
- /**
- * @return {!WebInspector.TimelineCategory}
- */
- get category()
- {
- return WebInspector.TimelinePresentationModel.recordStyle(this._record).category
- },
-
- /**
- * @return {string}
- */
- get title()
- {
- return this.type === WebInspector.TimelineModel.RecordType.TimeStamp ? this._record.data["message"] :
- WebInspector.TimelinePresentationModel.recordStyle(this._record).title;
- },
-
- /**
- * @return {number}
- */
- get startTime()
- {
- return WebInspector.TimelineModel.startTimeInSeconds(this._record);
- },
-
- /**
- * @return {number}
- */
- get endTime()
- {
- return WebInspector.TimelineModel.endTimeInSeconds(this._record);
- },
-
- /**
- * @return {boolean}
- */
- get isBackground()
- {
- return !!this._record.thread;
- },
-
- /**
- * @return {!Object}
- */
- get data()
- {
- return this._record.data;
- },
-
- /**
- * @return {string}
- */
- get type()
- {
- return this._record.type;
- },
-
- /**
- * @return {string}
- */
- get frameId()
- {
- return this._record.frameId;
- },
-
- /**
- * @return {number}
- */
- get usedHeapSizeDelta()
- {
- return this._record.usedHeapSizeDelta || 0;
- },
-
- /**
- * @return {number}
- */
- get usedHeapSize()
- {
- return this._record.usedHeapSize;
- },
-
- /**
- * @return {?Array.<!ConsoleAgent.CallFrame>}
- */
- get stackTrace()
- {
- if (this._record.stackTrace && this._record.stackTrace.length)
- return this._record.stackTrace;
- return null;
- },
-
- containsTime: function(time)
- {
- return this.startTime <= time && time <= this.endTime;
- },
-
- /**
- * @param {function(!DocumentFragment)} callback
- */
- generatePopupContent: function(callback)
- {
- var barrier = new CallbackBarrier();
- if (WebInspector.TimelinePresentationModel.needsPreviewElement(this.type) && !this._imagePreviewElement)
- WebInspector.DOMPresentationUtils.buildImagePreviewContents(this.url, false, barrier.createCallback(this._setImagePreviewElement.bind(this)));
- if (this._relatedBackendNodeId && !this._relatedNode)
- WebInspector.domAgent.pushNodeByBackendIdToFrontend(this._relatedBackendNodeId, barrier.createCallback(this._setRelatedNode.bind(this)));
-
- barrier.callWhenDone(callbackWrapper.bind(this));
-
- /**
- * @this {WebInspector.TimelinePresentationModel.Record}
- */
- function callbackWrapper()
- {
- callback(this._generatePopupContentSynchronously());
- }
- },
-
- /**
- * @param {string} key
- * @return {?Object}
- */
- getUserObject: function(key)
- {
- if (!this._userObjects)
- return null;
- return this._userObjects.get(key);
- },
-
- /**
- * @param {string} key
- * @param {!Object} value
- */
- setUserObject: function(key, value)
- {
- if (!this._userObjects)
- this._userObjects = new StringMap();
- this._userObjects.put(key, value);
- },
-
- /**
- * @param {!Element} element
- */
- _setImagePreviewElement: function(element)
- {
- this._imagePreviewElement = element;
- },
-
- /**
- * @param {?DOMAgent.NodeId} nodeId
- */
- _setRelatedNode: function(nodeId)
- {
- if (typeof nodeId === "number")
- this._relatedNode = WebInspector.domAgent.nodeForId(nodeId);
- },
-
- /**
- * @return {!DocumentFragment}
- */
- _generatePopupContentSynchronously: function()
- {
- var fragment = document.createDocumentFragment();
- var pie = WebInspector.TimelinePresentationModel.generatePieChart(this._aggregatedStats, this.category.name);
- // Insert self time.
- if (!this.coalesced && this._children.length) {
- pie.pieChart.addSlice(this._selfTime, this.category.fillColorStop1);
- var rowElement = document.createElement("div");
- pie.footerElement.insertBefore(rowElement, pie.footerElement.firstChild);
- rowElement.createChild("div", "timeline-aggregated-category timeline-" + this.category.name);
- rowElement.createTextChild(WebInspector.UIString("%s %s (Self)", Number.secondsToString(this._selfTime, true), this.category.title));
- }
- fragment.appendChild(pie.element);
-
- var contentHelper = new WebInspector.TimelineDetailsContentHelper(true);
-
- if (this.coalesced)
- return fragment;
-
- const recordTypes = WebInspector.TimelineModel.RecordType;
-
- // The messages may vary per record type;
- var callSiteStackTraceLabel;
- var callStackLabel;
- var relatedNodeLabel;
-
- switch (this.type) {
- case recordTypes.GCEvent:
- contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(this.data["usedHeapSizeDelta"]));
- break;
- case recordTypes.TimerFire:
- callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
- // Fall-through intended.
-
- case recordTypes.TimerInstall:
- case recordTypes.TimerRemove:
- contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), this.data["timerId"]);
- if (typeof this.timeout === "number") {
- contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.secondsToString(this.timeout / 1000));
- contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !this.singleShot);
- }
- break;
- case recordTypes.FireAnimationFrame:
- callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested");
- contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), this.data["id"]);
- break;
- case recordTypes.FunctionCall:
- if (this.scriptName)
- contentHelper.appendElementRow(WebInspector.UIString("Location"), this._linkifyLocation(this.scriptName, this.scriptLine, 0));
- break;
- case recordTypes.ScheduleResourceRequest:
- case recordTypes.ResourceSendRequest:
- case recordTypes.ResourceReceiveResponse:
- case recordTypes.ResourceReceivedData:
- case recordTypes.ResourceFinish:
- contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(this.url));
- if (this._imagePreviewElement)
- contentHelper.appendElementRow(WebInspector.UIString("Preview"), this._imagePreviewElement);
- if (this.data["requestMethod"])
- contentHelper.appendTextRow(WebInspector.UIString("Request Method"), this.data["requestMethod"]);
- if (typeof this.data["statusCode"] === "number")
- contentHelper.appendTextRow(WebInspector.UIString("Status Code"), this.data["statusCode"]);
- if (this.data["mimeType"])
- contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), this.data["mimeType"]);
- if (this.data["encodedDataLength"])
- contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", this.data["encodedDataLength"]));
- break;
- case recordTypes.EvaluateScript:
- if (this.data && this.url)
- contentHelper.appendElementRow(WebInspector.UIString("Script"), this._linkifyLocation(this.url, this.data["lineNumber"]));
- break;
- case recordTypes.Paint:
- var clip = this.data["clip"];
- if (clip) {
- contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1]));
- var clipWidth = WebInspector.TimelinePresentationModel.quadWidth(clip);
- var clipHeight = WebInspector.TimelinePresentationModel.quadHeight(clip);
- contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight));
- } else {
- // Backward compatibility: older version used x, y, width, height fields directly in data.
- if (typeof this.data["x"] !== "undefined" && typeof this.data["y"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", this.data["x"], this.data["y"]));
- if (typeof this.data["width"] !== "undefined" && typeof this.data["height"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d\u2009\u00d7\u2009%d", this.data["width"], this.data["height"]));
- }
- // Fall-through intended.
-
- case recordTypes.PaintSetup:
- case recordTypes.Rasterize:
- case recordTypes.ScrollLayer:
- relatedNodeLabel = WebInspector.UIString("Layer root");
- break;
- case recordTypes.AutosizeText:
- relatedNodeLabel = WebInspector.UIString("Root node");
- break;
- case recordTypes.DecodeImage:
- case recordTypes.ResizeImage:
- relatedNodeLabel = WebInspector.UIString("Image element");
- if (this.url)
- contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(this.url));
- break;
- case recordTypes.RecalculateStyles: // We don't want to see default details.
- if (this.data["elementCount"])
- contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), this.data["elementCount"]);
- callStackLabel = WebInspector.UIString("Styles recalculation forced");
- break;
- case recordTypes.Layout:
- if (this.data["dirtyObjects"])
- contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), this.data["dirtyObjects"]);
- if (this.data["totalObjects"])
- contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), this.data["totalObjects"]);
- if (typeof this.data["partialLayout"] === "boolean") {
- contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
- this.data["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document"));
- }
- callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
- callStackLabel = WebInspector.UIString("Layout forced");
- relatedNodeLabel = WebInspector.UIString("Layout root");
- break;
- case recordTypes.Time:
- case recordTypes.TimeEnd:
- contentHelper.appendTextRow(WebInspector.UIString("Message"), this.data["message"]);
- if (typeof this.intervalDuration === "number")
- contentHelper.appendTextRow(WebInspector.UIString("Interval Duration"), Number.secondsToString(this.intervalDuration, true));
- break;
- case recordTypes.WebSocketCreate:
- case recordTypes.WebSocketSendHandshakeRequest:
- case recordTypes.WebSocketReceiveHandshakeResponse:
- case recordTypes.WebSocketDestroy:
- if (typeof this.webSocketURL !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("URL"), this.webSocketURL);
- if (typeof this.webSocketProtocol !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), this.webSocketProtocol);
- if (typeof this.data["message"] !== "undefined")
- contentHelper.appendTextRow(WebInspector.UIString("Message"), this.data["message"]);
- break;
- default:
- if (this.detailsNode())
- contentHelper.appendElementRow(WebInspector.UIString("Details"), this.detailsNode().childNodes[1].cloneNode());
- break;
- }
-
- if (this._relatedNode)
- contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString("Related node"), this._createNodeAnchor(this._relatedNode));
-
- if (this.scriptName && this.type !== recordTypes.FunctionCall)
- contentHelper.appendElementRow(WebInspector.UIString("Function Call"), this._linkifyLocation(this.scriptName, this.scriptLine, 0));
-
- if (this.usedHeapSize) {
- if (this.usedHeapSizeDelta) {
- var sign = this.usedHeapSizeDelta > 0 ? "+" : "-";
- contentHelper.appendTextRow(WebInspector.UIString("Used Heap Size"),
- WebInspector.UIString("%s (%s%s)", Number.bytesToString(this.usedHeapSize), sign, Number.bytesToString(Math.abs(this.usedHeapSizeDelta))));
- } else if (this.category === WebInspector.TimelinePresentationModel.categories().scripting)
- contentHelper.appendTextRow(WebInspector.UIString("Used Heap Size"), Number.bytesToString(this.usedHeapSize));
- }
-
- if (this.callSiteStackTrace)
- contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.UIString("Call Site stack"), this.callSiteStackTrace, this._linkifyCallFrame.bind(this));
-
- if (this.stackTrace)
- contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("Call Stack"), this.stackTrace, this._linkifyCallFrame.bind(this));
-
- if (this._warnings) {
- var ul = document.createElement("ul");
- for (var i = 0; i < this._warnings.length; ++i)
- ul.createChild("li").textContent = this._warnings[i];
- contentHelper.appendElementRow(WebInspector.UIString("Warning"), ul);
- }
- fragment.appendChild(contentHelper.element);
- return fragment;
- },
-
- /**
- * @param {!WebInspector.DOMAgent} node
- */
- _createNodeAnchor: function(node)
- {
- var span = document.createElement("span");
- span.classList.add("node-link");
- span.addEventListener("click", onClick, false);
- WebInspector.DOMPresentationUtils.decorateNodeLabel(node, span);
- function onClick()
- {
- WebInspector.showPanel("elements").revealAndSelectNode(node.id);
- }
- return span;
- },
-
- _refreshDetails: function()
- {
- delete this._detailsNode;
- },
-
- /**
- * @return {?Node}
- */
- detailsNode: function()
- {
- if (typeof this._detailsNode === "undefined") {
- this._detailsNode = this._getRecordDetails();
-
- if (this._detailsNode && !this.coalesced) {
- this._detailsNode.insertBefore(document.createTextNode("("), this._detailsNode.firstChild);
- this._detailsNode.appendChild(document.createTextNode(")"));
- }
- }
- return this._detailsNode;
- },
-
- _createSpanWithText: function(textContent)
- {
- var node = document.createElement("span");
- node.textContent = textContent;
- return node;
- },
-
- /**
- * @return {?Node}
- */
- _getRecordDetails: function()
- {
- var details;
- if (this.coalesced)
- return this._createSpanWithText(WebInspector.UIString("× %d", this.children.length));
-
- switch (this.type) {
- case WebInspector.TimelineModel.RecordType.GCEvent:
- details = WebInspector.UIString("%s collected", Number.bytesToString(this.data["usedHeapSizeDelta"]));
- break;
- case WebInspector.TimelineModel.RecordType.TimerFire:
- details = this._linkifyScriptLocation(this.data["timerId"]);
- break;
- case WebInspector.TimelineModel.RecordType.FunctionCall:
- if (this.scriptName)
- details = this._linkifyLocation(this.scriptName, this.scriptLine, 0);
- break;
- case WebInspector.TimelineModel.RecordType.FireAnimationFrame:
- details = this._linkifyScriptLocation(this.data["id"]);
- break;
- case WebInspector.TimelineModel.RecordType.EventDispatch:
- details = this.data ? this.data["type"] : null;
- break;
- case WebInspector.TimelineModel.RecordType.Paint:
- var width = this.data.clip ? WebInspector.TimelinePresentationModel.quadWidth(this.data.clip) : this.data.width;
- var height = this.data.clip ? WebInspector.TimelinePresentationModel.quadHeight(this.data.clip) : this.data.height;
- if (width && height)
- details = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
- break;
- case WebInspector.TimelineModel.RecordType.TimerInstall:
- case WebInspector.TimelineModel.RecordType.TimerRemove:
- details = this._linkifyTopCallFrame(this.data["timerId"]);
- break;
- case WebInspector.TimelineModel.RecordType.RequestAnimationFrame:
- case WebInspector.TimelineModel.RecordType.CancelAnimationFrame:
- details = this._linkifyTopCallFrame(this.data["id"]);
- break;
- case WebInspector.TimelineModel.RecordType.ParseHTML:
- case WebInspector.TimelineModel.RecordType.RecalculateStyles:
- details = this._linkifyTopCallFrame();
- break;
- case WebInspector.TimelineModel.RecordType.EvaluateScript:
- details = this.url ? this._linkifyLocation(this.url, this.data["lineNumber"], 0) : null;
- break;
- case WebInspector.TimelineModel.RecordType.XHRReadyStateChange:
- case WebInspector.TimelineModel.RecordType.XHRLoad:
- case WebInspector.TimelineModel.RecordType.ScheduleResourceRequest:
- case WebInspector.TimelineModel.RecordType.ResourceSendRequest:
- case WebInspector.TimelineModel.RecordType.ResourceReceivedData:
- case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse:
- case WebInspector.TimelineModel.RecordType.ResourceFinish:
- case WebInspector.TimelineModel.RecordType.DecodeImage:
- case WebInspector.TimelineModel.RecordType.ResizeImage:
- details = WebInspector.displayNameForURL(this.url);
- break;
- case WebInspector.TimelineModel.RecordType.Time:
- case WebInspector.TimelineModel.RecordType.TimeEnd:
- details = this.data["message"];
- break;
- default:
- details = this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : (this._linkifyTopCallFrame() || null);
- break;
- }
-
- if (details) {
- if (details instanceof Node)
- details.tabIndex = -1;
- else
- return this._createSpanWithText("" + details);
- }
-
- return details || null;
- },
-
- /**
- * @param {string} url
- * @param {number} lineNumber
- * @param {number=} columnNumber
- */
- _linkifyLocation: function(url, lineNumber, columnNumber)
- {
- // FIXME(62725): stack trace line/column numbers are one-based.
- columnNumber = columnNumber ? columnNumber - 1 : 0;
- return this._linkifier.linkifyLocation(url, lineNumber - 1, columnNumber, "timeline-details");
- },
-
- /**
- * @param {!ConsoleAgent.CallFrame} callFrame
- */
- _linkifyCallFrame: function(callFrame)
- {
- return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
- },
-
- /**
- * @param {string=} defaultValue
- */
- _linkifyTopCallFrame: function(defaultValue)
- {
- if (this.stackTrace)
- return this._linkifyCallFrame(this.stackTrace[0]);
- if (this.callSiteStackTrace)
- return this._linkifyCallFrame(this.callSiteStackTrace[0]);
- return defaultValue;
- },
-
- /**
- * @param {*} defaultValue
- * @return {!Element|string}
- */
- _linkifyScriptLocation: function(defaultValue)
- {
- return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : "" + defaultValue;
- },
-
- calculateAggregatedStats: function()
- {
- this._aggregatedStats = {};
- this._cpuTime = this._selfTime;
-
- for (var index = this._children.length; index; --index) {
- var child = this._children[index - 1];
- for (var category in child._aggregatedStats)
- this._aggregatedStats[category] = (this._aggregatedStats[category] || 0) + child._aggregatedStats[category];
- }
- for (var category in this._aggregatedStats)
- this._cpuTime += this._aggregatedStats[category];
- this._aggregatedStats[this.category.name] = (this._aggregatedStats[this.category.name] || 0) + this._selfTime;
- },
-
- get aggregatedStats()
- {
- return this._aggregatedStats;
- },
-
- /**
- * @param {string} message
- */
- addWarning: function(message)
- {
- if (this._warnings)
- this._warnings.push(message);
- else
- this._warnings = [message];
- for (var parent = this.parent; parent && !parent._childHasWarnings; parent = parent.parent)
- parent._childHasWarnings = true;
- },
-
- /**
- * @return {boolean}
- */
- hasWarnings: function()
- {
- return !!this._warnings;
- },
-
- /**
- * @return {boolean}
- */
- childHasWarnings: function()
- {
- return this._childHasWarnings;
- }
-}
-
-/**
- * @param {!Object} aggregatedStats
- */
-WebInspector.TimelinePresentationModel._generateAggregatedInfo = function(aggregatedStats)
-{
- var cell = document.createElement("span");
- cell.className = "timeline-aggregated-info";
- for (var index in aggregatedStats) {
- var label = document.createElement("div");
- label.className = "timeline-aggregated-category timeline-" + index;
- cell.appendChild(label);
- var text = document.createElement("span");
- text.textContent = Number.secondsToString(aggregatedStats[index], true);
- cell.appendChild(text);
- }
- return cell;
-}
-
-/**
- * @param {!Object} aggregatedStats
- * @param {string=} firstCategoryName
- * @return {{pieChart: !WebInspector.PieChart, element: !Element, footerElement: !Element}}
- */
-WebInspector.TimelinePresentationModel.generatePieChart = function(aggregatedStats, firstCategoryName)
-{
- var element = document.createElement("div");
- element.className = "timeline-aggregated-info";
-
- var total = 0;
- var categoryNames = [];
- if (firstCategoryName)
- categoryNames.push(firstCategoryName);
- for (var categoryName in WebInspector.TimelinePresentationModel.categories()) {
- if (aggregatedStats[categoryName]) {
- total += aggregatedStats[categoryName];
- if (firstCategoryName !== categoryName)
- categoryNames.push(categoryName);
- }
- }
-
- var pieChart = new WebInspector.PieChart(total);
- element.appendChild(pieChart.element);
- var footerElement = element.createChild("div", "timeline-aggregated-info-legend");
-
- for (var i = 0; i < categoryNames.length; ++i) {
- var category = WebInspector.TimelinePresentationModel.categories()[categoryNames[i]];
- pieChart.addSlice(aggregatedStats[category.name], category.fillColorStop0);
- var rowElement = footerElement.createChild("div");
- rowElement.createChild("div", "timeline-aggregated-category timeline-" + category.name);
- rowElement.createTextChild(WebInspector.UIString("%s %s", Number.secondsToString(aggregatedStats[category.name], true), category.title));
- }
- return { pieChart: pieChart, element: element, footerElement: footerElement };
-}
-
-WebInspector.TimelinePresentationModel.generatePopupContentForFrame = function(frame)
-{
- var contentHelper = new WebInspector.TimelinePopupContentHelper(WebInspector.UIString("Frame"));
- var durationInSeconds = frame.endTime - frame.startTime;
- var durationText = WebInspector.UIString("%s (at %s)", Number.secondsToString(frame.endTime - frame.startTime, true),
- Number.secondsToString(frame.startTimeOffset, true));
- contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
- contentHelper.appendTextRow(WebInspector.UIString("FPS"), Math.floor(1 / durationInSeconds));
- contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.secondsToString(frame.cpuTime, true));
- contentHelper.appendTextRow(WebInspector.UIString("Thread"), frame.isBackground ? WebInspector.UIString("background") : WebInspector.UIString("main"));
- contentHelper.appendElementRow(WebInspector.UIString("Aggregated Time"),
- WebInspector.TimelinePresentationModel._generateAggregatedInfo(frame.timeByCategory));
- return contentHelper.contentTable();
-}
-
-/**
- * @param {!WebInspector.FrameStatistics} statistics
- */
-WebInspector.TimelinePresentationModel.generatePopupContentForFrameStatistics = function(statistics)
-{
- /**
- * @param {number} time
- */
- function formatTimeAndFPS(time)
- {
- return WebInspector.UIString("%s (%.0f FPS)", Number.secondsToString(time, true), 1 / time);
- }
-
- var contentHelper = new WebInspector.TimelineDetailsContentHelper(false);
- contentHelper.appendTextRow(WebInspector.UIString("Minimum Time"), formatTimeAndFPS(statistics.minDuration));
- contentHelper.appendTextRow(WebInspector.UIString("Average Time"), formatTimeAndFPS(statistics.average));
- contentHelper.appendTextRow(WebInspector.UIString("Maximum Time"), formatTimeAndFPS(statistics.maxDuration));
- contentHelper.appendTextRow(WebInspector.UIString("Standard Deviation"), Number.secondsToString(statistics.stddev, true));
-
- return contentHelper.element;
-}
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {number} width
- * @param {number} height
- * @param {string} color0
- * @param {string} color1
- * @param {string} color2
- */
-WebInspector.TimelinePresentationModel.createFillStyle = function(context, width, height, color0, color1, color2)
-{
- var gradient = context.createLinearGradient(0, 0, width, height);
- gradient.addColorStop(0, color0);
- gradient.addColorStop(0.25, color1);
- gradient.addColorStop(0.75, color1);
- gradient.addColorStop(1, color2);
- return gradient;
-}
-
-/**
- * @param {!CanvasRenderingContext2D} context
- * @param {number} width
- * @param {number} height
- * @param {!WebInspector.TimelineCategory} category
- */
-WebInspector.TimelinePresentationModel.createFillStyleForCategory = function(context, width, height, category)
-{
- return WebInspector.TimelinePresentationModel.createFillStyle(context, width, height, category.fillColorStop0, category.fillColorStop1, category.borderColor);
-}
-
-/**
- * @param {!WebInspector.TimelineCategory} category
- */
-WebInspector.TimelinePresentationModel.createStyleRuleForCategory = function(category)
-{
- var selector = ".timeline-category-" + category.name + " .timeline-graph-bar, " +
- ".panel.timeline .timeline-filters-header .filter-checkbox-filter.filter-checkbox-filter-" + category.name + " .checkbox-filter-checkbox, " +
- ".popover .timeline-" + category.name + ", " +
- ".timeline-details-view .timeline-" + category.name + ", " +
- ".timeline-category-" + category.name + " .timeline-tree-icon"
-
- return selector + " { background-image: -webkit-linear-gradient(" +
- category.fillColorStop0 + ", " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + ");" +
- " border-color: " + category.borderColor +
- "}";
-}
-
-
-/**
- * @param {!Object} rawRecord
- * @return {?string}
- */
-WebInspector.TimelinePresentationModel.coalescingKeyForRecord = function(rawRecord)
-{
- var recordTypes = WebInspector.TimelineModel.RecordType;
- switch (rawRecord.type)
- {
- case recordTypes.EventDispatch: return rawRecord.data["type"];
- case recordTypes.Time: return rawRecord.data["message"];
- case recordTypes.TimeStamp: return rawRecord.data["message"];
- default: return null;
- }
-}
-
-/**
- * @param {!Array.<number>} quad
- * @return {number}
- */
-WebInspector.TimelinePresentationModel.quadWidth = function(quad)
-{
- return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1] - quad[3], 2)));
-}
-
-/**
- * @param {!Array.<number>} quad
- * @return {number}
- */
-WebInspector.TimelinePresentationModel.quadHeight = function(quad)
-{
- return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1] - quad[7], 2)));
-}
-
-/**
- * @param {!Object} data
- * @return {?Array.<number>}
- */
-WebInspector.TimelinePresentationModel.quadFromRectData = function(data)
-{
- if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined")
- return null;
- var x0 = data["x"];
- var x1 = data["x"] + data["width"];
- var y0 = data["y"];
- var y1 = data["y"] + data["height"];
- return [x0, y0, x1, y0, x1, y1, x0, y1];
-}
-
-/**
- * @interface
- */
-WebInspector.TimelinePresentationModel.Filter = function()
-{
-}
-
-WebInspector.TimelinePresentationModel.Filter.prototype = {
- /**
- * @param {!WebInspector.TimelinePresentationModel.Record} record
- * @return {boolean}
- */
- accept: function(record) { return false; }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- * @param {string} name
- * @param {string} title
- * @param {number} overviewStripGroupIndex
- * @param {string} borderColor
- * @param {string} fillColorStop0
- * @param {string} fillColorStop1
- */
-WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, borderColor, fillColorStop0, fillColorStop1)
-{
- this.name = name;
- this.title = title;
- this.overviewStripGroupIndex = overviewStripGroupIndex;
- this.borderColor = borderColor;
- this.fillColorStop0 = fillColorStop0;
- this.fillColorStop1 = fillColorStop1;
- this.hidden = false;
-}
-
-WebInspector.TimelineCategory.Events = {
- VisibilityChanged: "VisibilityChanged"
-};
-
-WebInspector.TimelineCategory.prototype = {
- /**
- * @return {boolean}
- */
- get hidden()
- {
- return this._hidden;
- },
-
- set hidden(hidden)
- {
- this._hidden = hidden;
- this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged, this);
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @param {string} title
- */
-WebInspector.TimelinePopupContentHelper = function(title)
-{
- this._contentTable = document.createElement("table");
- var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title");
- titleCell.colSpan = 2;
- var titleRow = document.createElement("tr");
- titleRow.appendChild(titleCell);
- this._contentTable.appendChild(titleRow);
-}
-
-WebInspector.TimelinePopupContentHelper.prototype = {
- contentTable: function()
- {
- return this._contentTable;
- },
-
- /**
- * @param {string=} styleName
- */
- _createCell: function(content, styleName)
- {
- var text = document.createElement("label");
- text.appendChild(document.createTextNode(content));
- var cell = document.createElement("td");
- cell.className = "timeline-details";
- if (styleName)
- cell.className += " " + styleName;
- cell.textContent = content;
- return cell;
- },
-
- /**
- * @param {string} title
- * @param {string|number|boolean} content
- */
- appendTextRow: function(title, content)
- {
- var row = document.createElement("tr");
- row.appendChild(this._createCell(title, "timeline-details-row-title"));
- row.appendChild(this._createCell(content, "timeline-details-row-data"));
- this._contentTable.appendChild(row);
- },
-
- /**
- * @param {string} title
- * @param {!Element|string} content
- */
- appendElementRow: function(title, content)
- {
- var row = document.createElement("tr");
- var titleCell = this._createCell(title, "timeline-details-row-title");
- row.appendChild(titleCell);
- var cell = document.createElement("td");
- cell.className = "details";
- if (content instanceof Node)
- cell.appendChild(content);
- else
- cell.createTextChild(content || "");
- row.appendChild(cell);
- this._contentTable.appendChild(row);
- }
-}
-
-/**
- * @constructor
- * @param {boolean} monospaceValues
- */
-WebInspector.TimelineDetailsContentHelper = function(monospaceValues)
-{
- this.element = document.createElement("div");
- this.element.className = "timeline-details-view-block";
- this._monospaceValues = monospaceValues;
-}
-
-WebInspector.TimelineDetailsContentHelper.prototype = {
- /**
- * @param {string} title
- * @param {string|number|boolean} value
- */
- appendTextRow: function(title, value)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- rowElement.createChild("span", "timeline-details-view-row-value" + (this._monospaceValues ? " monospace" : "")).textContent = value;
- },
-
- /**
- * @param {string} title
- * @param {!Element|string} content
- */
- appendElementRow: function(title, content)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- var valueElement = rowElement.createChild("span", "timeline-details-view-row-details" + (this._monospaceValues ? " monospace" : ""));
- if (content instanceof Node)
- valueElement.appendChild(content);
- else
- valueElement.createTextChild(content || "");
- },
-
- /**
- * @param {string} title
- * @param {!Array.<!ConsoleAgent.CallFrame>} stackTrace
- * @param {function(!ConsoleAgent.CallFrame)} callFrameLinkifier
- */
- appendStackTrace: function(title, stackTrace, callFrameLinkifier)
- {
- var rowElement = this.element.createChild("div", "timeline-details-view-row");
- rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
- var stackTraceElement = rowElement.createChild("div", "timeline-details-view-row-stack-trace monospace");
-
- for (var i = 0; i < stackTrace.length; ++i) {
- var stackFrame = stackTrace[i];
- var row = stackTraceElement.createChild("div");
- row.createTextChild(stackFrame.functionName || WebInspector.UIString("(anonymous function)"));
- row.createTextChild(" @ ");
- var urlElement = callFrameLinkifier(stackFrame);
- row.appendChild(urlElement);
- }
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TracingAgent.js b/chromium/third_party/WebKit/Source/devtools/front_end/TracingAgent.js
deleted file mode 100644
index 989b674d499..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TracingAgent.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- */
-WebInspector.TracingAgent = function()
-{
- this._active = false;
- InspectorBackend.registerTracingDispatcher(new WebInspector.TracingDispatcher(this));
-}
-
-WebInspector.TracingAgent.prototype = {
- /**
- * @param {string} categoryPatterns
- * @param {string} options
- * @param {function(?string)=} callback
- */
- start: function(categoryPatterns, options, callback)
- {
- TracingAgent.start(categoryPatterns, options, callback);
- this._active = true;
- this._events = [];
- },
-
- /**
- * @param {function()} callback
- */
- stop: function(callback)
- {
- if (!this._active) {
- callback();
- return;
- }
- this._pendingStopCallback = callback;
- TracingAgent.end();
- },
-
- /**
- * @return {!Array.<{cat: string, args: !Object, ph: string, ts: number}>}
- */
- events: function()
- {
- return this._events;
- },
-
- _eventsCollected: function(events)
- {
- Array.prototype.push.apply(this._events, events);
- },
-
- _tracingComplete: function()
- {
- this._active = false;
- if (this._pendingStopCallback) {
- this._pendingStopCallback();
- this._pendingStopCallback = null;
- }
- }
-}
-
-/**
- * @constructor
- * @implements {TracingAgent.Dispatcher}
- * @param {!WebInspector.TracingAgent} tracingAgent
- */
-WebInspector.TracingDispatcher = function(tracingAgent)
-{
- this._tracingAgent = tracingAgent;
-}
-
-WebInspector.TracingDispatcher.prototype = {
- dataCollected: function(data)
- {
- this._tracingAgent._eventsCollected(data);
- },
-
- tracingComplete: function()
- {
- this._tracingAgent._tracingComplete();
- }
-}
-
-/**
- * @type {!WebInspector.TracingAgent}
- */
-WebInspector.tracingAgent;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ViewportControl.js b/chromium/third_party/WebKit/Source/devtools/front_end/ViewportControl.js
deleted file mode 100644
index 960feeb0dfd..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ViewportControl.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @param {!WebInspector.ViewportControl.Provider} provider
- */
-WebInspector.ViewportControl = function(provider)
-{
- this.element = document.createElement("div");
- this.element.className = "fill";
- this.element.style.overflow = "auto";
- this._topGapElement = this.element.createChild("div");
- this._contentElement = this.element.createChild("div");
- this._bottomGapElement = this.element.createChild("div");
-
- this._provider = provider;
- this.element.addEventListener("scroll", this._onScroll.bind(this), false);
- this._firstVisibleIndex = 0;
- this._lastVisibleIndex = -1;
-}
-
-/**
- * @interface
- */
-WebInspector.ViewportControl.Provider = function()
-{
-}
-
-WebInspector.ViewportControl.Provider.prototype = {
- /**
- * @return {number}
- */
- itemCount: function() { return 0; },
-
- /**
- * @param {number} index
- * @return {?Element}
- */
- itemElement: function(index) { return null; }
-}
-
-WebInspector.ViewportControl.prototype = {
- /**
- * @return {!Element}
- */
- contentElement: function()
- {
- return this._contentElement;
- },
-
- refresh: function()
- {
- if (!this.element.clientHeight)
- return; // Do nothing for invisible controls.
-
- // Secure scroller.
- this._contentElement.style.setProperty("height", "100000px");
- this._contentElement.removeChildren();
- var itemCount = this._provider.itemCount();
- if (!itemCount) {
- this._firstVisibleIndex = -1;
- this._lastVisibleIndex = -1;
- return;
- }
-
- if (!this._rowHeight) {
- var firstElement = this._provider.itemElement(0);
- this._rowHeight = firstElement.measurePreferredSize(this._contentElement).height;
- }
-
- var visibleFrom = this.element.scrollTop;
- var visibleTo = visibleFrom + this.element.clientHeight;
-
- this._firstVisibleIndex = Math.floor(visibleFrom / this._rowHeight);
- this._lastVisibleIndex = Math.min(Math.ceil(visibleTo / this._rowHeight), itemCount) - 1;
-
- this._topGapElement.style.height = (this._rowHeight * this._firstVisibleIndex) + "px";
- this._bottomGapElement.style.height = (this._rowHeight * (itemCount - this._lastVisibleIndex - 1)) + "px";
-
- for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i)
- this._contentElement.appendChild(this._provider.itemElement(i));
- // Release scroller protection.
- this._contentElement.style.removeProperty("height");
- },
-
- /**
- * @param {?Event} event
- */
- _onScroll: function(event)
- {
- this.refresh();
- },
-
- /**
- * @return {number}
- */
- rowsPerViewport: function()
- {
- return Math.floor(this.element.clientHeight / this._rowHeight);
- },
-
- /**
- * @return {number}
- */
- firstVisibleIndex: function()
- {
- return this._firstVisibleIndex;
- },
-
- /**
- * @return {number}
- */
- lastVisibleIndex: function()
- {
- return this._lastVisibleIndex;
- },
-
- /**
- * @return {?Element}
- */
- renderedElementAt: function(index)
- {
- if (index < this._firstVisibleIndex)
- return null;
- if (index > this._lastVisibleIndex)
- return null;
- return this._contentElement.childNodes[index - this._firstVisibleIndex];
- },
-
- /**
- * @param {number} index
- * @param {boolean=} makeLast
- */
- scrollItemIntoView: function(index, makeLast)
- {
- if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
- return;
-
- if (makeLast)
- this.element.scrollTop = this._rowHeight * (index + 1) - this.element.clientHeight;
- else
- this.element.scrollTop = this._rowHeight * index;
- }
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/WorkerManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/WorkerManager.js
deleted file mode 100644
index baaf0f9f1a9..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/WorkerManager.js
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.WorkerManager = function()
-{
- this._workerIdToWindow = {};
- InspectorBackend.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));
-}
-
-WebInspector.WorkerManager.isWorkerFrontend = function()
-{
- return !!WebInspector.queryParamsObject["dedicatedWorkerId"] ||
- !!WebInspector.queryParamsObject["isSharedWorker"];
-}
-
-WebInspector.WorkerManager.isDedicatedWorkerFrontend = function()
-{
- return !!WebInspector.queryParamsObject["dedicatedWorkerId"];
-}
-
-WebInspector.WorkerManager.loaded = function()
-{
- var workerId = WebInspector.queryParamsObject["dedicatedWorkerId"];
- if (workerId)
- WebInspector.WorkerManager._initializeDedicatedWorkerFrontend(workerId);
- else
- WebInspector.workerManager = new WebInspector.WorkerManager();
-}
-
-WebInspector.WorkerManager.loadCompleted = function()
-{
- // Make sure script execution of dedicated worker is resumed and then paused
- // on the first script statement in case we autoattached to it.
- if (WebInspector.queryParamsObject["workerPaused"]) {
- DebuggerAgent.pause();
- RuntimeAgent.run(calculateTitle);
- } else if (WebInspector.WorkerManager.isWorkerFrontend())
- calculateTitle();
-
- function calculateTitle()
- {
- WebInspector.WorkerManager._calculateWorkerInspectorTitle();
- }
-
- if (WebInspector.workerManager)
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, WebInspector.workerManager._mainFrameNavigated, WebInspector.workerManager);
-}
-
-WebInspector.WorkerManager._initializeDedicatedWorkerFrontend = function(workerId)
-{
- function receiveMessage(event)
- {
- var message = event.data;
- InspectorBackend.dispatch(message);
- }
- window.addEventListener("message", receiveMessage, true);
-
-
- InspectorBackend.sendMessageObjectToBackend = function(message)
- {
- window.opener.postMessage({workerId: workerId, command: "sendMessageToBackend", message: message}, "*");
- }
-}
-
-WebInspector.WorkerManager._calculateWorkerInspectorTitle = function()
-{
- var expression = "location.href";
- if (WebInspector.queryParamsObject["isSharedWorker"])
- expression += " + (this.name ? ' (' + this.name + ')' : '')";
- RuntimeAgent.evaluate.invoke({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback.bind(this));
-
- /**
- * @param {?Protocol.Error} error
- * @param {!RuntimeAgent.RemoteObject} result
- * @param {boolean=} wasThrown
- */
- function evalCallback(error, result, wasThrown)
- {
- if (error || wasThrown) {
- console.error(error);
- return;
- }
- InspectorFrontendHost.inspectedURLChanged(result.value);
- }
-}
-
-WebInspector.WorkerManager.Events = {
- WorkerAdded: "worker-added",
- WorkerRemoved: "worker-removed",
- WorkersCleared: "workers-cleared",
-}
-
-WebInspector.WorkerManager.prototype = {
- _workerCreated: function(workerId, url, inspectorConnected)
- {
- if (inspectorConnected)
- this._openInspectorWindow(workerId, true);
- this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});
- },
-
- _workerTerminated: function(workerId)
- {
- this.closeWorkerInspector(workerId);
- this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);
- },
-
- _sendMessageToWorkerInspector: function(workerId, message)
- {
- var workerInspectorWindow = this._workerIdToWindow[workerId];
- if (workerInspectorWindow)
- workerInspectorWindow.postMessage(message, "*");
- },
-
- openWorkerInspector: function(workerId)
- {
- var existingInspector = this._workerIdToWindow[workerId];
- if (existingInspector) {
- existingInspector.focus();
- return;
- }
-
- this._openInspectorWindow(workerId, false);
- WorkerAgent.connectToWorker(workerId);
- },
-
- _openInspectorWindow: function(workerId, workerIsPaused)
- {
- var search = window.location.search;
- var hash = window.location.hash;
- var url = window.location.href;
- // Make sure hash is in rear
- url = url.replace(hash, "");
- url += (search ? "&dedicatedWorkerId=" : "?dedicatedWorkerId=") + workerId;
- if (workerIsPaused)
- url += "&workerPaused=true";
- url = url.replace("docked=true&", "");
- url = url.replace("can_dock=true&", "");
- url += hash;
- var width = WebInspector.settings.workerInspectorWidth.get();
- var height = WebInspector.settings.workerInspectorHeight.get();
- // Set location=0 just to make sure the front-end will be opened in a separate window, not in new tab.
- var workerInspectorWindow = window.open(url, undefined, "location=0,width=" + width + ",height=" + height);
- workerInspectorWindow.addEventListener("resize", this._onWorkerInspectorResize.bind(this, workerInspectorWindow), false);
- this._workerIdToWindow[workerId] = workerInspectorWindow;
- workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);
-
- // Listen to beforeunload in detached state and to the InspectorClosing event in case of attached inspector.
- window.addEventListener("unload", this._pageInspectorClosing.bind(this), true);
- },
-
- closeWorkerInspector: function(workerId)
- {
- var workerInspectorWindow = this._workerIdToWindow[workerId];
- if (workerInspectorWindow)
- workerInspectorWindow.close();
- },
-
- _mainFrameNavigated: function(event)
- {
- for (var workerId in this._workerIdToWindow)
- this.closeWorkerInspector(workerId);
- this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);
- },
-
- _pageInspectorClosing: function()
- {
- this._ignoreWorkerInspectorClosing = true;
- for (var workerId in this._workerIdToWindow) {
- this._workerIdToWindow[workerId].close();
- WorkerAgent.disconnectFromWorker(parseInt(workerId, 10));
- }
- },
-
- _onWorkerInspectorResize: function(workerInspectorWindow)
- {
- var doc = workerInspectorWindow.document;
- WebInspector.settings.workerInspectorWidth.set(doc.width);
- WebInspector.settings.workerInspectorHeight.set(doc.height);
- },
-
- _workerInspectorClosing: function(workerId, event)
- {
- if (event.target.location.href === "about:blank")
- return;
- if (this._ignoreWorkerInspectorClosing)
- return;
- delete this._workerIdToWindow[workerId];
- WorkerAgent.disconnectFromWorker(workerId);
- },
-
- _disconnectedFromWorker: function()
- {
- var screen = new WebInspector.WorkerTerminatedScreen();
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, screen.hide, screen);
- screen.showModal();
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @implements {WorkerAgent.Dispatcher}
- */
-WebInspector.WorkerDispatcher = function(workerManager)
-{
- this._workerManager = workerManager;
- window.addEventListener("message", this._receiveMessage.bind(this), true);
-}
-
-WebInspector.WorkerDispatcher.prototype = {
- _receiveMessage: function(event)
- {
- var workerId = event.data["workerId"];
- workerId = parseInt(workerId, 10);
- var command = event.data.command;
- var message = event.data.message;
-
- if (command == "sendMessageToBackend")
- WorkerAgent.sendMessageToWorker(workerId, message);
- },
-
- workerCreated: function(workerId, url, inspectorConnected)
- {
- this._workerManager._workerCreated(workerId, url, inspectorConnected);
- },
-
- workerTerminated: function(workerId)
- {
- this._workerManager._workerTerminated(workerId);
- },
-
- dispatchMessageFromWorker: function(workerId, message)
- {
- this._workerManager._sendMessageToWorkerInspector(workerId, message);
- },
-
- disconnectedFromWorker: function()
- {
- this._workerManager._disconnectedFromWorker();
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.HelpScreen}
- */
-WebInspector.WorkerTerminatedScreen = function()
-{
- WebInspector.HelpScreen.call(this, WebInspector.UIString("Inspected worker terminated"));
- var p = this.contentElement.createChild("p");
- p.classList.add("help-section");
- p.textContent = WebInspector.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
-}
-
-WebInspector.WorkerTerminatedScreen.prototype = {
- /**
- * @override
- */
- willHide: function()
- {
- WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
- WebInspector.HelpScreen.prototype.willHide.call(this);
- },
-
- __proto__: WebInspector.HelpScreen.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditCategories.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategories.js
index ffd3f634209..848a455ace8 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditCategories.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategories.js
@@ -30,13 +30,13 @@
/**
* @constructor
- * @extends {WebInspector.AuditCategory}
+ * @extends {WebInspector.AuditCategoryImpl}
*/
WebInspector.AuditCategories.PagePerformance = function() {
- WebInspector.AuditCategory.call(this, WebInspector.AuditCategories.PagePerformance.AuditCategoryName);
+ WebInspector.AuditCategoryImpl.call(this, WebInspector.AuditCategories.PagePerformance.AuditCategoryName);
}
-WebInspector.AuditCategories.PagePerformance.AuditCategoryName = "Web Page Performance";
+WebInspector.AuditCategories.PagePerformance.AuditCategoryName = WebInspector.UIString("Web Page Performance");
WebInspector.AuditCategories.PagePerformance.prototype = {
initialize: function()
@@ -47,18 +47,18 @@ WebInspector.AuditCategories.PagePerformance.prototype = {
this.addRule(new WebInspector.AuditRules.VendorPrefixedCSSProperties(), WebInspector.AuditRule.Severity.Warning);
},
- __proto__: WebInspector.AuditCategory.prototype
+ __proto__: WebInspector.AuditCategoryImpl.prototype
}
/**
* @constructor
- * @extends {WebInspector.AuditCategory}
+ * @extends {WebInspector.AuditCategoryImpl}
*/
WebInspector.AuditCategories.NetworkUtilization = function() {
- WebInspector.AuditCategory.call(this, WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);
+ WebInspector.AuditCategoryImpl.call(this, WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName);
}
-WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName = "Network Utilization";
+WebInspector.AuditCategories.NetworkUtilization.AuditCategoryName = WebInspector.UIString("Network Utilization");
WebInspector.AuditCategories.NetworkUtilization.prototype = {
initialize: function()
@@ -75,5 +75,5 @@ WebInspector.AuditCategories.NetworkUtilization.prototype = {
this.addRule(new WebInspector.AuditRules.ProxyCacheControlRule(), WebInspector.AuditRule.Severity.Warning);
},
- __proto__: WebInspector.AuditCategory.prototype
+ __proto__: WebInspector.AuditCategoryImpl.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LayersPanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategory.js
index 95ad832993c..f6a0ab13df4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LayersPanelDescriptor.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditCategory.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -27,14 +27,35 @@
*/
/**
- * @constructor
- * @extends {WebInspector.PanelDescriptor}
+ * @interface
*/
-WebInspector.LayersPanelDescriptor = function()
+WebInspector.AuditCategory = function()
{
- WebInspector.PanelDescriptor.call(this, "layers", WebInspector.UIString("Layers"), "LayersPanel", "LayersPanel.js");
}
-WebInspector.LayersPanelDescriptor.prototype = {
- __proto__: WebInspector.PanelDescriptor.prototype
+WebInspector.AuditCategory.prototype = {
+ /**
+ * @return {string}
+ */
+ get id()
+ {
+ },
+
+ /**
+ * @return {string}
+ */
+ get displayName()
+ {
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ * @param {!Array.<!WebInspector.NetworkRequest>} requests
+ * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
+ * @param {function()} categoryDoneCallback
+ * @param {!WebInspector.Progress} progress
+ */
+ run: function(target, requests, ruleResultCallback, categoryDoneCallback, progress)
+ {
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditController.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditController.js
index 5e8c3d9d12f..95c6c6a2742 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditController.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditController.js
@@ -31,12 +31,15 @@
/**
* @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.AuditsPanel} auditsPanel
*/
-WebInspector.AuditController = function(auditsPanel)
+WebInspector.AuditController = function(target, auditsPanel)
{
+ WebInspector.TargetAware.call(this, target);
this._auditsPanel = auditsPanel;
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._didMainResourceLoad, this);
+ this.target().resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._didMainResourceLoad, this);
}
WebInspector.AuditController.prototype = {
@@ -63,7 +66,7 @@ WebInspector.AuditController.prototype = {
}
var results = [];
- var mainResourceURL = WebInspector.inspectedPageURL;
+ var mainResourceURL = this.target().resourceTreeModel.inspectedPageURL();
var categoriesDone = 0;
/**
@@ -77,7 +80,7 @@ WebInspector.AuditController.prototype = {
resultCallback(mainResourceURL, results)
}
- var requests = WebInspector.networkLog.requests.slice();
+ var requests = this.target().networkLog.requests.slice();
var compositeProgress = new WebInspector.CompositeProgress(this._progress);
var subprogresses = [];
for (var i = 0; i < categories.length; ++i)
@@ -86,7 +89,7 @@ WebInspector.AuditController.prototype = {
var category = categories[i];
var result = new WebInspector.AuditCategoryResult(category);
results.push(result);
- category.run(requests, ruleResultReadyCallback.bind(this, result), categoryDoneCallback.bind(this), subprogresses[i]);
+ category.run(this.target(), requests, ruleResultReadyCallback.bind(this, result), categoryDoneCallback.bind(this), subprogresses[i]);
}
},
@@ -143,7 +146,7 @@ WebInspector.AuditController.prototype = {
_reloadResources: function(callback)
{
this._pageReloadCallback = callback;
- WebInspector.resourceTreeModel.reloadPage();
+ this.target().resourceTreeModel.reloadPage();
},
_didMainResourceLoad: function()
@@ -158,5 +161,7 @@ WebInspector.AuditController.prototype = {
clearResults: function()
{
this._auditsPanel.clearResults();
- }
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditFormatters.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditFormatters.js
index 5bea55f8912..e24ccce83c3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditFormatters.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditFormatters.js
@@ -36,11 +36,20 @@ WebInspector.AuditFormatters = function()
}
WebInspector.AuditFormatters.Registry = {
+
+ /**
+ * @param {string} text
+ * @return {!Text}
+ */
text: function(text)
{
return document.createTextNode(text);
},
+ /**
+ * @param {string} snippetText
+ * @return {!Element}
+ */
snippet: function(snippetText)
{
var div = document.createElement("div");
@@ -49,6 +58,9 @@ WebInspector.AuditFormatters.Registry = {
return div;
},
+ /**
+ * @return {!Element}
+ */
concat: function()
{
var parent = document.createElement("span");
@@ -57,6 +69,12 @@ WebInspector.AuditFormatters.Registry = {
return parent;
},
+ /**
+ * @param {string} url
+ * @param {string=} displayText
+ * @param {boolean=} allowExternalNavigation
+ * @return {!Element}
+ */
url: function(url, displayText, allowExternalNavigation)
{
var a = document.createElement("a");
@@ -68,6 +86,11 @@ WebInspector.AuditFormatters.Registry = {
return a;
},
+ /**
+ * @param {string} url
+ * @param {number=} line
+ * @return {!Element}
+ */
resourceLink: function(url, line)
{
// FIXME: use WebInspector.Linkifier
@@ -78,6 +101,7 @@ WebInspector.AuditFormatters.Registry = {
WebInspector.AuditFormatters.prototype = {
/**
* @param {string|boolean|number|!Object} value
+ * @return {!Node}
*/
apply: function(value)
{
@@ -114,6 +138,7 @@ WebInspector.AuditFormatters.prototype = {
* @param {!Object} formatters
* @param {?Object} thisArgument
* @param {string|boolean|number|!Object} value
+ * @return {*}
*/
partiallyApply: function(formatters, thisArgument, value)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditLauncherView.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditLauncherView.js
index 10eaac3eb9e..06e15b83f2a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditLauncherView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditLauncherView.js
@@ -31,11 +31,12 @@
/**
* @constructor
* @param {!WebInspector.AuditController} auditController
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.AuditLauncherView = function(auditController)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
+ this.setMinimumSize(100, 25);
this._auditController = auditController;
@@ -59,8 +60,10 @@ WebInspector.AuditLauncherView = function(auditController)
this._headerElement.textContent = WebInspector.UIString("No audits to run");
this._contentElement.appendChild(this._headerElement);
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
+ var target = this._auditController.target();
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
+ target.profilingLock.addEventListener(WebInspector.Lock.Events.StateChanged, this._updateButton, this);
var defaultSelectedAuditCategory = {};
defaultSelectedAuditCategory[WebInspector.AuditLauncherView.AllCategoriesKey] = true;
@@ -139,10 +142,14 @@ WebInspector.AuditLauncherView.prototype = {
this._auditRunning = auditRunning;
this._updateButton();
this._toggleUIComponents(this._auditRunning);
- if (this._auditRunning)
+ var target = this._auditController.target();
+ if (this._auditRunning) {
+ target.profilingLock.acquire();
this._startAudit();
- else
+ } else {
this._stopAudit();
+ target.profilingLock.release();
+ }
},
_startAudit: function()
@@ -319,9 +326,12 @@ WebInspector.AuditLauncherView.prototype = {
_updateButton: function()
{
+ var target = this._auditController.target();
+ var enable = this._auditRunning || (this._currentCategoriesCount && !target.profilingLock.isAcquired());
this._launchButton.textContent = this._auditRunning ? WebInspector.UIString("Stop") : WebInspector.UIString("Run");
- this._launchButton.disabled = !this._currentCategoriesCount;
+ this._launchButton.disabled = !enable;
+ this._launchButton.title = enable ? "" : WebInspector.UIString("Another profiler is already active");
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditResultView.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditResultView.js
index f3eeadb2fed..5f7f0fcd92f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditResultView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditResultView.js
@@ -36,7 +36,8 @@
WebInspector.AuditResultView = function(categoryResults)
{
WebInspector.SidebarPaneStack.call(this);
- this.element.classList.add("audit-result-view");
+ this.setMinimumSize(100, 25);
+ this.element.classList.add("audit-result-view", "fill");
function categorySorter(a, b) {
return (a.title || "").localeCompare(b.title || "");
@@ -77,14 +78,8 @@ WebInspector.AuditCategoryResultPane = function(categoryResult)
for (var i = 0; i < categoryResult.ruleResults.length; ++i) {
var ruleResult = categoryResult.ruleResults[i];
- var treeElement = this._appendResult(this._treeOutline, ruleResult);
+ var treeElement = this._appendResult(this._treeOutline, ruleResult, ruleResult.severity);
treeElement.listItemElement.classList.add("audit-result");
-
- if (ruleResult.severity) {
- var severityElement = document.createElement("div");
- severityElement.className = "severity-" + ruleResult.severity;
- treeElement.listItemElement.appendChild(severityElement);
- }
}
this.expand();
}
@@ -93,8 +88,9 @@ WebInspector.AuditCategoryResultPane.prototype = {
/**
* @param {(!TreeOutline|!TreeElement)} parentTreeElement
* @param {!WebInspector.AuditRuleResult} result
+ * @param {?WebInspector.AuditRule.Severity=} severity
*/
- _appendResult: function(parentTreeElement, result)
+ _appendResult: function(parentTreeElement, result, severity)
{
var title = "";
@@ -104,7 +100,15 @@ WebInspector.AuditCategoryResultPane.prototype = {
title = String.sprintf("%s (%d)", title, result.violationCount);
}
- var treeElement = new TreeElement(title, null, !!result.children);
+ var titleFragment = document.createDocumentFragment();
+ if (severity) {
+ var severityElement = document.createElement("div");
+ severityElement.className = "severity-" + severity;
+ titleFragment.appendChild(severityElement);
+ }
+ titleFragment.appendChild(document.createTextNode(title));
+
+ var treeElement = new TreeElement(titleFragment, null, !!result.children);
parentTreeElement.appendChild(treeElement);
if (result.className)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditRules.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditRules.js
index 99531217dce..aa61a24f2b6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditRules.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditRules.js
@@ -75,17 +75,18 @@ WebInspector.AuditRules.getDomainToResourcesMap = function(requests, types, need
*/
WebInspector.AuditRules.GzipRule = function()
{
- WebInspector.AuditRule.call(this, "network-gzip", "Enable gzip compression");
+ WebInspector.AuditRule.call(this, "network-gzip", WebInspector.UIString("Enable gzip compression"));
}
WebInspector.AuditRules.GzipRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var totalSavings = 0;
var compressedSize = 0;
@@ -108,12 +109,17 @@ WebInspector.AuditRules.GzipRule.prototype = {
result.violationCount++;
}
}
- if (!totalSavings)
- return callback(null);
- summary.value = String.sprintf("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings));
+ if (!totalSavings) {
+ callback(null);
+ return;
+ }
+ summary.value = WebInspector.UIString("Compressing the following resources with gzip could reduce their transfer size by about two thirds (~%s):", Number.bytesToString(totalSavings));
callback(result);
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ */
_isCompressed: function(request)
{
var encodingHeader = request.responseHeaderValue("Content-Encoding");
@@ -123,6 +129,9 @@ WebInspector.AuditRules.GzipRule.prototype = {
return /\b(?:gzip|deflate)\b/.test(encodingHeader);
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ */
_shouldCompress: function(request)
{
return request.type.isTextType() && request.parsedURL.host && request.resourceSize !== undefined && request.resourceSize > 150;
@@ -145,12 +154,13 @@ WebInspector.AuditRules.CombineExternalResourcesRule = function(id, name, type,
WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, [this._type], false);
var penalizedResourceCount = 0;
@@ -162,13 +172,15 @@ WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
if (extraResourceCount <= 0)
continue;
penalizedResourceCount += extraResourceCount - 1;
- summary.addChild(String.sprintf("%d %s resources served from %s.", domainResources.length, this._resourceTypeName, WebInspector.AuditRuleResult.resourceDomain(domain)));
+ summary.addChild(WebInspector.UIString("%d %s resources served from %s.", domainResources.length, this._resourceTypeName, WebInspector.AuditRuleResult.resourceDomain(domain)));
result.violationCount += domainResources.length;
}
- if (!penalizedResourceCount)
- return callback(null);
+ if (!penalizedResourceCount) {
+ callback(null);
+ return;
+ }
- summary.value = "There are multiple resources served from same domain. Consider combining them into as few files as possible.";
+ summary.value = WebInspector.UIString("There are multiple resources served from same domain. Consider combining them into as few files as possible.");
callback(result);
},
@@ -180,7 +192,7 @@ WebInspector.AuditRules.CombineExternalResourcesRule.prototype = {
* @extends {WebInspector.AuditRules.CombineExternalResourcesRule}
*/
WebInspector.AuditRules.CombineJsResourcesRule = function(allowedPerDomain) {
- WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externaljs", "Combine external JavaScript", WebInspector.resourceTypes.Script, "JavaScript", allowedPerDomain);
+ WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externaljs", WebInspector.UIString("Combine external JavaScript"), WebInspector.resourceTypes.Script, "JavaScript", allowedPerDomain);
}
WebInspector.AuditRules.CombineJsResourcesRule.prototype = {
@@ -192,7 +204,7 @@ WebInspector.AuditRules.CombineJsResourcesRule.prototype = {
* @extends {WebInspector.AuditRules.CombineExternalResourcesRule}
*/
WebInspector.AuditRules.CombineCssResourcesRule = function(allowedPerDomain) {
- WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externalcss", "Combine external CSS", WebInspector.resourceTypes.Stylesheet, "CSS", allowedPerDomain);
+ WebInspector.AuditRules.CombineExternalResourcesRule.call(this, "page-externalcss", WebInspector.UIString("Combine external CSS"), WebInspector.resourceTypes.Stylesheet, "CSS", allowedPerDomain);
}
WebInspector.AuditRules.CombineCssResourcesRule.prototype = {
@@ -204,18 +216,19 @@ WebInspector.AuditRules.CombineCssResourcesRule.prototype = {
* @extends {WebInspector.AuditRule}
*/
WebInspector.AuditRules.MinimizeDnsLookupsRule = function(hostCountThreshold) {
- WebInspector.AuditRule.call(this, "network-minimizelookups", "Minimize DNS lookups");
+ WebInspector.AuditRule.call(this, "network-minimizelookups", WebInspector.UIString("Minimize DNS lookups"));
this._hostCountThreshold = hostCountThreshold;
}
WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var summary = result.addChild("");
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(requests, null, false);
@@ -230,10 +243,12 @@ WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = {
summary.addSnippet(domain);
result.violationCount++;
}
- if (!summary.children || summary.children.length <= this._hostCountThreshold)
- return callback(null);
+ if (!summary.children || summary.children.length <= this._hostCountThreshold) {
+ callback(null);
+ return;
+ }
- summary.value = "The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.";
+ summary.value = WebInspector.UIString("The following domains only serve one resource each. If possible, avoid the extra DNS lookups by serving these resources from existing domains.");
callback(result);
},
@@ -246,7 +261,7 @@ WebInspector.AuditRules.MinimizeDnsLookupsRule.prototype = {
*/
WebInspector.AuditRules.ParallelizeDownloadRule = function(optimalHostnameCount, minRequestThreshold, minBalanceThreshold)
{
- WebInspector.AuditRule.call(this, "network-parallelizehosts", "Parallelize downloads across hostnames");
+ WebInspector.AuditRule.call(this, "network-parallelizehosts", WebInspector.UIString("Parallelize downloads across hostnames"));
this._optimalHostnameCount = optimalHostnameCount;
this._minRequestThreshold = minRequestThreshold;
this._minBalanceThreshold = minBalanceThreshold;
@@ -254,18 +269,23 @@ WebInspector.AuditRules.ParallelizeDownloadRule = function(optimalHostnameCount,
WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
+ /**
+ * @param {string} a
+ * @param {string} b
+ */
function hostSorter(a, b)
{
var aCount = domainToResourcesMap[a].length;
var bCount = domainToResourcesMap[b].length;
- return (aCount < bCount) ? 1 : (aCount == bCount) ? 0 : -1;
+ return (aCount < bCount) ? 1 : (aCount === bCount) ? 0 : -1;
}
var domainToResourcesMap = WebInspector.AuditRules.getDomainToResourcesMap(
@@ -277,8 +297,10 @@ WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
for (var url in domainToResourcesMap)
hosts.push(url);
- if (!hosts.length)
- return callback(null); // no hosts (local file or something)
+ if (!hosts.length) {
+ callback(null); // no hosts (local file or something)
+ return;
+ }
hosts.sort(hostSorter);
@@ -288,8 +310,10 @@ WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
var busiestHostResourceCount = domainToResourcesMap[hosts[0]].length;
var requestCountAboveThreshold = busiestHostResourceCount - this._minRequestThreshold;
- if (requestCountAboveThreshold <= 0)
- return callback(null);
+ if (requestCountAboveThreshold <= 0) {
+ callback(null);
+ return;
+ }
var avgResourcesPerHost = 0;
for (var i = 0, size = hosts.length; i < size; ++i)
@@ -301,11 +325,13 @@ WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
var pctAboveAvg = (requestCountAboveThreshold / avgResourcesPerHost) - 1.0;
var minBalanceThreshold = this._minBalanceThreshold;
- if (pctAboveAvg < minBalanceThreshold)
- return callback(null);
+ if (pctAboveAvg < minBalanceThreshold) {
+ callback(null);
+ return;
+ }
var requestsOnBusiestHost = domainToResourcesMap[hosts[0]];
- var entry = result.addChild(String.sprintf("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.", busiestHostResourceCount, hosts[0]), true);
+ var entry = result.addChild(WebInspector.UIString("This page makes %d parallelizable requests to %s. Increase download parallelization by distributing the following requests across multiple hostnames.", busiestHostResourceCount, hosts[0]), true);
for (var i = 0; i < requestsOnBusiestHost.length; ++i)
entry.addURL(requestsOnBusiestHost[i].url);
@@ -324,27 +350,23 @@ WebInspector.AuditRules.ParallelizeDownloadRule.prototype = {
*/
WebInspector.AuditRules.UnusedCssRule = function()
{
- WebInspector.AuditRule.call(this, "page-unusedcss", "Remove unused CSS rules");
+ WebInspector.AuditRule.call(this, "page-unusedcss", WebInspector.UIString("Remove unused CSS rules"));
}
WebInspector.AuditRules.UnusedCssRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
- var self = this;
-
/**
- * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
+ * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
*/
function evalCallback(styleSheets) {
- if (progress.isCanceled())
- return;
-
if (!styleSheets.length)
return callback(null);
@@ -364,7 +386,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
var foundSelectors = {};
/**
- * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
+ * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
*/
function selectorsCallback(styleSheets)
{
@@ -392,8 +414,8 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
continue;
var resource = WebInspector.resourceForURL(styleSheet.sourceURL);
- var isInlineBlock = resource && resource.request && resource.request.type == WebInspector.resourceTypes.Document;
- var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : String.sprintf("Inline block #%d", ++inlineBlockOrdinal);
+ var isInlineBlock = resource && resource.request && resource.request.type === WebInspector.resourceTypes.Document;
+ var url = !isInlineBlock ? WebInspector.AuditRuleResult.linkifyDisplayName(styleSheet.sourceURL) : WebInspector.UIString("Inline block #%d", ++inlineBlockOrdinal);
var pctUnused = Math.round(100 * unusedRules.length / styleSheet.rules.length);
if (!summary)
summary = result.addChild("", true);
@@ -409,7 +431,7 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
return callback(null);
var totalUnusedPercent = Math.round(100 * totalUnusedStylesheetSize / totalStylesheetSize);
- summary.value = String.sprintf("%s rules (%d%) of CSS not used by the current page.", totalUnusedStylesheetSize, totalUnusedPercent);
+ summary.value = WebInspector.UIString("%s rules (%d%) of CSS not used by the current page.", totalUnusedStylesheetSize, totalUnusedPercent);
callback(result);
}
@@ -441,54 +463,97 @@ WebInspector.AuditRules.UnusedCssRule.prototype = {
if (progress.isCanceled())
return;
var effectiveSelector = selectors[i].replace(pseudoSelectorRegexp, "");
- WebInspector.domAgent.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i]));
+ target.domModel.querySelector(document.id, effectiveSelector, queryCallback.bind(null, i === selectors.length - 1 ? selectorsCallback.bind(null, styleSheets) : null, selectors[i]));
}
}
- WebInspector.domAgent.requestDocument(documentLoaded.bind(null, selectors));
+ target.domModel.requestDocument(documentLoaded.bind(null, selectors));
}
- /**
- * @param {!Array.<!WebInspector.CSSStyleSheet>} styleSheets
- * @param {string} sourceURL
- * @param {?function(!Array.<!WebInspector.CSSStyleSheet>)} continuation
- * @param {?WebInspector.CSSStyleSheet} styleSheet
- */
- function styleSheetCallback(styleSheets, sourceURL, continuation, styleSheet)
- {
- if (progress.isCanceled())
- return;
-
- if (styleSheet) {
- styleSheet.sourceURL = sourceURL;
- styleSheets.push(styleSheet);
- }
- if (continuation)
- continuation(styleSheets);
+ var styleSheetInfos = target.cssModel.allStyleSheets();
+ if (!styleSheetInfos || !styleSheetInfos.length) {
+ evalCallback([]);
+ return;
}
+ var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(styleSheetInfos, progress, evalCallback);
+ styleSheetProcessor.run();
+ },
- /**
- * @param {?Protocol.Error} error
- * @param {!Array.<!CSSAgent.CSSStyleSheetHeader>} styleSheetInfos
- */
- function allStylesCallback(error, styleSheetInfos)
- {
- if (progress.isCanceled())
- return;
+ __proto__: WebInspector.AuditRule.prototype
+}
- if (error || !styleSheetInfos || !styleSheetInfos.length)
- return evalCallback([]);
- var styleSheets = [];
- for (var i = 0; i < styleSheetInfos.length; ++i) {
- var info = styleSheetInfos[i];
- WebInspector.CSSStyleSheet.createForId(info.styleSheetId, styleSheetCallback.bind(null, styleSheets, info.sourceURL, i == styleSheetInfos.length - 1 ? evalCallback : null));
- }
+/**
+ * @typedef {!{sourceURL: string, rules: !Array.<!WebInspector.CSSParser.StyleRule>}}
+ */
+WebInspector.AuditRules.ParsedStyleSheet;
+
+/**
+ * @constructor
+ * @param {!Array.<!WebInspector.CSSStyleSheetHeader>} styleSheetHeaders
+ * @param {!WebInspector.Progress} progress
+ * @param {!function(!Array.<!WebInspector.AuditRules.ParsedStyleSheet>)} styleSheetsParsedCallback
+ */
+WebInspector.AuditRules.StyleSheetProcessor = function(styleSheetHeaders, progress, styleSheetsParsedCallback)
+{
+ this._styleSheetHeaders = styleSheetHeaders;
+ this._progress = progress;
+ this._styleSheets = [];
+ this._styleSheetsParsedCallback = styleSheetsParsedCallback;
+}
+
+WebInspector.AuditRules.StyleSheetProcessor.prototype = {
+ run: function()
+ {
+ this._parser = new WebInspector.CSSParser();
+ this._processNextStyleSheet();
+ },
+
+ _terminateWorker: function()
+ {
+ if (this._parser) {
+ this._parser.dispose();
+ delete this._parser;
}
+ },
- CSSAgent.getAllStyleSheets(allStylesCallback);
+ _finish: function()
+ {
+ this._terminateWorker();
+ this._styleSheetsParsedCallback(this._styleSheets);
},
- __proto__: WebInspector.AuditRule.prototype
+ _processNextStyleSheet: function()
+ {
+ if (!this._styleSheetHeaders.length) {
+ this._finish();
+ return;
+ }
+ this._currentStyleSheetHeader = this._styleSheetHeaders.shift();
+ this._parser.fetchAndParse(this._currentStyleSheetHeader, this._onStyleSheetParsed.bind(this));
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.CSSParser.Rule>} rules
+ */
+ _onStyleSheetParsed: function(rules)
+ {
+ if (this._progress.isCanceled()) {
+ this._terminateWorker();
+ return;
+ }
+
+ var styleRules = [];
+ for (var i = 0; i < rules.length; ++i) {
+ var rule = rules[i];
+ if (rule.selectorText)
+ styleRules.push(rule);
+ }
+ this._styleSheets.push({
+ sourceURL: this._currentStyleSheetHeader.sourceURL,
+ rules: styleRules
+ });
+ this._processNextStyleSheet();
+ },
}
/**
@@ -504,12 +569,13 @@ WebInspector.AuditRules.CacheControlRule.MillisPerMonth = 1000 * 60 * 60 * 24 *
WebInspector.AuditRules.CacheControlRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var cacheableAndNonCacheableResources = this._cacheableAndNonCacheableResources(requests);
if (cacheableAndNonCacheableResources[0].length)
@@ -553,6 +619,11 @@ WebInspector.AuditRules.CacheControlRule.prototype = {
}
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @param {number} timeMs
+ * @return {boolean}
+ */
freshnessLifetimeGreaterThan: function(request, timeMs)
{
var dateHeader = this.responseHeader(request, "Date");
@@ -580,21 +651,39 @@ WebInspector.AuditRules.CacheControlRule.prototype = {
return (isNaN(freshnessLifetimeMs)) ? false : freshnessLifetimeMs > timeMs;
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @param {string} header
+ * @return {string|undefined}
+ */
responseHeader: function(request, header)
{
return request.responseHeaderValue(header);
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @param {string} header
+ * @return {boolean}
+ */
hasResponseHeader: function(request, header)
{
return request.responseHeaderValue(header) !== undefined;
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
isCompressible: function(request)
{
return request.type.isTextType();
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
isPubliclyCacheable: function(request)
{
if (this._isExplicitlyNonCacheable(request))
@@ -603,32 +692,50 @@ WebInspector.AuditRules.CacheControlRule.prototype = {
if (this.responseHeaderMatch(request, "Cache-Control", "public"))
return true;
- return request.url.indexOf("?") == -1 && !this.responseHeaderMatch(request, "Cache-Control", "private");
+ return request.url.indexOf("?") === -1 && !this.responseHeaderMatch(request, "Cache-Control", "private");
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @param {string} header
+ * @param {string} regexp
+ * @return {?Array.<string>}
+ */
responseHeaderMatch: function(request, header, regexp)
{
return request.responseHeaderValue(header)
? request.responseHeaderValue(header).match(new RegExp(regexp, "im"))
- : undefined;
+ : null;
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
hasExplicitExpiration: function(request)
{
return this.hasResponseHeader(request, "Date") &&
- (this.hasResponseHeader(request, "Expires") || this.responseHeaderMatch(request, "Cache-Control", "max-age"));
+ (this.hasResponseHeader(request, "Expires") || !!this.responseHeaderMatch(request, "Cache-Control", "max-age"));
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
_isExplicitlyNonCacheable: function(request)
{
var hasExplicitExp = this.hasExplicitExpiration(request);
- return this.responseHeaderMatch(request, "Cache-Control", "(no-cache|no-store|must-revalidate)") ||
- this.responseHeaderMatch(request, "Pragma", "no-cache") ||
+ return !!this.responseHeaderMatch(request, "Cache-Control", "(no-cache|no-store|must-revalidate)") ||
+ !!this.responseHeaderMatch(request, "Pragma", "no-cache") ||
(hasExplicitExp && !this.freshnessLifetimeGreaterThan(request, 0)) ||
- (!hasExplicitExp && request.url && request.url.indexOf("?") >= 0) ||
+ (!hasExplicitExp && !!request.url && request.url.indexOf("?") >= 0) ||
(!hasExplicitExp && !this.isCacheableResource(request));
},
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
isCacheableResource: function(request)
{
return request.statusCode !== undefined && WebInspector.AuditRules.CacheableResponseCodes[request.statusCode];
@@ -643,14 +750,14 @@ WebInspector.AuditRules.CacheControlRule.prototype = {
*/
WebInspector.AuditRules.BrowserCacheControlRule = function()
{
- WebInspector.AuditRules.CacheControlRule.call(this, "http-browsercache", "Leverage browser caching");
+ WebInspector.AuditRules.CacheControlRule.call(this, "http-browsercache", WebInspector.UIString("Leverage browser caching"));
}
WebInspector.AuditRules.BrowserCacheControlRule.prototype = {
handleNonCacheableResources: function(requests, result)
{
if (requests.length) {
- var entry = result.addChild("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:", true);
+ var entry = result.addChild(WebInspector.UIString("The following resources are explicitly non-cacheable. Consider making them cacheable if possible:"), true);
result.violationCount += requests.length;
for (var i = 0; i < requests.length; ++i)
entry.addURL(requests[i].url);
@@ -659,15 +766,15 @@ WebInspector.AuditRules.BrowserCacheControlRule.prototype = {
runChecks: function(requests, result, callback)
{
- this.execCheck("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:",
+ this.execCheck(WebInspector.UIString("The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:"),
this._missingExpirationCheck, requests, result);
- this.execCheck("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:",
+ this.execCheck(WebInspector.UIString("The following resources specify a \"Vary\" header that disables caching in most versions of Internet Explorer:"),
this._varyCheck, requests, result);
- this.execCheck("The following cacheable resources have a short freshness lifetime:",
+ this.execCheck(WebInspector.UIString("The following cacheable resources have a short freshness lifetime:"),
this._oneMonthExpirationCheck, requests, result);
// Unable to implement the favicon check due to the WebKit limitations.
- this.execCheck("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:",
+ this.execCheck(WebInspector.UIString("To further improve cache hit rate, specify an expiration one year in the future for the following cacheable resources:"),
this._oneYearExpirationCheck, requests, result);
},
@@ -711,17 +818,17 @@ WebInspector.AuditRules.BrowserCacheControlRule.prototype = {
* @extends {WebInspector.AuditRules.CacheControlRule}
*/
WebInspector.AuditRules.ProxyCacheControlRule = function() {
- WebInspector.AuditRules.CacheControlRule.call(this, "http-proxycache", "Leverage proxy caching");
+ WebInspector.AuditRules.CacheControlRule.call(this, "http-proxycache", WebInspector.UIString("Leverage proxy caching"));
}
WebInspector.AuditRules.ProxyCacheControlRule.prototype = {
runChecks: function(requests, result, callback)
{
- this.execCheck("Resources with a \"?\" in the URL are not cached by most proxy caching servers:",
+ this.execCheck(WebInspector.UIString("Resources with a \"?\" in the URL are not cached by most proxy caching servers:"),
this._questionMarkCheck, requests, result);
- this.execCheck("Consider adding a \"Cache-Control: public\" header to the following resources:",
+ this.execCheck(WebInspector.UIString("Consider adding a \"Cache-Control: public\" header to the following resources:"),
this._publicCachingCheck, requests, result);
- this.execCheck("The following publicly cacheable resources contain a Set-Cookie header. This security vulnerability can cause cookies to be shared by multiple users.",
+ this.execCheck(WebInspector.UIString("The following publicly cacheable resources contain a Set-Cookie header. This security vulnerability can cause cookies to be shared by multiple users."),
this._setCookieCacheableCheck, requests, result);
},
@@ -752,24 +859,25 @@ WebInspector.AuditRules.ProxyCacheControlRule.prototype = {
*/
WebInspector.AuditRules.ImageDimensionsRule = function()
{
- WebInspector.AuditRule.call(this, "page-imagedims", "Specify image dimensions");
+ WebInspector.AuditRule.call(this, "page-imagedims", WebInspector.UIString("Specify image dimensions"));
}
WebInspector.AuditRules.ImageDimensionsRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var urlToNoDimensionCount = {};
function doneCallback()
{
for (var url in urlToNoDimensionCount) {
- var entry = entry || result.addChild("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:", true);
+ var entry = entry || result.addChild(WebInspector.UIString("A width and height should be specified for all images in order to speed up page display. The following image(s) are missing a width and/or height:"), true);
var format = "%r";
if (urlToNoDimensionCount[url] > 1)
format += " (%d uses)";
@@ -784,7 +892,7 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
if (progress.isCanceled())
return;
- const node = WebInspector.domAgent.nodeForId(imageId);
+ const node = target.domModel.nodeForId(imageId);
var src = node.getAttribute("src");
if (!src.asParsedURL()) {
for (var frameOwnerCandidate = node; frameOwnerCandidate; frameOwnerCandidate = frameOwnerCandidate.parentNode) {
@@ -860,9 +968,9 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
doneCallback();
for (var i = 0; nodeIds && i < nodeIds.length; ++i) {
- WebInspector.cssModel.getMatchedStylesAsync(nodeIds[i], false, false, matchedCallback);
- WebInspector.cssModel.getInlineStylesAsync(nodeIds[i], inlineCallback);
- WebInspector.cssModel.getComputedStyleAsync(nodeIds[i], imageStylesReady.bind(null, nodeIds[i], targetResult, i === nodeIds.length - 1));
+ target.cssModel.getMatchedStylesAsync(nodeIds[i], false, false, matchedCallback);
+ target.cssModel.getInlineStylesAsync(nodeIds[i], inlineCallback);
+ target.cssModel.getComputedStyleAsync(nodeIds[i], imageStylesReady.bind(null, nodeIds[i], targetResult, i === nodeIds.length - 1));
}
}
@@ -870,12 +978,12 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
{
if (progress.isCanceled())
return;
- WebInspector.domAgent.querySelectorAll(root.id, "img[src]", getStyles);
+ target.domModel.querySelectorAll(root.id, "img[src]", getStyles);
}
if (progress.isCanceled())
return;
- WebInspector.domAgent.requestDocument(onDocumentAvailable);
+ target.domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
@@ -887,17 +995,18 @@ WebInspector.AuditRules.ImageDimensionsRule.prototype = {
*/
WebInspector.AuditRules.CssInHeadRule = function()
{
- WebInspector.AuditRule.call(this, "page-cssinhead", "Put CSS in the document head");
+ WebInspector.AuditRule.call(this, "page-cssinhead", WebInspector.UIString("Put CSS in the document head"));
}
WebInspector.AuditRules.CssInHeadRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
function evalCallback(evalResult)
{
@@ -920,11 +1029,13 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
result.addFormatted("Link node %r should be moved to the document head in %r", urlViolations[1][i], url);
result.violationCount += urlViolations[1].length;
}
- summary.value = String.sprintf("CSS in the document body adversely impacts rendering performance.");
+ summary.value = WebInspector.UIString("CSS in the document body adversely impacts rendering performance.");
callback(result);
}
/**
+ * @param {!WebInspector.DOMNode} root
+ * @param {!Array.<!DOMAgent.NodeId>=} inlineStyleNodeIds
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function externalStylesheetsReceived(root, inlineStyleNodeIds, nodeIds)
@@ -940,7 +1051,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
var urlToViolationsArray = {};
var externalStylesheetHrefs = [];
for (var j = 0; j < externalStylesheetNodeIds.length; ++j) {
- var linkNode = WebInspector.domAgent.nodeForId(externalStylesheetNodeIds[j]);
+ var linkNode = target.domModel.nodeForId(externalStylesheetNodeIds[j]);
var completeHref = WebInspector.ParsedURL.completeURL(linkNode.ownerDocument.baseURL, linkNode.getAttribute("href"));
externalStylesheetHrefs.push(completeHref || "<empty>");
}
@@ -951,6 +1062,7 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
}
/**
+ * @param {!WebInspector.DOMNode} root
* @param {!Array.<!DOMAgent.NodeId>=} nodeIds
*/
function inlineStylesReceived(root, nodeIds)
@@ -960,18 +1072,21 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
if (!nodeIds)
return;
- WebInspector.domAgent.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
+ target.domModel.querySelectorAll(root.id, "body link[rel~='stylesheet'][href]", externalStylesheetsReceived.bind(null, root, nodeIds));
}
+ /**
+ * @param {!WebInspector.DOMNode} root
+ */
function onDocumentAvailable(root)
{
if (progress.isCanceled())
return;
- WebInspector.domAgent.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
+ target.domModel.querySelectorAll(root.id, "body style", inlineStylesReceived.bind(null, root));
}
- WebInspector.domAgent.requestDocument(onDocumentAvailable);
+ target.domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
@@ -983,17 +1098,18 @@ WebInspector.AuditRules.CssInHeadRule.prototype = {
*/
WebInspector.AuditRules.StylesScriptsOrderRule = function()
{
- WebInspector.AuditRule.call(this, "page-stylescriptorder", "Optimize the order of styles and scripts");
+ WebInspector.AuditRule.call(this, "page-stylescriptorder", WebInspector.UIString("Optimize the order of styles and scripts"));
}
WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
function evalCallback(resultValue)
{
@@ -1007,13 +1123,13 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
var cssBeforeInlineCount = resultValue[1];
if (lateCssUrls.length) {
- var entry = result.addChild("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript.", true);
+ var entry = result.addChild(WebInspector.UIString("The following external CSS files were included after an external JavaScript file in the document head. To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript."), true);
entry.addURLs(lateCssUrls);
result.violationCount += lateCssUrls.length;
}
if (cssBeforeInlineCount) {
- result.addChild(String.sprintf(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.", cssBeforeInlineCount, cssBeforeInlineCount > 1 ? "s were" : " was"));
+ result.addChild(WebInspector.UIString(" %d inline script block%s found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.", cssBeforeInlineCount, cssBeforeInlineCount > 1 ? "s were" : " was"));
result.violationCount += cssBeforeInlineCount;
}
callback(result);
@@ -1036,7 +1152,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
if (lateStyleIds.length || cssBeforeInlineCount) {
var lateStyleUrls = [];
for (var i = 0; i < lateStyleIds.length; ++i) {
- var lateStyleNode = WebInspector.domAgent.nodeForId(lateStyleIds[i]);
+ var lateStyleNode = target.domModel.nodeForId(lateStyleIds[i]);
var completeHref = WebInspector.ParsedURL.completeURL(lateStyleNode.ownerDocument.baseURL, lateStyleNode.getAttribute("href"));
lateStyleUrls.push(completeHref || "<empty>");
}
@@ -1058,7 +1174,7 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
if (!nodeIds)
return;
- WebInspector.domAgent.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
+ target.domModel.querySelectorAll(root.id, "head link[rel~='stylesheet'][href] ~ script:not([src])", cssBeforeInlineReceived.bind(null, nodeIds));
}
/**
@@ -1069,10 +1185,10 @@ WebInspector.AuditRules.StylesScriptsOrderRule.prototype = {
if (progress.isCanceled())
return;
- WebInspector.domAgent.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
+ target.domModel.querySelectorAll(root.id, "head script[src] ~ link[rel~='stylesheet'][href]", lateStylesReceived.bind(null, root));
}
- WebInspector.domAgent.requestDocument(onDocumentAvailable);
+ target.domModel.requestDocument(onDocumentAvailable);
},
__proto__: WebInspector.AuditRule.prototype
@@ -1089,103 +1205,116 @@ WebInspector.AuditRules.CSSRuleBase = function(id, name)
WebInspector.AuditRules.CSSRuleBase.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(?WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
- CSSAgent.getAllStyleSheets(sheetsCallback.bind(this));
-
- /**
- * @param {?Protocol.Error} error
- * @param {!Array.<!CSSAgent.CSSStyleSheetHeader>} headers
- * @this {WebInspector.AuditRules.CSSRuleBase}
- */
- function sheetsCallback(error, headers)
- {
- if (error)
- return callback(null);
-
- if (!headers.length)
- return callback(null);
- for (var i = 0; i < headers.length; ++i) {
- var header = headers[i];
- if (header.disabled)
- continue; // Do not check disabled stylesheets.
+ var headers = target.cssModel.allStyleSheets();
- this._visitStyleSheet(header.styleSheetId, i === headers.length - 1 ? finishedCallback : null, result, progress);
- }
+ if (!headers.length) {
+ callback(null);
+ return;
}
-
- function finishedCallback()
- {
- callback(result);
+ var activeHeaders = []
+ for (var i = 0; i < headers.length; ++i) {
+ if (!headers[i].disabled)
+ activeHeaders.push(headers[i]);
}
+
+ var styleSheetProcessor = new WebInspector.AuditRules.StyleSheetProcessor(activeHeaders, progress, this._styleSheetsLoaded.bind(this, result, callback, progress));
+ styleSheetProcessor.run();
},
- _visitStyleSheet: function(styleSheetId, callback, result, progress)
+ /**
+ * @param {!WebInspector.AuditRuleResult} result
+ * @param {function(!WebInspector.AuditRuleResult)} callback
+ * @param {!WebInspector.Progress} progress
+ * @param {!Array.<!WebInspector.AuditRules.ParsedStyleSheet>} styleSheets
+ */
+ _styleSheetsLoaded: function(result, callback, progress, styleSheets)
{
- WebInspector.CSSStyleSheet.createForId(styleSheetId, sheetCallback.bind(this));
-
- /**
- * @param {?WebInspector.CSSStyleSheet} styleSheet
- * @this {WebInspector.AuditRules.CSSRuleBase}
- */
- function sheetCallback(styleSheet)
- {
- if (progress.isCanceled())
- return;
-
- if (!styleSheet) {
- if (callback)
- callback();
- return;
- }
-
- this.visitStyleSheet(styleSheet, result);
+ for (var i = 0; i < styleSheets.length; ++i)
+ this._visitStyleSheet(styleSheets[i], result);
+ callback(result);
+ },
- for (var i = 0; i < styleSheet.rules.length; ++i)
- this._visitRule(styleSheet, styleSheet.rules[i], result);
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.AuditRuleResult} result
+ */
+ _visitStyleSheet: function(styleSheet, result)
+ {
+ this.visitStyleSheet(styleSheet, result);
- this.didVisitStyleSheet(styleSheet, result);
+ for (var i = 0; i < styleSheet.rules.length; ++i)
+ this._visitRule(styleSheet, styleSheet.rules[i], result);
- if (callback)
- callback();
- }
+ this.didVisitStyleSheet(styleSheet, result);
},
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ * @param {!WebInspector.AuditRuleResult} result
+ */
_visitRule: function(styleSheet, rule, result)
{
this.visitRule(styleSheet, rule, result);
- var allProperties = rule.style.allProperties;
+ var allProperties = rule.properties;
for (var i = 0; i < allProperties.length; ++i)
- this.visitProperty(styleSheet, allProperties[i], result);
+ this.visitProperty(styleSheet, rule, allProperties[i], result);
this.didVisitRule(styleSheet, rule, result);
},
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.AuditRuleResult} result
+ */
visitStyleSheet: function(styleSheet, result)
{
// Subclasses can implement.
},
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.AuditRuleResult} result
+ */
didVisitStyleSheet: function(styleSheet, result)
{
// Subclasses can implement.
},
-
+
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ * @param {!WebInspector.AuditRuleResult} result
+ */
visitRule: function(styleSheet, rule, result)
{
// Subclasses can implement.
},
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ * @param {!WebInspector.AuditRuleResult} result
+ */
didVisitRule: function(styleSheet, rule, result)
{
// Subclasses can implement.
},
-
- visitProperty: function(styleSheet, property, result)
+
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ * @param {!WebInspector.CSSParser.Property} property
+ * @param {!WebInspector.AuditRuleResult} result
+ */
+ visitProperty: function(styleSheet, rule, property, result)
{
// Subclasses can implement.
},
@@ -1199,7 +1328,7 @@ WebInspector.AuditRules.CSSRuleBase.prototype = {
*/
WebInspector.AuditRules.VendorPrefixedCSSProperties = function()
{
- WebInspector.AuditRules.CSSRuleBase.call(this, "page-vendorprefixedcss", "Use normal CSS property names instead of vendor-prefixed ones");
+ WebInspector.AuditRules.CSSRuleBase.call(this, "page-vendorprefixedcss", WebInspector.UIString("Use normal CSS property names instead of vendor-prefixed ones"));
this._webkitPrefix = "-webkit-";
}
@@ -1210,11 +1339,17 @@ WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties = [
].keySet();
WebInspector.AuditRules.VendorPrefixedCSSProperties.prototype = {
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ */
didVisitStyleSheet: function(styleSheet)
{
delete this._styleSheetResult;
},
+ /**
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ */
visitRule: function(rule)
{
this._mentionedProperties = {};
@@ -1226,30 +1361,29 @@ WebInspector.AuditRules.VendorPrefixedCSSProperties.prototype = {
delete this._mentionedProperties;
},
- visitProperty: function(styleSheet, property, result)
+ /**
+ * @param {!WebInspector.AuditRules.ParsedStyleSheet} styleSheet
+ * @param {!WebInspector.CSSParser.StyleRule} rule
+ * @param {!WebInspector.CSSParser.Property} property
+ * @param {!WebInspector.AuditRuleResult} result
+ */
+ visitProperty: function(styleSheet, rule, property, result)
{
if (!property.name.startsWith(this._webkitPrefix))
return;
var normalPropertyName = property.name.substring(this._webkitPrefix.length).toLowerCase(); // Start just after the "-webkit-" prefix.
if (WebInspector.AuditRules.VendorPrefixedCSSProperties.supportedProperties[normalPropertyName] && !this._mentionedProperties[normalPropertyName]) {
- var style = property.ownerStyle;
- var liveProperty = style.getLiveProperty(normalPropertyName);
- if (liveProperty && !liveProperty.styleBased)
- return; // WebCore can provide normal versions of prefixed properties automatically, so be careful to skip only normal source-based properties.
-
- var rule = style.parentRule;
this._mentionedProperties[normalPropertyName] = true;
if (!this._styleSheetResult)
- this._styleSheetResult = result.addChild(rule.sourceURL ? WebInspector.linkifyResourceAsNode(rule.sourceURL) : "<unknown>");
+ this._styleSheetResult = result.addChild(styleSheet.sourceURL ? WebInspector.linkifyResourceAsNode(styleSheet.sourceURL) : WebInspector.UIString("<unknown>"));
if (!this._ruleResult) {
- var anchor = WebInspector.linkifyURLAsNode(rule.sourceURL, rule.selectorText);
- anchor.preferredPanel = "resources";
- anchor.lineNumber = rule.lineNumberInSource();
+ var anchor = WebInspector.linkifyURLAsNode(styleSheet.sourceURL, rule.selectorText);
+ anchor.lineNumber = rule.lineNumber;
this._ruleResult = this._styleSheetResult.addChild(anchor);
}
++result.violationCount;
- this._ruleResult.addSnippet(String.sprintf("\"" + this._webkitPrefix + "%s\" is used, but \"%s\" is supported.", normalPropertyName, normalPropertyName));
+ this._ruleResult.addSnippet(WebInspector.UIString("\"%s%s\" is used, but \"%s\" is supported.", this._webkitPrefix, normalPropertyName, normalPropertyName));
}
},
@@ -1267,12 +1401,13 @@ WebInspector.AuditRules.CookieRuleBase = function(id, name)
WebInspector.AuditRules.CookieRuleBase.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
var self = this;
function resultCallback(receivedCookies) {
@@ -1315,7 +1450,7 @@ WebInspector.AuditRules.CookieRuleBase.prototype = {
*/
WebInspector.AuditRules.CookieSizeRule = function(avgBytesThreshold)
{
- WebInspector.AuditRules.CookieRuleBase.call(this, "http-cookiesize", "Minimize cookie size");
+ WebInspector.AuditRules.CookieRuleBase.call(this, "http-cookiesize", WebInspector.UIString("Minimize cookie size"));
this._avgBytesThreshold = avgBytesThreshold;
this._maxBytesThreshold = 1000;
}
@@ -1370,7 +1505,7 @@ WebInspector.AuditRules.CookieSizeRule.prototype = {
null,
true);
var matchingResourceData = {};
- this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback.bind(this));
+ this.mapResourceCookies(domainToResourcesMap, allCookies, collectorCallback);
for (var requestDomain in cookiesPerResourceDomain) {
var cookies = cookiesPerResourceDomain[requestDomain];
@@ -1399,17 +1534,17 @@ WebInspector.AuditRules.CookieSizeRule.prototype = {
if (avgCookieSize > this._avgBytesThreshold && avgCookieSize < this._maxBytesThreshold)
bigAvgCookieDomains.push(WebInspector.AuditRuleResult.resourceDomain(domain) + ": " + Number.bytesToString(avgCookieSize));
}
- result.addChild(String.sprintf("The average cookie size for all requests on this page is %s", Number.bytesToString(avgAllCookiesSize)));
+ result.addChild(WebInspector.UIString("The average cookie size for all requests on this page is %s", Number.bytesToString(avgAllCookiesSize)));
var message;
if (hugeCookieDomains.length) {
- var entry = result.addChild("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet.", true);
+ var entry = result.addChild(WebInspector.UIString("The following domains have a cookie size in excess of 1KB. This is harmful because requests with cookies larger than 1KB typically cannot fit into a single network packet."), true);
entry.addURLs(hugeCookieDomains);
result.violationCount += hugeCookieDomains.length;
}
if (bigAvgCookieDomains.length) {
- var entry = result.addChild(String.sprintf("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.", this._avgBytesThreshold), true);
+ var entry = result.addChild(WebInspector.UIString("The following domains have an average cookie size in excess of %d bytes. Reducing the size of cookies for these domains can reduce the time it takes to send requests.", this._avgBytesThreshold), true);
entry.addURLs(bigAvgCookieDomains);
result.violationCount += bigAvgCookieDomains.length;
}
@@ -1424,7 +1559,7 @@ WebInspector.AuditRules.CookieSizeRule.prototype = {
*/
WebInspector.AuditRules.StaticCookielessRule = function(minResources)
{
- WebInspector.AuditRules.CookieRuleBase.call(this, "http-staticcookieless", "Serve static content from a cookieless domain");
+ WebInspector.AuditRules.CookieRuleBase.call(this, "http-staticcookieless", WebInspector.UIString("Serve static content from a cookieless domain"));
this._minResources = minResources;
}
@@ -1452,7 +1587,7 @@ WebInspector.AuditRules.StaticCookielessRule.prototype = {
if (badUrls.length < this._minResources)
return;
- var entry = result.addChild(String.sprintf("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:", Number.bytesToString(cookieBytes)), true);
+ var entry = result.addChild(WebInspector.UIString("%s of cookies were sent with the following static resources. Serve these static resources from a domain that does not set cookies:", Number.bytesToString(cookieBytes)), true);
entry.addURLs(badUrls);
result.violationCount = badUrls.length;
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AuditsPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditsPanel.js
index 863ad5ee3ba..96bb7958cc1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AuditsPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/AuditsPanel.js
@@ -30,17 +30,14 @@
/**
* @constructor
- * @extends {WebInspector.Panel}
+ * @extends {WebInspector.PanelWithSidebarTree}
*/
WebInspector.AuditsPanel = function()
{
- WebInspector.Panel.call(this, "audits");
+ WebInspector.PanelWithSidebarTree.call(this, "audits");
this.registerRequiredCSS("panelEnablerView.css");
this.registerRequiredCSS("auditsPanel.css");
- this.createSidebarViewWithTree();
- this.splitView.mainElement.classList.add("vbox");
-
this.auditsTreeElement = new WebInspector.SidebarSectionTreeElement("", {}, true);
this.sidebarTree.appendChild(this.auditsTreeElement);
this.auditsTreeElement.listItemElement.classList.add("hidden");
@@ -52,11 +49,10 @@ WebInspector.AuditsPanel = function()
this.sidebarTree.appendChild(this.auditResultsTreeElement);
this.auditResultsTreeElement.expand();
- this.viewsContainerElement = this.splitView.mainElement;
-
this._constructCategories();
- this._auditController = new WebInspector.AuditController(this);
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._auditController = new WebInspector.AuditController(target, this);
this._launcherView = new WebInspector.AuditLauncherView(this._auditController);
for (var id in this.categoriesById)
this._launcherView.addCategory(this.categoriesById[id]);
@@ -157,7 +153,7 @@ WebInspector.AuditsPanel.prototype = {
this._visibleView = x;
if (x)
- x.show(this.viewsContainerElement);
+ x.show(this.mainElement());
},
wasShown: function()
@@ -173,21 +169,23 @@ WebInspector.AuditsPanel.prototype = {
this.auditResultsTreeElement.removeChildren();
},
- __proto__: WebInspector.Panel.prototype
+ __proto__: WebInspector.PanelWithSidebarTree.prototype
}
/**
* @constructor
+ * @implements {WebInspector.AuditCategory}
* @param {string} displayName
*/
-WebInspector.AuditCategory = function(displayName)
+WebInspector.AuditCategoryImpl = function(displayName)
{
this._displayName = displayName;
this._rules = [];
}
-WebInspector.AuditCategory.prototype = {
+WebInspector.AuditCategoryImpl.prototype = {
/**
+ * @override
* @return {string}
*/
get id()
@@ -197,6 +195,7 @@ WebInspector.AuditCategory.prototype = {
},
/**
+ * @override
* @return {string}
*/
get displayName()
@@ -215,12 +214,14 @@ WebInspector.AuditCategory.prototype = {
},
/**
+ * @override
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {function()} categoryDoneCallback
* @param {!WebInspector.Progress} progress
*/
- run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
+ run: function(target, requests, ruleResultCallback, categoryDoneCallback, progress)
{
this._ensureInitialized();
var remainingRulesCount = this._rules.length;
@@ -233,7 +234,7 @@ WebInspector.AuditCategory.prototype = {
categoryDoneCallback();
}
for (var i = 0; i < this._rules.length; ++i)
- this._rules[i].run(requests, callbackWrapper, progress);
+ this._rules[i].run(target, requests, callbackWrapper, progress);
},
_ensureInitialized: function()
@@ -295,27 +296,29 @@ WebInspector.AuditRule.prototype = {
},
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- run: function(requests, callback, progress)
+ run: function(target, requests, callback, progress)
{
if (progress.isCanceled())
return;
var result = new WebInspector.AuditRuleResult(this.displayName);
result.severity = this._severity;
- this.doRun(requests, result, callback, progress);
+ this.doRun(target, requests, result, callback, progress);
},
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
* @param {!WebInspector.AuditRuleResult} result
* @param {function(!WebInspector.AuditRuleResult)} callback
* @param {!WebInspector.Progress} progress
*/
- doRun: function(requests, result, callback, progress)
+ doRun: function(target, requests, result, callback, progress)
{
throw new Error("doRun() not implemented");
}
@@ -370,6 +373,10 @@ WebInspector.AuditRuleResult.linkifyDisplayName = function(url)
return WebInspector.linkifyURLAsNode(url, WebInspector.displayNameForURL(url));
}
+/**
+ * @param {string} domain
+ * @return {string}
+ */
WebInspector.AuditRuleResult.resourceDomain = function(domain)
{
return domain || WebInspector.UIString("[empty domain]");
@@ -516,6 +523,7 @@ WebInspector.AuditRules = {};
*/
WebInspector.AuditCategories = {};
+importScript("AuditCategory.js");
importScript("AuditCategories.js");
importScript("AuditController.js");
importScript("AuditFormatters.js");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/audits/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/audits/module.json
new file mode 100644
index 00000000000..87920f7ed9d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/audits/module.json
@@ -0,0 +1,12 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "audits",
+ "title": "Audits",
+ "order": 6,
+ "className": "WebInspector.AuditsPanel"
+ }
+ ],
+ "scripts": [ "AuditsPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/auditsPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/auditsPanel.css
index 28b930087cb..90ecb07d360 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/auditsPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/auditsPanel.css
@@ -85,13 +85,14 @@
.audit-launcher-view button:active {
background-color: rgb(215, 215, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
.panel-enabler-view.audit-launcher-view label {
padding: 0 0 5px 0;
margin: 0;
- -webkit-flex: none;
+ display: flex;
+ flex-shrink: 0;
}
.panel-enabler-view.audit-launcher-view label.disabled {
@@ -100,6 +101,8 @@
.audit-launcher-view input[type="checkbox"] {
margin-left: 0;
+ height: 14px;
+ width: 14px;
}
.audit-result-view {
@@ -120,12 +123,13 @@
.audit-result-view .severity-warning,
.audit-result-view .severity-info {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
display: inline-block;
width: 10px;
+ margin-right: -10px;
height: 10px;
- float: left;
- margin-left: -28px;
+ position: relative;
+ left: -28px;
margin-top: 3px;
}
@@ -133,7 +137,7 @@
.audit-result-view .severity-severe,
.audit-result-view .severity-warning,
.audit-result-view .severity-info {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -152,7 +156,7 @@
.audit-result-tree li.parent::before {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
float: left;
width: 8px;
@@ -167,7 +171,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.audit-result-tree li.parent::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/breakpointsList.css b/chromium/third_party/WebKit/Source/devtools/front_end/breakpointsList.css
index afe528c70e7..d91363c51d2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/breakpointsList.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/breakpointsList.css
@@ -35,6 +35,11 @@
margin-right: 8px;
}
+.breakpoint-list .editing.being-edited {
+ overflow: hidden;
+ white-space: nowrap;
+}
+
#breakpoint-condition-input {
display: block;
margin-left: 0;
@@ -96,6 +101,11 @@ li.breakpoint-hit .breakpoint-hit-marker {
z-index: -1;
}
+.event-listener-breakpoints.properties-tree li {
+ height: 16px;
+ padding-top: 3px;
+}
+
.event-listener-breakpoints.properties-tree .children li {
margin-left: 12px;
height: 16px;
@@ -103,8 +113,7 @@ li.breakpoint-hit .breakpoint-hit-marker {
.event-listener-breakpoints .checkbox-elem {
float: left;
- top: -2px;
position: relative;
- left: -1px;
+ top: 1px;
font-size: 10px;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/buildSystemOnly.js b/chromium/third_party/WebKit/Source/devtools/front_end/buildSystemOnly.js
deleted file mode 100644
index 7be07f72081..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/buildSystemOnly.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * This flag notifies inspector that it was deployed with the help
- * of a build system. Build system flattenes all css and js files,
- * so in this case inspector has to correct paths for dynamic resource loading.
- */
-window.flattenImports = true;
-window.DEBUG = false; \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/canvasProfiler.css b/chromium/third_party/WebKit/Source/devtools/front_end/canvasProfiler.css
index 22604b93dbc..bb8e267f5da 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/canvasProfiler.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/canvasProfiler.css
@@ -63,10 +63,10 @@
bottom: 6px;
}
-.canvas-spinner-icon {
- content: url(Images/spinnerActiveSelected.gif);
+.canvas-profile-view .spinner-icon {
position: absolute;
width: 16px;
+ height: 16px;
right: 4px;
bottom: 4px;
}
@@ -83,13 +83,8 @@
border: none;
}
-button.status-bar-item.canvas-sidebar-show-hide-button {
- right: 15px;
- z-index: 13;
-}
-
-button.status-bar-item.canvas-sidebar-show-hide-button.toggled-left {
- right: 0;
+.canvas-profile-view button.right-sidebar-show-hide-button.canvas-sidebar-show-hide-button.toggled-hide {
+ margin-right: 15px;
}
.canvas-replay-button {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/clike.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/clike.js
index 3fcc1a757b2..f6626cd0ea2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/clike.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/clike.js
@@ -158,7 +158,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
electricChars: "{}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
- lineComment: "//"
+ lineComment: "//",
+ fold: "brace"
};
});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js
index 88718b77292..6cabed6ecad 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/closebrackets.js
@@ -1,8 +1,17 @@
-(function() {
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
var DEFAULT_BRACKETS = "()[]{}''\"\"";
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
var SPACE_CHAR_REGEX = /\s/;
+ var Pos = CodeMirror.Pos;
+
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseBrackets");
@@ -19,8 +28,8 @@
});
function charsAround(cm, pos) {
- var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1),
- CodeMirror.Pos(pos.line, pos.ch + 1));
+ var str = cm.getRange(Pos(pos.line, pos.ch - 1),
+ Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null;
}
@@ -28,55 +37,103 @@
var map = {
name : "autoCloseBrackets",
Backspace: function(cm) {
- if (cm.somethingSelected()) return CodeMirror.Pass;
- var cur = cm.getCursor(), around = charsAround(cm, cur);
- if (around && pairs.indexOf(around) % 2 == 0)
- cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1));
- else
- return CodeMirror.Pass;
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
+ var ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++) {
+ if (!ranges[i].empty()) return CodeMirror.Pass;
+ var around = charsAround(cm, ranges[i].head);
+ if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
+ }
+ for (var i = ranges.length - 1; i >= 0; i--) {
+ var cur = ranges[i].head;
+ cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
+ }
}
};
var closingBrackets = "";
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
if (left != right) closingBrackets += right;
- function surround(cm) {
- var selection = cm.getSelection();
- cm.replaceSelection(left + selection + right);
- }
- function maybeOverwrite(cm) {
- var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1));
- if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass;
- else cm.execCommand("goCharRight");
- }
map["'" + left + "'"] = function(cm) {
- if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment")
- return CodeMirror.Pass;
- if (cm.somethingSelected()) return surround(cm);
- if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return;
- var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1);
- var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch), curChar = cur.ch > 0 ? line.charAt(cur.ch - 1) : "";
- if (left == right && CodeMirror.isWordChar(curChar))
- return CodeMirror.Pass;
- if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar))
- cm.replaceSelection(left + right, {head: ahead, anchor: ahead});
- else
- return CodeMirror.Pass;
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
+ var ranges = cm.listSelections(), type, next;
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i], cur = range.head, curType;
+ if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
+ return CodeMirror.Pass;
+ var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
+ if (!range.empty())
+ curType = "surround";
+ else if (left == right && next == right) {
+ if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
+ curType = "skipThree";
+ else
+ curType = "skip";
+ } else if (left == right && cur.ch > 1 &&
+ cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left)
+ curType = "addFour";
+ else if (left == right && CodeMirror.isWordChar(next))
+ return CodeMirror.Pass;
+ else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
+ curType = "both";
+ else
+ return CodeMirror.Pass;
+ if (!type) type = curType;
+ else if (type != curType) return CodeMirror.Pass;
+ }
+
+ cm.operation(function() {
+ if (type == "skip") {
+ cm.execCommand("goCharRight");
+ } else if (type == "skipThree") {
+ for (var i = 0; i < 3; i++)
+ cm.execCommand("goCharRight");
+ } else if (type == "surround") {
+ var sels = cm.getSelections();
+ for (var i = 0; i < sels.length; i++)
+ sels[i] = left + sels[i] + right;
+ cm.replaceSelections(sels, "around");
+ } else if (type == "both") {
+ cm.replaceSelection(left + right, null);
+ cm.execCommand("goCharLeft");
+ } else if (type == "addFour") {
+ cm.replaceSelection(left + left + left + left, "before");
+ cm.execCommand("goCharRight");
+ }
+ });
+ };
+ if (left != right) map["'" + right + "'"] = function(cm) {
+ var ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i];
+ if (!range.empty() ||
+ cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
+ return CodeMirror.Pass;
+ }
+ cm.execCommand("goCharRight");
};
- if (left != right) map["'" + right + "'"] = maybeOverwrite;
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
}
function buildExplodeHandler(pairs) {
return function(cm) {
- var cur = cm.getCursor(), around = charsAround(cm, cur);
- if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
+ if (cm.getOption("disableInput")) return CodeMirror.Pass;
+ var ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++) {
+ if (!ranges[i].empty()) return CodeMirror.Pass;
+ var around = charsAround(cm, ranges[i].head);
+ if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
+ }
cm.operation(function() {
- var newPos = CodeMirror.Pos(cur.line + 1, 0);
- cm.replaceSelection("\n\n", {anchor: newPos, head: newPos}, "+input");
- cm.indentLine(cur.line + 1, null, true);
- cm.indentLine(cur.line + 2, null, true);
+ cm.replaceSelection("\n\n", null);
+ cm.execCommand("goCharLeft");
+ ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++) {
+ var line = ranges[i].head.line;
+ cm.indentLine(line, null, true);
+ cm.indentLine(line + 1, null, true);
+ }
});
};
}
-})();
+});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/cmdevtools.css b/chromium/third_party/WebKit/Source/devtools/front_end/cm/cmdevtools.css
index 8d9501cd591..68069fc0fe6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/cmdevtools.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/cmdevtools.css
@@ -49,10 +49,18 @@
to { background-color: white; }
}
+.cm-highlight.cm-execution-line {
+ -webkit-animation: "fadeout-execution-line" 1s 0s;
+}
+@-webkit-keyframes fadeout-execution-line {
+ from {background-color: rgb(121, 141, 254); }
+ to { background-color: rgb(171, 191, 254); }
+}
+
.cm-breakpoint .CodeMirror-linenumber {
color: white;
border-width: 1px 4px 1px 1px !important;
- -webkit-border-image: url(Images/breakpoint2.png) 1 4 1 1;
+ -webkit-border-image: url(Images/breakpoint.png) 1 4 1 1;
margin: 0px 0px 0px 3px !important;
padding-right: 3px;
padding-left: 1px;
@@ -61,15 +69,15 @@
}
.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {
- -webkit-border-image: url(Images/breakpointConditional2.png) 1 4 1 1;
+ -webkit-border-image: url(Images/breakpointConditional.png) 1 4 1 1;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
.cm-breakpoint .CodeMirror-linenumber {
- -webkit-border-image: url(Images/breakpoint2_2x.png) 2 8 2 2;
+ -webkit-border-image: url(Images/breakpoint_2x.png) 2 8 2 2;
}
.cm-breakpoint.cm-breakpoint-conditional .CodeMirror-linenumber {
- -webkit-border-image: url(Images/breakpointConditional2_2x.png) 2 8 2 2;
+ -webkit-border-image: url(Images/breakpointConditional_2x.png) 2 8 2 2;
}
} /* media */
@@ -120,7 +128,7 @@
}
.cm-execution-line {
- background-color: rgb(171, 191, 254) !important;
+ background-color: rgb(171, 191, 254);
outline: 1px solid rgb(64, 115, 244);
}
@@ -234,3 +242,8 @@
background-color: rgb(100%, 42%, 42%);
border: 2px solid rgb(100%, 31%, 31%);
}
+
+/** @see crbug.com/358161 */
+.CodeMirror .CodeMirror-vscrollbar, .CodeMirror .CodeMirror-hscrollbar {
+ -webkit-transform: translateZ(0);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.css b/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.css
index 4e300b2be2e..098a317a229 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.css
@@ -36,13 +36,14 @@
min-width: 20px;
text-align: right;
color: #999;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
}
/* CURSOR */
.CodeMirror div.CodeMirror-cursor {
border-left: 1px solid black;
- z-index: 3;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
@@ -52,29 +53,33 @@
width: auto;
border: 0;
background: #7e7;
- z-index: 1;
}
/* Can style cursor different in overwrite (non-insert) mode */
-.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
+div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-tab { display: inline-block; }
+.CodeMirror-ruler {
+ border-left: 1px solid #ccc;
+ position: absolute;
+}
+
/* DEFAULT THEME */
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
-.cm-s-default .cm-variable {color: black;}
+.cm-s-default .cm-variable,
+.cm-s-default .cm-punctuation,
+.cm-s-default .cm-property,
+.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
-.cm-s-default .cm-property {color: black;}
-.cm-s-default .cm-operator {color: black;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
-.cm-s-default .cm-error {color: #f00;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
@@ -91,6 +96,7 @@
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
+.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
@@ -114,7 +120,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
- padding-bottom: 30px; padding-right: 30px;
+ padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
@@ -123,6 +129,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
}
.CodeMirror-sizer {
position: relative;
+ border-right: 30px solid transparent;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@@ -197,16 +206,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
white-space: pre-wrap;
word-break: normal;
}
-.CodeMirror-code pre {
- border-right: 30px solid transparent;
- width: -webkit-fit-content;
- width: -moz-fit-content;
- width: fit-content;
-}
-.CodeMirror-wrap .CodeMirror-code pre {
- border-right: none;
- width: auto;
-}
+
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
@@ -236,16 +236,22 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror div.CodeMirror-cursor {
position: absolute;
- visibility: hidden;
border-right: none;
width: 0;
}
-.CodeMirror-focused div.CodeMirror-cursor {
+
+div.CodeMirror-cursors {
+ visibility: hidden;
+ position: relative;
+ z-index: 1;
+}
+.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
+.CodeMirror-crosshair { cursor: crosshair; }
.cm-searching {
background: #ffa;
@@ -255,9 +261,12 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }
+/* Used to force a border model for a node */
+.cm-force-border { padding-right: .1px; }
+
@media print {
/* Hide the cursor when printing */
- .CodeMirror div.CodeMirror-cursor {
+ .CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.js
index a14ce5358f4..ddb25146188 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/codemirror.js
@@ -1,22 +1,41 @@
-// CodeMirror is the only global var we claim
-window.CodeMirror = (function() {
+// CodeMirror 4.1.1, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// This is CodeMirror (http://codemirror.net), a code editor
+// implemented in JavaScript on top of the browser's DOM.
+//
+// You can find some technical background for some of the code below
+// at http://marijnhaverbeke.nl/blog/#cm-internals .
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ module.exports = mod();
+ else if (typeof define == "function" && define.amd) // AMD
+ return define([], mod);
+ else // Plain browser env
+ this.CodeMirror = mod();
+})(function() {
"use strict";
// BROWSER SNIFFING
- // Crude, but necessary to handle a number of hard-to-feature-detect
- // bugs and behavior differences.
+ // Kludges for bugs and behavior differences that can't be feature
+ // detected are enabled based on userAgent etc sniffing.
+
var gecko = /gecko\/\d/i.test(navigator.userAgent);
- var ie = /MSIE \d/.test(navigator.userAgent);
- var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
- var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+ // ie_uptoN means Internet Explorer version N or lower
+ var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
+ var ie_upto7 = ie_upto10 && (document.documentMode == null || document.documentMode < 8);
+ var ie_upto8 = ie_upto10 && (document.documentMode == null || document.documentMode < 9);
+ var ie_upto9 = ie_upto10 && (document.documentMode == null || document.documentMode < 10);
+ var ie_11up = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent);
+ var ie = ie_upto10 || ie_11up;
var webkit = /WebKit\//.test(navigator.userAgent);
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
var chrome = /Chrome\//.test(navigator.userAgent);
- var opera = /Opera\//.test(navigator.userAgent);
+ var presto = /Opera\//.test(navigator.userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
var khtml = /KHTML\//.test(navigator.userAgent);
- var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
var phantom = /PhantomJS/.test(navigator.userAgent);
@@ -26,151 +45,182 @@ window.CodeMirror = (function() {
var mac = ios || /Mac/.test(navigator.platform);
var windows = /win/i.test(navigator.platform);
- var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
- if (opera_version) opera_version = Number(opera_version[1]);
- if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
+ var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
+ if (presto_version) presto_version = Number(presto_version[1]);
+ if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
- var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
- var captureMiddleClick = gecko || (ie && !ie_lt9);
+ var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
+ var captureRightClick = gecko || (ie && !ie_upto8);
- // Optimize some code when these features are not used
+ // Optimize some code when these features are not used.
var sawReadOnlySpans = false, sawCollapsedSpans = false;
- // CONSTRUCTOR
+ // EDITOR CONSTRUCTOR
+
+ // A CodeMirror instance represents an editor. This is the object
+ // that user code is usually dealing with.
function CodeMirror(place, options) {
if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
this.options = options = options || {};
// Determine effective options based on given values and defaults.
- for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
- options[opt] = defaults[opt];
+ copyObj(defaults, options, false);
setGuttersForLineNumbers(options);
- var docStart = typeof options.value == "string" ? 0 : options.value.first;
- var display = this.display = makeDisplay(place, docStart);
+ var doc = options.value;
+ if (typeof doc == "string") doc = new Doc(doc, options.mode);
+ this.doc = doc;
+
+ var display = this.display = new Display(place, doc);
display.wrapper.CodeMirror = this;
updateGutters(this);
- if (options.autofocus && !mobile) focusInput(this);
-
- this.state = {keyMaps: [],
- overlays: [],
- modeGen: 0,
- overwrite: false, focused: false,
- suppressEdits: false, pasteIncoming: false,
- draggingText: false,
- highlight: new Delayed()};
-
themeChanged(this);
if (options.lineWrapping)
this.display.wrapper.className += " CodeMirror-wrap";
+ if (options.autofocus && !mobile) focusInput(this);
- var doc = options.value;
- if (typeof doc == "string") doc = new Doc(options.value, options.mode);
- operation(this, attachDoc)(this, doc);
+ this.state = {
+ keyMaps: [], // stores maps added by addKeyMap
+ overlays: [], // highlighting overlays, as added by addOverlay
+ modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
+ overwrite: false, focused: false,
+ suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
+ pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
+ draggingText: false,
+ highlight: new Delayed() // stores highlight worker timeout
+ };
// Override magic textarea content restore that IE sometimes does
// on our hidden textarea on reload
- if (ie) setTimeout(bind(resetInput, this, true), 20);
+ if (ie_upto10) setTimeout(bind(resetInput, this, true), 20);
registerEventHandlers(this);
- // IE throws unspecified error in certain cases, when
- // trying to access activeElement before onload
- var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
- if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
- else onBlur(this);
+ ensureGlobalHandlers();
+
+ var cm = this;
+ runInOp(this, function() {
+ cm.curOp.forceUpdate = true;
+ attachDoc(cm, doc);
+
+ if ((options.autofocus && !mobile) || activeElt() == display.input)
+ setTimeout(bind(onFocus, cm), 20);
+ else
+ onBlur(cm);
- operation(this, function() {
- for (var opt in optionHandlers)
- if (optionHandlers.propertyIsEnumerable(opt))
- optionHandlers[opt](this, options[opt], Init);
- for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
- })();
+ for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
+ optionHandlers[opt](cm, options[opt], Init);
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm);
+ });
}
// DISPLAY CONSTRUCTOR
- function makeDisplay(place, docStart) {
- var d = {};
+ // The display handles the DOM integration, both for input reading
+ // and content drawing. It holds references to DOM nodes and
+ // display-related state.
+
+ function Display(place, doc) {
+ var d = this;
- var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
+ // The semihidden textarea that is focused when the editor is
+ // focused, and receives input.
+ var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
+ // The textarea is kept positioned near the cursor to prevent the
+ // fact that it'll be scrolled into view on input from scrolling
+ // our fake cursor out of view. On webkit, when wrap=off, paste is
+ // very slow. So make the area wide instead.
if (webkit) input.style.width = "1000px";
else input.setAttribute("wrap", "off");
- // if border: 0; -- iOS fails to open keyboard (issue #1287)
+ // If border: 0; -- iOS fails to open keyboard (issue #1287)
if (ios) input.style.border = "1px solid black";
input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
// Wraps and hides input textarea
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
- // The actual fake scrollbars.
- d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
- d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
+ // The fake scrollbar elements.
+ d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+ d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
+ // Covers bottom-right square when both scrollbars are present.
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
+ // Covers bottom of gutter when coverGutterNextToScrollbar is on
+ // and h scrollbar is present.
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
- // DIVs containing the selection and the actual code
+ // Will contain the actual code, positioned to cover the viewport.
d.lineDiv = elt("div", null, "CodeMirror-code");
+ // Elements are added to these to represent selection and cursors.
d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
- // Blinky cursor, and element used to ensure cursor fits at the end of a line
- d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
- // Secondary cursor, shown when on a 'jump' in bi-directional text
- d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
- // Used to measure text size
+ d.cursorDiv = elt("div", null, "CodeMirror-cursors");
+ // A visibility: hidden element used to find the size of things.
d.measure = elt("div", null, "CodeMirror-measure");
+ // When lines outside of the viewport are measured, they are drawn in this.
+ d.lineMeasure = elt("div", null, "CodeMirror-measure");
// Wraps everything that needs to exist inside the vertically-padded coordinate system
- d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
- null, "position: relative; outline: none");
- // Moved around its parent to cover visible view
+ d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
+ null, "position: relative; outline: none");
+ // Moved around its parent to cover visible view.
d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
- // Set to the height of the text, causes scrolling
+ // Set to the height of the document, allowing scrolling.
d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
- // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
+ // Behavior of elts with overflow: auto and padding is
+ // inconsistent across browsers. This is used to ensure the
+ // scrollable area is big enough.
d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
- // Will contain the gutters, if any
+ // Will contain the gutters, if any.
d.gutters = elt("div", null, "CodeMirror-gutters");
d.lineGutter = null;
- // Provides scrolling
+ // Actual scrollable element.
d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
d.scroller.setAttribute("tabIndex", "-1");
// The element in which the editor lives.
d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
- // Work around IE7 z-index bug
- if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
- if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
+ // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
+ if (ie_upto7) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
// Needed to hide big blue blinking cursor on Mobile Safari
if (ios) input.style.width = "0px";
if (!webkit) d.scroller.draggable = true;
// Needed to handle Tab key in KHTML
if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
// Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
- else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
-
- // Current visible range (may be bigger than the view window).
- d.viewOffset = d.lastSizeC = 0;
- d.showingFrom = d.showingTo = docStart;
+ if (ie_upto7) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
+
+ if (place.appendChild) place.appendChild(d.wrapper);
+ else place(d.wrapper);
+
+ // Current rendered range (may be bigger than the view window).
+ d.viewFrom = d.viewTo = doc.first;
+ // Information about the rendered lines.
+ d.view = [];
+ // Holds info about a single rendered line when it was rendered
+ // for measurement, while not in view.
+ d.externalMeasured = null;
+ // Empty space (in pixels) above the view
+ d.viewOffset = 0;
+ d.lastSizeC = 0;
+ d.updateLineNumbers = null;
// Used to only resize the line number gutter when necessary (when
// the amount of lines crosses a boundary that makes its width change)
d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
// See readInput and resetInput
d.prevInput = "";
- // Set to true when a non-horizontal-scrolling widget is added. As
- // an optimization, widget aligning is skipped when d is false.
+ // Set to true when a non-horizontal-scrolling line widget is
+ // added. As an optimization, line widget aligning is skipped when
+ // this is false.
d.alignWidgets = false;
- // Flag that indicates whether we currently expect input to appear
- // (after some event like 'keypress' or 'input') and are polling
- // intensively.
+ // Flag that indicates whether we expect input to appear real soon
+ // now (after some event like 'keypress' or 'input') and are
+ // polling intensively.
d.pollingFast = false;
// Self-resetting timeout for the poller
d.poll = new Delayed();
- d.cachedCharWidth = d.cachedTextHeight = null;
- d.measureLineCache = [];
- d.measureLineCachePos = 0;
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
// Tracks when resetInput has punted to just putting a short
- // string instead of the (large) selection.
+ // string into the textarea instead of the full selection.
d.inaccurateSelection = false;
// Tracks the maximum line length so that the horizontal scrollbar
@@ -182,7 +232,12 @@ window.CodeMirror = (function() {
// Used for measuring wheel scrolling granularity
d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
- return d;
+ // True when shift is held down.
+ d.shift = false;
+
+ // Used to track whether anything happened since the context menu
+ // was opened.
+ d.selForContextMenu = null;
}
// STATE UPDATES
@@ -191,6 +246,10 @@ window.CodeMirror = (function() {
function loadMode(cm) {
cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
+ resetModeState(cm);
+ }
+
+ function resetModeState(cm) {
cm.doc.iter(function(line) {
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
@@ -203,11 +262,11 @@ window.CodeMirror = (function() {
function wrappingChanged(cm) {
if (cm.options.lineWrapping) {
- cm.display.wrapper.className += " CodeMirror-wrap";
+ addClass(cm.display.wrapper, "CodeMirror-wrap");
cm.display.sizer.style.minWidth = "";
} else {
- cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
- computeMaxLength(cm);
+ rmClass(cm.display.wrapper, "CodeMirror-wrap");
+ findMaxLine(cm);
}
estimateLineHeights(cm);
regChange(cm);
@@ -215,16 +274,24 @@ window.CodeMirror = (function() {
setTimeout(function(){updateScrollbars(cm);}, 100);
}
+ // Returns a function that estimates the height of a line, to use as
+ // first approximation until the line becomes visible (and is thus
+ // properly measurable).
function estimateHeight(cm) {
var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
return function(line) {
- if (lineIsHidden(cm.doc, line))
- return 0;
- else if (wrapping)
- return (Math.ceil(line.text.length / perLine) || 1) * th;
+ if (lineIsHidden(cm.doc, line)) return 0;
+
+ var widgetsHeight = 0;
+ if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
+ if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
+ }
+
+ if (wrapping)
+ return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
else
- return th;
+ return widgetsHeight + th;
};
}
@@ -240,7 +307,6 @@ window.CodeMirror = (function() {
var map = keyMap[cm.options.keyMap], style = map.style;
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
(style ? " cm-keymap-" + style : "");
- cm.state.disableInput = map.disableInput;
}
function themeChanged(cm) {
@@ -255,6 +321,8 @@ window.CodeMirror = (function() {
setTimeout(function(){alignHorizontally(cm);}, 20);
}
+ // Rebuild the gutter elements, ensure the margin to the left of the
+ // code matches their width.
function updateGutters(cm) {
var gutters = cm.display.gutters, specs = cm.options.gutters;
removeChildren(gutters);
@@ -267,33 +335,44 @@ window.CodeMirror = (function() {
}
}
gutters.style.display = i ? "" : "none";
+ updateGutterSpace(cm);
+ }
+
+ function updateGutterSpace(cm) {
+ var width = cm.display.gutters.offsetWidth;
+ cm.display.sizer.style.marginLeft = width + "px";
+ cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
}
- function lineLength(doc, line) {
+ // Compute the character length of a line, taking into account
+ // collapsed ranges (see markText) that might hide parts, and join
+ // other lines onto it.
+ function lineLength(line) {
if (line.height == 0) return 0;
var len = line.text.length, merged, cur = line;
while (merged = collapsedSpanAtStart(cur)) {
- var found = merged.find();
- cur = getLine(doc, found.from.line);
+ var found = merged.find(0, true);
+ cur = found.from.line;
len += found.from.ch - found.to.ch;
}
cur = line;
while (merged = collapsedSpanAtEnd(cur)) {
- var found = merged.find();
+ var found = merged.find(0, true);
len -= cur.text.length - found.from.ch;
- cur = getLine(doc, found.to.line);
+ cur = found.to.line;
len += cur.text.length - found.to.ch;
}
return len;
}
- function computeMaxLength(cm) {
+ // Find the longest line in the document.
+ function findMaxLine(cm) {
var d = cm.display, doc = cm.doc;
d.maxLine = getLine(doc, doc.first);
- d.maxLineLength = lineLength(doc, d.maxLine);
+ d.maxLineLength = lineLength(d.maxLine);
d.maxLineChanged = true;
doc.iter(function(line) {
- var len = lineLength(doc, line);
+ var len = lineLength(line);
if (len > d.maxLineLength) {
d.maxLineLength = len;
d.maxLine = line;
@@ -309,27 +388,39 @@ window.CodeMirror = (function() {
options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
} else if (found > -1 && !options.lineNumbers) {
options.gutters = options.gutters.slice(0);
- options.gutters.splice(i, 1);
+ options.gutters.splice(found, 1);
}
}
// SCROLLBARS
+ // Prepare DOM reads needed to update the scrollbars. Done in one
+ // shot to minimize update/measure roundtrips.
+ function measureForScrollbars(cm) {
+ var scroll = cm.display.scroller;
+ return {
+ clientHeight: scroll.clientHeight,
+ barHeight: cm.display.scrollbarV.clientHeight,
+ scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth,
+ barWidth: cm.display.scrollbarH.clientWidth,
+ docHeight: Math.round(cm.doc.height + paddingVert(cm.display))
+ };
+ }
+
// Re-synchronize the fake scrollbars with the actual size of the
- // content. Optionally force a scrollTop.
- function updateScrollbars(cm) {
- var d = cm.display, docHeight = cm.doc.height;
- var totalHeight = docHeight + paddingVert(d);
- d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
- d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
- var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
- var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
- var needsV = scrollHeight > (d.scroller.clientHeight + 1);
+ // content.
+ function updateScrollbars(cm, measure) {
+ if (!measure) measure = measureForScrollbars(cm);
+ var d = cm.display;
+ var scrollHeight = measure.docHeight + scrollerCutOff;
+ var needsH = measure.scrollWidth > measure.clientWidth;
+ var needsV = scrollHeight > measure.clientHeight;
if (needsV) {
d.scrollbarV.style.display = "block";
d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
+ // A bug in IE8 can cause this value to be negative, so guard it.
d.scrollbarV.firstChild.style.height =
- (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
+ Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
} else {
d.scrollbarV.style.display = "";
d.scrollbarV.firstChild.style.height = "0";
@@ -338,7 +429,7 @@ window.CodeMirror = (function() {
d.scrollbarH.style.display = "block";
d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
d.scrollbarH.firstChild.style.width =
- (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
+ (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
} else {
d.scrollbarH.style.display = "";
d.scrollbarH.firstChild.style.width = "0";
@@ -353,33 +444,67 @@ window.CodeMirror = (function() {
d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
} else d.gutterFiller.style.display = "";
- if (mac_geLion && scrollbarWidth(d.measure) === 0)
- d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
+ if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) {
+ if (scrollbarWidth(d.measure) === 0) {
+ var w = mac && !mac_geMountainLion ? "12px" : "18px";
+ d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w;
+ var barMouseDown = function(e) {
+ if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
+ operation(cm, onMouseDown)(e);
+ };
+ on(d.scrollbarV, "mousedown", barMouseDown);
+ on(d.scrollbarH, "mousedown", barMouseDown);
+ }
+ cm.state.checkedOverlayScrollbar = true;
+ }
}
+ // Compute the lines that are visible in a given viewport (defaults
+ // the the current scroll position). viewPort may contain top,
+ // height, and ensure (see op.scrollToPos) properties.
function visibleLines(display, doc, viewPort) {
- var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
- if (typeof viewPort == "number") top = viewPort;
- else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
+ var top = viewPort && viewPort.top != null ? Math.max(0, viewPort.top) : display.scroller.scrollTop;
top = Math.floor(top - paddingTop(display));
- var bottom = Math.ceil(top + height);
- return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
+ var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight;
+
+ var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
+ // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
+ // forces those lines into the viewport (if possible).
+ if (viewPort && viewPort.ensure) {
+ var ensureFrom = viewPort.ensure.from.line, ensureTo = viewPort.ensure.to.line;
+ if (ensureFrom < from)
+ return {from: ensureFrom,
+ to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
+ if (Math.min(ensureTo, doc.lastLine()) >= to)
+ return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
+ to: ensureTo};
+ }
+ return {from: from, to: to};
}
// LINE NUMBERS
+ // Re-align line numbers and gutter marks to compensate for
+ // horizontal scrolling.
function alignHorizontally(cm) {
- var display = cm.display;
+ var display = cm.display, view = display.view;
if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
- var gutterW = display.gutters.offsetWidth, l = comp + "px";
- for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
- for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
+ var gutterW = display.gutters.offsetWidth, left = comp + "px";
+ for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
+ if (cm.options.fixedGutter && view[i].gutter)
+ view[i].gutter.style.left = left;
+ var align = view[i].alignable;
+ if (align) for (var j = 0; j < align.length; j++)
+ align[j].style.left = left;
}
if (cm.options.fixedGutter)
display.gutters.style.left = (comp + gutterW) + "px";
}
+ // Used to ensure that the line number gutter is still the right
+ // size for the current document size. Returns true when an update
+ // is needed.
function maybeUpdateLineNumberWidth(cm) {
if (!cm.options.lineNumbers) return false;
var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
@@ -392,6 +517,7 @@ window.CodeMirror = (function() {
display.lineNumWidth = display.lineNumInnerWidth + padding;
display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
display.lineGutter.style.width = display.lineNumWidth + "px";
+ updateGutterSpace(cm);
return true;
}
return false;
@@ -400,191 +526,192 @@ window.CodeMirror = (function() {
function lineNumberFor(options, i) {
return String(options.lineNumberFormatter(i + options.firstLineNumber));
}
+
+ // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
+ // but using getBoundingClientRect to get a sub-pixel-accurate
+ // result.
function compensateForHScroll(display) {
- return getRect(display.scroller).left - getRect(display.sizer).left;
+ return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
}
// DISPLAY DRAWING
- function updateDisplay(cm, changes, viewPort, forced) {
- var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
+ // Updates the display, selection, and scrollbars, using the
+ // information in display.view to find out which nodes are no longer
+ // up-to-date. Tries to bail out early when no changes are needed,
+ // unless forced is true.
+ // Returns true if an actual update happened, false otherwise.
+ function updateDisplay(cm, viewPort, forced) {
+ var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated;
var visible = visibleLines(cm.display, cm.doc, viewPort);
- for (;;) {
+ for (var first = true;; first = false) {
var oldWidth = cm.display.scroller.clientWidth;
- if (!updateDisplayInner(cm, changes, visible, forced)) break;
+ if (!updateDisplayInner(cm, visible, forced)) break;
updated = true;
- changes = [];
+
+ // If the max line changed since it was last measured, measure it,
+ // and ensure the document's width matches it.
+ if (cm.display.maxLineChanged && !cm.options.lineWrapping)
+ adjustContentWidth(cm);
+
+ var barMeasure = measureForScrollbars(cm);
updateSelection(cm);
- updateScrollbars(cm);
- if (cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
+ setDocumentHeight(cm, barMeasure);
+ updateScrollbars(cm, barMeasure);
+ if (webkit && cm.options.lineWrapping)
+ checkForWebkitWidthBug(cm, barMeasure); // (Issue #2420)
+ if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
forced = true;
continue;
}
forced = false;
- // Clip forced viewport to actual scrollable area
- if (viewPort)
- viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
- typeof viewPort == "number" ? viewPort : viewPort.top);
+ // Clip forced viewport to actual scrollable area.
+ if (viewPort && viewPort.top != null)
+ viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)};
+ // Updated line heights might result in the drawn area not
+ // actually covering the viewport. Keep looping until it does.
visible = visibleLines(cm.display, cm.doc, viewPort);
- if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
+ if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo)
break;
}
+ cm.display.updateLineNumbers = null;
if (updated) {
signalLater(cm, "update", cm);
- if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
- signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
+ if (cm.display.viewFrom != oldFrom || cm.display.viewTo != oldTo)
+ signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
}
return updated;
}
- // Uses a set of changes plus the current scroll position to
- // determine which DOM updates have to be made, and makes the
- // updates.
- function updateDisplayInner(cm, changes, visible, forced) {
+ // Does the actual updating of the line display. Bails out
+ // (returning false) when there is nothing to be done and forced is
+ // false.
+ function updateDisplayInner(cm, visible, forced) {
var display = cm.display, doc = cm.doc;
- if (!display.wrapper.clientWidth) {
- display.showingFrom = display.showingTo = doc.first;
- display.viewOffset = 0;
+ if (!display.wrapper.offsetWidth) {
+ resetView(cm);
return;
}
// Bail out if the visible area is already rendered and nothing changed.
- if (!forced && changes.length == 0 &&
- visible.from > display.showingFrom && visible.to < display.showingTo)
+ if (!forced && visible.from >= display.viewFrom && visible.to <= display.viewTo &&
+ countDirtyView(cm) == 0)
return;
if (maybeUpdateLineNumberWidth(cm))
- changes = [{from: doc.first, to: doc.first + doc.size}];
- var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
- display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
-
- // Used to determine which lines need their line numbers updated
- var positionsChangedFrom = Infinity;
- if (cm.options.lineNumbers)
- for (var i = 0; i < changes.length; ++i)
- if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; }
+ resetView(cm);
+ var dims = getDimensions(cm);
+ // Compute a suitable new viewport (from & to)
var end = doc.first + doc.size;
var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
var to = Math.min(end, visible.to + cm.options.viewportMargin);
- if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
- if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
+ if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
+ if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
if (sawCollapsedSpans) {
- from = lineNo(visualLine(doc, getLine(doc, from)));
- while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
- }
-
- // Create a range of theoretically intact lines, and punch holes
- // in that using the change info.
- var intact = [{from: Math.max(display.showingFrom, doc.first),
- to: Math.min(display.showingTo, end)}];
- if (intact[0].from >= intact[0].to) intact = [];
- else intact = computeIntact(intact, changes);
- // When merged lines are present, we might have to reduce the
- // intact ranges because changes in continued fragments of the
- // intact lines do require the lines to be redrawn.
- if (sawCollapsedSpans)
- for (var i = 0; i < intact.length; ++i) {
- var range = intact[i], merged;
- while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
- var newTo = merged.find().from.line;
- if (newTo > range.from) range.to = newTo;
- else { intact.splice(i--, 1); break; }
- }
- }
-
- // Clip off the parts that won't be visible
- var intactLines = 0;
- for (var i = 0; i < intact.length; ++i) {
- var range = intact[i];
- if (range.from < from) range.from = from;
- if (range.to > to) range.to = to;
- if (range.from >= range.to) intact.splice(i--, 1);
- else intactLines += range.to - range.from;
- }
- if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
- updateViewOffset(cm);
- return;
+ from = visualLineNo(cm.doc, from);
+ to = visualLineEndNo(cm.doc, to);
}
- intact.sort(function(a, b) {return a.from - b.from;});
- // Avoid crashing on IE's "unspecified error" when in iframes
- try {
- var focused = document.activeElement;
- } catch(e) {}
- if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
- patchDisplay(cm, from, to, intact, positionsChangedFrom);
- display.lineDiv.style.display = "";
- if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
-
- var different = from != display.showingFrom || to != display.showingTo ||
+ var different = from != display.viewFrom || to != display.viewTo ||
display.lastSizeC != display.wrapper.clientHeight;
- // This is just a bogus formula that detects when the editor is
- // resized or the font size changes.
+ adjustView(cm, from, to);
+
+ display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
+ // Position the mover div to align with the current scroll position
+ cm.display.mover.style.top = display.viewOffset + "px";
+
+ var toUpdate = countDirtyView(cm);
+ if (!different && toUpdate == 0 && !forced) return;
+
+ // For big changes, we hide the enclosing element during the
+ // update, since that speeds up the operations on most browsers.
+ var focused = activeElt();
+ if (toUpdate > 4) display.lineDiv.style.display = "none";
+ patchDisplay(cm, display.updateLineNumbers, dims);
+ if (toUpdate > 4) display.lineDiv.style.display = "";
+ // There might have been a widget with a focused element that got
+ // hidden or updated, if so re-focus it.
+ if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
+
+ // Prevent selection and cursors from interfering with the scroll
+ // width.
+ removeChildren(display.cursorDiv);
+ removeChildren(display.selectionDiv);
+
if (different) {
display.lastSizeC = display.wrapper.clientHeight;
startWorker(cm, 400);
}
- display.showingFrom = from; display.showingTo = to;
updateHeightsInViewport(cm);
- updateViewOffset(cm);
return true;
}
+ function adjustContentWidth(cm) {
+ var display = cm.display;
+ var width = measureChar(cm, display.maxLine, display.maxLine.text.length).left;
+ display.maxLineChanged = false;
+ var minWidth = Math.max(0, width + 3);
+ var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + minWidth + scrollerCutOff - display.scroller.clientWidth);
+ display.sizer.style.minWidth = minWidth + "px";
+ if (maxScrollLeft < cm.doc.scrollLeft)
+ setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
+ }
+
+ function setDocumentHeight(cm, measure) {
+ cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
+ cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
+ }
+
+ function checkForWebkitWidthBug(cm, measure) {
+ // Work around Webkit bug where it sometimes reserves space for a
+ // non-existing phantom scrollbar in the scroller (Issue #2420)
+ if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) {
+ cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px";
+ cm.display.gutters.style.height = measure.docHeight + "px";
+ }
+ }
+
+ // Read the actual heights of the rendered lines, and update their
+ // stored heights to match.
function updateHeightsInViewport(cm) {
var display = cm.display;
var prevBottom = display.lineDiv.offsetTop;
- for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
- if (ie_lt8) {
- var bot = node.offsetTop + node.offsetHeight;
+ for (var i = 0; i < display.view.length; i++) {
+ var cur = display.view[i], height;
+ if (cur.hidden) continue;
+ if (ie_upto7) {
+ var bot = cur.node.offsetTop + cur.node.offsetHeight;
height = bot - prevBottom;
prevBottom = bot;
} else {
- var box = getRect(node);
+ var box = cur.node.getBoundingClientRect();
height = box.bottom - box.top;
}
- var diff = node.lineObj.height - height;
+ var diff = cur.line.height - height;
if (height < 2) height = textHeight(display);
if (diff > .001 || diff < -.001) {
- updateLineHeight(node.lineObj, height);
- var widgets = node.lineObj.widgets;
- if (widgets) for (var i = 0; i < widgets.length; ++i)
- widgets[i].height = widgets[i].node.offsetHeight;
+ updateLineHeight(cur.line, height);
+ updateWidgetHeight(cur.line);
+ if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
+ updateWidgetHeight(cur.rest[j]);
}
}
}
- function updateViewOffset(cm) {
- var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
- // Position the mover div to align with the current virtual scroll position
- cm.display.mover.style.top = off + "px";
- }
-
- function computeIntact(intact, changes) {
- for (var i = 0, l = changes.length || 0; i < l; ++i) {
- var change = changes[i], intact2 = [], diff = change.diff || 0;
- for (var j = 0, l2 = intact.length; j < l2; ++j) {
- var range = intact[j];
- if (change.to <= range.from && change.diff) {
- intact2.push({from: range.from + diff, to: range.to + diff});
- } else if (change.to <= range.from || change.from >= range.to) {
- intact2.push(range);
- } else {
- if (change.from > range.from)
- intact2.push({from: range.from, to: change.from});
- if (change.to < range.to)
- intact2.push({from: change.to + diff, to: range.to + diff});
- }
- }
- intact = intact2;
- }
- return intact;
+ // Read and store the height of line widgets associated with the
+ // given line.
+ function updateWidgetHeight(line) {
+ if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
+ line.widgets[i].height = line.widgets[i].node.offsetHeight;
}
+ // Do a bulk-read of the DOM positions and sizes needed to draw the
+ // view, so that we don't interleave reading and writing to the DOM.
function getDimensions(cm) {
var d = cm.display, left = {}, width = {};
for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
@@ -598,154 +725,207 @@ window.CodeMirror = (function() {
wrapperWidth: d.wrapper.clientWidth};
}
- function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
- var dims = getDimensions(cm);
+ // Sync the actual display DOM structure with display.view, removing
+ // nodes for lines that are no longer in view, and creating the ones
+ // that are not there yet, and updating the ones that are out of
+ // date.
+ function patchDisplay(cm, updateNumbersFrom, dims) {
var display = cm.display, lineNumbers = cm.options.lineNumbers;
- if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
- removeChildren(display.lineDiv);
var container = display.lineDiv, cur = container.firstChild;
function rm(node) {
var next = node.nextSibling;
- if (webkit && mac && cm.display.currentWheelTarget == node) {
+ // Works around a throw-scroll bug in OS X Webkit
+ if (webkit && mac && cm.display.currentWheelTarget == node)
node.style.display = "none";
- node.lineObj = null;
- } else {
+ else
node.parentNode.removeChild(node);
- }
return next;
}
- var nextIntact = intact.shift(), lineN = from;
- cm.doc.iter(from, to, function(line) {
- if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
- if (lineIsHidden(cm.doc, line)) {
- if (line.height != 0) updateLineHeight(line, 0);
- if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
- var w = line.widgets[i];
- if (w.showIfHidden) {
- var prev = cur.previousSibling;
- if (/pre/i.test(prev.nodeName)) {
- var wrap = elt("div", null, null, "position: relative");
- prev.parentNode.replaceChild(wrap, prev);
- wrap.appendChild(prev);
- prev = wrap;
- }
- var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
- if (!w.handleMouseEvents) wnode.ignoreEvents = true;
- positionLineWidget(w, wnode, prev, dims);
- }
+ var view = display.view, lineN = display.viewFrom;
+ // Loop over the elements in the view, syncing cur (the DOM nodes
+ // in display.lineDiv) with the view as we go.
+ for (var i = 0; i < view.length; i++) {
+ var lineView = view[i];
+ if (lineView.hidden) {
+ } else if (!lineView.node) { // Not drawn yet
+ var node = buildLineElement(cm, lineView, lineN, dims);
+ container.insertBefore(node, cur);
+ } else { // Already drawn
+ while (cur != lineView.node) cur = rm(cur);
+ var updateNumber = lineNumbers && updateNumbersFrom != null &&
+ updateNumbersFrom <= lineN && lineView.lineNumber;
+ if (lineView.changes) {
+ if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
+ updateLineForChanges(cm, lineView, lineN, dims);
}
- } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
- // This line is intact. Skip to the actual node. Update its
- // line number if needed.
- while (cur.lineObj != line) cur = rm(cur);
- if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
- setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
- cur = cur.nextSibling;
- } else {
- // For lines with widgets, make an attempt to find and reuse
- // the existing element, so that widgets aren't needlessly
- // removed and re-inserted into the dom
- if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
- if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
- // This line needs to be generated.
- var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
- if (lineNode != reuse) {
- container.insertBefore(lineNode, cur);
- } else {
- while (cur != reuse) cur = rm(cur);
- cur = cur.nextSibling;
+ if (updateNumber) {
+ removeChildren(lineView.lineNumber);
+ lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
}
-
- lineNode.lineObj = line;
+ cur = lineView.node.nextSibling;
}
- ++lineN;
- });
+ lineN += lineView.size;
+ }
while (cur) cur = rm(cur);
}
- function buildLineElement(cm, line, lineNo, dims, reuse) {
- var built = buildLineContent(cm, line), lineElement = built.pre;
- var markers = line.gutterMarkers, display = cm.display, wrap;
-
- var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass;
- if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets)
- return lineElement;
+ // When an aspect of a line changes, a string is added to
+ // lineView.changes. This updates the relevant part of the line's
+ // DOM structure.
+ function updateLineForChanges(cm, lineView, lineN, dims) {
+ for (var j = 0; j < lineView.changes.length; j++) {
+ var type = lineView.changes[j];
+ if (type == "text") updateLineText(cm, lineView);
+ else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
+ else if (type == "class") updateLineClasses(lineView);
+ else if (type == "widget") updateLineWidgets(lineView, dims);
+ }
+ lineView.changes = null;
+ }
- // Lines with gutter elements, widgets or a background class need
- // to be wrapped again, and have the extra elements added to the
- // wrapper div
+ // Lines with gutter elements, widgets or a background class need to
+ // be wrapped, and have the extra elements added to the wrapper div
+ function ensureLineWrapped(lineView) {
+ if (lineView.node == lineView.text) {
+ lineView.node = elt("div", null, null, "position: relative");
+ if (lineView.text.parentNode)
+ lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
+ lineView.node.appendChild(lineView.text);
+ if (ie_upto7) lineView.node.style.zIndex = 2;
+ }
+ return lineView.node;
+ }
- if (reuse) {
- reuse.alignable = null;
- var isOk = true, widgetsSeen = 0, insertBefore = null;
- for (var n = reuse.firstChild, next; n; n = next) {
- next = n.nextSibling;
- if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
- reuse.removeChild(n);
- } else {
- for (var i = 0; i < line.widgets.length; ++i) {
- var widget = line.widgets[i];
- if (widget.node == n.firstChild) {
- if (!widget.above && !insertBefore) insertBefore = n;
- positionLineWidget(widget, n, reuse, dims);
- ++widgetsSeen;
- break;
- }
- }
- if (i == line.widgets.length) { isOk = false; break; }
- }
- }
- reuse.insertBefore(lineElement, insertBefore);
- if (isOk && widgetsSeen == line.widgets.length) {
- wrap = reuse;
- reuse.className = line.wrapClass || "";
- }
+ function updateLineBackground(lineView) {
+ var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
+ if (cls) cls += " CodeMirror-linebackground";
+ if (lineView.background) {
+ if (cls) lineView.background.className = cls;
+ else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
+ } else if (cls) {
+ var wrap = ensureLineWrapped(lineView);
+ lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
}
- if (!wrap) {
- wrap = elt("div", null, line.wrapClass, "position: relative");
- wrap.appendChild(lineElement);
+ }
+
+ // Wrapper around buildLineContent which will reuse the structure
+ // in display.externalMeasured when possible.
+ function getLineContent(cm, lineView) {
+ var ext = cm.display.externalMeasured;
+ if (ext && ext.line == lineView.line) {
+ cm.display.externalMeasured = null;
+ lineView.measure = ext.measure;
+ return ext.built;
}
- // Kludge to make sure the styled element lies behind the selection (by z-index)
- if (bgClass)
- wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild);
+ return buildLineContent(cm, lineView);
+ }
+
+ // Redraw the line's text. Interacts with the background and text
+ // classes because the mode may output tokens that influence these
+ // classes.
+ function updateLineText(cm, lineView) {
+ var cls = lineView.text.className;
+ var built = getLineContent(cm, lineView);
+ if (lineView.text == lineView.node) lineView.node = built.pre;
+ lineView.text.parentNode.replaceChild(built.pre, lineView.text);
+ lineView.text = built.pre;
+ if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
+ lineView.bgClass = built.bgClass;
+ lineView.textClass = built.textClass;
+ updateLineClasses(lineView);
+ } else if (cls) {
+ lineView.text.className = cls;
+ }
+ }
+
+ function updateLineClasses(lineView) {
+ updateLineBackground(lineView);
+ if (lineView.line.wrapClass)
+ ensureLineWrapped(lineView).className = lineView.line.wrapClass;
+ else if (lineView.node != lineView.text)
+ lineView.node.className = "";
+ var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
+ lineView.text.className = textClass || "";
+ }
+
+ function updateLineGutter(cm, lineView, lineN, dims) {
+ if (lineView.gutter) {
+ lineView.node.removeChild(lineView.gutter);
+ lineView.gutter = null;
+ }
+ var markers = lineView.line.gutterMarkers;
if (cm.options.lineNumbers || markers) {
- var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
- (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
- wrap.firstChild);
- if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
+ var wrap = ensureLineWrapped(lineView);
+ var gutterWrap = lineView.gutter =
+ wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
+ lineView.text);
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
- wrap.lineNumber = gutterWrap.appendChild(
- elt("div", lineNumberFor(cm.options, lineNo),
+ lineView.lineNumber = gutterWrap.appendChild(
+ elt("div", lineNumberFor(cm.options, lineN),
"CodeMirror-linenumber CodeMirror-gutter-elt",
"left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
- + display.lineNumInnerWidth + "px"));
- if (markers)
- for (var k = 0; k < cm.options.gutters.length; ++k) {
- var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
- if (found)
- gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
- dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
- }
+ + cm.display.lineNumInnerWidth + "px"));
+ if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
+ if (found)
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
+ }
}
- if (ie_lt8) wrap.style.zIndex = 2;
- if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
+ }
+
+ function updateLineWidgets(lineView, dims) {
+ if (lineView.alignable) lineView.alignable = null;
+ for (var node = lineView.node.firstChild, next; node; node = next) {
+ var next = node.nextSibling;
+ if (node.className == "CodeMirror-linewidget")
+ lineView.node.removeChild(node);
+ }
+ insertLineWidgets(lineView, dims);
+ }
+
+ // Build a line's DOM representation from scratch
+ function buildLineElement(cm, lineView, lineN, dims) {
+ var built = getLineContent(cm, lineView);
+ lineView.text = lineView.node = built.pre;
+ if (built.bgClass) lineView.bgClass = built.bgClass;
+ if (built.textClass) lineView.textClass = built.textClass;
+
+ updateLineClasses(lineView);
+ updateLineGutter(cm, lineView, lineN, dims);
+ insertLineWidgets(lineView, dims);
+ return lineView.node;
+ }
+
+ // A lineView may contain multiple logical lines (when merged by
+ // collapsed spans). The widgets for all of them need to be drawn.
+ function insertLineWidgets(lineView, dims) {
+ insertLineWidgetsFor(lineView.line, lineView, dims, true);
+ if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+ insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
+ }
+
+ function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
+ if (!line.widgets) return;
+ var wrap = ensureLineWrapped(lineView);
+ for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
if (!widget.handleMouseEvents) node.ignoreEvents = true;
- positionLineWidget(widget, node, wrap, dims);
- if (widget.above)
- wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
+ positionLineWidget(widget, node, lineView, dims);
+ if (allowAbove && widget.above)
+ wrap.insertBefore(node, lineView.gutter || lineView.text);
else
wrap.appendChild(node);
signalLater(widget, "redraw");
}
- return wrap;
}
- function positionLineWidget(widget, node, wrap, dims) {
+ function positionLineWidget(widget, node, lineView, dims) {
if (widget.noHScroll) {
- (wrap.alignable || (wrap.alignable = [])).push(node);
+ (lineView.alignable || (lineView.alignable = [])).push(node);
var width = dims.wrapperWidth;
node.style.left = dims.fixedPos + "px";
if (!widget.coverGutter) {
@@ -761,57 +941,370 @@ window.CodeMirror = (function() {
}
}
+ // POSITION OBJECT
+
+ // A Pos instance represents a position within the text.
+ var Pos = CodeMirror.Pos = function(line, ch) {
+ if (!(this instanceof Pos)) return new Pos(line, ch);
+ this.line = line; this.ch = ch;
+ };
+
+ // Compare two positions, return 0 if they are the same, a negative
+ // number when a is less, and a positive number otherwise.
+ var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
+
+ function copyPos(x) {return Pos(x.line, x.ch);}
+ function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
+ function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
+
// SELECTION / CURSOR
+ // Selection objects are immutable. A new one is created every time
+ // the selection changes. A selection is one or more non-overlapping
+ // (and non-touching) ranges, sorted, and an integer that indicates
+ // which one is the primary selection (the one that's scrolled into
+ // view, that getCursor returns, etc).
+ function Selection(ranges, primIndex) {
+ this.ranges = ranges;
+ this.primIndex = primIndex;
+ }
+
+ Selection.prototype = {
+ primary: function() { return this.ranges[this.primIndex]; },
+ equals: function(other) {
+ if (other == this) return true;
+ if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
+ for (var i = 0; i < this.ranges.length; i++) {
+ var here = this.ranges[i], there = other.ranges[i];
+ if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
+ }
+ return true;
+ },
+ deepCopy: function() {
+ for (var out = [], i = 0; i < this.ranges.length; i++)
+ out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
+ return new Selection(out, this.primIndex);
+ },
+ somethingSelected: function() {
+ for (var i = 0; i < this.ranges.length; i++)
+ if (!this.ranges[i].empty()) return true;
+ return false;
+ },
+ contains: function(pos, end) {
+ if (!end) end = pos;
+ for (var i = 0; i < this.ranges.length; i++) {
+ var range = this.ranges[i];
+ if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
+ return i;
+ }
+ return -1;
+ }
+ };
+
+ function Range(anchor, head) {
+ this.anchor = anchor; this.head = head;
+ }
+
+ Range.prototype = {
+ from: function() { return minPos(this.anchor, this.head); },
+ to: function() { return maxPos(this.anchor, this.head); },
+ empty: function() {
+ return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
+ }
+ };
+
+ // Take an unsorted, potentially overlapping set of ranges, and
+ // build a selection out of it. 'Consumes' ranges array (modifying
+ // it).
+ function normalizeSelection(ranges, primIndex) {
+ var prim = ranges[primIndex];
+ ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
+ primIndex = indexOf(ranges, prim);
+ for (var i = 1; i < ranges.length; i++) {
+ var cur = ranges[i], prev = ranges[i - 1];
+ if (cmp(prev.to(), cur.from()) >= 0) {
+ var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
+ var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
+ if (i <= primIndex) --primIndex;
+ ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
+ }
+ }
+ return new Selection(ranges, primIndex);
+ }
+
+ function simpleSelection(anchor, head) {
+ return new Selection([new Range(anchor, head || anchor)], 0);
+ }
+
+ // Most of the external API clips given positions to make sure they
+ // actually exist within the document.
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
+ function clipPos(doc, pos) {
+ if (pos.line < doc.first) return Pos(doc.first, 0);
+ var last = doc.first + doc.size - 1;
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
+ }
+ function clipToLen(pos, linelen) {
+ var ch = pos.ch;
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
+ else if (ch < 0) return Pos(pos.line, 0);
+ else return pos;
+ }
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
+ function clipPosArray(doc, array) {
+ for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
+ return out;
+ }
+
+ // SELECTION UPDATES
+
+ // The 'scroll' parameter given to many of these indicated whether
+ // the new cursor position should be scrolled into view after
+ // modifying the selection.
+
+ // If shift is held or the extend flag is set, extends a range to
+ // include a given position (and optionally a second position).
+ // Otherwise, simply returns the range between the given positions.
+ // Used for cursor motion and such.
+ function extendRange(doc, range, head, other) {
+ if (doc.cm && doc.cm.display.shift || doc.extend) {
+ var anchor = range.anchor;
+ if (other) {
+ var posBefore = cmp(head, anchor) < 0;
+ if (posBefore != (cmp(other, anchor) < 0)) {
+ anchor = head;
+ head = other;
+ } else if (posBefore != (cmp(head, other) < 0)) {
+ head = other;
+ }
+ }
+ return new Range(anchor, head);
+ } else {
+ return new Range(other || head, head);
+ }
+ }
+
+ // Extend the primary selection range, discard the rest.
+ function extendSelection(doc, head, other, options) {
+ setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
+ }
+
+ // Extend all selections (pos is an array of selections with length
+ // equal the number of selections)
+ function extendSelections(doc, heads, options) {
+ for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
+ out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
+ var newSel = normalizeSelection(out, doc.sel.primIndex);
+ setSelection(doc, newSel, options);
+ }
+
+ // Updates a single range in the selection.
+ function replaceOneSelection(doc, i, range, options) {
+ var ranges = doc.sel.ranges.slice(0);
+ ranges[i] = range;
+ setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
+ }
+
+ // Reset the selection to a single range.
+ function setSimpleSelection(doc, anchor, head, options) {
+ setSelection(doc, simpleSelection(anchor, head), options);
+ }
+
+ // Give beforeSelectionChange handlers a change to influence a
+ // selection update.
+ function filterSelectionChange(doc, sel) {
+ var obj = {
+ ranges: sel.ranges,
+ update: function(ranges) {
+ this.ranges = [];
+ for (var i = 0; i < ranges.length; i++)
+ this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
+ clipPos(doc, ranges[i].head));
+ }
+ };
+ signal(doc, "beforeSelectionChange", doc, obj);
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
+ if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
+ else return sel;
+ }
+
+ function setSelectionReplaceHistory(doc, sel, options) {
+ var done = doc.history.done, last = lst(done);
+ if (last && last.ranges) {
+ done[done.length - 1] = sel;
+ setSelectionNoUndo(doc, sel, options);
+ } else {
+ setSelection(doc, sel, options);
+ }
+ }
+
+ // Set a new selection.
+ function setSelection(doc, sel, options) {
+ setSelectionNoUndo(doc, sel, options);
+ addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
+ }
+
+ function setSelectionNoUndo(doc, sel, options) {
+ if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
+ sel = filterSelectionChange(doc, sel);
+
+ var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1;
+ setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
+
+ if (!(options && options.scroll === false) && doc.cm)
+ ensureCursorVisible(doc.cm);
+ }
+
+ function setSelectionInner(doc, sel) {
+ if (sel.equals(doc.sel)) return;
+
+ doc.sel = sel;
+
+ if (doc.cm) {
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
+ signalCursorActivity(doc.cm);
+ }
+ signalLater(doc, "cursorActivity", doc);
+ }
+
+ // Verify that the selection does not partially select any atomic
+ // marked ranges.
+ function reCheckSelection(doc) {
+ setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
+ }
+
+ // Return a selection that does not partially select any atomic
+ // ranges.
+ function skipAtomicInSelection(doc, sel, bias, mayClear) {
+ var out;
+ for (var i = 0; i < sel.ranges.length; i++) {
+ var range = sel.ranges[i];
+ var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
+ var newHead = skipAtomic(doc, range.head, bias, mayClear);
+ if (out || newAnchor != range.anchor || newHead != range.head) {
+ if (!out) out = sel.ranges.slice(0, i);
+ out[i] = new Range(newAnchor, newHead);
+ }
+ }
+ return out ? normalizeSelection(out, sel.primIndex) : sel;
+ }
+
+ // Ensure a given position is not inside an atomic range.
+ function skipAtomic(doc, pos, bias, mayClear) {
+ var flipped = false, curPos = pos;
+ var dir = bias || 1;
+ doc.cantEdit = false;
+ search: for (;;) {
+ var line = getLine(doc, curPos.line);
+ if (line.markedSpans) {
+ for (var i = 0; i < line.markedSpans.length; ++i) {
+ var sp = line.markedSpans[i], m = sp.marker;
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
+ (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
+ if (mayClear) {
+ signal(m, "beforeCursorEnter");
+ if (m.explicitlyCleared) {
+ if (!line.markedSpans) break;
+ else {--i; continue;}
+ }
+ }
+ if (!m.atomic) continue;
+ var newPos = m.find(dir < 0 ? -1 : 1);
+ if (cmp(newPos, curPos) == 0) {
+ newPos.ch += dir;
+ if (newPos.ch < 0) {
+ if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
+ else newPos = null;
+ } else if (newPos.ch > line.text.length) {
+ if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
+ else newPos = null;
+ }
+ if (!newPos) {
+ if (flipped) {
+ // Driven in a corner -- no valid cursor position found at all
+ // -- try again *with* clearing, if we didn't already
+ if (!mayClear) return skipAtomic(doc, pos, bias, true);
+ // Otherwise, turn off editing until further notice, and return the start of the doc
+ doc.cantEdit = true;
+ return Pos(doc.first, 0);
+ }
+ flipped = true; newPos = pos; dir = -dir;
+ }
+ }
+ curPos = newPos;
+ continue search;
+ }
+ }
+ }
+ return curPos;
+ }
+ }
+
+ // SELECTION DRAWING
+
+ // Redraw the selection and/or cursor
function updateSelection(cm) {
- var display = cm.display;
- var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
- if (collapsed || cm.options.showCursorWhenSelecting)
- updateSelectionCursor(cm);
- else
- display.cursor.style.display = display.otherCursor.style.display = "none";
- if (!collapsed)
- updateSelectionRange(cm);
- else
- display.selectionDiv.style.display = "none";
+ var display = cm.display, doc = cm.doc;
+ var curFragment = document.createDocumentFragment();
+ var selFragment = document.createDocumentFragment();
+
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
+ var range = doc.sel.ranges[i];
+ var collapsed = range.empty();
+ if (collapsed || cm.options.showCursorWhenSelecting)
+ drawSelectionCursor(cm, range, curFragment);
+ if (!collapsed)
+ drawSelectionRange(cm, range, selFragment);
+ }
// Move the hidden textarea near the cursor to prevent scrolling artifacts
if (cm.options.moveInputWithCursor) {
- var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
- var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
- display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
- headPos.top + lineOff.top - wrapOff.top)) + "px";
- display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
- headPos.left + lineOff.left - wrapOff.left)) + "px";
+ var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
+ var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
+ var top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
+ headPos.top + lineOff.top - wrapOff.top));
+ var left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
+ headPos.left + lineOff.left - wrapOff.left));
+ display.inputDiv.style.top = top + "px";
+ display.inputDiv.style.left = left + "px";
}
+
+ removeChildrenAndAdd(display.cursorDiv, curFragment);
+ removeChildrenAndAdd(display.selectionDiv, selFragment);
}
- // No selection, plain cursor
- function updateSelectionCursor(cm) {
- var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
- display.cursor.style.left = pos.left + "px";
- display.cursor.style.top = pos.top + "px";
- display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
- display.cursor.style.display = "";
+ // Draws a cursor for the given range
+ function drawSelectionCursor(cm, range, output) {
+ var pos = cursorCoords(cm, range.head, "div");
+
+ var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
+ cursor.style.left = pos.left + "px";
+ cursor.style.top = pos.top + "px";
+ cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
if (pos.other) {
- display.otherCursor.style.display = "";
- display.otherCursor.style.left = pos.other.left + "px";
- display.otherCursor.style.top = pos.other.top + "px";
- display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
- } else { display.otherCursor.style.display = "none"; }
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
+ var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
+ otherCursor.style.display = "";
+ otherCursor.style.left = pos.other.left + "px";
+ otherCursor.style.top = pos.other.top + "px";
+ otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
+ }
}
- // Highlight selection
- function updateSelectionRange(cm) {
- var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
+ // Draws the given range as a highlighted selection
+ function drawSelectionRange(cm, range, output) {
+ var display = cm.display, doc = cm.doc;
var fragment = document.createDocumentFragment();
- var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
+ var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
function add(left, top, width, bottom) {
if (top < 0) top = 0;
+ top = Math.round(top);
+ bottom = Math.round(bottom);
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
- "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
+ "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
"px; height: " + (bottom - top) + "px"));
}
@@ -834,44 +1327,44 @@ window.CodeMirror = (function() {
left = leftPos.left;
right = rightPos.right;
}
- if (fromArg == null && from == 0) left = pl;
+ if (fromArg == null && from == 0) left = leftSide;
if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
add(left, leftPos.top, null, leftPos.bottom);
- left = pl;
+ left = leftSide;
if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
}
- if (toArg == null && to == lineLen) right = clientWidth;
+ if (toArg == null && to == lineLen) right = rightSide;
if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
start = leftPos;
if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
end = rightPos;
- if (left < pl + 1) left = pl;
+ if (left < leftSide + 1) left = leftSide;
add(left, rightPos.top, right - left, rightPos.bottom);
});
return {start: start, end: end};
}
- if (sel.from.line == sel.to.line) {
- drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
+ var sFrom = range.from(), sTo = range.to();
+ if (sFrom.line == sTo.line) {
+ drawForLine(sFrom.line, sFrom.ch, sTo.ch);
} else {
- var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
- var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
- var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
- var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
+ var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
+ var singleVLine = visualLine(fromLine) == visualLine(toLine);
+ var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
+ var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
if (singleVLine) {
if (leftEnd.top < rightStart.top - 2) {
add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
- add(pl, rightStart.top, rightStart.left, rightStart.bottom);
+ add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
} else {
add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
}
}
if (leftEnd.bottom < rightStart.top)
- add(pl, leftEnd.bottom, null, rightStart.top);
+ add(leftSide, leftEnd.bottom, null, rightStart.top);
}
- removeChildrenAndAdd(display.selectionDiv, fragment);
- display.selectionDiv.style.display = "";
+ output.appendChild(fragment);
}
// Cursor-blinking
@@ -880,40 +1373,41 @@ window.CodeMirror = (function() {
var display = cm.display;
clearInterval(display.blinker);
var on = true;
- display.cursor.style.visibility = display.otherCursor.style.visibility = "";
+ display.cursorDiv.style.visibility = "";
if (cm.options.cursorBlinkRate > 0)
display.blinker = setInterval(function() {
- display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
+ display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
}, cm.options.cursorBlinkRate);
}
// HIGHLIGHT WORKER
function startWorker(cm, time) {
- if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
cm.state.highlight.set(time, bind(highlightWorker, cm));
}
function highlightWorker(cm) {
var doc = cm.doc;
if (doc.frontier < doc.first) doc.frontier = doc.first;
- if (doc.frontier >= cm.display.showingTo) return;
+ if (doc.frontier >= cm.display.viewTo) return;
var end = +new Date + cm.options.workTime;
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
- var changed = [], prevChange;
- doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
- if (doc.frontier >= cm.display.showingFrom) { // Visible
+
+ runInOp(cm, function() {
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
+ if (doc.frontier >= cm.display.viewFrom) { // Visible
var oldStyles = line.styles;
- line.styles = highlightLine(cm, line, state);
+ var highlighted = highlightLine(cm, line, state, true);
+ line.styles = highlighted.styles;
+ if (highlighted.classes) line.styleClasses = highlighted.classes;
+ else if (line.styleClasses) line.styleClasses = null;
var ischange = !oldStyles || oldStyles.length != line.styles.length;
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
- if (ischange) {
- if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
- else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
- }
+ if (ischange) regLineChange(cm, doc.frontier, "text");
line.stateAfter = copyState(doc.mode, state);
} else {
- processLine(cm, line, state);
+ processLine(cm, line.text, state);
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
}
++doc.frontier;
@@ -922,11 +1416,7 @@ window.CodeMirror = (function() {
return true;
}
});
- if (changed.length)
- operation(cm, function() {
- for (var i = 0; i < changed.length; ++i)
- regChange(this, changed[i].start, changed[i].end);
- })();
+ });
}
// Finds the line to start with when starting a parse. Tries to
@@ -935,8 +1425,9 @@ window.CodeMirror = (function() {
// smallest indentation, which tends to need the least context to
// parse correctly.
function findStartLine(cm, n, precise) {
- var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100;
- for (var search = n, lim = n - maxScan; search > lim; --search) {
+ var minindent, minline, doc = cm.doc;
+ var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
+ for (var search = n; search > lim; --search) {
if (search <= doc.first) return doc.first;
var line = getLine(doc, search - 1);
if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
@@ -956,11 +1447,12 @@ window.CodeMirror = (function() {
if (!state) state = startState(doc.mode);
else state = copyState(doc.mode, state);
doc.iter(pos, n, function(line) {
- processLine(cm, line, state);
- var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
+ processLine(cm, line.text, state);
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
line.stateAfter = save ? copyState(doc.mode, state) : null;
++pos;
});
+ if (precise) doc.frontier = pos;
return state;
}
@@ -968,183 +1460,223 @@ window.CodeMirror = (function() {
function paddingTop(display) {return display.lineSpace.offsetTop;}
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
- function paddingLeft(display) {
- var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
- return e.offsetLeft;
- }
-
- function measureChar(cm, line, ch, data, bias) {
- var dir = -1;
- data = data || measureLine(cm, line);
- if (data.crude) {
- var left = data.left + ch * data.width;
- return {left: left, right: left + data.width, top: data.top, bottom: data.bottom};
- }
-
- for (var pos = ch;; pos += dir) {
- var r = data[pos];
- if (r) break;
- if (dir < 0 && pos == 0) dir = 1;
- }
- bias = pos > ch ? "left" : pos < ch ? "right" : bias;
- if (bias == "left" && r.leftSide) r = r.leftSide;
- else if (bias == "right" && r.rightSide) r = r.rightSide;
- return {left: pos < ch ? r.right : r.left,
- right: pos > ch ? r.left : r.right,
- top: r.top,
- bottom: r.bottom};
- }
-
- function findCachedMeasurement(cm, line) {
- var cache = cm.display.measureLineCache;
- for (var i = 0; i < cache.length; ++i) {
- var memo = cache[i];
- if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
- cm.display.scroller.clientWidth == memo.width &&
- memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
- return memo;
- }
- }
-
- function clearCachedMeasurement(cm, line) {
- var exists = findCachedMeasurement(cm, line);
- if (exists) exists.text = exists.measure = exists.markedSpans = null;
- }
-
- function measureLine(cm, line) {
- // First look in the cache
- var cached = findCachedMeasurement(cm, line);
- if (cached) return cached.measure;
-
- // Failing that, recompute and store result in cache
- var measure = measureLineInner(cm, line);
- var cache = cm.display.measureLineCache;
- var memo = {text: line.text, width: cm.display.scroller.clientWidth,
- markedSpans: line.markedSpans, measure: measure,
- classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
- if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
- else cache.push(memo);
- return measure;
- }
-
- function measureLineInner(cm, line) {
- if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom)
- return crudelyMeasureLine(cm, line);
-
- var display = cm.display, measure = emptyArray(line.text.length);
- var pre = buildLineContent(cm, line, measure, true).pre;
-
- // IE does not cache element positions of inline elements between
- // calls to getBoundingClientRect. This makes the loop below,
- // which gathers the positions of all the characters on the line,
- // do an amount of layout work quadratic to the number of
- // characters. When line wrapping is off, we try to improve things
- // by first subdividing the line into a bunch of inline blocks, so
- // that IE can reuse most of the layout information from caches
- // for those blocks. This does interfere with line wrapping, so it
- // doesn't work when wrapping is on, but in that case the
- // situation is slightly better, since IE does cache line-wrapping
- // information and only recomputes per-line.
- if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
- var fragment = document.createDocumentFragment();
- var chunk = 10, n = pre.childNodes.length;
- for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
- var wrap = elt("div", null, null, "display: inline-block");
- for (var j = 0; j < chunk && n; ++j) {
- wrap.appendChild(pre.firstChild);
- --n;
+ function paddingH(display) {
+ if (display.cachedPaddingH) return display.cachedPaddingH;
+ var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
+ var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
+ var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
+ if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
+ return data;
+ }
+
+ // Ensure the lineView.wrapping.heights array is populated. This is
+ // an array of bottom offsets for the lines that make up a drawn
+ // line. When lineWrapping is on, there might be more than one
+ // height.
+ function ensureLineHeights(cm, lineView, rect) {
+ var wrapping = cm.options.lineWrapping;
+ var curWidth = wrapping && cm.display.scroller.clientWidth;
+ if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
+ var heights = lineView.measure.heights = [];
+ if (wrapping) {
+ lineView.measure.width = curWidth;
+ var rects = lineView.text.firstChild.getClientRects();
+ for (var i = 0; i < rects.length - 1; i++) {
+ var cur = rects[i], next = rects[i + 1];
+ if (Math.abs(cur.bottom - next.bottom) > 2)
+ heights.push((cur.bottom + next.top) / 2 - rect.top);
}
- fragment.appendChild(wrap);
}
- pre.appendChild(fragment);
- }
-
- removeChildrenAndAdd(display.measure, pre);
-
- var outer = getRect(display.lineDiv);
- var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
- // Work around an IE7/8 bug where it will sometimes have randomly
- // replaced our pre with a clone at this point.
- if (ie_lt9 && display.measure.first != pre)
- removeChildrenAndAdd(display.measure, pre);
+ heights.push(rect.bottom - rect.top);
+ }
+ }
+
+ // Find a line map (mapping character offsets to text nodes) and a
+ // measurement cache for the given line number. (A line view might
+ // contain multiple lines when collapsed ranges are present.)
+ function mapFromLineView(lineView, line, lineN) {
+ if (lineView.line == line)
+ return {map: lineView.measure.map, cache: lineView.measure.cache};
+ for (var i = 0; i < lineView.rest.length; i++)
+ if (lineView.rest[i] == line)
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
+ for (var i = 0; i < lineView.rest.length; i++)
+ if (lineNo(lineView.rest[i]) > lineN)
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
+ }
+
+ // Render a line into the hidden node display.externalMeasured. Used
+ // when measurement is needed for a line that's not in the viewport.
+ function updateExternalMeasurement(cm, line) {
+ line = visualLine(line);
+ var lineN = lineNo(line);
+ var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
+ view.lineN = lineN;
+ var built = view.built = buildLineContent(cm, view);
+ view.text = built.pre;
+ removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
+ return view;
+ }
+
+ // Get a {top, bottom, left, right} box (in line-local coordinates)
+ // for a given character.
+ function measureChar(cm, line, ch, bias) {
+ return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
+ }
+
+ // Find a line view that corresponds to the given line number.
+ function findViewForLine(cm, lineN) {
+ if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
+ return cm.display.view[findViewIndex(cm, lineN)];
+ var ext = cm.display.externalMeasured;
+ if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
+ return ext;
+ }
+
+ // Measurement can be split in two steps, the set-up work that
+ // applies to the whole line, and the measurement of the actual
+ // character. Functions like coordsChar, that need to do a lot of
+ // measurements in a row, can thus ensure that the set-up work is
+ // only done once.
+ function prepareMeasureForLine(cm, line) {
+ var lineN = lineNo(line);
+ var view = findViewForLine(cm, lineN);
+ if (view && !view.text)
+ view = null;
+ else if (view && view.changes)
+ updateLineForChanges(cm, view, lineN, getDimensions(cm));
+ if (!view)
+ view = updateExternalMeasurement(cm, line);
+
+ var info = mapFromLineView(view, line, lineN);
+ return {
+ line: line, view: view, rect: null,
+ map: info.map, cache: info.cache, before: info.before,
+ hasHeights: false
+ };
+ }
- function measureRect(rect) {
- var top = rect.top - outer.top, bot = rect.bottom - outer.top;
- if (bot > maxBot) bot = maxBot;
- if (top < 0) top = 0;
- for (var i = vranges.length - 2; i >= 0; i -= 2) {
- var rtop = vranges[i], rbot = vranges[i+1];
- if (rtop > bot || rbot < top) continue;
- if (rtop <= top && rbot >= bot ||
- top <= rtop && bot >= rbot ||
- Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
- vranges[i] = Math.min(top, rtop);
- vranges[i+1] = Math.max(bot, rbot);
- break;
- }
+ // Given a prepared measurement object, measures the position of an
+ // actual character (or fetches it from the cache).
+ function measureCharPrepared(cm, prepared, ch, bias) {
+ if (prepared.before) ch = -1;
+ var key = ch + (bias || ""), found;
+ if (prepared.cache.hasOwnProperty(key)) {
+ found = prepared.cache[key];
+ } else {
+ if (!prepared.rect)
+ prepared.rect = prepared.view.text.getBoundingClientRect();
+ if (!prepared.hasHeights) {
+ ensureLineHeights(cm, prepared.view, prepared.rect);
+ prepared.hasHeights = true;
}
- if (i < 0) { i = vranges.length; vranges.push(top, bot); }
- return {left: rect.left - outer.left,
- right: rect.right - outer.left,
- top: i, bottom: null};
- }
- function finishRect(rect) {
- rect.bottom = vranges[rect.top+1];
- rect.top = vranges[rect.top];
- }
-
- for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
- var node = cur, rect = null;
- // A widget might wrap, needs special care
- if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
- if (cur.firstChild.nodeType == 1) node = cur.firstChild;
- var rects = node.getClientRects();
- if (rects.length > 1) {
- rect = data[i] = measureRect(rects[0]);
- rect.rightSide = measureRect(rects[rects.length - 1]);
- }
+ found = measureCharInner(cm, prepared, ch, bias);
+ if (!found.bogus) prepared.cache[key] = found;
+ }
+ return {left: found.left, right: found.right, top: found.top, bottom: found.bottom};
+ }
+
+ var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
+
+ function measureCharInner(cm, prepared, ch, bias) {
+ var map = prepared.map;
+
+ var node, start, end, collapse;
+ // First, search the line map for the text node corresponding to,
+ // or closest to, the target character.
+ for (var i = 0; i < map.length; i += 3) {
+ var mStart = map[i], mEnd = map[i + 1];
+ if (ch < mStart) {
+ start = 0; end = 1;
+ collapse = "left";
+ } else if (ch < mEnd) {
+ start = ch - mStart;
+ end = start + 1;
+ } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
+ end = mEnd - mStart;
+ start = end - 1;
+ if (ch >= mEnd) collapse = "right";
+ }
+ if (start != null) {
+ node = map[i + 2];
+ if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
+ collapse = bias;
+ if (bias == "left" && start == 0)
+ while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
+ node = map[(i -= 3) + 2];
+ collapse = "left";
+ }
+ if (bias == "right" && start == mEnd - mStart)
+ while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
+ node = map[(i += 3) + 2];
+ collapse = "right";
+ }
+ break;
}
- if (!rect) rect = data[i] = measureRect(getRect(node));
- if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
- if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
- }
- removeChildren(cm.display.measure);
- for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
- finishRect(cur);
- if (cur.leftSide) finishRect(cur.leftSide);
- if (cur.rightSide) finishRect(cur.rightSide);
}
- return data;
- }
- function crudelyMeasureLine(cm, line) {
- var copy = new Line(line.text.slice(0, 100), null);
- if (line.textClass) copy.textClass = line.textClass;
- var measure = measureLineInner(cm, copy);
- var left = measureChar(cm, copy, 0, measure, "left");
- var right = measureChar(cm, copy, 99, measure, "right");
- return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100};
+ var rect;
+ if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
+ while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
+ while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
+ if (ie_upto8 && start == 0 && end == mEnd - mStart) {
+ rect = node.parentNode.getBoundingClientRect();
+ } else if (ie && cm.options.lineWrapping) {
+ var rects = range(node, start, end).getClientRects();
+ if (rects.length)
+ rect = rects[bias == "right" ? rects.length - 1 : 0];
+ else
+ rect = nullRect;
+ } else {
+ rect = range(node, start, end).getBoundingClientRect() || nullRect;
+ }
+ } else { // If it is a widget, simply get the box for the whole widget.
+ if (start > 0) collapse = bias = "right";
+ var rects;
+ if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
+ rect = rects[bias == "right" ? rects.length - 1 : 0];
+ else
+ rect = node.getBoundingClientRect();
+ }
+ if (ie_upto8 && !start && (!rect || !rect.left && !rect.right)) {
+ var rSpan = node.parentNode.getClientRects()[0];
+ if (rSpan)
+ rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
+ else
+ rect = nullRect;
+ }
+
+ var top, bot = (rect.bottom + rect.top) / 2 - prepared.rect.top;
+ var heights = prepared.view.measure.heights;
+ for (var i = 0; i < heights.length - 1; i++)
+ if (bot < heights[i]) break;
+ top = i ? heights[i - 1] : 0; bot = heights[i];
+ var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
+ right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
+ top: top, bottom: bot};
+ if (!rect.left && !rect.right) result.bogus = true;
+ return result;
}
- function measureLineWidth(cm, line) {
- var hasBadSpan = false;
- if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
- var sp = line.markedSpans[i];
- if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
+ function clearLineMeasurementCacheFor(lineView) {
+ if (lineView.measure) {
+ lineView.measure.cache = {};
+ lineView.measure.heights = null;
+ if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+ lineView.measure.caches[i] = {};
}
- var cached = !hasBadSpan && findCachedMeasurement(cm, line);
- if (cached || line.text.length >= cm.options.crudeMeasuringFrom)
- return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right;
+ }
- var pre = buildLineContent(cm, line, null, true).pre;
- var end = pre.appendChild(zeroWidthElement(cm.display.measure));
- removeChildrenAndAdd(cm.display.measure, pre);
- return getRect(end).right - getRect(cm.display.lineDiv).left;
+ function clearLineMeasurementCache(cm) {
+ cm.display.externalMeasure = null;
+ removeChildren(cm.display.lineMeasure);
+ for (var i = 0; i < cm.display.view.length; i++)
+ clearLineMeasurementCacheFor(cm.display.view[i]);
}
function clearCaches(cm) {
- cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
- cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
+ clearLineMeasurementCache(cm);
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
cm.display.lineNumChars = null;
}
@@ -1152,7 +1684,9 @@ window.CodeMirror = (function() {
function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
- // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
+ // Converts a {top, bottom, left, right} box from line-local
+ // coordinates into another coordinate system. Context may be one of
+ // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
function intoCoordSystem(cm, lineObj, rect, context) {
if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
var size = widgetHeight(lineObj.widgets[i]);
@@ -1160,11 +1694,11 @@ window.CodeMirror = (function() {
}
if (context == "line") return rect;
if (!context) context = "local";
- var yOff = heightAtLine(cm, lineObj);
+ var yOff = heightAtLine(lineObj);
if (context == "local") yOff += paddingTop(cm.display);
else yOff -= cm.display.viewOffset;
if (context == "page" || context == "window") {
- var lOff = getRect(cm.display.lineSpace);
+ var lOff = cm.display.lineSpace.getBoundingClientRect();
yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
rect.left += xOff; rect.right += xOff;
@@ -1173,8 +1707,8 @@ window.CodeMirror = (function() {
return rect;
}
- // Context may be "window", "page", "div", or "local"/null
- // Result is in "div" coords
+ // Coverts a box from "div" coords to another coordinate system.
+ // Context may be "window", "page", "div", or "local"/null.
function fromCoordSystem(cm, coords, context) {
if (context == "div") return coords;
var left = coords.left, top = coords.top;
@@ -1183,25 +1717,28 @@ window.CodeMirror = (function() {
left -= pageScrollX();
top -= pageScrollY();
} else if (context == "local" || !context) {
- var localBox = getRect(cm.display.sizer);
+ var localBox = cm.display.sizer.getBoundingClientRect();
left += localBox.left;
top += localBox.top;
}
- var lineSpaceBox = getRect(cm.display.lineSpace);
+ var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
}
function charCoords(cm, pos, context, lineObj, bias) {
if (!lineObj) lineObj = getLine(cm.doc, pos.line);
- return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
}
- function cursorCoords(cm, pos, context, lineObj, measurement) {
+ // Returns a box for a given cursor position, which may have an
+ // 'other' property containing the position of the secondary cursor
+ // on a bidi boundary.
+ function cursorCoords(cm, pos, context, lineObj, preparedMeasure) {
lineObj = lineObj || getLine(cm.doc, pos.line);
- if (!measurement) measurement = measureLine(cm, lineObj);
+ if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
function get(ch, right) {
- var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
+ var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left");
if (right) m.left = m.right; else m.right = m.left;
return intoCoordSystem(cm, lineObj, m, context);
}
@@ -1227,43 +1764,59 @@ window.CodeMirror = (function() {
return val;
}
+ // Used to cheaply estimate the coordinates for a position. Used for
+ // intermediate scroll updates.
+ function estimateCoords(cm, pos) {
+ var left = 0, pos = clipPos(cm.doc, pos);
+ if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
+ var lineObj = getLine(cm.doc, pos.line);
+ var top = heightAtLine(lineObj) + paddingTop(cm.display);
+ return {left: left, right: left, top: top, bottom: top + lineObj.height};
+ }
+
+ // Positions returned by coordsChar contain some extra information.
+ // xRel is the relative x position of the input coordinates compared
+ // to the found position (so xRel > 0 means the coordinates are to
+ // the right of the character position, for example). When outside
+ // is true, that means the coordinates lie outside the line's
+ // vertical range.
function PosWithInfo(line, ch, outside, xRel) {
- var pos = new Pos(line, ch);
+ var pos = Pos(line, ch);
pos.xRel = xRel;
if (outside) pos.outside = true;
return pos;
}
- // Coords must be lineSpace-local
+ // Compute the character position closest to the given coordinates.
+ // Input must be lineSpace-local ("div" coordinate system).
function coordsChar(cm, x, y) {
var doc = cm.doc;
y += cm.display.viewOffset;
if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
- var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
- if (lineNo > last)
+ var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
+ if (lineN > last)
return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
if (x < 0) x = 0;
+ var lineObj = getLine(doc, lineN);
for (;;) {
- var lineObj = getLine(doc, lineNo);
- var found = coordsCharInner(cm, lineObj, lineNo, x, y);
+ var found = coordsCharInner(cm, lineObj, lineN, x, y);
var merged = collapsedSpanAtEnd(lineObj);
- var mergedPos = merged && merged.find();
+ var mergedPos = merged && merged.find(0, true);
if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
- lineNo = mergedPos.to.line;
+ lineN = lineNo(lineObj = mergedPos.to.line);
else
return found;
}
}
function coordsCharInner(cm, lineObj, lineNo, x, y) {
- var innerOff = y - heightAtLine(cm, lineObj);
+ var innerOff = y - heightAtLine(lineObj);
var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
- var measurement = measureLine(cm, lineObj);
+ var preparedMeasure = prepareMeasureForLine(cm, lineObj);
function getX(ch) {
- var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
- lineObj, measurement);
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
wrongLine = true;
if (innerOff > sp.bottom) return sp.left - adjust;
else if (innerOff < sp.top) return sp.left + adjust;
@@ -1281,9 +1834,9 @@ window.CodeMirror = (function() {
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
var ch = x < fromX || x - fromX <= toX - x ? from : to;
var xDiff = x - (ch == from ? fromX : toX);
- while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
+ while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
- xDiff < 0 ? -1 : xDiff ? 1 : 0);
+ xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
return pos;
}
var step = Math.ceil(dist / 2), middle = from + step;
@@ -1298,6 +1851,7 @@ window.CodeMirror = (function() {
}
var measureText;
+ // Compute the default text height.
function textHeight(display) {
if (display.cachedTextHeight != null) return display.cachedTextHeight;
if (measureText == null) {
@@ -1317,81 +1871,92 @@ window.CodeMirror = (function() {
return height || 1;
}
+ // Compute the default character width.
function charWidth(display) {
if (display.cachedCharWidth != null) return display.cachedCharWidth;
- var anchor = elt("span", "x");
+ var anchor = elt("span", "xxxxxxxxxx");
var pre = elt("pre", [anchor]);
removeChildrenAndAdd(display.measure, pre);
- var width = anchor.offsetWidth;
+ var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
if (width > 2) display.cachedCharWidth = width;
return width || 10;
}
// OPERATIONS
- // Operations are used to wrap changes in such a way that each
- // change won't have to update the cursor and display (which would
- // be awkward, slow, and error-prone), but instead updates are
- // batched and then all combined and executed at once.
+ // Operations are used to wrap a series of changes to the editor
+ // state in such a way that each change won't have to update the
+ // cursor and display (which would be awkward, slow, and
+ // error-prone). Instead, display updates are batched and then all
+ // combined and executed at once.
var nextOpId = 0;
+ // Start a new operation.
function startOperation(cm) {
cm.curOp = {
- // An array of ranges of lines that have to be updated. See
- // updateDisplay.
- changes: [],
- forceUpdate: false,
- updateInput: null,
- userSelChange: null,
- textChanged: null,
- selectionChanged: false,
- cursorActivity: false,
- updateMaxLine: false,
- updateScrollPos: false,
- id: ++nextOpId
+ viewChanged: false, // Flag that indicates that lines might need to be redrawn
+ startHeight: cm.doc.height, // Used to detect need to update scrollbar
+ forceUpdate: false, // Used to force a redraw
+ updateInput: null, // Whether to reset the input textarea
+ typing: false, // Whether this reset should be careful to leave existing text (for compositing)
+ changeObjs: null, // Accumulated changes, for firing change events
+ cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
+ selectionChanged: false, // Whether the selection needs to be redrawn
+ updateMaxLine: false, // Set when the widest line needs to be determined anew
+ scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
+ scrollToPos: null, // Used to scroll to a specific position
+ id: ++nextOpId // Unique ID
};
if (!delayedCallbackDepth++) delayedCallbacks = [];
}
+ // Finish an operation, updating the display and signalling delayed events
function endOperation(cm) {
var op = cm.curOp, doc = cm.doc, display = cm.display;
cm.curOp = null;
- if (op.updateMaxLine) computeMaxLength(cm);
- if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
- var width = measureLineWidth(cm, display.maxLine);
- display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
- display.maxLineChanged = false;
- var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
- if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
- setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
- }
- var newScrollPos, updated;
- if (op.updateScrollPos) {
- newScrollPos = op.updateScrollPos;
- } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
- var coords = cursorCoords(cm, doc.sel.head);
- newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
- }
- if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
- updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
+ if (op.updateMaxLine) findMaxLine(cm);
+
+ // If it looks like an update might be needed, call updateDisplay
+ if (op.viewChanged || op.forceUpdate || op.scrollTop != null ||
+ op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
+ op.scrollToPos.to.line >= display.viewTo) ||
+ display.maxLineChanged && cm.options.lineWrapping) {
+ var updated = updateDisplay(cm, {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
}
+ // If no update was run, but the selection changed, redraw that.
if (!updated && op.selectionChanged) updateSelection(cm);
- if (op.updateScrollPos) {
- display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
- display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
+ if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm);
+
+ // Abort mouse wheel delta measurement, when scrolling explicitly
+ if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
+ display.wheelStartX = display.wheelStartY = null;
+
+ // Propagate the scroll position to the actual DOM scroller
+ if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) {
+ var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
+ }
+ if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) {
+ var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
alignHorizontally(cm);
- if (op.scrollToPos)
- scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
- } else if (newScrollPos) {
- scrollCursorIntoView(cm);
}
+ // If we need to scroll a specific position into view, do so.
+ if (op.scrollToPos) {
+ var coords = scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from),
+ clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin);
+ if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
+ }
+
if (op.selectionChanged) restartBlink(cm);
if (cm.state.focused && op.updateInput)
- resetInput(cm, op.userSelChange);
+ resetInput(cm, op.typing);
+ // Fire events for markers that are hidden/unidden by editing or
+ // undoing
var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
if (hidden) for (var i = 0; i < hidden.length; ++i)
if (!hidden[i].lines.length) signal(hidden[i], "hide");
@@ -1403,47 +1968,242 @@ window.CodeMirror = (function() {
delayed = delayedCallbacks;
delayedCallbacks = null;
}
- if (op.textChanged)
- signal(cm, "change", cm, op.textChanged);
- if (op.cursorActivity) signal(cm, "cursorActivity", cm);
+ // Fire change events, and delayed event handlers
+ if (op.changeObjs)
+ signal(cm, "changes", cm, op.changeObjs);
if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
+ if (op.cursorActivityHandlers)
+ for (var i = 0; i < op.cursorActivityHandlers.length; i++)
+ op.cursorActivityHandlers[i](cm);
}
+ // Run the given function in an operation
+ function runInOp(cm, f) {
+ if (cm.curOp) return f();
+ startOperation(cm);
+ try { return f(); }
+ finally { endOperation(cm); }
+ }
// Wraps a function in an operation. Returns the wrapped function.
- function operation(cm1, f) {
+ function operation(cm, f) {
return function() {
- var cm = cm1 || this, withOp = !cm.curOp;
- if (withOp) startOperation(cm);
- try { var result = f.apply(cm, arguments); }
- finally { if (withOp) endOperation(cm); }
- return result;
+ if (cm.curOp) return f.apply(cm, arguments);
+ startOperation(cm);
+ try { return f.apply(cm, arguments); }
+ finally { endOperation(cm); }
};
}
- function docOperation(f) {
+ // Used to add methods to editor and doc instances, wrapping them in
+ // operations.
+ function methodOp(f) {
return function() {
- var withOp = this.cm && !this.cm.curOp, result;
- if (withOp) startOperation(this.cm);
- try { result = f.apply(this, arguments); }
- finally { if (withOp) endOperation(this.cm); }
- return result;
+ if (this.curOp) return f.apply(this, arguments);
+ startOperation(this);
+ try { return f.apply(this, arguments); }
+ finally { endOperation(this); }
};
}
- function runInOp(cm, f) {
- var withOp = !cm.curOp, result;
- if (withOp) startOperation(cm);
- try { result = f(); }
- finally { if (withOp) endOperation(cm); }
- return result;
+ function docMethodOp(f) {
+ return function() {
+ var cm = this.cm;
+ if (!cm || cm.curOp) return f.apply(this, arguments);
+ startOperation(cm);
+ try { return f.apply(this, arguments); }
+ finally { endOperation(cm); }
+ };
+ }
+
+ // VIEW TRACKING
+
+ // These objects are used to represent the visible (currently drawn)
+ // part of the document. A LineView may correspond to multiple
+ // logical lines, if those are connected by collapsed ranges.
+ function LineView(doc, line, lineN) {
+ // The starting line
+ this.line = line;
+ // Continuing lines, if any
+ this.rest = visualLineContinued(line);
+ // Number of logical lines in this visual line
+ this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
+ this.node = this.text = null;
+ this.hidden = lineIsHidden(doc, line);
}
+ // Create a range of LineView objects for the given lines.
+ function buildViewArray(cm, from, to) {
+ var array = [], nextPos;
+ for (var pos = from; pos < to; pos = nextPos) {
+ var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
+ nextPos = pos + view.size;
+ array.push(view);
+ }
+ return array;
+ }
+
+ // Updates the display.view data structure for a given change to the
+ // document. From and to are in pre-change coordinates. Lendiff is
+ // the amount of lines added or subtracted by the change. This is
+ // used for changes that span multiple lines, or change the way
+ // lines are divided into visual lines. regLineChange (below)
+ // registers single-line changes.
function regChange(cm, from, to, lendiff) {
if (from == null) from = cm.doc.first;
if (to == null) to = cm.doc.first + cm.doc.size;
- cm.curOp.changes.push({from: from, to: to, diff: lendiff});
+ if (!lendiff) lendiff = 0;
+
+ var display = cm.display;
+ if (lendiff && to < display.viewTo &&
+ (display.updateLineNumbers == null || display.updateLineNumbers > from))
+ display.updateLineNumbers = from;
+
+ cm.curOp.viewChanged = true;
+
+ if (from >= display.viewTo) { // Change after
+ if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
+ resetView(cm);
+ } else if (to <= display.viewFrom) { // Change before
+ if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
+ resetView(cm);
+ } else {
+ display.viewFrom += lendiff;
+ display.viewTo += lendiff;
+ }
+ } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
+ resetView(cm);
+ } else if (from <= display.viewFrom) { // Top overlap
+ var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
+ if (cut) {
+ display.view = display.view.slice(cut.index);
+ display.viewFrom = cut.lineN;
+ display.viewTo += lendiff;
+ } else {
+ resetView(cm);
+ }
+ } else if (to >= display.viewTo) { // Bottom overlap
+ var cut = viewCuttingPoint(cm, from, from, -1);
+ if (cut) {
+ display.view = display.view.slice(0, cut.index);
+ display.viewTo = cut.lineN;
+ } else {
+ resetView(cm);
+ }
+ } else { // Gap in the middle
+ var cutTop = viewCuttingPoint(cm, from, from, -1);
+ var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
+ if (cutTop && cutBot) {
+ display.view = display.view.slice(0, cutTop.index)
+ .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
+ .concat(display.view.slice(cutBot.index));
+ display.viewTo += lendiff;
+ } else {
+ resetView(cm);
+ }
+ }
+
+ var ext = display.externalMeasured;
+ if (ext) {
+ if (to < ext.lineN)
+ ext.lineN += lendiff;
+ else if (from < ext.lineN + ext.size)
+ display.externalMeasured = null;
+ }
+ }
+
+ // Register a change to a single line. Type must be one of "text",
+ // "gutter", "class", "widget"
+ function regLineChange(cm, line, type) {
+ cm.curOp.viewChanged = true;
+ var display = cm.display, ext = cm.display.externalMeasured;
+ if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
+ display.externalMeasured = null;
+
+ if (line < display.viewFrom || line >= display.viewTo) return;
+ var lineView = display.view[findViewIndex(cm, line)];
+ if (lineView.node == null) return;
+ var arr = lineView.changes || (lineView.changes = []);
+ if (indexOf(arr, type) == -1) arr.push(type);
+ }
+
+ // Clear the view.
+ function resetView(cm) {
+ cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
+ cm.display.view = [];
+ cm.display.viewOffset = 0;
+ }
+
+ // Find the view element corresponding to a given line. Return null
+ // when the line isn't visible.
+ function findViewIndex(cm, n) {
+ if (n >= cm.display.viewTo) return null;
+ n -= cm.display.viewFrom;
+ if (n < 0) return null;
+ var view = cm.display.view;
+ for (var i = 0; i < view.length; i++) {
+ n -= view[i].size;
+ if (n < 0) return i;
+ }
+ }
+
+ function viewCuttingPoint(cm, oldN, newN, dir) {
+ var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
+ if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
+ return {index: index, lineN: newN};
+ for (var i = 0, n = cm.display.viewFrom; i < index; i++)
+ n += view[i].size;
+ if (n != oldN) {
+ if (dir > 0) {
+ if (index == view.length - 1) return null;
+ diff = (n + view[index].size) - oldN;
+ index++;
+ } else {
+ diff = n - oldN;
+ }
+ oldN += diff; newN += diff;
+ }
+ while (visualLineNo(cm.doc, newN) != newN) {
+ if (index == (dir < 0 ? 0 : view.length - 1)) return null;
+ newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
+ index += dir;
+ }
+ return {index: index, lineN: newN};
+ }
+
+ // Force the view to cover a given range, adding empty view element
+ // or clipping off existing ones as needed.
+ function adjustView(cm, from, to) {
+ var display = cm.display, view = display.view;
+ if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
+ display.view = buildViewArray(cm, from, to);
+ display.viewFrom = from;
+ } else {
+ if (display.viewFrom > from)
+ display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
+ else if (display.viewFrom < from)
+ display.view = display.view.slice(findViewIndex(cm, from));
+ display.viewFrom = from;
+ if (display.viewTo < to)
+ display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
+ else if (display.viewTo > to)
+ display.view = display.view.slice(0, findViewIndex(cm, to));
+ }
+ display.viewTo = to;
+ }
+
+ // Count the number of lines in the view whose DOM representation is
+ // out of date (or nonexistent).
+ function countDirtyView(cm) {
+ var view = cm.display.view, dirty = 0;
+ for (var i = 0; i < view.length; i++) {
+ var lineView = view[i];
+ if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
+ }
+ return dirty;
}
// INPUT HANDLING
+ // Poll for input changes, using the normal rate of polling. This
+ // runs as long as the editor is focused.
function slowPoll(cm) {
if (cm.display.pollingFast) return;
cm.display.poll.set(cm.options.pollInterval, function() {
@@ -1452,6 +2212,9 @@ window.CodeMirror = (function() {
});
}
+ // When an event has just come in that is likely to add or change
+ // something in the input textarea, we poll faster, to ensure that
+ // the change appears on the screen quickly.
function fastPoll(cm) {
var missed = false;
cm.display.pollingFast = true;
@@ -1463,100 +2226,155 @@ window.CodeMirror = (function() {
cm.display.poll.set(20, p);
}
- // prevInput is a hack to work with IME. If we reset the textarea
- // on every change, that breaks IME. So we look for changes
- // compared to the previous content instead. (Modern browsers have
- // events that indicate IME taking place, but these are not widely
- // supported or compatible enough yet to rely on.)
+ // Read input from the textarea, and update the document to match.
+ // When something is selected, it is present in the textarea, and
+ // selected (unless it is huge, in which case a placeholder is
+ // used). When nothing is selected, the cursor sits after previously
+ // seen text (can be empty), which is stored in prevInput (we must
+ // not reset the textarea when typing, because that breaks IME).
function readInput(cm) {
- var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
- if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
+ var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
+ // Since this is called a *lot*, try to bail out as cheaply as
+ // possible when it is clear that nothing happened. hasSelection
+ // will be the case when there is a lot of text in the textarea,
+ // in which case reading its value would be expensive.
+ if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput)
+ return false;
+ // See paste handler for more on the fakedLastChar kludge
if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
input.value = input.value.substring(0, input.value.length - 1);
cm.state.fakedLastChar = false;
}
var text = input.value;
- if (text == prevInput && posEq(sel.from, sel.to)) return false;
- if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
- resetInput(cm, true);
+ // If nothing changed, bail.
+ if (text == prevInput && !cm.somethingSelected()) return false;
+ // Work around nonsensical selection resetting in IE9/10
+ if (ie && !ie_upto8 && cm.display.inputHasSelection === text) {
+ resetInput(cm);
return false;
}
var withOp = !cm.curOp;
if (withOp) startOperation(cm);
- sel.shift = false;
+ cm.display.shift = false;
+
+ if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
+ prevInput = "\u200b";
+ // Find the part of the input that is actually new
var same = 0, l = Math.min(prevInput.length, text.length);
while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
- var from = sel.from, to = sel.to;
- if (same < prevInput.length)
- from = Pos(from.line, from.ch - (prevInput.length - same));
- else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
- to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
-
- var updateInput = cm.curOp.updateInput;
- var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
- origin: cm.state.pasteIncoming ? "paste" : "+input"};
- makeChange(cm.doc, changeEvent, "end");
+ var inserted = text.slice(same), textLines = splitLines(inserted);
+
+ // When pasing N lines into N selections, insert one line per selection
+ var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length;
+
+ // Normal behavior is to insert the new text into every selection
+ for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
+ var range = doc.sel.ranges[i];
+ var from = range.from(), to = range.to();
+ // Handle deletion
+ if (same < prevInput.length)
+ from = Pos(from.line, from.ch - (prevInput.length - same));
+ // Handle overwrite
+ else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
+ var updateInput = cm.curOp.updateInput;
+ var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines,
+ origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
+ makeChange(cm.doc, changeEvent);
+ signalLater(cm, "inputRead", cm, changeEvent);
+ // When an 'electric' character is inserted, immediately trigger a reindent
+ if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
+ cm.options.smartIndent && range.head.ch < 100 &&
+ (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
+ var mode = cm.getModeAt(range.head);
+ if (mode.electricChars) {
+ for (var j = 0; j < mode.electricChars.length; j++)
+ if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
+ indentLine(cm, range.head.line, "smart");
+ break;
+ }
+ } else if (mode.electricInput) {
+ var end = changeEnd(changeEvent);
+ if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
+ indentLine(cm, range.head.line, "smart");
+ }
+ }
+ }
+ ensureCursorVisible(cm);
cm.curOp.updateInput = updateInput;
- signalLater(cm, "inputRead", cm, changeEvent);
+ cm.curOp.typing = true;
+ // Don't leave long text in the textarea, since it makes further polling slow
if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
else cm.display.prevInput = text;
if (withOp) endOperation(cm);
- cm.state.pasteIncoming = false;
+ cm.state.pasteIncoming = cm.state.cutIncoming = false;
return true;
}
- function resetInput(cm, user) {
+ // Reset the input to correspond to the selection (or to be empty,
+ // when not typing and nothing is selected)
+ function resetInput(cm, typing) {
var minimal, selected, doc = cm.doc;
- if (!posEq(doc.sel.from, doc.sel.to)) {
+ if (cm.somethingSelected()) {
cm.display.prevInput = "";
+ var range = doc.sel.primary();
minimal = hasCopyEvent &&
- (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
+ (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
var content = minimal ? "-" : selected || cm.getSelection();
cm.display.input.value = content;
if (cm.state.focused) selectInput(cm.display.input);
- if (ie && !ie_lt9) cm.display.inputHasSelection = content;
- } else if (user) {
+ if (ie && !ie_upto8) cm.display.inputHasSelection = content;
+ } else if (!typing) {
cm.display.prevInput = cm.display.input.value = "";
- if (ie && !ie_lt9) cm.display.inputHasSelection = null;
+ if (ie && !ie_upto8) cm.display.inputHasSelection = null;
}
cm.display.inaccurateSelection = minimal;
}
function focusInput(cm) {
- if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
+ if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
cm.display.input.focus();
}
+ function ensureFocus(cm) {
+ if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
+ }
+
function isReadOnly(cm) {
return cm.options.readOnly || cm.doc.cantEdit;
}
// EVENT HANDLERS
+ // Attach the necessary event handlers when initializing the editor
function registerEventHandlers(cm) {
var d = cm.display;
on(d.scroller, "mousedown", operation(cm, onMouseDown));
- if (ie)
+ // Older IE's will not fire a second mousedown for a double click
+ if (ie_upto10)
on(d.scroller, "dblclick", operation(cm, function(e) {
if (signalDOMEvent(cm, e)) return;
var pos = posFromMouse(cm, e);
if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
e_preventDefault(e);
- var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
- extendSelection(cm.doc, word.from, word.to);
+ var word = findWordAt(cm, pos);
+ extendSelection(cm.doc, word.anchor, word.head);
}));
else
on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
+ // Prevent normal selection in the editor (we handle our own)
on(d.lineSpace, "selectstart", function(e) {
if (!eventInWidget(d, e)) e_preventDefault(e);
});
- // Gecko browsers fire contextmenu *after* opening the menu, at
+ // Some browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
- // handled in onMouseDown for Gecko.
- if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
+ // handled in onMouseDown for these browsers.
+ if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
+ // Sync scrolling between fake scrollbars and real scrollable
+ // area, ensure viewport is updated when scrolling.
on(d.scroller, "scroll", function() {
if (d.scroller.clientHeight) {
setScrollTop(cm, d.scroller.scrollTop);
@@ -1571,49 +2389,29 @@ window.CodeMirror = (function() {
if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
});
+ // Listen to wheel events in order to try and update the viewport on time.
on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
+ // Prevent clicks in the scrollbars from killing focus
function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
on(d.scrollbarH, "mousedown", reFocus);
on(d.scrollbarV, "mousedown", reFocus);
// Prevent wrapper from ever scrolling
on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
- var resizeTimer;
- function onResize() {
- if (resizeTimer == null) resizeTimer = setTimeout(function() {
- resizeTimer = null;
- // Might be a text scaling operation, clear size caches.
- d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
- clearCaches(cm);
- runInOp(cm, bind(regChange, cm));
- }, 100);
- }
- on(window, "resize", onResize);
- // Above handler holds on to the editor and its data structures.
- // Here we poll to unregister it when the editor is no longer in
- // the document, so that it can be garbage-collected.
- function unregister() {
- for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
- if (p) setTimeout(unregister, 5000);
- else off(window, "resize", onResize);
- }
- setTimeout(unregister, 5000);
-
- on(d.input, "keyup", operation(cm, function(e) {
- if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
- if (e.keyCode == 16) cm.doc.sel.shift = false;
- }));
- on(d.input, "input", bind(fastPoll, cm));
+ on(d.input, "keyup", operation(cm, onKeyUp));
+ on(d.input, "input", function() {
+ if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
+ fastPoll(cm);
+ });
on(d.input, "keydown", operation(cm, onKeyDown));
on(d.input, "keypress", operation(cm, onKeyPress));
on(d.input, "focus", bind(onFocus, cm));
on(d.input, "blur", bind(onBlur, cm));
function drag_(e) {
- if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
- e_stop(e);
+ if (!signalDOMEvent(cm, e)) e_stop(e);
}
if (cm.options.dragDrop) {
on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
@@ -1623,6 +2421,7 @@ window.CodeMirror = (function() {
}
on(d.scroller, "paste", function(e) {
if (eventInWidget(d, e)) return;
+ cm.state.pasteIncoming = true;
focusInput(cm);
fastPoll(cm);
});
@@ -1641,52 +2440,97 @@ window.CodeMirror = (function() {
fastPoll(cm);
});
- function prepareCopy() {
- if (d.inaccurateSelection) {
- d.prevInput = "";
- d.inaccurateSelection = false;
- d.input.value = cm.getSelection();
- selectInput(d.input);
+ function prepareCopyCut(e) {
+ if (cm.somethingSelected()) {
+ if (d.inaccurateSelection) {
+ d.prevInput = "";
+ d.inaccurateSelection = false;
+ d.input.value = cm.getSelection();
+ selectInput(d.input);
+ }
+ } else {
+ var text = "", ranges = [];
+ for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
+ var line = cm.doc.sel.ranges[i].head.line;
+ var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
+ ranges.push(lineRange);
+ text += cm.getRange(lineRange.anchor, lineRange.head);
+ }
+ if (e.type == "cut") {
+ cm.setSelections(ranges, null, sel_dontScroll);
+ } else {
+ d.prevInput = "";
+ d.input.value = text;
+ selectInput(d.input);
+ }
}
+ if (e.type == "cut") cm.state.cutIncoming = true;
}
- on(d.input, "cut", prepareCopy);
- on(d.input, "copy", prepareCopy);
+ on(d.input, "cut", prepareCopyCut);
+ on(d.input, "copy", prepareCopyCut);
// Needed to handle Tab key in KHTML
if (khtml) on(d.sizer, "mouseup", function() {
- if (document.activeElement == d.input) d.input.blur();
- focusInput(cm);
+ if (activeElt() == d.input) d.input.blur();
+ focusInput(cm);
});
}
+ // Called when the window resizes
+ function onResize(cm) {
+ // Might be a text scaling operation, clear size caches.
+ var d = cm.display;
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+ cm.setSize();
+ }
+
+ // MOUSE EVENTS
+
+ // Return true when the given mouse event happened in a widget
function eventInWidget(display, e) {
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
}
}
- function posFromMouse(cm, e, liberal) {
+ // Given a mouse event, find the corresponding position. If liberal
+ // is false, it checks whether a gutter or scrollbar was clicked,
+ // and returns null if it was. forRect is used by rectangular
+ // selections, and tries to estimate a character position even for
+ // coordinates beyond the right of the text.
+ function posFromMouse(cm, e, liberal, forRect) {
var display = cm.display;
if (!liberal) {
var target = e_target(e);
- if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
- target == display.scrollbarV || target == display.scrollbarV.firstChild ||
+ if (target == display.scrollbarH || target == display.scrollbarV ||
target == display.scrollbarFiller || target == display.gutterFiller) return null;
}
- var x, y, space = getRect(display.lineSpace);
+ var x, y, space = display.lineSpace.getBoundingClientRect();
// Fails unpredictably on IE[67] when mouse is dragged around quickly.
- try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
- return coordsChar(cm, x - space.left, y - space.top);
+ try { x = e.clientX - space.left; y = e.clientY - space.top; }
+ catch (e) { return null; }
+ var coords = coordsChar(cm, x, y), line;
+ if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
+ var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
+ coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
+ }
+ return coords;
}
- var lastClick, lastDoubleClick;
+ // A mouse down can be a single click, double click, triple click,
+ // start of selection drag, start of text drag, new cursor
+ // (ctrl-click), rectangle drag (alt-drag), or xwin
+ // middle-click-paste. Or it might be a click on something we should
+ // not interfere with, such as a scrollbar or widget.
function onMouseDown(e) {
if (signalDOMEvent(this, e)) return;
- var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
- sel.shift = e.shiftKey;
+ var cm = this, display = cm.display;
+ display.shift = e.shiftKey;
if (eventInWidget(display, e)) {
if (!webkit) {
+ // Briefly turn off draggability, to allow widgets to do
+ // normal dragging things.
display.scroller.draggable = false;
setTimeout(function(){display.scroller.draggable = true;}, 100);
}
@@ -1694,89 +2538,171 @@ window.CodeMirror = (function() {
}
if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
+ window.focus();
switch (e_button(e)) {
- case 3:
- if (captureMiddleClick) onContextMenu.call(cm, cm, e);
- return;
+ case 1:
+ if (start)
+ leftButtonDown(cm, e, start);
+ else if (e_target(e) == display.scroller)
+ e_preventDefault(e);
+ break;
case 2:
if (webkit) cm.state.lastMiddleDown = +new Date;
if (start) extendSelection(cm.doc, start);
setTimeout(bind(focusInput, cm), 20);
e_preventDefault(e);
- return;
+ break;
+ case 3:
+ if (captureRightClick) onContextMenu(cm, e);
+ break;
}
- // For button 1, if it was clicked inside the editor
- // (posFromMouse returning non-null), we have to adjust the
- // selection.
- if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
+ }
- if (!cm.state.focused) onFocus(cm);
+ var lastClick, lastDoubleClick;
+ function leftButtonDown(cm, e, start) {
+ setTimeout(bind(ensureFocus, cm), 0);
- var now = +new Date, type = "single";
- if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
+ var now = +new Date, type;
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
type = "triple";
- e_preventDefault(e);
- setTimeout(bind(focusInput, cm), 20);
- selectLine(cm, start.line);
- } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
+ } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
type = "double";
lastDoubleClick = {time: now, pos: start};
- e_preventDefault(e);
- var word = findWordAt(getLine(doc, start.line).text, start);
- extendSelection(cm.doc, word.from, word.to);
- } else { lastClick = {time: now, pos: start}; }
-
- var last = start;
- if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
- !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
- var dragEnd = operation(cm, function(e2) {
- if (webkit) display.scroller.draggable = false;
- cm.state.draggingText = false;
- off(document, "mouseup", dragEnd);
- off(display.scroller, "drop", dragEnd);
- if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
- e_preventDefault(e2);
- extendSelection(cm.doc, start);
- focusInput(cm);
- }
- });
- // Let the drag handler handle this.
- if (webkit) display.scroller.draggable = true;
- cm.state.draggingText = dragEnd;
- // IE's approach to draggable
- if (display.scroller.dragDrop) display.scroller.dragDrop();
- on(document, "mouseup", dragEnd);
- on(display.scroller, "drop", dragEnd);
- return;
+ } else {
+ type = "single";
+ lastClick = {time: now, pos: start};
}
- e_preventDefault(e);
- if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
-
- var startstart = sel.from, startend = sel.to, lastPos = start;
- function doSelect(cur) {
- if (posEq(lastPos, cur)) return;
- lastPos = cur;
+ var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey;
+ if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) &&
+ type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
+ leftButtonStartDrag(cm, e, start);
+ else
+ leftButtonSelect(cm, e, start, type, addNew);
+ }
- if (type == "single") {
- extendSelection(cm.doc, clipPos(doc, start), cur);
- return;
+ // Start a text drag. When it ends, see if any dragging actually
+ // happen, and treat as a click if it didn't.
+ function leftButtonStartDrag(cm, e, start) {
+ var display = cm.display;
+ var dragEnd = operation(cm, function(e2) {
+ if (webkit) display.scroller.draggable = false;
+ cm.state.draggingText = false;
+ off(document, "mouseup", dragEnd);
+ off(display.scroller, "drop", dragEnd);
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
+ e_preventDefault(e2);
+ extendSelection(cm.doc, start);
+ focusInput(cm);
+ // Work around unexplainable focus problem in IE9 (#2127)
+ if (ie_upto10 && !ie_upto8)
+ setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
}
+ });
+ // Let the drag handler handle this.
+ if (webkit) display.scroller.draggable = true;
+ cm.state.draggingText = dragEnd;
+ // IE's approach to draggable
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
+ on(document, "mouseup", dragEnd);
+ on(display.scroller, "drop", dragEnd);
+ }
- startstart = clipPos(doc, startstart);
- startend = clipPos(doc, startend);
- if (type == "double") {
- var word = findWordAt(getLine(doc, cur.line).text, cur);
- if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
- else extendSelection(cm.doc, startstart, word.to);
- } else if (type == "triple") {
- if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
- else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
+ // Normal selection, as opposed to text dragging.
+ function leftButtonSelect(cm, e, start, type, addNew) {
+ var display = cm.display, doc = cm.doc;
+ e_preventDefault(e);
+
+ var ourRange, ourIndex, startSel = doc.sel;
+ if (addNew && !e.shiftKey) {
+ ourIndex = doc.sel.contains(start);
+ if (ourIndex > -1)
+ ourRange = doc.sel.ranges[ourIndex];
+ else
+ ourRange = new Range(start, start);
+ } else {
+ ourRange = doc.sel.primary();
+ }
+
+ if (e.altKey) {
+ type = "rect";
+ if (!addNew) ourRange = new Range(start, start);
+ start = posFromMouse(cm, e, true, true);
+ ourIndex = -1;
+ } else if (type == "double") {
+ var word = findWordAt(cm, start);
+ if (cm.display.shift || doc.extend)
+ ourRange = extendRange(doc, ourRange, word.anchor, word.head);
+ else
+ ourRange = word;
+ } else if (type == "triple") {
+ var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
+ if (cm.display.shift || doc.extend)
+ ourRange = extendRange(doc, ourRange, line.anchor, line.head);
+ else
+ ourRange = line;
+ } else {
+ ourRange = extendRange(doc, ourRange, start);
+ }
+
+ if (!addNew) {
+ ourIndex = 0;
+ setSelection(doc, new Selection([ourRange], 0), sel_mouse);
+ startSel = doc.sel;
+ } else if (ourIndex > -1) {
+ replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
+ } else {
+ ourIndex = doc.sel.ranges.length;
+ setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
+ {scroll: false, origin: "*mouse"});
+ }
+
+ var lastPos = start;
+ function extendTo(pos) {
+ if (cmp(lastPos, pos) == 0) return;
+ lastPos = pos;
+
+ if (type == "rect") {
+ var ranges = [], tabSize = cm.options.tabSize;
+ var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
+ var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
+ var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
+ for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
+ line <= end; line++) {
+ var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
+ if (left == right)
+ ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
+ else if (text.length > leftPos)
+ ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
+ }
+ if (!ranges.length) ranges.push(new Range(start, start));
+ setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
+ {origin: "*mouse", scroll: false});
+ cm.scrollIntoView(pos);
+ } else {
+ var oldRange = ourRange;
+ var anchor = oldRange.anchor, head = pos;
+ if (type != "single") {
+ if (type == "double")
+ var range = findWordAt(cm, pos);
+ else
+ var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
+ if (cmp(range.anchor, anchor) > 0) {
+ head = range.head;
+ anchor = minPos(oldRange.from(), range.anchor);
+ } else {
+ head = range.anchor;
+ anchor = maxPos(oldRange.to(), range.head);
+ }
+ }
+ var ranges = startSel.ranges.slice(0);
+ ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
+ setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
}
}
- var editorSize = getRect(display.wrapper);
+ var editorSize = display.wrapper.getBoundingClientRect();
// Used to ensure timeout re-tries don't fire when another extend
// happened in the meantime (clearTimeout isn't reliable -- at
// least on Chrome, the timeouts still happen even when cleared,
@@ -1785,12 +2711,11 @@ window.CodeMirror = (function() {
function extend(e) {
var curCount = ++counter;
- var cur = posFromMouse(cm, e, true);
+ var cur = posFromMouse(cm, e, true, type == "rect");
if (!cur) return;
- if (!posEq(cur, last)) {
- if (!cm.state.focused) onFocus(cm);
- last = cur;
- doSelect(cur);
+ if (cmp(cur, lastPos) != 0) {
+ ensureFocus(cm);
+ extendTo(cur);
var visible = visibleLines(display, doc);
if (cur.line >= visible.to || cur.line < visible.from)
setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
@@ -1810,10 +2735,11 @@ window.CodeMirror = (function() {
focusInput(cm);
off(document, "mousemove", move);
off(document, "mouseup", up);
+ doc.history.lastSelOrigin = null;
}
var move = operation(cm, function(e) {
- if (!ie && !e_button(e)) done(e);
+ if ((ie && !ie_upto9) ? !e.buttons : !e_button(e)) done(e);
else extend(e);
});
var up = operation(cm, done);
@@ -1821,21 +2747,23 @@ window.CodeMirror = (function() {
on(document, "mouseup", up);
}
+ // Determines whether an event happened in the gutter, and fires the
+ // handlers for the corresponding event.
function gutterEvent(cm, e, type, prevent, signalfn) {
try { var mX = e.clientX, mY = e.clientY; }
catch(e) { return false; }
- if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false;
+ if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
if (prevent) e_preventDefault(e);
var display = cm.display;
- var lineBox = getRect(display.lineDiv);
+ var lineBox = display.lineDiv.getBoundingClientRect();
if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
mY -= lineBox.top - display.viewOffset;
for (var i = 0; i < cm.options.gutters.length; ++i) {
var g = display.gutters.childNodes[i];
- if (g && getRect(g).right >= mX) {
+ if (g && g.getBoundingClientRect().right >= mX) {
var line = lineAtHeight(cm.doc, mY);
var gutter = cm.options.gutters[i];
signalfn(cm, type, cm, line, gutter, e);
@@ -1844,11 +2772,6 @@ window.CodeMirror = (function() {
}
}
- function contextMenuInGutter(cm, e) {
- if (!hasHandler(cm, "gutterContextMenu")) return false;
- return gutterEvent(cm, e, "gutterContextMenu", false, signal);
- }
-
function clickInGutter(cm, e) {
return gutterEvent(cm, e, "gutterClick", true, signalLater);
}
@@ -1859,29 +2782,33 @@ window.CodeMirror = (function() {
function onDrop(e) {
var cm = this;
- if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
return;
e_preventDefault(e);
if (ie) lastDrop = +new Date;
var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
if (!pos || isReadOnly(cm)) return;
+ // Might be a file drop, in which case we simply extract the text
+ // and insert it.
if (files && files.length && window.FileReader && window.File) {
var n = files.length, text = Array(n), read = 0;
var loadFile = function(file, i) {
var reader = new FileReader;
- reader.onload = function() {
+ reader.onload = operation(cm, function() {
text[i] = reader.result;
if (++read == n) {
pos = clipPos(cm.doc, pos);
- makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
+ var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
+ makeChange(cm.doc, change);
+ setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
}
- };
+ });
reader.readAsText(file);
};
for (var i = 0; i < n; ++i) loadFile(files[i], i);
- } else {
+ } else { // Normal drop
// Don't do a replace if the drop happened inside of the selected text.
- if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
+ if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
cm.state.draggingText(e);
// Ensure the editor is re-focused
setTimeout(bind(focusInput, cm), 20);
@@ -1890,12 +2817,12 @@ window.CodeMirror = (function() {
try {
var text = e.dataTransfer.getData("Text");
if (text) {
- var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
- setSelection(cm.doc, pos, pos);
- if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
- cm.replaceSelection(text, null, "paste");
+ var selected = cm.state.draggingText && cm.listSelections();
+ setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
+ if (selected) for (var i = 0; i < selected.length; ++i)
+ replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
+ cm.replaceSelection(text, "around", "paste");
focusInput(cm);
- onFocus(cm);
}
}
catch(e){}
@@ -1906,34 +2833,39 @@ window.CodeMirror = (function() {
if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
- var txt = cm.getSelection();
- e.dataTransfer.setData("Text", txt);
+ e.dataTransfer.setData("Text", cm.getSelection());
// Use dummy image instead of default browsers image.
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
if (e.dataTransfer.setDragImage && !safari) {
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
- if (opera) {
+ if (presto) {
img.width = img.height = 1;
cm.display.wrapper.appendChild(img);
// Force a relayout, or Opera won't use our image for some obscure reason
img._top = img.offsetTop;
}
e.dataTransfer.setDragImage(img, 0, 0);
- if (opera) img.parentNode.removeChild(img);
+ if (presto) img.parentNode.removeChild(img);
}
}
+ // SCROLL EVENTS
+
+ // Sync the scrollable area and scrollbars, ensure the viewport
+ // covers the visible area.
function setScrollTop(cm, val) {
if (Math.abs(cm.doc.scrollTop - val) < 2) return;
cm.doc.scrollTop = val;
- if (!gecko) updateDisplay(cm, [], val);
+ if (!gecko) updateDisplay(cm, {top: val});
if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
- if (gecko) updateDisplay(cm, []);
+ if (gecko) updateDisplay(cm);
startWorker(cm, 100);
}
+ // Sync scroller and scrollbar, ensure the gutter elements are
+ // aligned.
function setScrollLeft(cm, val, isScroller) {
if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
@@ -1980,10 +2912,12 @@ window.CodeMirror = (function() {
// This hack (see related code in patchDisplay) makes sure the
// element is kept around.
if (dy && mac && webkit) {
- for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
- if (cur.lineObj) {
- cm.display.currentWheelTarget = cur;
- break;
+ outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
+ for (var i = 0; i < view.length; i++) {
+ if (view[i].node == cur) {
+ cm.display.currentWheelTarget = cur;
+ break outer;
+ }
}
}
}
@@ -1994,7 +2928,7 @@ window.CodeMirror = (function() {
// estimated pixels/delta value, we just handle horizontal
// scrolling entirely here. It'll be slightly off from native, but
// better than glitching out.
- if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
+ if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
if (dy)
setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
@@ -2003,12 +2937,14 @@ window.CodeMirror = (function() {
return;
}
+ // 'Project' the visible viewport to cover the area that is being
+ // scrolled into view (if we know enough to estimate it).
if (dy && wheelPixelsPerUnit != null) {
var pixels = dy * wheelPixelsPerUnit;
var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
if (pixels < 0) top = Math.max(0, top + pixels - 50);
else bot = Math.min(cm.doc.height, bot + pixels + 50);
- updateDisplay(cm, [], {top: top, bottom: bot});
+ updateDisplay(cm, {top: top, bottom: bot});
}
if (wheelSamples < 20) {
@@ -2032,6 +2968,9 @@ window.CodeMirror = (function() {
}
}
+ // KEY EVENTS
+
+ // Run a handler that was bound to a key.
function doHandleBinding(cm, bound, dropShift) {
if (typeof bound == "string") {
bound = commands[bound];
@@ -2040,18 +2979,19 @@ window.CodeMirror = (function() {
// Ensure previous input has been read, so that the handler sees a
// consistent view of the document
if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
- var doc = cm.doc, prevShift = doc.sel.shift, done = false;
+ var prevShift = cm.display.shift, done = false;
try {
if (isReadOnly(cm)) cm.state.suppressEdits = true;
- if (dropShift) doc.sel.shift = false;
+ if (dropShift) cm.display.shift = false;
done = bound(cm) != Pass;
} finally {
- doc.sel.shift = prevShift;
+ cm.display.shift = prevShift;
cm.state.suppressEdits = false;
}
return done;
}
+ // Collect the currently active keymaps.
function allKeyMaps(cm) {
var maps = cm.state.keyMaps.slice(0);
if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
@@ -2060,8 +3000,9 @@ window.CodeMirror = (function() {
}
var maybeTransition;
+ // Handle a key from the keydown event.
function handleKeyBinding(cm, e) {
- // Handle auto keymap transitions
+ // Handle automatic keymap transitions
var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
clearTimeout(maybeTransition);
if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
@@ -2091,12 +3032,12 @@ window.CodeMirror = (function() {
if (handled) {
e_preventDefault(e);
restartBlink(cm);
- if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
signalLater(cm, "keyHandled", cm, name, e);
}
return handled;
}
+ // Handle a key from the keypress event
function handleCharBinding(cm, e, ch) {
var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
function(b) { return doHandleBinding(cm, b, true); });
@@ -2111,47 +3052,70 @@ window.CodeMirror = (function() {
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
- if (!cm.state.focused) onFocus(cm);
- if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
- if (ie && e.keyCode == 27) e.returnValue = false;
- var code = e.keyCode;
+ ensureFocus(cm);
+ if (signalDOMEvent(cm, e)) return;
// IE does strange things with escape.
- cm.doc.sel.shift = code == 16 || e.shiftKey;
- // First give onKeyEvent option a chance to handle this.
+ if (ie_upto10 && e.keyCode == 27) e.returnValue = false;
+ var code = e.keyCode;
+ cm.display.shift = code == 16 || e.shiftKey;
var handled = handleKeyBinding(cm, e);
- if (opera) {
+ if (presto) {
lastStoppedKey = handled ? code : null;
// Opera has no cut event... we try to at least catch the key combo
if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
- cm.replaceSelection("");
+ cm.replaceSelection("", null, "cut");
}
+
+ // Turn mouse into crosshair when Alt is held on Mac.
+ if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
+ showCrossHair(cm);
+ }
+
+ function showCrossHair(cm) {
+ var lineDiv = cm.display.lineDiv;
+ addClass(lineDiv, "CodeMirror-crosshair");
+
+ function up(e) {
+ if (e.keyCode == 18 || !e.altKey) {
+ rmClass(lineDiv, "CodeMirror-crosshair");
+ off(document, "keyup", up);
+ off(document, "mouseover", up);
+ }
+ }
+ on(document, "keyup", up);
+ on(document, "mouseover", up);
+ }
+
+ function onKeyUp(e) {
+ if (signalDOMEvent(this, e)) return;
+ if (e.keyCode == 16) this.doc.sel.shift = false;
}
function onKeyPress(e) {
var cm = this;
- if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
+ if (signalDOMEvent(cm, e)) return;
var keyCode = e.keyCode, charCode = e.charCode;
- if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
- if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
+ if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
+ if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
- if (this.options.electricChars && this.doc.mode.electricChars &&
- this.options.smartIndent && !isReadOnly(this) &&
- this.doc.mode.electricChars.indexOf(ch) > -1)
- setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
if (handleCharBinding(cm, e, ch)) return;
- if (ie && !ie_lt9) cm.display.inputHasSelection = null;
+ if (ie && !ie_upto8) cm.display.inputHasSelection = null;
fastPoll(cm);
}
+ // FOCUS/BLUR EVENTS
+
function onFocus(cm) {
if (cm.options.readOnly == "nocursor") return;
if (!cm.state.focused) {
signal(cm, "focus", cm);
cm.state.focused = true;
- if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
- cm.display.wrapper.className += " CodeMirror-focused";
- if (!cm.curOp) {
- resetInput(cm, true);
+ addClass(cm.display.wrapper, "CodeMirror-focused");
+ // The prevInput test prevents this from firing when a context
+ // menu is closed (since the resetInput would kill the
+ // select-all detection hack)
+ if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
+ resetInput(cm);
if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
}
}
@@ -2162,62 +3126,76 @@ window.CodeMirror = (function() {
if (cm.state.focused) {
signal(cm, "blur", cm);
cm.state.focused = false;
- cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
+ rmClass(cm.display.wrapper, "CodeMirror-focused");
}
clearInterval(cm.display.blinker);
- setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
+ setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
}
- var detectingSelectAll;
+ // CONTEXT MENU HANDLING
+
+ // To make the context menu work, we need to briefly unhide the
+ // textarea (making it as unobtrusive as possible) to let the
+ // right-click take effect on it.
function onContextMenu(cm, e) {
if (signalDOMEvent(cm, e, "contextmenu")) return;
- var display = cm.display, sel = cm.doc.sel;
+ var display = cm.display;
if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
- if (!pos || opera) return; // Opera is difficult.
- if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
- operation(cm, setSelection)(cm.doc, pos, pos);
+ if (!pos || presto) return; // Opera is difficult.
+
+ // Reset the current text selection only if the click is done outside of the selection
+ // and 'resetSelectionOnContextMenu' option is true.
+ var reset = cm.options.resetSelectionOnContextMenu;
+ if (reset && cm.doc.sel.contains(pos) == -1)
+ operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
var oldCSS = display.input.style.cssText;
display.inputDiv.style.position = "absolute";
display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
- "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
- "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
+ (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
+ "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
focusInput(cm);
- resetInput(cm, true);
+ resetInput(cm);
// Adds "Select all" to context menu in FF
- if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
+ if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
+ display.selForContextMenu = cm.doc.sel;
+ clearTimeout(display.detectingSelectAll);
+ // Select-all will be greyed out if there's nothing to select, so
+ // this adds a zero-width space so that we can later check whether
+ // it got selected.
function prepareSelectAllHack() {
if (display.input.selectionStart != null) {
- var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value);
- display.prevInput = "\u200b";
+ var selected = cm.somethingSelected();
+ var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
+ display.prevInput = selected ? "" : "\u200b";
display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
}
}
function rehide() {
display.inputDiv.style.position = "relative";
display.input.style.cssText = oldCSS;
- if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
+ if (ie_upto8) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
slowPoll(cm);
// Try to detect the user choosing select-all
if (display.input.selectionStart != null) {
- if (!ie || ie_lt9) prepareSelectAllHack();
- clearTimeout(detectingSelectAll);
- var i = 0, poll = function(){
- if (display.prevInput == " " && display.input.selectionStart == 0)
+ if (!ie || ie_upto8) prepareSelectAllHack();
+ var i = 0, poll = function() {
+ if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
operation(cm, commands.selectAll)(cm);
- else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
+ else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
else resetInput(cm);
};
- detectingSelectAll = setTimeout(poll, 200);
+ display.detectingSelectAll = setTimeout(poll, 200);
}
}
- if (ie && !ie_lt9) prepareSelectAllHack();
- if (captureMiddleClick) {
+ if (ie && !ie_upto8) prepareSelectAllHack();
+ if (captureRightClick) {
e_stop(e);
var mouseup = function() {
off(window, "mouseup", mouseup);
@@ -2229,54 +3207,71 @@ window.CodeMirror = (function() {
}
}
+ function contextMenuInGutter(cm, e) {
+ if (!hasHandler(cm, "gutterContextMenu")) return false;
+ return gutterEvent(cm, e, "gutterContextMenu", false, signal);
+ }
+
// UPDATING
+ // Compute the position of the end of a change (its 'to' property
+ // refers to the pre-change end).
var changeEnd = CodeMirror.changeEnd = function(change) {
if (!change.text) return change.to;
return Pos(change.from.line + change.text.length - 1,
lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
};
- // Make sure a position will be valid after the given change.
- function clipPostChange(doc, change, pos) {
- if (!posLess(change.from, pos)) return clipPos(doc, pos);
- var diff = (change.text.length - 1) - (change.to.line - change.from.line);
- if (pos.line > change.to.line + diff) {
- var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
- if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
- return clipToLen(pos, getLine(doc, preLine).text.length);
- }
- if (pos.line == change.to.line + diff)
- return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
- getLine(doc, change.to.line).text.length - change.to.ch);
- var inside = pos.line - change.from.line;
- return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
- }
-
- // Hint can be null|"end"|"start"|"around"|{anchor,head}
- function computeSelAfterChange(doc, change, hint) {
- if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
- return {anchor: clipPostChange(doc, change, hint.anchor),
- head: clipPostChange(doc, change, hint.head)};
-
- if (hint == "start") return {anchor: change.from, head: change.from};
-
- var end = changeEnd(change);
- if (hint == "around") return {anchor: change.from, head: end};
- if (hint == "end") return {anchor: end, head: end};
-
- // hint is null, leave the selection alone as much as possible
- var adjustPos = function(pos) {
- if (posLess(pos, change.from)) return pos;
- if (!posLess(change.to, pos)) return end;
-
- var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
- if (pos.line == change.to.line) ch += end.ch - change.to.ch;
- return Pos(line, ch);
- };
- return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
+ // Adjust a position to refer to the post-change position of the
+ // same text, or the end of the change if the change covers it.
+ function adjustForChange(pos, change) {
+ if (cmp(pos, change.from) < 0) return pos;
+ if (cmp(pos, change.to) <= 0) return changeEnd(change);
+
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
+ if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
+ return Pos(line, ch);
}
+ function computeSelAfterChange(doc, change) {
+ var out = [];
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
+ var range = doc.sel.ranges[i];
+ out.push(new Range(adjustForChange(range.anchor, change),
+ adjustForChange(range.head, change)));
+ }
+ return normalizeSelection(out, doc.sel.primIndex);
+ }
+
+ function offsetPos(pos, old, nw) {
+ if (pos.line == old.line)
+ return Pos(nw.line, pos.ch - old.ch + nw.ch);
+ else
+ return Pos(nw.line + (pos.line - old.line), pos.ch);
+ }
+
+ // Used by replaceSelections to allow moving the selection to the
+ // start or around the replaced test. Hint may be "start" or "around".
+ function computeReplacedSel(doc, changes, hint) {
+ var out = [];
+ var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
+ for (var i = 0; i < changes.length; i++) {
+ var change = changes[i];
+ var from = offsetPos(change.from, oldPrev, newPrev);
+ var to = offsetPos(changeEnd(change), oldPrev, newPrev);
+ oldPrev = change.to;
+ newPrev = to;
+ if (hint == "around") {
+ var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
+ out[i] = new Range(inv ? to : from, inv ? from : to);
+ } else {
+ out[i] = new Range(from, from);
+ }
+ }
+ return new Selection(out, doc.sel.primIndex);
+ }
+
+ // Allow "beforeChange" event handlers to influence a change
function filterChange(doc, change, update) {
var obj = {
canceled: false,
@@ -2299,11 +3294,11 @@ window.CodeMirror = (function() {
return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
}
- // Replace the range from from to to by the strings in replacement.
- // change is a {from, to, text [, origin]} object
- function makeChange(doc, change, selUpdate, ignoreReadOnly) {
+ // Apply a change to a document, and add it to the document's
+ // history, and propagating it to all linked documents.
+ function makeChange(doc, change, ignoreReadOnly) {
if (doc.cm) {
- if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
if (doc.cm.state.suppressEdits) return;
}
@@ -2316,18 +3311,17 @@ window.CodeMirror = (function() {
// of read-only spans in its range.
var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
if (split) {
- for (var i = split.length - 1; i >= 1; --i)
- makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
- if (split.length)
- makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
+ for (var i = split.length - 1; i >= 0; --i)
+ makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
} else {
- makeChangeNoReadonly(doc, change, selUpdate);
+ makeChangeInner(doc, change);
}
}
- function makeChangeNoReadonly(doc, change, selUpdate) {
- var selAfter = computeSelAfterChange(doc, change, selUpdate);
- addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
+ function makeChangeInner(doc, change) {
+ if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
+ var selAfter = computeSelAfterChange(doc, change);
+ addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
var rebased = [];
@@ -2341,17 +3335,41 @@ window.CodeMirror = (function() {
});
}
- function makeChangeFromHistory(doc, type) {
+ // Revert a change stored in a document's history.
+ function makeChangeFromHistory(doc, type, allowSelectionOnly) {
if (doc.cm && doc.cm.state.suppressEdits) return;
- var hist = doc.history;
- var event = (type == "undo" ? hist.done : hist.undone).pop();
- if (!event) return;
+ var hist = doc.history, event, selAfter = doc.sel;
+ var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
- var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
- anchorAfter: event.anchorBefore, headAfter: event.headBefore,
- generation: hist.generation};
- (type == "undo" ? hist.undone : hist.done).push(anti);
+ // Verify that there is a useable event (so that ctrl-z won't
+ // needlessly clear selection events)
+ for (var i = 0; i < source.length; i++) {
+ event = source[i];
+ if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
+ break;
+ }
+ if (i == source.length) return;
+ hist.lastOrigin = hist.lastSelOrigin = null;
+
+ for (;;) {
+ event = source.pop();
+ if (event.ranges) {
+ pushSelectionToHistory(event, dest);
+ if (allowSelectionOnly && !event.equals(doc.sel)) {
+ setSelection(doc, event, {clearRedo: false});
+ return;
+ }
+ selAfter = event;
+ }
+ else break;
+ }
+
+ // Build up a reverse change object to add to the opposite history
+ // stack (redo when undoing, and vice versa).
+ var antiChanges = [];
+ pushSelectionToHistory(selAfter, dest);
+ dest.push({changes: antiChanges, generation: hist.generation});
hist.generation = event.generation || ++hist.maxGeneration;
var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
@@ -2360,17 +3378,18 @@ window.CodeMirror = (function() {
var change = event.changes[i];
change.origin = type;
if (filter && !filterChange(doc, change, false)) {
- (type == "undo" ? hist.done : hist.undone).length = 0;
+ source.length = 0;
return;
}
- anti.changes.push(historyChangeFromChange(doc, change));
+ antiChanges.push(historyChangeFromChange(doc, change));
- var after = i ? computeSelAfterChange(doc, change, null)
- : {anchor: event.anchorBefore, head: event.headBefore};
+ var after = i ? computeSelAfterChange(doc, change, null) : lst(source);
makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
+ if (!i && doc.cm) doc.cm.scrollIntoView(change);
var rebased = [];
+ // Propagate to the linked documents
linkedDocs(doc, function(doc, sharedHist) {
if (!sharedHist && indexOf(rebased, doc.history) == -1) {
rebaseHist(doc.history, change);
@@ -2381,14 +3400,24 @@ window.CodeMirror = (function() {
}
}
+ // Sub-views need their line numbers shifted when text is added
+ // above or below them in the parent document.
function shiftDoc(doc, distance) {
- function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
+ if (distance == 0) return;
doc.first += distance;
- if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
- doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
- doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
+ doc.sel = new Selection(map(doc.sel.ranges, function(range) {
+ return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
+ Pos(range.head.line + distance, range.head.ch));
+ }), doc.sel.primIndex);
+ if (doc.cm) {
+ regChange(doc.cm, doc.first, doc.first - distance, distance);
+ for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
+ regLineChange(doc.cm, l, "gutter");
+ }
}
+ // More lower-level change function, handling only a single document
+ // (not linked ones).
function makeChangeSingleDoc(doc, change, selAfter, spans) {
if (doc.cm && !doc.cm.curOp)
return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
@@ -2415,16 +3444,19 @@ window.CodeMirror = (function() {
change.removed = getBetween(doc, change.from, change.to);
if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
- if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
- else updateDoc(doc, change, spans, selAfter);
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
+ else updateDoc(doc, change, spans);
+ setSelectionNoUndo(doc, selAfter, sel_dontScroll);
}
- function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
+ // Handle the interaction of a change to a document with the editor
+ // that this document is part of.
+ function makeChangeSingleDocInEditor(cm, change, spans) {
var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
var recomputeMaxLength = false, checkWidthStart = from.line;
if (!cm.options.lineWrapping) {
- checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
+ checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
doc.iter(checkWidthStart, to.line + 1, function(line) {
if (line == display.maxLine) {
recomputeMaxLength = true;
@@ -2433,14 +3465,14 @@ window.CodeMirror = (function() {
});
}
- if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
- cm.curOp.cursorActivity = true;
+ if (doc.sel.contains(change.from, change.to) > -1)
+ signalCursorActivity(cm);
- updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
+ updateDoc(doc, change, spans, estimateHeight(cm));
if (!cm.options.lineWrapping) {
doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
- var len = lineLength(doc, line);
+ var len = lineLength(line);
if (len > display.maxLineLength) {
display.maxLine = line;
display.maxLineLength = len;
@@ -2457,197 +3489,63 @@ window.CodeMirror = (function() {
var lendiff = change.text.length - (to.line - from.line) - 1;
// Remember that these lines changed, for updating the display
- regChange(cm, from.line, to.line + 1, lendiff);
-
- if (hasHandler(cm, "change")) {
- var changeObj = {from: from, to: to,
- text: change.text,
- removed: change.removed,
- origin: change.origin};
- if (cm.curOp.textChanged) {
- for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
- cur.next = changeObj;
- } else cm.curOp.textChanged = changeObj;
+ if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
+ regLineChange(cm, from.line, "text");
+ else
+ regChange(cm, from.line, to.line + 1, lendiff);
+
+ var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
+ if (changeHandler || changesHandler) {
+ var obj = {
+ from: from, to: to,
+ text: change.text,
+ removed: change.removed,
+ origin: change.origin
+ };
+ if (changeHandler) signalLater(cm, "change", cm, obj);
+ if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
}
+ cm.display.selForContextMenu = null;
}
function replaceRange(doc, code, from, to, origin) {
if (!to) to = from;
- if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
+ if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
if (typeof code == "string") code = splitLines(code);
- makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
- }
-
- // POSITION OBJECT
-
- function Pos(line, ch) {
- if (!(this instanceof Pos)) return new Pos(line, ch);
- this.line = line; this.ch = ch;
- }
- CodeMirror.Pos = Pos;
-
- function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
- function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
- function copyPos(x) {return Pos(x.line, x.ch);}
-
- // SELECTION
-
- function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
- function clipPos(doc, pos) {
- if (pos.line < doc.first) return Pos(doc.first, 0);
- var last = doc.first + doc.size - 1;
- if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
- return clipToLen(pos, getLine(doc, pos.line).text.length);
- }
- function clipToLen(pos, linelen) {
- var ch = pos.ch;
- if (ch == null || ch > linelen) return Pos(pos.line, linelen);
- else if (ch < 0) return Pos(pos.line, 0);
- else return pos;
- }
- function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
-
- // If shift is held, this will move the selection anchor. Otherwise,
- // it'll set the whole selection.
- function extendSelection(doc, pos, other, bias) {
- if (doc.sel.shift || doc.sel.extend) {
- var anchor = doc.sel.anchor;
- if (other) {
- var posBefore = posLess(pos, anchor);
- if (posBefore != posLess(other, anchor)) {
- anchor = pos;
- pos = other;
- } else if (posBefore != posLess(pos, other)) {
- pos = other;
- }
- }
- setSelection(doc, anchor, pos, bias);
- } else {
- setSelection(doc, pos, other || pos, bias);
- }
- if (doc.cm) doc.cm.curOp.userSelChange = true;
- }
-
- function filterSelectionChange(doc, anchor, head) {
- var obj = {anchor: anchor, head: head};
- signal(doc, "beforeSelectionChange", doc, obj);
- if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
- obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
- return obj;
+ makeChange(doc, {from: from, to: to, text: code, origin: origin});
}
- // Update the selection. Last two args are only used by
- // updateDoc, since they have to be expressed in the line
- // numbers before the update.
- function setSelection(doc, anchor, head, bias, checkAtomic) {
- if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
- var filtered = filterSelectionChange(doc, anchor, head);
- head = filtered.head;
- anchor = filtered.anchor;
- }
-
- var sel = doc.sel;
- sel.goalColumn = null;
- if (bias == null) bias = posLess(head, sel.head) ? -1 : 1;
- // Skip over atomic spans.
- if (checkAtomic || !posEq(anchor, sel.anchor))
- anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
- if (checkAtomic || !posEq(head, sel.head))
- head = skipAtomic(doc, head, bias, checkAtomic != "push");
-
- if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
+ // SCROLLING THINGS INTO VIEW
- sel.anchor = anchor; sel.head = head;
- var inv = posLess(head, anchor);
- sel.from = inv ? head : anchor;
- sel.to = inv ? anchor : head;
-
- if (doc.cm)
- doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
- doc.cm.curOp.cursorActivity = true;
-
- signalLater(doc, "cursorActivity", doc);
- }
-
- function reCheckSelection(cm) {
- setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
- }
-
- function skipAtomic(doc, pos, bias, mayClear) {
- var flipped = false, curPos = pos;
- var dir = bias || 1;
- doc.cantEdit = false;
- search: for (;;) {
- var line = getLine(doc, curPos.line);
- if (line.markedSpans) {
- for (var i = 0; i < line.markedSpans.length; ++i) {
- var sp = line.markedSpans[i], m = sp.marker;
- if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
- (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
- if (mayClear) {
- signal(m, "beforeCursorEnter");
- if (m.explicitlyCleared) {
- if (!line.markedSpans) break;
- else {--i; continue;}
- }
- }
- if (!m.atomic) continue;
- var newPos = m.find()[dir < 0 ? "from" : "to"];
- if (posEq(newPos, curPos)) {
- newPos.ch += dir;
- if (newPos.ch < 0) {
- if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
- else newPos = null;
- } else if (newPos.ch > line.text.length) {
- if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
- else newPos = null;
- }
- if (!newPos) {
- if (flipped) {
- // Driven in a corner -- no valid cursor position found at all
- // -- try again *with* clearing, if we didn't already
- if (!mayClear) return skipAtomic(doc, pos, bias, true);
- // Otherwise, turn off editing until further notice, and return the start of the doc
- doc.cantEdit = true;
- return Pos(doc.first, 0);
- }
- flipped = true; newPos = pos; dir = -dir;
- }
- }
- curPos = newPos;
- continue search;
- }
- }
- }
- return curPos;
- }
- }
-
- // SCROLLING
-
- function scrollCursorIntoView(cm) {
- var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
- if (!cm.state.focused) return;
- var display = cm.display, box = getRect(display.sizer), doScroll = null;
+ // If an editor sits on the top or bottom of the window, partially
+ // scrolled out of view, this ensures that the cursor is visible.
+ function maybeScrollWindow(cm, coords) {
+ var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
if (doScroll != null && !phantom) {
- var hidden = display.cursor.style.display == "none";
- if (hidden) {
- display.cursor.style.display = "";
- display.cursor.style.left = coords.left + "px";
- display.cursor.style.top = (coords.top - display.viewOffset) + "px";
- }
- display.cursor.scrollIntoView(doScroll);
- if (hidden) display.cursor.style.display = "none";
+ var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
+ (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
+ (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
+ coords.left + "px; width: 2px;");
+ cm.display.lineSpace.appendChild(scrollNode);
+ scrollNode.scrollIntoView(doScroll);
+ cm.display.lineSpace.removeChild(scrollNode);
}
}
- function scrollPosIntoView(cm, pos, margin) {
+ // Scroll a given position into view (immediately), verifying that
+ // it actually became visible (as line heights are accurately
+ // measured, the position of something may 'drift' during drawing).
+ function scrollPosIntoView(cm, pos, end, margin) {
if (margin == null) margin = 0;
for (;;) {
var changed = false, coords = cursorCoords(cm, pos);
- var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
+ var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
+ Math.min(coords.top, endCoords.top) - margin,
+ Math.max(coords.left, endCoords.left),
+ Math.max(coords.bottom, endCoords.bottom) + margin);
var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
if (scrollPos.scrollTop != null) {
setScrollTop(cm, scrollPos.scrollTop);
@@ -2661,16 +3559,22 @@ window.CodeMirror = (function() {
}
}
+ // Scroll a given set of coordinates into view (immediately).
function scrollIntoView(cm, x1, y1, x2, y2) {
var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
}
+ // Calculate a new scroll position needed to scroll the given
+ // rectangle into view. Returns an object with scrollTop and
+ // scrollLeft properties. When these are undefined, the
+ // vertical/horizontal position does not need to be adjusted.
function calculateScrollPos(cm, x1, y1, x2, y2) {
var display = cm.display, snapMargin = textHeight(cm.display);
if (y1 < 0) y1 = 0;
- var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
+ var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
+ var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
var docBottom = cm.doc.height + paddingVert(display);
var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
if (y1 < screentop) {
@@ -2680,7 +3584,8 @@ window.CodeMirror = (function() {
if (newTop != screentop) result.scrollTop = newTop;
}
- var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
+ var screenw = display.scroller.clientWidth - scrollerCutOff;
x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
var gutterw = display.gutters.offsetWidth;
var atLeft = x1 < gutterw + 10;
@@ -2693,32 +3598,70 @@ window.CodeMirror = (function() {
return result;
}
- function updateScrollPos(cm, left, top) {
- cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
- scrollTop: top == null ? cm.doc.scrollTop : top};
+ // Store a relative adjustment to the scroll position in the current
+ // operation (to be applied when the operation finishes).
+ function addToScrollPos(cm, left, top) {
+ if (left != null || top != null) resolveScrollToPos(cm);
+ if (left != null)
+ cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
+ if (top != null)
+ cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
+ }
+
+ // Make sure that at the end of the operation the current cursor is
+ // shown.
+ function ensureCursorVisible(cm) {
+ resolveScrollToPos(cm);
+ var cur = cm.getCursor(), from = cur, to = cur;
+ if (!cm.options.lineWrapping) {
+ from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
+ to = Pos(cur.line, cur.ch + 1);
+ }
+ cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
}
- function addToScrollPos(cm, left, top) {
- var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
- var scroll = cm.display.scroller;
- pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
- pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
+ // When an operation has its scrollToPos property set, and another
+ // scroll action is applied before the end of the operation, this
+ // 'simulates' scrolling that position into view in a cheap way, so
+ // that the effect of intermediate scroll commands is not ignored.
+ function resolveScrollToPos(cm) {
+ var range = cm.curOp.scrollToPos;
+ if (range) {
+ cm.curOp.scrollToPos = null;
+ var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
+ var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
+ Math.min(from.top, to.top) - range.margin,
+ Math.max(from.right, to.right),
+ Math.max(from.bottom, to.bottom) + range.margin);
+ cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
+ }
}
// API UTILITIES
+ // Indent the given line. The how parameter can be "smart",
+ // "add"/null, "subtract", or "prev". When aggressive is false
+ // (typically set to true for forced single-line indents), empty
+ // lines are not indented, and places where the mode returns Pass
+ // are left alone.
function indentLine(cm, n, how, aggressive) {
- var doc = cm.doc;
+ var doc = cm.doc, state;
if (how == null) how = "add";
if (how == "smart") {
+ // Fall back to "prev" when the mode doesn't have an indentation
+ // method.
if (!cm.doc.mode.indent) how = "prev";
- else var state = getStateBefore(cm, n);
+ else state = getStateBefore(cm, n);
}
var tabSize = cm.options.tabSize;
var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
+ if (line.stateAfter) line.stateAfter = null;
var curSpaceString = line.text.match(/^\s*/)[0], indentation;
- if (how == "smart") {
+ if (!aggressive && !/\S/.test(line.text)) {
+ indentation = 0;
+ how = "not";
+ } else if (how == "smart") {
indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
if (indentation == Pass) {
if (!aggressive) return;
@@ -2742,21 +3685,69 @@ window.CodeMirror = (function() {
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
if (pos < indentation) indentString += spaceStr(indentation - pos);
- if (indentString != curSpaceString)
+ if (indentString != curSpaceString) {
replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
+ } else {
+ // Ensure that, if the cursor was in the whitespace at the start
+ // of the line, it is moved to the end of that space.
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
+ var range = doc.sel.ranges[i];
+ if (range.head.line == n && range.head.ch < curSpaceString.length) {
+ var pos = Pos(n, curSpaceString.length);
+ replaceOneSelection(doc, i, new Range(pos, pos));
+ break;
+ }
+ }
+ }
line.stateAfter = null;
}
- function changeLine(cm, handle, op) {
+ // Utility for applying a change to a line by handle or number,
+ // returning the number and optionally registering the line as
+ // changed.
+ function changeLine(cm, handle, changeType, op) {
var no = handle, line = handle, doc = cm.doc;
if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
else no = lineNo(handle);
if (no == null) return null;
- if (op(line, no)) regChange(cm, no, no + 1);
- else return null;
+ if (op(line, no)) regLineChange(cm, no, changeType);
return line;
}
+ // Helper for deleting text near the selection(s), used to implement
+ // backspace, delete, and similar functionality.
+ function deleteNearSelection(cm, compute) {
+ var ranges = cm.doc.sel.ranges, kill = [];
+ // Build up a set of ranges to kill first, merging overlapping
+ // ranges.
+ for (var i = 0; i < ranges.length; i++) {
+ var toKill = compute(ranges[i]);
+ while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
+ var replaced = kill.pop();
+ if (cmp(replaced.from, toKill.from) < 0) {
+ toKill.from = replaced.from;
+ break;
+ }
+ }
+ kill.push(toKill);
+ }
+ // Next, remove those actual ranges.
+ runInOp(cm, function() {
+ for (var i = kill.length - 1; i >= 0; i--)
+ replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
+ ensureCursorVisible(cm);
+ });
+ }
+
+ // Used for horizontal relative motion. Dir is -1 or 1 (left or
+ // right), unit can be "char", "column" (like char, but doesn't
+ // cross line boundaries), "word" (across next word), or "group" (to
+ // the start of next group of word or non-word-non-whitespace
+ // chars). The visually param controls whether, in right-to-left
+ // text, direction 1 means to move towards the next index in the
+ // string, or towards the character to the right of the current
+ // position. The resulting position will have a hitSide=true
+ // property if it reached the end of the document.
function findPosH(doc, pos, dir, unit, visually) {
var line = pos.line, ch = pos.ch, origDir = dir;
var lineObj = getLine(doc, line);
@@ -2782,17 +3773,20 @@ window.CodeMirror = (function() {
else if (unit == "column") moveOnce(true);
else if (unit == "word" || unit == "group") {
var sawType = null, group = unit == "group";
+ var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
for (var first = true;; first = false) {
if (dir < 0 && !moveOnce(!first)) break;
var cur = lineObj.text.charAt(ch) || "\n";
- var type = isWordChar(cur) ? "w"
- : !group ? null
- : /\s/.test(cur) ? null
+ var type = isWordChar(cur, helper) ? "w"
+ : group && cur == "\n" ? "n"
+ : !group || /\s/.test(cur) ? null
: "p";
+ if (group && !first && !type) type = "s";
if (sawType && sawType != type) {
if (dir < 0) {dir = 1; moveOnce();}
break;
}
+
if (type) sawType = type;
if (dir > 0 && !moveOnce(!first)) break;
}
@@ -2802,6 +3796,9 @@ window.CodeMirror = (function() {
return result;
}
+ // For relative vertical movement. Dir may be -1 or 1. Unit can be
+ // "page" or "line". The resulting position will have a hitSide=true
+ // property if it reached the end of the document.
function findPosV(cm, pos, dir, unit) {
var doc = cm.doc, x = pos.left, y;
if (unit == "page") {
@@ -2819,32 +3816,37 @@ window.CodeMirror = (function() {
return target;
}
- function findWordAt(line, pos) {
+ // Find the word at the given position (as returned by coordsChar).
+ function findWordAt(cm, pos) {
+ var doc = cm.doc, line = getLine(doc, pos.line).text;
var start = pos.ch, end = pos.ch;
if (line) {
+ var helper = cm.getHelper(pos, "wordChars");
if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
var startChar = line.charAt(start);
- var check = isWordChar(startChar) ? isWordChar
+ var check = isWordChar(startChar, helper)
+ ? function(ch) { return isWordChar(ch, helper); }
: /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
: function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
while (start > 0 && check(line.charAt(start - 1))) --start;
while (end < line.length && check(line.charAt(end))) ++end;
}
- return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
+ return new Range(Pos(pos.line, start), Pos(pos.line, end));
}
- function selectLine(cm, line) {
- extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
- }
+ // EDITOR METHODS
- // PROTOTYPE
+ // The publicly visible API. Note that methodOp(f) means
+ // 'wrap f in an operation, performed on its `this` parameter'.
- // The publicly visible API. Note that operation(null, f) means
- // 'wrap f in an operation, performed on its `this` parameter'
+ // This is not the complete set of editor methods. Most of the
+ // methods defined on the Doc type are also injected into
+ // CodeMirror.prototype, for backwards compatibility and
+ // convenience.
CodeMirror.prototype = {
constructor: CodeMirror,
- focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
+ focus: function(){window.focus(); focusInput(this); fastPoll(this);},
setOption: function(option, value) {
var options = this.options, old = options[option];
@@ -2869,14 +3871,14 @@ window.CodeMirror = (function() {
}
},
- addOverlay: operation(null, function(spec, options) {
+ addOverlay: methodOp(function(spec, options) {
var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
if (mode.startState) throw new Error("Overlays may not be stateful.");
this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
this.state.modeGen++;
regChange(this);
}),
- removeOverlay: operation(null, function(spec) {
+ removeOverlay: methodOp(function(spec) {
var overlays = this.state.overlays;
for (var i = 0; i < overlays.length; ++i) {
var cur = overlays[i].modeSpec;
@@ -2889,18 +3891,29 @@ window.CodeMirror = (function() {
}
}),
- indentLine: operation(null, function(n, dir, aggressive) {
+ indentLine: methodOp(function(n, dir, aggressive) {
if (typeof dir != "string" && typeof dir != "number") {
if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
else dir = dir ? "add" : "subtract";
}
if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
}),
- indentSelection: operation(null, function(how) {
- var sel = this.doc.sel;
- if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
- var e = sel.to.line - (sel.to.ch ? 0 : 1);
- for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
+ indentSelection: methodOp(function(how) {
+ var ranges = this.doc.sel.ranges, end = -1;
+ for (var i = 0; i < ranges.length; i++) {
+ var range = ranges[i];
+ if (!range.empty()) {
+ var start = Math.max(end, range.from().line);
+ var to = range.to();
+ end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
+ for (var j = start; j < end; ++j)
+ indentLine(this, j, how);
+ } else if (range.head.line > end) {
+ indentLine(this, range.head.line, how, true);
+ end = range.head.line;
+ if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
+ }
+ }
}),
// Fetch the parser token for a given character. Useful for hacks
@@ -2913,12 +3926,11 @@ window.CodeMirror = (function() {
var stream = new StringStream(line.text, this.options.tabSize);
while (stream.pos < pos.ch && !stream.eol()) {
stream.start = stream.pos;
- var style = mode.token(stream, state);
+ var style = readToken(mode, stream, state);
}
return {start: stream.start,
end: stream.pos,
string: stream.current(),
- className: style || null, // Deprecated, use 'type' instead
type: style || null,
state: state};
},
@@ -2927,13 +3939,16 @@ window.CodeMirror = (function() {
pos = clipPos(this.doc, pos);
var styles = getLineStyles(this, getLine(this.doc, pos.line));
var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
- if (ch == 0) return styles[2];
- for (;;) {
+ var type;
+ if (ch == 0) type = styles[2];
+ else for (;;) {
var mid = (before + after) >> 1;
if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
else if (styles[mid * 2 + 1] < ch) before = mid + 1;
- else return styles[mid * 2 + 2];
+ else { type = styles[mid * 2 + 2]; break; }
}
+ var cut = type ? type.indexOf("cm-overlay ") : -1;
+ return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
},
getModeAt: function(pos) {
@@ -2943,11 +3958,31 @@ window.CodeMirror = (function() {
},
getHelper: function(pos, type) {
- if (!helpers.hasOwnProperty(type)) return;
+ return this.getHelpers(pos, type)[0];
+ },
+
+ getHelpers: function(pos, type) {
+ var found = [];
+ if (!helpers.hasOwnProperty(type)) return helpers;
var help = helpers[type], mode = this.getModeAt(pos);
- return mode[type] && help[mode[type]] ||
- mode.helperType && help[mode.helperType] ||
- help[mode.name];
+ if (typeof mode[type] == "string") {
+ if (help[mode[type]]) found.push(help[mode[type]]);
+ } else if (mode[type]) {
+ for (var i = 0; i < mode[type].length; i++) {
+ var val = help[mode[type][i]];
+ if (val) found.push(val);
+ }
+ } else if (mode.helperType && help[mode.helperType]) {
+ found.push(help[mode.helperType]);
+ } else if (help[mode.name]) {
+ found.push(help[mode.name]);
+ }
+ for (var i = 0; i < help._global.length; i++) {
+ var cur = help._global[i];
+ if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
+ found.push(cur.val);
+ }
+ return found;
},
getStateAfter: function(line, precise) {
@@ -2957,10 +3992,10 @@ window.CodeMirror = (function() {
},
cursorCoords: function(start, mode) {
- var pos, sel = this.doc.sel;
- if (start == null) pos = sel.head;
+ var pos, range = this.doc.sel.primary();
+ if (start == null) pos = range.head;
else if (typeof start == "object") pos = clipPos(this.doc, start);
- else pos = start ? sel.from : sel.to;
+ else pos = start ? range.from() : range.to();
return cursorCoords(this, pos, mode || "page");
},
@@ -2982,15 +4017,15 @@ window.CodeMirror = (function() {
if (line < this.doc.first) line = this.doc.first;
else if (line > last) { line = last; end = true; }
var lineObj = getLine(this.doc, line);
- return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
- (end ? lineObj.height : 0);
+ return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
+ (end ? this.doc.height - heightAtLine(lineObj) : 0);
},
defaultTextHeight: function() { return textHeight(this.display); },
defaultCharWidth: function() { return charWidth(this.display); },
- setGutterMarker: operation(null, function(line, gutterID, value) {
- return changeLine(this, line, function(line) {
+ setGutterMarker: methodOp(function(line, gutterID, value) {
+ return changeLine(this, line, "gutter", function(line) {
var markers = line.gutterMarkers || (line.gutterMarkers = {});
markers[gutterID] = value;
if (!value && isEmpty(markers)) line.gutterMarkers = null;
@@ -2998,20 +4033,20 @@ window.CodeMirror = (function() {
});
}),
- clearGutter: operation(null, function(gutterID) {
+ clearGutter: methodOp(function(gutterID) {
var cm = this, doc = cm.doc, i = doc.first;
doc.iter(function(line) {
if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
line.gutterMarkers[gutterID] = null;
- regChange(cm, i, i + 1);
+ regLineChange(cm, i, "gutter");
if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
}
++i;
});
}),
- addLineClass: operation(null, function(handle, where, cls) {
- return changeLine(this, handle, function(line) {
+ addLineClass: methodOp(function(handle, where, cls) {
+ return changeLine(this, handle, "class", function(line) {
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
if (!line[prop]) line[prop] = cls;
else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
@@ -3020,8 +4055,8 @@ window.CodeMirror = (function() {
});
}),
- removeLineClass: operation(null, function(handle, where, cls) {
- return changeLine(this, handle, function(line) {
+ removeLineClass: methodOp(function(handle, where, cls) {
+ return changeLine(this, handle, "class", function(line) {
var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
var cur = line[prop];
if (!cur) return false;
@@ -3036,7 +4071,7 @@ window.CodeMirror = (function() {
});
}),
- addLineWidget: operation(null, function(handle, node, options) {
+ addLineWidget: methodOp(function(handle, node, options) {
return addLineWidget(this, handle, node, options);
}),
@@ -3057,7 +4092,7 @@ window.CodeMirror = (function() {
widgets: line.widgets};
},
- getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
+ getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
addWidget: function(pos, node, scroll, vert, horiz) {
var display = this.display;
@@ -3092,9 +4127,14 @@ window.CodeMirror = (function() {
scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
},
- triggerOnKeyDown: operation(null, onKeyDown),
+ triggerOnKeyDown: methodOp(onKeyDown),
+ triggerOnKeyPress: methodOp(onKeyPress),
+ triggerOnKeyUp: methodOp(onKeyUp),
- execCommand: function(cmd) {return commands[cmd](this);},
+ execCommand: function(cmd) {
+ if (commands.hasOwnProperty(cmd))
+ return commands[cmd](this);
+ },
findPosH: function(from, amount, unit, visually) {
var dir = 1;
@@ -3106,20 +4146,25 @@ window.CodeMirror = (function() {
return cur;
},
- moveH: operation(null, function(dir, unit) {
- var sel = this.doc.sel, pos;
- if (sel.shift || sel.extend || posEq(sel.from, sel.to))
- pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
- else
- pos = dir < 0 ? sel.from : sel.to;
- extendSelection(this.doc, pos, pos, dir);
+ moveH: methodOp(function(dir, unit) {
+ var cm = this;
+ cm.extendSelectionsBy(function(range) {
+ if (cm.display.shift || cm.doc.extend || range.empty())
+ return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
+ else
+ return dir < 0 ? range.from() : range.to();
+ }, sel_move);
}),
- deleteH: operation(null, function(dir, unit) {
- var sel = this.doc.sel;
- if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
- else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
- this.curOp.userSelChange = true;
+ deleteH: methodOp(function(dir, unit) {
+ var sel = this.doc.sel, doc = this.doc;
+ if (sel.somethingSelected())
+ doc.replaceSelection("", null, "+delete");
+ else
+ deleteNearSelection(this, function(range) {
+ var other = findPosH(doc, range.head, dir, unit, false);
+ return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
+ });
}),
findPosV: function(from, amount, unit, goalColumn) {
@@ -3135,28 +4180,39 @@ window.CodeMirror = (function() {
return cur;
},
- moveV: operation(null, function(dir, unit) {
- var sel = this.doc.sel;
- var pos = cursorCoords(this, sel.head, "div");
- if (sel.goalColumn != null) pos.left = sel.goalColumn;
- var target = findPosV(this, pos, dir, unit);
-
- if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
- extendSelection(this.doc, target, target, dir);
- sel.goalColumn = pos.left;
+ moveV: methodOp(function(dir, unit) {
+ var cm = this, doc = this.doc, goals = [];
+ var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
+ doc.extendSelectionsBy(function(range) {
+ if (collapse)
+ return dir < 0 ? range.from() : range.to();
+ var headPos = cursorCoords(cm, range.head, "div");
+ if (range.goalColumn != null) headPos.left = range.goalColumn;
+ goals.push(headPos.left);
+ var pos = findPosV(cm, headPos, dir, unit);
+ if (unit == "page" && range == doc.sel.primary())
+ addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
+ return pos;
+ }, sel_move);
+ if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
+ doc.sel.ranges[i].goalColumn = goals[i];
}),
toggleOverwrite: function(value) {
if (value != null && value == this.state.overwrite) return;
if (this.state.overwrite = !this.state.overwrite)
- this.display.cursor.className += " CodeMirror-overwrite";
+ addClass(this.display.cursorDiv, "CodeMirror-overwrite");
else
- this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
+ rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
+
+ signal(this, "overwriteToggle", this, this.state.overwrite);
},
- hasFocus: function() { return this.state.focused; },
+ hasFocus: function() { return activeElt() == this.display.input; },
- scrollTo: operation(null, function(x, y) {
- updateScrollPos(this, x, y);
+ scrollTo: methodOp(function(x, y) {
+ if (x != null || y != null) resolveScrollToPos(this);
+ if (x != null) this.curOp.scrollLeft = x;
+ if (y != null) this.curOp.scrollTop = y;
}),
getScrollInfo: function() {
var scroller = this.display.scroller, co = scrollerCutOff;
@@ -3165,48 +4221,63 @@ window.CodeMirror = (function() {
clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
},
- scrollIntoView: operation(null, function(pos, margin) {
- if (typeof pos == "number") pos = Pos(pos, 0);
- if (!margin) margin = 0;
- var coords = pos;
+ scrollIntoView: methodOp(function(range, margin) {
+ if (range == null) {
+ range = {from: this.doc.sel.primary().head, to: null};
+ if (margin == null) margin = this.options.cursorScrollMargin;
+ } else if (typeof range == "number") {
+ range = {from: Pos(range, 0), to: null};
+ } else if (range.from == null) {
+ range = {from: range, to: null};
+ }
+ if (!range.to) range.to = range.from;
+ range.margin = margin || 0;
- if (!pos || pos.line != null) {
- this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
- this.curOp.scrollToPosMargin = margin;
- coords = cursorCoords(this, this.curOp.scrollToPos);
+ if (range.from.line != null) {
+ resolveScrollToPos(this);
+ this.curOp.scrollToPos = range;
+ } else {
+ var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
+ Math.min(range.from.top, range.to.top) - range.margin,
+ Math.max(range.from.right, range.to.right),
+ Math.max(range.from.bottom, range.to.bottom) + range.margin);
+ this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
}
- var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
- updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
}),
- setSize: operation(null, function(width, height) {
+ setSize: methodOp(function(width, height) {
function interpret(val) {
return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
}
if (width != null) this.display.wrapper.style.width = interpret(width);
if (height != null) this.display.wrapper.style.height = interpret(height);
- if (this.options.lineWrapping)
- this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
+ if (this.options.lineWrapping) clearLineMeasurementCache(this);
this.curOp.forceUpdate = true;
+ signal(this, "refresh", this);
}),
operation: function(f){return runInOp(this, f);},
- refresh: operation(null, function() {
- var badHeight = this.display.cachedTextHeight == null;
- clearCaches(this);
- updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
+ refresh: methodOp(function() {
+ var oldHeight = this.display.cachedTextHeight;
regChange(this);
- if (badHeight) estimateLineHeights(this);
+ this.curOp.forceUpdate = true;
+ clearCaches(this);
+ this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
+ updateGutterSpace(this);
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+ estimateLineHeights(this);
+ signal(this, "refresh", this);
}),
- swapDoc: operation(null, function(doc) {
+ swapDoc: methodOp(function(doc) {
var old = this.doc;
old.cm = null;
attachDoc(this, doc);
clearCaches(this);
- resetInput(this, true);
- updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
+ resetInput(this);
+ this.scrollTo(doc.scrollLeft, doc.scrollTop);
+ signalLater(this, "swapDoc", this, old);
return old;
}),
@@ -3219,10 +4290,10 @@ window.CodeMirror = (function() {
// OPTION DEFAULTS
- var optionHandlers = CodeMirror.optionHandlers = {};
-
// The default configuration options.
var defaults = CodeMirror.defaults = {};
+ // Functions to run when options are changed.
+ var optionHandlers = CodeMirror.optionHandlers = {};
function option(name, deflt, handle, notOnInit) {
CodeMirror.defaults[name] = deflt;
@@ -3230,6 +4301,7 @@ window.CodeMirror = (function() {
notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
}
+ // Passed to option handlers when there is no old value.
var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
// These two are, on init, called from the constructor because they
@@ -3246,12 +4318,18 @@ window.CodeMirror = (function() {
option("indentWithTabs", false);
option("smartIndent", true);
option("tabSize", 4, function(cm) {
- loadMode(cm);
+ resetModeState(cm);
clearCaches(cm);
regChange(cm);
}, true);
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
+ cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
+ cm.refresh();
+ }, true);
+ option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
option("electricChars", true);
option("rtlMoveVisually", !windows);
+ option("wholeLineUpdateBefore", true);
option("theme", "default", function(cm) {
themeChanged(cm);
@@ -3260,9 +4338,6 @@ window.CodeMirror = (function() {
option("keyMap", "default", keyMapChanged);
option("extraKeys", null);
- option("onKeyEvent", null);
- option("onDragEvent", null);
-
option("lineWrapping", false, wrappingChanged, true);
option("gutters", [], function(cm) {
setGuttersForLineNumbers(cm.options);
@@ -3281,10 +4356,19 @@ window.CodeMirror = (function() {
option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
option("showCursorWhenSelecting", false, updateSelection, true);
+ option("resetSelectionOnContextMenu", true);
+
option("readOnly", false, function(cm, val) {
- if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
- else if (!val) resetInput(cm, true);
+ if (val == "nocursor") {
+ onBlur(cm);
+ cm.display.input.blur();
+ cm.display.disabled = true;
+ } else {
+ cm.display.disabled = false;
+ if (!val) resetInput(cm);
+ }
});
+ option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
option("dragDrop", true);
option("cursorBlinkRate", 530);
@@ -3292,13 +4376,13 @@ window.CodeMirror = (function() {
option("cursorHeight", 1);
option("workTime", 100);
option("workDelay", 100);
- option("flattenSpans", true);
+ option("flattenSpans", true, resetModeState, true);
+ option("addModeClass", false, resetModeState, true);
option("pollInterval", 100);
- option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
- option("historyEventDelay", 500);
+ option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
+ option("historyEventDelay", 1250);
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
- option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
- option("crudeMeasuringFrom", 10000);
+ option("maxHighlightLength", 10000, resetModeState, true);
option("moveInputWithCursor", true, function(cm, val) {
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
});
@@ -3313,6 +4397,9 @@ window.CodeMirror = (function() {
// Known modes, by name and by MIME
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+ // Extra arguments are stored as the mode's dependencies, which is
+ // used by (legacy) mechanisms like loadmode.js to automatically
+ // load a mode. (Preferred mechanism is the require/define calls.)
CodeMirror.defineMode = function(name, mode) {
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
if (arguments.length > 2) {
@@ -3326,11 +4413,14 @@ window.CodeMirror = (function() {
mimeModes[mime] = spec;
};
+ // Given a MIME type, a {name, ...options} config object, or a name
+ // string, return a mode config object.
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
var found = mimeModes[spec.name];
+ if (typeof found == "string") found = {name: found};
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
@@ -3340,6 +4430,8 @@ window.CodeMirror = (function() {
else return spec || {name: "null"};
};
+ // Given a mode spec (anything that resolveMode accepts), find and
+ // initialize an actual mode object.
CodeMirror.getMode = function(options, spec) {
var spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
@@ -3354,15 +4446,21 @@ window.CodeMirror = (function() {
}
}
modeObj.name = spec.name;
+ if (spec.helperType) modeObj.helperType = spec.helperType;
+ if (spec.modeProps) for (var prop in spec.modeProps)
+ modeObj[prop] = spec.modeProps[prop];
return modeObj;
};
+ // Minimal default mode.
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
+ // This can be used to attach properties to mode objects from
+ // outside the actual mode definition.
var modeExtensions = CodeMirror.modeExtensions = {};
CodeMirror.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
@@ -3384,19 +4482,20 @@ window.CodeMirror = (function() {
var helpers = CodeMirror.helpers = {};
CodeMirror.registerHelper = function(type, name, value) {
- if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
helpers[type][name] = value;
};
-
- // UTILITIES
-
- CodeMirror.isWordChar = isWordChar;
+ CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
+ CodeMirror.registerHelper(type, name, value);
+ helpers[type]._global.push({pred: predicate, val: value});
+ };
// MODE STATE HANDLING
- // Utility functions for working with state. Exported because modes
- // sometimes need to do this.
- function copyState(mode, state) {
+ // Utility functions for working with state. Exported because nested
+ // modes need to do this for their inner modes.
+
+ var copyState = CodeMirror.copyState = function(mode, state) {
if (state === true) return state;
if (mode.copyState) return mode.copyState(state);
var nstate = {};
@@ -3406,14 +4505,14 @@ window.CodeMirror = (function() {
nstate[n] = val;
}
return nstate;
- }
- CodeMirror.copyState = copyState;
+ };
- function startState(mode, a1, a2) {
+ var startState = CodeMirror.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
- }
- CodeMirror.startState = startState;
+ };
+ // Given a mode and a state (for that mode), find the inner mode and
+ // state at the position that the state refers to.
CodeMirror.innerMode = function(mode, state) {
while (mode.innerMode) {
var info = mode.innerMode(state);
@@ -3426,49 +4525,73 @@ window.CodeMirror = (function() {
// STANDARD COMMANDS
+ // Commands are parameter-less actions that can be performed on an
+ // editor, mostly used for keybindings.
var commands = CodeMirror.commands = {
- selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
+ singleSelection: function(cm) {
+ cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
+ },
killLine: function(cm) {
- var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
- if (!sel && cm.getLine(from.line).length == from.ch)
- cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
- else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
+ deleteNearSelection(cm, function(range) {
+ if (range.empty()) {
+ var len = getLine(cm.doc, range.head.line).text.length;
+ if (range.head.ch == len && range.head.line < cm.lastLine())
+ return {from: range.head, to: Pos(range.head.line + 1, 0)};
+ else
+ return {from: range.head, to: Pos(range.head.line, len)};
+ } else {
+ return {from: range.from(), to: range.to()};
+ }
+ });
},
deleteLine: function(cm) {
- var l = cm.getCursor().line;
- cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
+ deleteNearSelection(cm, function(range) {
+ return {from: Pos(range.from().line, 0),
+ to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
+ });
},
delLineLeft: function(cm) {
- var cur = cm.getCursor();
- cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
+ deleteNearSelection(cm, function(range) {
+ return {from: Pos(range.from().line, 0), to: range.from()};
+ });
},
undo: function(cm) {cm.undo();},
redo: function(cm) {cm.redo();},
+ undoSelection: function(cm) {cm.undoSelection();},
+ redoSelection: function(cm) {cm.redoSelection();},
goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
goLineStart: function(cm) {
- cm.extendSelection(lineStart(cm, cm.getCursor().line));
+ cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, sel_move);
},
goLineStartSmart: function(cm) {
- var cur = cm.getCursor(), start = lineStart(cm, cur.line);
- var line = cm.getLineHandle(start.line);
- var order = getOrder(line);
- if (!order || order[0].level == 0) {
- var firstNonWS = Math.max(0, line.text.search(/\S/));
- var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
- cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
- } else cm.extendSelection(start);
+ cm.extendSelectionsBy(function(range) {
+ var start = lineStart(cm, range.head.line);
+ var line = cm.getLineHandle(start.line);
+ var order = getOrder(line);
+ if (!order || order[0].level == 0) {
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
+ var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch;
+ return Pos(start.line, inWS ? 0 : firstNonWS);
+ }
+ return start;
+ }, sel_move);
},
goLineEnd: function(cm) {
- cm.extendSelection(lineEnd(cm, cm.getCursor().line));
+ cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, sel_move);
},
goLineRight: function(cm) {
- var top = cm.charCoords(cm.getCursor(), "div").top + 5;
- cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
+ cm.extendSelectionsBy(function(range) {
+ var top = cm.charCoords(range.head, "div").top + 5;
+ return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
+ }, sel_move);
},
goLineLeft: function(cm) {
- var top = cm.charCoords(cm.getCursor(), "div").top + 5;
- cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
+ cm.extendSelectionsBy(function(range) {
+ var top = cm.charCoords(range.head, "div").top + 5;
+ return cm.coordsChar({left: 0, top: top}, "div");
+ }, sel_move);
},
goLineUp: function(cm) {cm.moveV(-1, "line");},
goLineDown: function(cm) {cm.moveV(1, "line");},
@@ -3491,22 +4614,53 @@ window.CodeMirror = (function() {
indentAuto: function(cm) {cm.indentSelection("smart");},
indentMore: function(cm) {cm.indentSelection("add");},
indentLess: function(cm) {cm.indentSelection("subtract");},
- insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
+ insertTab: function(cm) {cm.replaceSelection("\t");},
+ insertSoftTab: function(cm) {
+ var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
+ for (var i = 0; i < ranges.length; i++) {
+ var pos = ranges[i].from();
+ var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
+ spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
+ }
+ cm.replaceSelections(spaces);
+ },
defaultTab: function(cm) {
if (cm.somethingSelected()) cm.indentSelection("add");
- else cm.replaceSelection("\t", "end", "+input");
+ else cm.execCommand("insertTab");
},
transposeChars: function(cm) {
- var cur = cm.getCursor(), line = cm.getLine(cur.line);
- if (cur.ch > 0 && cur.ch < line.length - 1)
- cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
- Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
+ runInOp(cm, function() {
+ var ranges = cm.listSelections(), newSel = [];
+ for (var i = 0; i < ranges.length; i++) {
+ var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
+ if (line) {
+ if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
+ if (cur.ch > 0) {
+ cur = new Pos(cur.line, cur.ch + 1);
+ cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
+ Pos(cur.line, cur.ch - 2), cur, "+transpose");
+ } else if (cur.line > cm.doc.first) {
+ var prev = getLine(cm.doc, cur.line - 1).text;
+ if (prev)
+ cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
+ Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
+ }
+ }
+ newSel.push(new Range(cur, cur));
+ }
+ cm.setSelections(newSel);
+ });
},
newlineAndIndent: function(cm) {
- operation(cm, function() {
- cm.replaceSelection("\n", "end", "+input");
- cm.indentLine(cm.getCursor().line, null, true);
- })();
+ runInOp(cm, function() {
+ var len = cm.listSelections().length;
+ for (var i = 0; i < len; i++) {
+ var range = cm.listSelections()[i];
+ cm.replaceRange("\n", range.anchor, range.head, "+input");
+ cm.indentLine(range.from().line + 1, null, true);
+ ensureCursorVisible(cm);
+ }
+ });
},
toggleOverwrite: function(cm) {cm.toggleOverwrite();}
};
@@ -3517,18 +4671,22 @@ window.CodeMirror = (function() {
keyMap.basic = {
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
- "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
- "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
+ "Tab": "defaultTab", "Shift-Tab": "indentAuto",
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
+ "Esc": "singleSelection"
};
// Note that the save and find-related commands aren't defined by
- // default. Unknown commands are simply ignored.
+ // default. User code or addons can define them. Unknown commands
+ // are simply ignored.
keyMap.pcDefault = {
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
- "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
+ "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
+ "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
fallthrough: "basic"
};
keyMap.macDefault = {
@@ -3538,15 +4696,17 @@ window.CodeMirror = (function() {
"Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
+ "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection",
fallthrough: ["basic", "emacsy"]
};
- keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
+ // Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = {
"Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
"Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
"Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
"Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
};
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
// KEYMAP DISPATCH
@@ -3555,7 +4715,11 @@ window.CodeMirror = (function() {
else return val;
}
- function lookupKey(name, maps, handle) {
+ // Given an array of keymaps and a key name, call handle on any
+ // bindings found, until that returns a truthy value, at which point
+ // we consider the key handled. Implements things like binding a key
+ // to false stopping further handling and keymap fallthrough.
+ var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) {
function lookup(map) {
map = getKeyMap(map);
var found = map[name];
@@ -3567,7 +4731,7 @@ window.CodeMirror = (function() {
if (fallthrough == null) return false;
if (Object.prototype.toString.call(fallthrough) != "[object Array]")
return lookup(fallthrough);
- for (var i = 0, e = fallthrough.length; i < e; ++i) {
+ for (var i = 0; i < fallthrough.length; ++i) {
var done = lookup(fallthrough[i]);
if (done) return done;
}
@@ -3578,13 +4742,18 @@ window.CodeMirror = (function() {
var done = lookup(maps[i]);
if (done) return done != "stop";
}
- }
- function isModifierKey(event) {
+ };
+
+ // Modifier key presses don't count as 'real' key presses for the
+ // purpose of keymap fallthrough.
+ var isModifierKey = CodeMirror.isModifierKey = function(event) {
var name = keyNames[event.keyCode];
return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
- }
- function keyName(event, noShift) {
- if (opera && event.keyCode == 34 && event["char"]) return false;
+ };
+
+ // Look up the name of a key as indicated by an event object.
+ var keyName = CodeMirror.keyName = function(event, noShift) {
+ if (presto && event.keyCode == 34 && event["char"]) return false;
var name = keyNames[event.keyCode];
if (name == null || event.altGraphKey) return false;
if (event.altKey) name = "Alt-" + name;
@@ -3592,10 +4761,7 @@ window.CodeMirror = (function() {
if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
if (!noShift && event.shiftKey) name = "Shift-" + name;
return name;
- }
- CodeMirror.lookupKey = lookupKey;
- CodeMirror.isModifierKey = isModifierKey;
- CodeMirror.keyName = keyName;
+ };
// FROMTEXTAREA
@@ -3609,9 +4775,7 @@ window.CodeMirror = (function() {
// Set autofocus to true if this textarea is focused, or if it has
// autofocus and no other element is focused.
if (options.autofocus == null) {
- var hasFocus = document.body;
- // doc.activeElement occasionally throws on IE
- try { hasFocus = document.activeElement; } catch(e) {}
+ var hasFocus = activeElt();
options.autofocus = hasFocus == textarea ||
textarea.getAttribute("autofocus") != null && hasFocus == document.body;
}
@@ -3657,17 +4821,17 @@ window.CodeMirror = (function() {
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
- // The character stream used by a mode's parser.
- function StringStream(string, tabSize) {
+ var StringStream = CodeMirror.StringStream = function(string, tabSize) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
- }
+ this.lineStart = 0;
+ };
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
- sol: function() {return this.pos == 0;},
+ sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
@@ -3700,9 +4864,12 @@ window.CodeMirror = (function() {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
- return this.lastColumnValue;
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+ },
+ indentation: function() {
+ return countColumn(this.string, null, this.tabSize) -
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
- indentation: function() {return countColumn(this.string, null, this.tabSize);},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
@@ -3718,20 +4885,34 @@ window.CodeMirror = (function() {
return match;
}
},
- current: function(){return this.string.slice(this.start, this.pos);}
+ current: function(){return this.string.slice(this.start, this.pos);},
+ hideFirstChars: function(n, inner) {
+ this.lineStart += n;
+ try { return inner(); }
+ finally { this.lineStart -= n; }
+ }
};
- CodeMirror.StringStream = StringStream;
// TEXTMARKERS
- function TextMarker(doc, type) {
+ // Created with markText and setBookmark methods. A TextMarker is a
+ // handle that can be used to clear or find a marked position in the
+ // document. Line objects hold arrays (markedSpans) containing
+ // {from, to, marker} object pointing to such marker objects, and
+ // indicating that such a marker is present on that line. Multiple
+ // lines may point to the same marker when it spans across lines.
+ // The spans will have null for their from/to properties when the
+ // marker continues beyond the start/end of the line. Markers have
+ // links back to the lines they currently touch.
+
+ var TextMarker = CodeMirror.TextMarker = function(doc, type) {
this.lines = [];
this.type = type;
this.doc = doc;
- }
- CodeMirror.TextMarker = TextMarker;
+ };
eventMixin(TextMarker);
+ // Clear the marker.
TextMarker.prototype.clear = function() {
if (this.explicitlyCleared) return;
var cm = this.doc.cm, withOp = cm && !cm.curOp;
@@ -3744,15 +4925,17 @@ window.CodeMirror = (function() {
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
- if (span.to != null) max = lineNo(line);
+ if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
+ else if (cm) {
+ if (span.to != null) max = lineNo(line);
+ if (span.from != null) min = lineNo(line);
+ }
line.markedSpans = removeMarkedSpan(line.markedSpans, span);
- if (span.from != null)
- min = lineNo(line);
- else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
+ if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
updateLineHeight(line, textHeight(cm.display));
}
if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
- var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
+ var visual = visualLine(this.lines[i]), len = lineLength(visual);
if (len > cm.display.maxLineLength) {
cm.display.maxLine = visual;
cm.display.maxLineLength = len;
@@ -3760,46 +4943,62 @@ window.CodeMirror = (function() {
}
}
- if (min != null && cm) regChange(cm, min, max + 1);
+ if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
this.lines.length = 0;
this.explicitlyCleared = true;
if (this.atomic && this.doc.cantEdit) {
this.doc.cantEdit = false;
- if (cm) reCheckSelection(cm);
+ if (cm) reCheckSelection(cm.doc);
}
+ if (cm) signalLater(cm, "markerCleared", cm, this);
if (withOp) endOperation(cm);
+ if (this.parent) this.parent.clear();
};
- TextMarker.prototype.find = function() {
+ // Find the position of the marker in the document. Returns a {from,
+ // to} object by default. Side can be passed to get a specific side
+ // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
+ // Pos objects returned contain a line object, rather than a line
+ // number (used to prevent looking up the same line twice).
+ TextMarker.prototype.find = function(side, lineObj) {
+ if (side == null && this.type == "bookmark") side = 1;
var from, to;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
- if (span.from != null || span.to != null) {
- var found = lineNo(line);
- if (span.from != null) from = Pos(found, span.from);
- if (span.to != null) to = Pos(found, span.to);
+ if (span.from != null) {
+ from = Pos(lineObj ? line : lineNo(line), span.from);
+ if (side == -1) return from;
+ }
+ if (span.to != null) {
+ to = Pos(lineObj ? line : lineNo(line), span.to);
+ if (side == 1) return to;
}
}
- if (this.type == "bookmark") return from;
return from && {from: from, to: to};
};
+ // Signals that the marker's widget changed, and surrounding layout
+ // should be recomputed.
TextMarker.prototype.changed = function() {
- var pos = this.find(), cm = this.doc.cm;
+ var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
if (!pos || !cm) return;
- if (this.type != "bookmark") pos = pos.from;
- var line = getLine(this.doc, pos.line);
- clearCachedMeasurement(cm, line);
- if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) {
- for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
- if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
- break;
+ runInOp(cm, function() {
+ var line = pos.line, lineN = lineNo(pos.line);
+ var view = findViewForLine(cm, lineN);
+ if (view) {
+ clearLineMeasurementCacheFor(view);
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
}
- runInOp(cm, function() {
- cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
- });
- }
+ cm.curOp.updateMaxLine = true;
+ if (!lineIsHidden(widget.doc, line) && widget.height != null) {
+ var oldHeight = widget.height;
+ widget.height = null;
+ var dHeight = widgetHeight(widget) - oldHeight;
+ if (dHeight)
+ updateLineHeight(line, line.height + dHeight);
+ }
+ });
};
TextMarker.prototype.attachLine = function(line) {
@@ -3818,40 +5017,53 @@ window.CodeMirror = (function() {
}
};
+ // Collapsed markers have unique ids, in order to be able to order
+ // them, which is needed for uniquely determining an outer marker
+ // when they overlap (they may nest, but not partially overlap).
+ var nextMarkerId = 0;
+
+ // Create a marker, wire it up to the right lines, and
function markText(doc, from, to, options, type) {
+ // Shared markers (across linked documents) are handled separately
+ // (markTextShared will call out to this again, once per
+ // document).
if (options && options.shared) return markTextShared(doc, from, to, options, type);
+ // Ensure we are in an operation.
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
- var marker = new TextMarker(doc, type);
- if (type == "range" && !posLess(from, to)) return marker;
- if (options) copyObj(options, marker);
+ var marker = new TextMarker(doc, type), diff = cmp(from, to);
+ if (options) copyObj(options, marker, false);
+ // Don't connect empty markers unless clearWhenEmpty is false
+ if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
+ return marker;
if (marker.replacedWith) {
+ // Showing up as a widget implies collapsed (widget replaces text)
marker.collapsed = true;
- marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
- if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
+ marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
+ if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true;
+ if (options.insertLeft) marker.widgetNode.insertLeft = true;
+ }
+ if (marker.collapsed) {
+ if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
+ from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
+ throw new Error("Inserting collapsed marker partially overlapping an existing one");
+ sawCollapsedSpans = true;
}
- if (marker.collapsed) sawCollapsedSpans = true;
if (marker.addToHistory)
- addToHistory(doc, {from: from, to: to, origin: "markText"},
- {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
+ addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
- var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
+ var curLine = from.line, cm = doc.cm, updateMaxLine;
doc.iter(curLine, to.line + 1, function(line) {
- if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
updateMaxLine = true;
- var span = {from: null, to: null, marker: marker};
- size += line.text.length;
- if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
- if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
- if (marker.collapsed) {
- if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
- if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
- else updateLineHeight(line, 0);
- }
- addMarkedSpan(line, span);
+ if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
+ addMarkedSpan(line, new MarkedSpan(marker,
+ curLine == from.line ? from.ch : null,
+ curLine == to.line ? to.ch : null));
++curLine;
});
+ // lineIsHidden depends on the presence of the spans, so needs a second pass
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
});
@@ -3864,31 +5076,33 @@ window.CodeMirror = (function() {
doc.clearHistory();
}
if (marker.collapsed) {
- if (collapsedAtStart != collapsedAtEnd)
- throw new Error("Inserting collapsed marker overlapping an existing one");
- marker.size = size;
+ marker.id = ++nextMarkerId;
marker.atomic = true;
}
if (cm) {
+ // Sync editor state
if (updateMaxLine) cm.curOp.updateMaxLine = true;
- if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
+ if (marker.collapsed)
regChange(cm, from.line, to.line + 1);
- if (marker.atomic) reCheckSelection(cm);
+ else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
+ for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
+ if (marker.atomic) reCheckSelection(cm.doc);
+ signalLater(cm, "markerAdded", cm, marker);
}
return marker;
}
// SHARED TEXTMARKERS
- function SharedTextMarker(markers, primary) {
+ // A shared marker spans multiple linked documents. It is
+ // implemented as a meta-marker-object controlling multiple normal
+ // markers.
+ var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
this.markers = markers;
this.primary = primary;
- for (var i = 0, me = this; i < markers.length; ++i) {
+ for (var i = 0; i < markers.length; ++i)
markers[i].parent = this;
- on(markers[i], "clear", function(){me.clear();});
- }
- }
- CodeMirror.SharedTextMarker = SharedTextMarker;
+ };
eventMixin(SharedTextMarker);
SharedTextMarker.prototype.clear = function() {
@@ -3898,17 +5112,17 @@ window.CodeMirror = (function() {
this.markers[i].clear();
signalLater(this, "clear");
};
- SharedTextMarker.prototype.find = function() {
- return this.primary.find();
+ SharedTextMarker.prototype.find = function(side, lineObj) {
+ return this.primary.find(side, lineObj);
};
function markTextShared(doc, from, to, options, type) {
options = copyObj(options);
options.shared = false;
var markers = [markText(doc, from, to, options, type)], primary = markers[0];
- var widget = options.replacedWith;
+ var widget = options.widgetNode;
linkedDocs(doc, function(doc) {
- if (widget) options.replacedWith = widget.cloneNode(true);
+ if (widget) options.widgetNode = widget.cloneNode(true);
markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
for (var i = 0; i < doc.linked.length; ++i)
if (doc.linked[i].isParent) return;
@@ -3917,58 +5131,104 @@ window.CodeMirror = (function() {
return new SharedTextMarker(markers, primary);
}
+ function findSharedMarkers(doc) {
+ return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
+ function(m) { return m.parent; });
+ }
+
+ function copySharedMarkers(doc, markers) {
+ for (var i = 0; i < markers.length; i++) {
+ var marker = markers[i], pos = marker.find();
+ var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
+ if (cmp(mFrom, mTo)) {
+ var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
+ marker.markers.push(subMark);
+ subMark.parent = marker;
+ }
+ }
+ }
+
+ function detachSharedMarkers(markers) {
+ for (var i = 0; i < markers.length; i++) {
+ var marker = markers[i], linked = [marker.primary.doc];;
+ linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
+ for (var j = 0; j < marker.markers.length; j++) {
+ var subMarker = marker.markers[j];
+ if (indexOf(linked, subMarker.doc) == -1) {
+ subMarker.parent = null;
+ marker.markers.splice(j--, 1);
+ }
+ }
+ }
+ }
+
// TEXTMARKER SPANS
+ function MarkedSpan(marker, from, to) {
+ this.marker = marker;
+ this.from = from; this.to = to;
+ }
+
+ // Search an array of spans for a span matching the given marker.
function getMarkedSpanFor(spans, marker) {
if (spans) for (var i = 0; i < spans.length; ++i) {
var span = spans[i];
if (span.marker == marker) return span;
}
}
+ // Remove a span from an array, returning undefined if no spans are
+ // left (we don't store arrays for lines without spans).
function removeMarkedSpan(spans, span) {
for (var r, i = 0; i < spans.length; ++i)
if (spans[i] != span) (r || (r = [])).push(spans[i]);
return r;
}
+ // Add a span to a line.
function addMarkedSpan(line, span) {
line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
span.marker.attachLine(line);
}
+ // Used for the algorithm that adjusts markers for a change in the
+ // document. These functions cut an array of spans at a given
+ // character position, returning an array of remaining chunks (or
+ // undefined if nothing remains).
function markedSpansBefore(old, startCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
- if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
+ if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
- (nw || (nw = [])).push({from: span.from,
- to: endsAfter ? null : span.to,
- marker: marker});
+ (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
}
}
return nw;
}
-
function markedSpansAfter(old, endCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
- if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
+ if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
- (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
- to: span.to == null ? null : span.to - endCh,
- marker: marker});
+ (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
+ span.to == null ? null : span.to - endCh));
}
}
return nw;
}
+ // Given a change object, compute the new set of marker spans that
+ // cover the line in which the change took place. Removes spans
+ // entirely within the change, reconnects spans belonging to the
+ // same marker that appear on both sides of the change, and cuts off
+ // spans partially within the change. Returns an array of span
+ // arrays with one element for each line in (after) the change.
function stretchSpansOverChange(doc, change) {
var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
if (!oldFirst && !oldLast) return null;
- var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
// Get the spans that 'stick out' on both sides
var first = markedSpansBefore(oldFirst, startCh, isInsert);
var last = markedSpansAfter(oldLast, endCh, isInsert);
@@ -4003,13 +5263,9 @@ window.CodeMirror = (function() {
}
}
}
- if (sameLine && first) {
- // Make sure we didn't create any zero-length spans
- for (var i = 0; i < first.length; ++i)
- if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
- first.splice(i--, 1);
- if (!first.length) first = null;
- }
+ // Make sure we didn't create any zero-length spans
+ if (first) first = clearEmptySpans(first);
+ if (last && last != first) last = clearEmptySpans(last);
var newMarkers = [first];
if (!sameLine) {
@@ -4018,7 +5274,7 @@ window.CodeMirror = (function() {
if (gap > 0 && first)
for (var i = 0; i < first.length; ++i)
if (first[i].to == null)
- (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
+ (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
for (var i = 0; i < gap; ++i)
newMarkers.push(gapMarkers);
newMarkers.push(last);
@@ -4026,6 +5282,22 @@ window.CodeMirror = (function() {
return newMarkers;
}
+ // Remove spans that are empty and don't have a clearWhenEmpty
+ // option of false.
+ function clearEmptySpans(spans) {
+ for (var i = 0; i < spans.length; ++i) {
+ var span = spans[i];
+ if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
+ spans.splice(i--, 1);
+ }
+ if (!spans.length) return null;
+ return spans;
+ }
+
+ // Used for un/re-doing changes from the history. Combines the
+ // result of computing the existing spans with the set of spans that
+ // existed in the history (so that deleting around a span and then
+ // undoing brings back the span).
function mergeOldSpans(doc, change) {
var old = getOldSpans(doc, change);
var stretched = stretchSpansOverChange(doc, change);
@@ -4048,6 +5320,7 @@ window.CodeMirror = (function() {
return old;
}
+ // Used to 'clip' out readOnly ranges when making a change.
function removeReadOnlyRanges(doc, from, to) {
var markers = null;
doc.iter(from.line, to.line + 1, function(line) {
@@ -4060,14 +5333,14 @@ window.CodeMirror = (function() {
if (!markers) return null;
var parts = [{from: from, to: to}];
for (var i = 0; i < markers.length; ++i) {
- var mk = markers[i], m = mk.find();
+ var mk = markers[i], m = mk.find(0);
for (var j = 0; j < parts.length; ++j) {
var p = parts[j];
- if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
- var newParts = [j, 1];
- if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
+ if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
+ var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
+ if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
newParts.push({from: p.from, to: m.from});
- if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
+ if (dto > 0 || !mk.inclusiveRight && !dto)
newParts.push({from: m.to, to: p.to});
parts.splice.apply(parts, newParts);
j += newParts.length - 1;
@@ -4076,71 +5349,148 @@ window.CodeMirror = (function() {
return parts;
}
- function collapsedSpanAt(line, ch) {
+ // Connect or disconnect spans from a line.
+ function detachMarkedSpans(line) {
+ var spans = line.markedSpans;
+ if (!spans) return;
+ for (var i = 0; i < spans.length; ++i)
+ spans[i].marker.detachLine(line);
+ line.markedSpans = null;
+ }
+ function attachMarkedSpans(line, spans) {
+ if (!spans) return;
+ for (var i = 0; i < spans.length; ++i)
+ spans[i].marker.attachLine(line);
+ line.markedSpans = spans;
+ }
+
+ // Helpers used when computing which overlapping collapsed span
+ // counts as the larger one.
+ function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
+ function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
+
+ // Returns a number indicating which of two overlapping collapsed
+ // spans is larger (and thus includes the other). Falls back to
+ // comparing ids when the spans cover exactly the same range.
+ function compareCollapsedMarkers(a, b) {
+ var lenDiff = a.lines.length - b.lines.length;
+ if (lenDiff != 0) return lenDiff;
+ var aPos = a.find(), bPos = b.find();
+ var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
+ if (fromCmp) return -fromCmp;
+ var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
+ if (toCmp) return toCmp;
+ return b.id - a.id;
+ }
+
+ // Find out whether a line ends or starts in a collapsed span. If
+ // so, return the marker for that span.
+ function collapsedSpanAtSide(line, start) {
var sps = sawCollapsedSpans && line.markedSpans, found;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
- if (!sp.marker.collapsed) continue;
- if ((sp.from == null || sp.from < ch) &&
- (sp.to == null || sp.to > ch) &&
- (!found || found.width < sp.marker.width))
+ if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0))
found = sp.marker;
}
return found;
}
- function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
- function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
+ function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
+ function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
- function visualLine(doc, line) {
+ // Test whether there exists a collapsed span that partially
+ // overlaps (covers the start or end, but not both) of a new span.
+ // Such overlap is not allowed.
+ function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
+ var line = getLine(doc, lineNo);
+ var sps = sawCollapsedSpans && line.markedSpans;
+ if (sps) for (var i = 0; i < sps.length; ++i) {
+ var sp = sps[i];
+ if (!sp.marker.collapsed) continue;
+ var found = sp.marker.find(0);
+ var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
+ var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
+ if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
+ if (fromCmp <= 0 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 ||
+ fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0)
+ return true;
+ }
+ }
+
+ // A visual line is a line as drawn on the screen. Folding, for
+ // example, can cause multiple logical lines to appear on the same
+ // visual line. This finds the start of the visual line that the
+ // given line is part of (usually that is the line itself).
+ function visualLine(line) {
var merged;
while (merged = collapsedSpanAtStart(line))
- line = getLine(doc, merged.find().from.line);
+ line = merged.find(-1, true).line;
return line;
}
+ // Returns an array of logical lines that continue the visual line
+ // started by the argument, or undefined if there are no such lines.
+ function visualLineContinued(line) {
+ var merged, lines;
+ while (merged = collapsedSpanAtEnd(line)) {
+ line = merged.find(1, true).line;
+ (lines || (lines = [])).push(line);
+ }
+ return lines;
+ }
+
+ // Get the line number of the start of the visual line that the
+ // given line number is part of.
+ function visualLineNo(doc, lineN) {
+ var line = getLine(doc, lineN), vis = visualLine(line);
+ if (line == vis) return lineN;
+ return lineNo(vis);
+ }
+ // Get the line number of the start of the next visual line after
+ // the given line.
+ function visualLineEndNo(doc, lineN) {
+ if (lineN > doc.lastLine()) return lineN;
+ var line = getLine(doc, lineN), merged;
+ if (!lineIsHidden(doc, line)) return lineN;
+ while (merged = collapsedSpanAtEnd(line))
+ line = merged.find(1, true).line;
+ return lineNo(line) + 1;
+ }
+
+ // Compute whether a line is hidden. Lines count as hidden when they
+ // are part of a visual line that starts with another line, or when
+ // they are entirely covered by collapsed, non-widget span.
function lineIsHidden(doc, line) {
var sps = sawCollapsedSpans && line.markedSpans;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
if (!sp.marker.collapsed) continue;
if (sp.from == null) return true;
- if (sp.marker.replacedWith) continue;
+ if (sp.marker.widgetNode) continue;
if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
return true;
}
}
function lineIsHiddenInner(doc, line, span) {
if (span.to == null) {
- var end = span.marker.find().to, endLine = getLine(doc, end.line);
- return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
+ var end = span.marker.find(1, true);
+ return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
}
if (span.marker.inclusiveRight && span.to == line.text.length)
return true;
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
sp = line.markedSpans[i];
- if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
+ if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
+ (sp.to == null || sp.to != span.from) &&
(sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
lineIsHiddenInner(doc, line, sp)) return true;
}
}
- function detachMarkedSpans(line) {
- var spans = line.markedSpans;
- if (!spans) return;
- for (var i = 0; i < spans.length; ++i)
- spans[i].marker.detachLine(line);
- line.markedSpans = null;
- }
-
- function attachMarkedSpans(line, spans) {
- if (!spans) return;
- for (var i = 0; i < spans.length; ++i)
- spans[i].marker.attachLine(line);
- line.markedSpans = spans;
- }
-
// LINE WIDGETS
+ // Line widgets are block elements displayed above or below a line.
+
var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
if (options) for (var opt in options) if (options.hasOwnProperty(opt))
this[opt] = options[opt];
@@ -4148,38 +5498,39 @@ window.CodeMirror = (function() {
this.node = node;
};
eventMixin(LineWidget);
- function widgetOperation(f) {
- return function() {
- var withOp = !this.cm.curOp;
- if (withOp) startOperation(this.cm);
- try {var result = f.apply(this, arguments);}
- finally {if (withOp) endOperation(this.cm);}
- return result;
- };
+
+ function adjustScrollWhenAboveVisible(cm, line, diff) {
+ if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
+ addToScrollPos(cm, null, diff);
}
- LineWidget.prototype.clear = widgetOperation(function() {
- var ws = this.line.widgets, no = lineNo(this.line);
+
+ LineWidget.prototype.clear = function() {
+ var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
if (no == null || !ws) return;
for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
- if (!ws.length) this.line.widgets = null;
- var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
- updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
- if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
- regChange(this.cm, no, no + 1);
- });
- LineWidget.prototype.changed = widgetOperation(function() {
- var oldH = this.height;
+ if (!ws.length) line.widgets = null;
+ var height = widgetHeight(this);
+ runInOp(cm, function() {
+ adjustScrollWhenAboveVisible(cm, line, -height);
+ regLineChange(cm, no, "widget");
+ updateLineHeight(line, Math.max(0, line.height - height));
+ });
+ };
+ LineWidget.prototype.changed = function() {
+ var oldH = this.height, cm = this.cm, line = this.line;
this.height = null;
var diff = widgetHeight(this) - oldH;
if (!diff) return;
- updateLineHeight(this.line, this.line.height + diff);
- var no = lineNo(this.line);
- regChange(this.cm, no, no + 1);
- });
+ runInOp(cm, function() {
+ cm.curOp.forceUpdate = true;
+ adjustScrollWhenAboveVisible(cm, line, diff);
+ updateLineHeight(line, line.height + diff);
+ });
+ };
function widgetHeight(widget) {
if (widget.height != null) return widget.height;
- if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
+ if (!contains(document.body, widget.node))
removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
return widget.height = widget.node.offsetHeight;
}
@@ -4187,15 +5538,16 @@ window.CodeMirror = (function() {
function addLineWidget(cm, handle, node, options) {
var widget = new LineWidget(cm, node, options);
if (widget.noHScroll) cm.display.alignWidgets = true;
- changeLine(cm, handle, function(line) {
+ changeLine(cm, handle, "widget", function(line) {
var widgets = line.widgets || (line.widgets = []);
if (widget.insertAt == null) widgets.push(widget);
else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
widget.line = line;
- if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
- var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
+ if (!lineIsHidden(cm.doc, line)) {
+ var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
updateLineHeight(line, line.height + widgetHeight(widget));
- if (aboveVisible) addToScrollPos(cm, 0, widget.height);
+ if (aboveVisible) addToScrollPos(cm, null, widget.height);
+ cm.curOp.forceUpdate = true;
}
return true;
});
@@ -4212,7 +5564,11 @@ window.CodeMirror = (function() {
this.height = estimateHeight ? estimateHeight(this) : 1;
};
eventMixin(Line);
+ Line.prototype.lineNo = function() { return lineNo(this); };
+ // Change the content (text, markers) of a line. Automatically
+ // invalidates cached information and tries to re-estimate the
+ // line's height.
function updateLine(line, text, markedSpans, estimateHeight) {
line.text = text;
if (line.stateAfter) line.stateAfter = null;
@@ -4224,27 +5580,60 @@ window.CodeMirror = (function() {
if (estHeight != line.height) updateLineHeight(line, estHeight);
}
+ // Detach a line from the document tree and its markers.
function cleanUpLine(line) {
line.parent = null;
detachMarkedSpans(line);
}
- // Run the given mode's parser over a line, update the styles
- // array, which contains alternating fragments of text and CSS
- // classes.
- function runMode(cm, text, mode, state, f) {
+ function extractLineClasses(type, output) {
+ if (type) for (;;) {
+ var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
+ if (!lineClass) break;
+ type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
+ var prop = lineClass[1] ? "bgClass" : "textClass";
+ if (output[prop] == null)
+ output[prop] = lineClass[2];
+ else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
+ output[prop] += " " + lineClass[2];
+ }
+ return type;
+ }
+
+ function callBlankLine(mode, state) {
+ if (mode.blankLine) return mode.blankLine(state);
+ if (!mode.innerMode) return;
+ var inner = CodeMirror.innerMode(mode, state);
+ if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
+ }
+
+ function readToken(mode, stream, state) {
+ for (var i = 0; i < 10; i++) {
+ var style = mode.token(stream, state);
+ if (stream.pos > stream.start) return style;
+ }
+ throw new Error("Mode " + mode.name + " failed to advance stream.");
+ }
+
+ // Run the given mode's parser over a line, calling f for each token.
+ function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
var flattenSpans = mode.flattenSpans;
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
var curStart = 0, curStyle = null;
var stream = new StringStream(text, cm.options.tabSize), style;
- if (text == "" && mode.blankLine) mode.blankLine(state);
+ if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
while (!stream.eol()) {
if (stream.pos > cm.options.maxHighlightLength) {
flattenSpans = false;
+ if (forceToEnd) processLine(cm, text, state, stream.pos);
stream.pos = text.length;
style = null;
} else {
- style = mode.token(stream, state);
+ style = extractLineClasses(readToken(mode, stream, state), lineClasses);
+ }
+ if (cm.options.addModeClass) {
+ var mName = CodeMirror.innerMode(mode, state).mode.name;
+ if (mName) style = "m-" + (style ? mName + " " + style : mName);
}
if (!flattenSpans || curStyle != style) {
if (curStart < stream.start) f(stream.start, curStyle);
@@ -4260,12 +5649,18 @@ window.CodeMirror = (function() {
}
}
- function highlightLine(cm, line, state) {
+ // Compute a style array (an array starting with a mode generation
+ // -- for invalidation -- followed by pairs of end positions and
+ // style strings), which is used to highlight the tokens on the
+ // line.
+ function highlightLine(cm, line, state, forceToEnd) {
// A styles array always starts with a number identifying the
// mode/overlays that it is based on (for easy invalidation).
- var st = [cm.state.modeGen];
+ var st = [cm.state.modeGen], lineClasses = {};
// Compute the base array of styles
- runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
+ st.push(end, style);
+ }, lineClasses, forceToEnd);
// Run overlays, adjust style array.
for (var o = 0; o < cm.state.overlays.length; ++o) {
@@ -4282,171 +5677,162 @@ window.CodeMirror = (function() {
}
if (!style) return;
if (overlay.opaque) {
- st.splice(start, i - start, end, style);
+ st.splice(start, i - start, end, "cm-overlay " + style);
i = start + 2;
} else {
for (; start < i; start += 2) {
var cur = st[start+1];
- st[start+1] = cur ? cur + " " + style : style;
+ st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
}
}
- });
+ }, lineClasses);
}
- return st;
+ return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
}
function getLineStyles(cm, line) {
- if (!line.styles || line.styles[0] != cm.state.modeGen)
- line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
+ if (!line.styles || line.styles[0] != cm.state.modeGen) {
+ var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
+ line.styles = result.styles;
+ if (result.classes) line.styleClasses = result.classes;
+ else if (line.styleClasses) line.styleClasses = null;
+ }
return line.styles;
}
// Lightweight form of highlight -- proceed over this line and
- // update state, but don't save a style array.
- function processLine(cm, line, state) {
+ // update state, but don't save a style array. Used for lines that
+ // aren't currently visible.
+ function processLine(cm, text, state, startAt) {
var mode = cm.doc.mode;
- var stream = new StringStream(line.text, cm.options.tabSize);
- if (line.text == "" && mode.blankLine) mode.blankLine(state);
+ var stream = new StringStream(text, cm.options.tabSize);
+ stream.start = stream.pos = startAt || 0;
+ if (text == "") callBlankLine(mode, state);
while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
- mode.token(stream, state);
+ readToken(mode, stream, state);
stream.start = stream.pos;
}
}
- var styleToClassCache = {};
- function interpretTokenStyle(style, builder) {
- if (!style) return null;
- for (;;) {
- var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/);
- if (!lineClass) break;
- style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
- var prop = lineClass[1] ? "bgClass" : "textClass";
- if (builder[prop] == null)
- builder[prop] = lineClass[2];
- else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
- builder[prop] += " " + lineClass[2];
- }
- return styleToClassCache[style] ||
- (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
- }
-
- function buildLineContent(cm, realLine, measure, copyWidgets) {
- var merged, line = realLine, empty = true;
- while (merged = collapsedSpanAtStart(line))
- line = getLine(cm.doc, merged.find().from.line);
-
- var builder = {pre: elt("pre"), col: 0, pos: 0,
- measure: null, measuredSomething: false, cm: cm,
- copyWidgets: copyWidgets};
-
- do {
- if (line.text) empty = false;
- builder.measure = line == realLine && measure;
+ // Convert a style as returned by a mode (either null, or a string
+ // containing one or more styles) to a CSS style. This is cached,
+ // and also looks for line-wide styles.
+ var styleToClassCache = {}, styleToClassCacheWithMode = {};
+ function interpretTokenStyle(style, options) {
+ if (!style || /^\s*$/.test(style)) return null;
+ var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
+ return cache[style] ||
+ (cache[style] = style.replace(/\S+/g, "cm-$&"));
+ }
+
+ // Render the DOM representation of the text of a line. Also builds
+ // up a 'line map', which points at the DOM nodes that represent
+ // specific stretches of text, and is used by the measuring code.
+ // The returned object contains the DOM node, this map, and
+ // information about line-wide styles that were set by the mode.
+ function buildLineContent(cm, lineView) {
+ // The padding-right forces the element to have a 'border', which
+ // is needed on Webkit to be able to get line-level bounding
+ // rectangles for it (in measureChar).
+ var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
+ var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
+ lineView.measure = {};
+
+ // Iterate over the logical lines that make up this visual line.
+ for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
+ var line = i ? lineView.rest[i - 1] : lineView.line, order;
builder.pos = 0;
- builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
+ builder.addToken = buildToken;
+ // Optionally wire in some hacks into the token-rendering
+ // algorithm, to deal with browser quirks.
if ((ie || webkit) && cm.getOption("lineWrapping"))
builder.addToken = buildTokenSplitSpaces(builder.addToken);
- var next = insertLineContent(line, builder, getLineStyles(cm, line));
- if (measure && line == realLine && !builder.measuredSomething) {
- measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
- builder.measuredSomething = true;
- }
- if (next) line = getLine(cm.doc, next.to.line);
- } while (next);
-
- if (measure && !builder.measuredSomething && !measure[0])
- measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
- if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
- builder.pre.appendChild(document.createTextNode("\u00a0"));
-
- var order;
- // Work around problem with the reported dimensions of single-char
- // direction spans on IE (issue #1129). See also the comment in
- // cursorCoords.
- if (measure && ie && (order = getOrder(line))) {
- var l = order.length - 1;
- if (order[l].from == order[l].to) --l;
- var last = order[l], prev = order[l - 1];
- if (last.from + 1 == last.to && prev && last.level < prev.level) {
- var span = measure[builder.pos - 1];
- if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
- span.nextSibling);
- }
- }
-
- var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass;
- if (textClass) builder.pre.className = textClass;
-
- signal(cm, "renderLine", cm, realLine, builder.pre);
+ if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
+ builder.addToken = buildTokenBadBidi(builder.addToken, order);
+ builder.map = [];
+ insertLineContent(line, builder, getLineStyles(cm, line));
+ if (line.styleClasses) {
+ if (line.styleClasses.bgClass)
+ builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
+ if (line.styleClasses.textClass)
+ builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
+ }
+
+ // Ensure at least a single node is present, for measuring.
+ if (builder.map.length == 0)
+ builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
+
+ // Store the map and a cache object for the current logical line
+ if (i == 0) {
+ lineView.measure.map = builder.map;
+ lineView.measure.cache = {};
+ } else {
+ (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
+ (lineView.measure.caches || (lineView.measure.caches = [])).push({});
+ }
+ }
+
+ signal(cm, "renderLine", cm, lineView.line, builder.pre);
return builder;
}
- var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
+ function defaultSpecialCharPlaceholder(ch) {
+ var token = elt("span", "\u2022", "cm-invalidchar");
+ token.title = "\\u" + ch.charCodeAt(0).toString(16);
+ return token;
+ }
+
+ // Build up the DOM representation for a single token, and add it to
+ // the line map. Takes care to render special characters separately.
function buildToken(builder, text, style, startStyle, endStyle, title) {
if (!text) return;
- if (!tokenSpecialChars.test(text)) {
+ var special = builder.cm.options.specialChars, mustWrap = false;
+ if (!special.test(text)) {
builder.col += text.length;
var content = document.createTextNode(text);
+ builder.map.push(builder.pos, builder.pos + text.length, content);
+ if (ie_upto8) mustWrap = true;
+ builder.pos += text.length;
} else {
var content = document.createDocumentFragment(), pos = 0;
while (true) {
- tokenSpecialChars.lastIndex = pos;
- var m = tokenSpecialChars.exec(text);
+ special.lastIndex = pos;
+ var m = special.exec(text);
var skipped = m ? m.index - pos : text.length - pos;
if (skipped) {
- content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
+ var txt = document.createTextNode(text.slice(pos, pos + skipped));
+ if (ie_upto8) content.appendChild(elt("span", [txt]));
+ else content.appendChild(txt);
+ builder.map.push(builder.pos, builder.pos + skipped, txt);
builder.col += skipped;
+ builder.pos += skipped;
}
if (!m) break;
pos += skipped + 1;
if (m[0] == "\t") {
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
- content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
+ var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
builder.col += tabWidth;
} else {
- var token = elt("span", "\u2022", "cm-invalidchar");
- token.title = "\\u" + m[0].charCodeAt(0).toString(16);
- content.appendChild(token);
+ var txt = builder.cm.options.specialCharPlaceholder(m[0]);
+ if (ie_upto8) content.appendChild(elt("span", [txt]));
+ else content.appendChild(txt);
builder.col += 1;
}
+ builder.map.push(builder.pos, builder.pos + 1, txt);
+ builder.pos++;
}
}
- if (style || startStyle || endStyle || builder.measure) {
+ if (style || startStyle || endStyle || mustWrap) {
var fullStyle = style || "";
if (startStyle) fullStyle += startStyle;
if (endStyle) fullStyle += endStyle;
var token = elt("span", [content], fullStyle);
if (title) token.title = title;
- return builder.pre.appendChild(token);
+ return builder.content.appendChild(token);
}
- builder.pre.appendChild(content);
- }
-
- function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
- var wrapping = builder.cm.options.lineWrapping;
- for (var i = 0; i < text.length; ++i) {
- var ch = text.charAt(i), start = i == 0;
- if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
- ch = text.slice(i, i + 2);
- ++i;
- } else if (i && wrapping && spanAffectsWrapping(text, i)) {
- builder.pre.appendChild(elt("wbr"));
- }
- var old = builder.measure[builder.pos];
- var span = builder.measure[builder.pos] =
- buildToken(builder, ch, style,
- start && startStyle, i == text.length - 1 && endStyle);
- if (old) span.leftSide = old.leftSide || old;
- // In IE single-space nodes wrap differently than spaces
- // embedded in larger text nodes, except when set to
- // white-space: normal (issue #1268).
- if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
- i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
- span.style.whiteSpace = "normal";
- builder.pos += ch.length;
- }
- if (text.length) builder.measuredSomething = true;
+ builder.content.appendChild(content);
}
function buildTokenSplitSpaces(inner) {
@@ -4457,29 +5843,36 @@ window.CodeMirror = (function() {
return out;
}
return function(builder, text, style, startStyle, endStyle, title) {
- return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
+ inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
};
}
- function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
- var widget = !ignoreWidget && marker.replacedWith;
- if (widget) {
- if (builder.copyWidgets) widget = widget.cloneNode(true);
- builder.pre.appendChild(widget);
- if (builder.measure) {
- if (size) {
- builder.measure[builder.pos] = widget;
- } else {
- var elt = zeroWidthElement(builder.cm.display.measure);
- if (marker.type == "bookmark" && !marker.insertLeft)
- builder.measure[builder.pos] = builder.pre.appendChild(elt);
- else if (builder.measure[builder.pos])
- return;
- else
- builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget);
+ // Work around nonsense dimensions being reported for stretches of
+ // right-to-left text.
+ function buildTokenBadBidi(inner, order) {
+ return function(builder, text, style, startStyle, endStyle, title) {
+ style = style ? style + " cm-force-border" : "cm-force-border";
+ var start = builder.pos, end = start + text.length;
+ for (;;) {
+ // Find the part that overlaps with the start of this text
+ for (var i = 0; i < order.length; i++) {
+ var part = order[i];
+ if (part.to > start && part.from <= start) break;
}
- builder.measuredSomething = true;
+ if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
+ inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
+ startStyle = null;
+ text = text.slice(part.to - start);
+ start = part.to;
}
+ };
+ }
+
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
+ var widget = !ignoreWidget && marker.widgetNode;
+ if (widget) {
+ builder.map.push(builder.pos, builder.pos + size, widget);
+ builder.content.appendChild(widget);
}
builder.pos += size;
}
@@ -4490,7 +5883,7 @@ window.CodeMirror = (function() {
var spans = line.markedSpans, allText = line.text, at = 0;
if (!spans) {
for (var i = 1; i < styles.length; i+=2)
- builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
+ builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
return;
}
@@ -4509,17 +5902,17 @@ window.CodeMirror = (function() {
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
if (m.title && !title) title = m.title;
- if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
+ if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
collapsed = sp;
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
- if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m);
+ if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
}
if (collapsed && (collapsed.from || 0) == pos) {
- buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
+ buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
collapsed.marker, collapsed.from == null);
- if (collapsed.to == null) return collapsed.marker.find();
+ if (collapsed.to == null) return;
}
if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
buildCollapsedSpan(builder, 0, foundBookmarks[j]);
@@ -4540,14 +5933,23 @@ window.CodeMirror = (function() {
spanStartStyle = "";
}
text = allText.slice(at, at = styles[i++]);
- style = interpretTokenStyle(styles[i++], builder);
+ style = interpretTokenStyle(styles[i++], builder.cm.options);
}
}
}
// DOCUMENT DATA STRUCTURE
- function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
+ // By default, updates that start and end at the beginning of a line
+ // are treated specially, in order to make the association of line
+ // widgets and marker elements with the text behave more intuitive.
+ function isWholeLineUpdate(doc, change) {
+ return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
+ }
+
+ // Perform a change on the document data structure.
+ function updateDoc(doc, change, markedSpans, estimateHeight) {
function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
function update(line, text, spans) {
updateLine(line, text, spans, estimateHeight);
@@ -4558,11 +5960,11 @@ window.CodeMirror = (function() {
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
- // First adjust the line structure
- if (from.ch == 0 && to.ch == 0 && lastText == "") {
+ // Adjust the line structure
+ if (isWholeLineUpdate(doc, change)) {
// This is a whole-line replace. Treated specially to make
// sure line objects move the way they are supposed to.
- for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
+ for (var i = 0, added = []; i < text.length - 1; ++i)
added.push(new Line(text[i], spansFor(i), estimateHeight));
update(lastLine, lastLine.text, lastSpans);
if (nlines) doc.remove(from.line, nlines);
@@ -4571,7 +5973,7 @@ window.CodeMirror = (function() {
if (text.length == 1) {
update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
} else {
- for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
+ for (var added = [], i = 1; i < text.length - 1; ++i)
added.push(new Line(text[i], spansFor(i), estimateHeight));
added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
@@ -4583,20 +5985,32 @@ window.CodeMirror = (function() {
} else {
update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
- for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
+ for (var i = 1, added = []; i < text.length - 1; ++i)
added.push(new Line(text[i], spansFor(i), estimateHeight));
if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
doc.insert(from.line + 1, added);
}
signalLater(doc, "change", doc, change);
- setSelection(doc, selAfter.anchor, selAfter.head, null, true);
}
+ // The document is represented as a BTree consisting of leaves, with
+ // chunk of lines in them, and branches, with up to ten leaves or
+ // other branch nodes below them. The top node is always a branch
+ // node, and is the document object itself (meaning it has
+ // additional methods and properties).
+ //
+ // All nodes have parent links. The tree is used both to go from
+ // line numbers to line objects, and to go from objects to numbers.
+ // It also indexes by height, and is used to convert between height
+ // and line object, and to find the total height of the document.
+ //
+ // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
+
function LeafChunk(lines) {
this.lines = lines;
this.parent = null;
- for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
+ for (var i = 0, height = 0; i < lines.length; ++i) {
lines[i].parent = this;
height += lines[i].height;
}
@@ -4605,6 +6019,7 @@ window.CodeMirror = (function() {
LeafChunk.prototype = {
chunkSize: function() { return this.lines.length; },
+ // Remove the n lines at offset 'at'.
removeInner: function(at, n) {
for (var i = at, e = at + n; i < e; ++i) {
var line = this.lines[i];
@@ -4614,14 +6029,18 @@ window.CodeMirror = (function() {
}
this.lines.splice(at, n);
},
+ // Helper used to collapse a small branch into a single leaf.
collapse: function(lines) {
- lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
+ lines.push.apply(lines, this.lines);
},
+ // Insert the given array of lines at offset 'at', count them as
+ // having the given height.
insertInner: function(at, lines, height) {
this.height += height;
this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
- for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
+ for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
},
+ // Used to iterate over a part of the tree.
iterN: function(at, n, op) {
for (var e = at + n; at < e; ++at)
if (op(this.lines[at])) return true;
@@ -4631,7 +6050,7 @@ window.CodeMirror = (function() {
function BranchChunk(children) {
this.children = children;
var size = 0, height = 0;
- for (var i = 0, e = children.length; i < e; ++i) {
+ for (var i = 0; i < children.length; ++i) {
var ch = children[i];
size += ch.chunkSize(); height += ch.height;
ch.parent = this;
@@ -4656,7 +6075,10 @@ window.CodeMirror = (function() {
at = 0;
} else at -= sz;
}
- if (this.size - n < 25) {
+ // If the result is smaller than 25 lines, ensure that it is a
+ // single leaf node.
+ if (this.size - n < 25 &&
+ (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
var lines = [];
this.collapse(lines);
this.children = [new LeafChunk(lines)];
@@ -4664,12 +6086,12 @@ window.CodeMirror = (function() {
}
},
collapse: function(lines) {
- for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
+ for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
},
insertInner: function(at, lines, height) {
this.size += lines.length;
this.height += height;
- for (var i = 0, e = this.children.length; i < e; ++i) {
+ for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at <= sz) {
child.insertInner(at, lines, height);
@@ -4688,6 +6110,7 @@ window.CodeMirror = (function() {
at -= sz;
}
},
+ // When a node has grown, check whether it should be split.
maybeSpill: function() {
if (this.children.length <= 10) return;
var me = this;
@@ -4710,7 +6133,7 @@ window.CodeMirror = (function() {
me.parent.maybeSpill();
},
iterN: function(at, n, op) {
- for (var i = 0, e = this.children.length; i < e; ++i) {
+ for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i], sz = child.chunkSize();
if (at < sz) {
var used = Math.min(n, sz - at);
@@ -4731,43 +6154,52 @@ window.CodeMirror = (function() {
this.first = firstLine;
this.scrollTop = this.scrollLeft = 0;
this.cantEdit = false;
- this.history = makeHistory();
this.cleanGeneration = 1;
this.frontier = firstLine;
var start = Pos(firstLine, 0);
- this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
+ this.sel = simpleSelection(start);
+ this.history = new History(null);
this.id = ++nextDocId;
this.modeOption = mode;
if (typeof text == "string") text = splitLines(text);
- updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
+ updateDoc(this, {from: start, to: start, text: text});
+ setSelection(this, simpleSelection(start), sel_dontScroll);
};
Doc.prototype = createObj(BranchChunk.prototype, {
constructor: Doc,
+ // Iterate over the document. Supports two forms -- with only one
+ // argument, it calls that for each line in the document. With
+ // three, it iterates over the range given by the first two (with
+ // the second being non-inclusive).
iter: function(from, to, op) {
if (op) this.iterN(from - this.first, to - from, op);
else this.iterN(this.first, this.first + this.size, from);
},
+ // Non-public interface for adding and removing lines.
insert: function(at, lines) {
var height = 0;
- for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
+ for (var i = 0; i < lines.length; ++i) height += lines[i].height;
this.insertInner(at - this.first, lines, height);
},
remove: function(at, n) { this.removeInner(at - this.first, n); },
+ // From here, the methods are part of the public interface. Most
+ // are also available from CodeMirror (editor) instances.
+
getValue: function(lineSep) {
var lines = getLines(this, this.first, this.first + this.size);
if (lineSep === false) return lines;
return lines.join(lineSep || "\n");
},
- setValue: function(code) {
+ setValue: docMethodOp(function(code) {
var top = Pos(this.first, 0), last = this.first + this.size - 1;
makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
- text: splitLines(code), origin: "setValue"},
- {head: top, anchor: top}, true);
- },
+ text: splitLines(code), origin: "setValue"}, true);
+ setSelection(this, simpleSelection(top));
+ }),
replaceRange: function(code, from, to, origin) {
from = clipPos(this, from);
to = to ? clipPos(this, to) : from;
@@ -4780,21 +6212,13 @@ window.CodeMirror = (function() {
},
getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
- setLine: function(line, text) {
- if (isLine(this, line))
- replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
- },
- removeLine: function(line) {
- if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
- else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
- },
getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
getLineNumber: function(line) {return lineNo(line);},
getLineHandleVisualStart: function(line) {
if (typeof line == "number") line = getLine(this, line);
- return visualLine(this, line);
+ return visualLine(line);
},
lineCount: function() {return this.size;},
@@ -4804,47 +6228,103 @@ window.CodeMirror = (function() {
clipPos: function(pos) {return clipPos(this, pos);},
getCursor: function(start) {
- var sel = this.sel, pos;
- if (start == null || start == "head") pos = sel.head;
- else if (start == "anchor") pos = sel.anchor;
- else if (start == "end" || start === false) pos = sel.to;
- else pos = sel.from;
- return copyPos(pos);
+ var range = this.sel.primary(), pos;
+ if (start == null || start == "head") pos = range.head;
+ else if (start == "anchor") pos = range.anchor;
+ else if (start == "end" || start == "to" || start === false) pos = range.to();
+ else pos = range.from();
+ return pos;
},
- somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
+ listSelections: function() { return this.sel.ranges; },
+ somethingSelected: function() {return this.sel.somethingSelected();},
- setCursor: docOperation(function(line, ch, extend) {
- var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
- if (extend) extendSelection(this, pos);
- else setSelection(this, pos, pos);
+ setCursor: docMethodOp(function(line, ch, options) {
+ setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
+ }),
+ setSelection: docMethodOp(function(anchor, head, options) {
+ setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
}),
- setSelection: docOperation(function(anchor, head, bias) {
- setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias);
+ extendSelection: docMethodOp(function(head, other, options) {
+ extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
}),
- extendSelection: docOperation(function(from, to, bias) {
- extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias);
+ extendSelections: docMethodOp(function(heads, options) {
+ extendSelections(this, clipPosArray(this, heads, options));
+ }),
+ extendSelectionsBy: docMethodOp(function(f, options) {
+ extendSelections(this, map(this.sel.ranges, f), options);
+ }),
+ setSelections: docMethodOp(function(ranges, primary, options) {
+ if (!ranges.length) return;
+ for (var i = 0, out = []; i < ranges.length; i++)
+ out[i] = new Range(clipPos(this, ranges[i].anchor),
+ clipPos(this, ranges[i].head));
+ if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
+ setSelection(this, normalizeSelection(out, primary), options);
+ }),
+ addSelection: docMethodOp(function(anchor, head, options) {
+ var ranges = this.sel.ranges.slice(0);
+ ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
+ setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
}),
- getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
+ getSelection: function(lineSep) {
+ var ranges = this.sel.ranges, lines;
+ for (var i = 0; i < ranges.length; i++) {
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+ lines = lines ? lines.concat(sel) : sel;
+ }
+ if (lineSep === false) return lines;
+ else return lines.join(lineSep || "\n");
+ },
+ getSelections: function(lineSep) {
+ var parts = [], ranges = this.sel.ranges;
+ for (var i = 0; i < ranges.length; i++) {
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+ if (lineSep !== false) sel = sel.join(lineSep || "\n");
+ parts[i] = sel;
+ }
+ return parts;
+ },
replaceSelection: function(code, collapse, origin) {
- makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
+ var dup = [];
+ for (var i = 0; i < this.sel.ranges.length; i++)
+ dup[i] = code;
+ this.replaceSelections(dup, collapse, origin || "+input");
},
- undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
- redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
+ replaceSelections: docMethodOp(function(code, collapse, origin) {
+ var changes = [], sel = this.sel;
+ for (var i = 0; i < sel.ranges.length; i++) {
+ var range = sel.ranges[i];
+ changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
+ }
+ var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
+ for (var i = changes.length - 1; i >= 0; i--)
+ makeChange(this, changes[i]);
+ if (newSel) setSelectionReplaceHistory(this, newSel);
+ else if (this.cm) ensureCursorVisible(this.cm);
+ }),
+ undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
+ redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
+ undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
+ redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
- setExtending: function(val) {this.sel.extend = val;},
+ setExtending: function(val) {this.extend = val;},
+ getExtending: function() {return this.extend;},
historySize: function() {
- var hist = this.history;
- return {undo: hist.done.length, redo: hist.undone.length};
+ var hist = this.history, done = 0, undone = 0;
+ for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
+ for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
+ return {undo: done, redo: undone};
},
- clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
+ clearHistory: function() {this.history = new History(this.history.maxGeneration);},
markClean: function() {
- this.cleanGeneration = this.changeGeneration();
+ this.cleanGeneration = this.changeGeneration(true);
},
- changeGeneration: function() {
- this.history.lastOp = this.history.lastOrigin = null;
+ changeGeneration: function(forceSplit) {
+ if (forceSplit)
+ this.history.lastOp = this.history.lastOrigin = null;
return this.history.generation;
},
isClean: function (gen) {
@@ -4856,9 +6336,9 @@ window.CodeMirror = (function() {
undone: copyHistoryArray(this.history.undone)};
},
setHistory: function(histData) {
- var hist = this.history = makeHistory(this.history.maxGeneration);
- hist.done = histData.done.slice(0);
- hist.undone = histData.undone.slice(0);
+ var hist = this.history = new History(this.history.maxGeneration);
+ hist.done = copyHistoryArray(histData.done.slice(0), null, true);
+ hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
},
markText: function(from, to, options) {
@@ -4866,7 +6346,8 @@ window.CodeMirror = (function() {
},
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
- insertLeft: options && options.insertLeft};
+ insertLeft: options && options.insertLeft,
+ clearWhenEmpty: false, shared: options && options.shared};
pos = clipPos(this, pos);
return markText(this, pos, pos, realOpts, "bookmark");
},
@@ -4881,6 +6362,23 @@ window.CodeMirror = (function() {
}
return markers;
},
+ findMarks: function(from, to, filter) {
+ from = clipPos(this, from); to = clipPos(this, to);
+ var found = [], lineNo = from.line;
+ this.iter(from.line, to.line + 1, function(line) {
+ var spans = line.markedSpans;
+ if (spans) for (var i = 0; i < spans.length; i++) {
+ var span = spans[i];
+ if (!(lineNo == from.line && from.ch > span.to ||
+ span.from == null && lineNo != from.line||
+ lineNo == to.line && span.from > to.ch) &&
+ (!filter || filter(span.marker)))
+ found.push(span.marker.parent || span.marker);
+ }
+ ++lineNo;
+ });
+ return found;
+ },
getAllMarks: function() {
var markers = [];
this.iter(function(line) {
@@ -4914,8 +6412,8 @@ window.CodeMirror = (function() {
copy: function(copyHistory) {
var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
- doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
- shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
+ doc.sel = this.sel;
+ doc.extend = false;
if (copyHistory) {
doc.history.undoDepth = this.history.undoDepth;
doc.setHistory(this.getHistory());
@@ -4932,6 +6430,7 @@ window.CodeMirror = (function() {
if (options.sharedHist) copy.history = this.history;
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
+ copySharedMarkers(copy, findSharedMarkers(this));
return copy;
},
unlinkDoc: function(other) {
@@ -4941,13 +6440,14 @@ window.CodeMirror = (function() {
if (link.doc != other) continue;
this.linked.splice(i, 1);
other.unlinkDoc(this);
+ detachSharedMarkers(findSharedMarkers(this));
break;
}
// If the histories were shared, split them again
if (other.history == this.history) {
var splitIds = [other.id];
linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
- other.history = makeHistory();
+ other.history = new History(null);
other.history.done = copyHistoryArray(this.history.done, splitIds);
other.history.undone = copyHistoryArray(this.history.undone, splitIds);
}
@@ -4958,9 +6458,10 @@ window.CodeMirror = (function() {
getEditor: function() {return this.cm;}
});
+ // Public alias.
Doc.prototype.eachLine = Doc.prototype.iter;
- // The Doc methods that should be available on CodeMirror instances
+ // Set up methods on CodeMirror's prototype to redirect to the editor's document.
var dontDelegate = "iter insert remove copy getEditor".split(" ");
for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
CodeMirror.prototype[prop] = (function(method) {
@@ -4969,6 +6470,7 @@ window.CodeMirror = (function() {
eventMixin(Doc);
+ // Call f for all linked documents.
function linkedDocs(doc, f, sharedHistOnly) {
function propagate(doc, skip, sharedHist) {
if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
@@ -4983,22 +6485,25 @@ window.CodeMirror = (function() {
propagate(doc, null, true);
}
+ // Attach a document to an editor.
function attachDoc(cm, doc) {
if (doc.cm) throw new Error("This document is already in use.");
cm.doc = doc;
doc.cm = cm;
estimateLineHeights(cm);
loadMode(cm);
- if (!cm.options.lineWrapping) computeMaxLength(cm);
+ if (!cm.options.lineWrapping) findMaxLine(cm);
cm.options.mode = doc.modeOption;
regChange(cm);
}
// LINE UTILITIES
- function getLine(chunk, n) {
- n -= chunk.first;
- while (!chunk.lines) {
+ // Find the line object corresponding to the given line number.
+ function getLine(doc, n) {
+ n -= doc.first;
+ if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
+ for (var chunk = doc; !chunk.lines;) {
for (var i = 0;; ++i) {
var child = chunk.children[i], sz = child.chunkSize();
if (n < sz) { chunk = child; break; }
@@ -5008,6 +6513,8 @@ window.CodeMirror = (function() {
return chunk.lines[n];
}
+ // Get the part of a document between two positions, as an array of
+ // strings.
function getBetween(doc, start, end) {
var out = [], n = start.line;
doc.iter(start.line, end.line + 1, function(line) {
@@ -5019,17 +6526,22 @@ window.CodeMirror = (function() {
});
return out;
}
+ // Get the lines between from and to, as array of strings.
function getLines(doc, from, to) {
var out = [];
doc.iter(from, to, function(line) { out.push(line.text); });
return out;
}
+ // Update the height of a line, propagating the height change
+ // upwards to parent nodes.
function updateLineHeight(line, height) {
var diff = height - line.height;
- for (var n = line; n; n = n.parent) n.height += diff;
+ if (diff) for (var n = line; n; n = n.parent) n.height += diff;
}
+ // Given a line object, find its line number by walking up through
+ // its parent links.
function lineNo(line) {
if (line.parent == null) return null;
var cur = line.parent, no = indexOf(cur.lines, line);
@@ -5042,10 +6554,12 @@ window.CodeMirror = (function() {
return no + cur.first;
}
+ // Find the line at the given vertical position, using the height
+ // information in the document tree.
function lineAtHeight(chunk, h) {
var n = chunk.first;
outer: do {
- for (var i = 0, e = chunk.children.length; i < e; ++i) {
+ for (var i = 0; i < chunk.children.length; ++i) {
var child = chunk.children[i], ch = child.height;
if (h < ch) { chunk = child; continue outer; }
h -= ch;
@@ -5053,7 +6567,7 @@ window.CodeMirror = (function() {
}
return n;
} while (!chunk.lines);
- for (var i = 0, e = chunk.lines.length; i < e; ++i) {
+ for (var i = 0; i < chunk.lines.length; ++i) {
var line = chunk.lines[i], lh = line.height;
if (h < lh) break;
h -= lh;
@@ -5061,8 +6575,10 @@ window.CodeMirror = (function() {
return n + i;
}
- function heightAtLine(cm, lineObj) {
- lineObj = visualLine(cm.doc, lineObj);
+
+ // Find the height above the given line.
+ function heightAtLine(lineObj) {
+ lineObj = visualLine(lineObj);
var h = 0, chunk = lineObj.parent;
for (var i = 0; i < chunk.lines.length; ++i) {
@@ -5080,6 +6596,9 @@ window.CodeMirror = (function() {
return h;
}
+ // Get the bidi ordering for the given line (and cache it). Returns
+ // false for lines that are fully left-to-right, and an array of
+ // BidiSpan objects otherwise.
function getOrder(line) {
var order = line.order;
if (order == null) order = line.order = bidiOrdering(line.text);
@@ -5088,50 +6607,70 @@ window.CodeMirror = (function() {
// HISTORY
- function makeHistory(startGen) {
- return {
- // Arrays of history events. Doing something adds an event to
- // done and clears undo. Undoing moves events from done to
- // undone, redoing moves them in the other direction.
- done: [], undone: [], undoDepth: Infinity,
- // Used to track when changes can be merged into a single undo
- // event
- lastTime: 0, lastOp: null, lastOrigin: null,
- // Used by the isClean() method
- generation: startGen || 1, maxGeneration: startGen || 1
- };
- }
-
- function attachLocalSpans(doc, change, from, to) {
- var existing = change["spans_" + doc.id], n = 0;
- doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
- if (line.markedSpans)
- (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
- ++n;
- });
- }
-
+ function History(startGen) {
+ // Arrays of change events and selections. Doing something adds an
+ // event to done and clears undo. Undoing moves events from done
+ // to undone, redoing moves them in the other direction.
+ this.done = []; this.undone = [];
+ this.undoDepth = Infinity;
+ // Used to track when changes can be merged into a single undo
+ // event
+ this.lastModTime = this.lastSelTime = 0;
+ this.lastOp = null;
+ this.lastOrigin = this.lastSelOrigin = null;
+ // Used by the isClean() method
+ this.generation = this.maxGeneration = startGen || 1;
+ }
+
+ // Create a history change event from an updateDoc-style change
+ // object.
function historyChangeFromChange(doc, change) {
- var from = { line: change.from.line, ch: change.from.ch };
- var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
+ var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
return histChange;
}
- function addToHistory(doc, change, selAfter, opId) {
+ // Pop all selection events off the end of a history array. Stop at
+ // a change event.
+ function clearSelectionEvents(array) {
+ while (array.length) {
+ var last = lst(array);
+ if (last.ranges) array.pop();
+ else break;
+ }
+ }
+
+ // Find the top change event in the history. Pop off selection
+ // events that are in the way.
+ function lastChangeEvent(hist, force) {
+ if (force) {
+ clearSelectionEvents(hist.done);
+ return lst(hist.done);
+ } else if (hist.done.length && !lst(hist.done).ranges) {
+ return lst(hist.done);
+ } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
+ hist.done.pop();
+ return lst(hist.done);
+ }
+ }
+
+ // Register a change in the history. Merges changes that are within
+ // a single operation, ore are close together with an origin that
+ // allows merging (starting with "+") into a single event.
+ function addChangeToHistory(doc, change, selAfter, opId) {
var hist = doc.history;
hist.undone.length = 0;
- var time = +new Date, cur = lst(hist.done);
+ var time = +new Date, cur;
- if (cur &&
- (hist.lastOp == opId ||
+ if ((hist.lastOp == opId ||
hist.lastOrigin == change.origin && change.origin &&
- ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
- change.origin.charAt(0) == "*"))) {
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
+ change.origin.charAt(0) == "*")) &&
+ (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
// Merge this change into the last event
var last = lst(cur.changes);
- if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
+ if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
// Optimized case for simple insertion -- don't want to add
// new changesets for every character typed
last.to = changeEnd(change);
@@ -5139,23 +6678,81 @@ window.CodeMirror = (function() {
// Add new sub-event
cur.changes.push(historyChangeFromChange(doc, change));
}
- cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
} else {
// Can not be merged, start a new event.
+ var before = lst(hist.done);
+ if (!before || !before.ranges)
+ pushSelectionToHistory(doc.sel, hist.done);
cur = {changes: [historyChangeFromChange(doc, change)],
- generation: hist.generation,
- anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
- anchorAfter: selAfter.anchor, headAfter: selAfter.head};
+ generation: hist.generation};
hist.done.push(cur);
- hist.generation = ++hist.maxGeneration;
- while (hist.done.length > hist.undoDepth)
+ while (hist.done.length > hist.undoDepth) {
hist.done.shift();
+ if (!hist.done[0].ranges) hist.done.shift();
+ }
}
- hist.lastTime = time;
+ hist.done.push(selAfter);
+ hist.generation = ++hist.maxGeneration;
+ hist.lastModTime = hist.lastSelTime = time;
hist.lastOp = opId;
- hist.lastOrigin = change.origin;
+ hist.lastOrigin = hist.lastSelOrigin = change.origin;
+
+ if (!last) signal(doc, "historyAdded");
+ }
+
+ function selectionEventCanBeMerged(doc, origin, prev, sel) {
+ var ch = origin.charAt(0);
+ return ch == "*" ||
+ ch == "+" &&
+ prev.ranges.length == sel.ranges.length &&
+ prev.somethingSelected() == sel.somethingSelected() &&
+ new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
+ }
+
+ // Called whenever the selection changes, sets the new selection as
+ // the pending selection in the history, and pushes the old pending
+ // selection into the 'done' array when it was significantly
+ // different (in number of selected ranges, emptiness, or time).
+ function addSelectionToHistory(doc, sel, opId, options) {
+ var hist = doc.history, origin = options && options.origin;
+
+ // A new event is started when the previous origin does not match
+ // the current, or the origins don't allow matching. Origins
+ // starting with * are always merged, those starting with + are
+ // merged when similar and close together in time.
+ if (opId == hist.lastOp ||
+ (origin && hist.lastSelOrigin == origin &&
+ (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
+ selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
+ hist.done[hist.done.length - 1] = sel;
+ else
+ pushSelectionToHistory(sel, hist.done);
+
+ hist.lastSelTime = +new Date;
+ hist.lastSelOrigin = origin;
+ hist.lastOp = opId;
+ if (options && options.clearRedo !== false)
+ clearSelectionEvents(hist.undone);
+ }
+
+ function pushSelectionToHistory(sel, dest) {
+ var top = lst(dest);
+ if (!(top && top.ranges && top.equals(sel)))
+ dest.push(sel);
}
+ // Used to store marked span information in the history.
+ function attachLocalSpans(doc, change, from, to) {
+ var existing = change["spans_" + doc.id], n = 0;
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
+ if (line.markedSpans)
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
+ ++n;
+ });
+ }
+
+ // When un/re-doing restores text containing marked spans, those
+ // that have been explicitly cleared should not be restored.
function removeClearedSpans(spans) {
if (!spans) return null;
for (var i = 0, out; i < spans.length; ++i) {
@@ -5165,6 +6762,7 @@ window.CodeMirror = (function() {
return !out ? spans : out.length ? out : null;
}
+ // Retrieve and filter the old marked spans stored in a change event.
function getOldSpans(doc, change) {
var found = change["spans_" + doc.id];
if (!found) return null;
@@ -5175,11 +6773,15 @@ window.CodeMirror = (function() {
// Used both to provide a JSON-safe object in .getHistory, and, when
// detaching a document, to split the history in two
- function copyHistoryArray(events, newGroup) {
+ function copyHistoryArray(events, newGroup, instantiateSel) {
for (var i = 0, copy = []; i < events.length; ++i) {
- var event = events[i], changes = event.changes, newChanges = [];
- copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
- anchorAfter: event.anchorAfter, headAfter: event.headAfter});
+ var event = events[i];
+ if (event.ranges) {
+ copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
+ continue;
+ }
+ var changes = event.changes, newChanges = [];
+ copy.push({changes: newChanges});
for (var j = 0; j < changes.length; ++j) {
var change = changes[j], m;
newChanges.push({from: change.from, to: change.to, text: change.text});
@@ -5196,7 +6798,7 @@ window.CodeMirror = (function() {
// Rebasing/resetting history to deal with externally-sourced changes
- function rebaseHistSel(pos, from, to, diff) {
+ function rebaseHistSelSingle(pos, from, to, diff) {
if (to < pos.line) {
pos.line += diff;
} else if (from < pos.line) {
@@ -5215,28 +6817,27 @@ window.CodeMirror = (function() {
function rebaseHistArray(array, from, to, diff) {
for (var i = 0; i < array.length; ++i) {
var sub = array[i], ok = true;
+ if (sub.ranges) {
+ if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
+ for (var j = 0; j < sub.ranges.length; j++) {
+ rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
+ rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
+ }
+ continue;
+ }
for (var j = 0; j < sub.changes.length; ++j) {
var cur = sub.changes[j];
- if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
if (to < cur.from.line) {
- cur.from.line += diff;
- cur.to.line += diff;
+ cur.from = Pos(cur.from.line + diff, cur.from.ch);
+ cur.to = Pos(cur.to.line + diff, cur.to.ch);
} else if (from <= cur.to.line) {
ok = false;
break;
}
}
- if (!sub.copied) {
- sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
- sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
- sub.copied = true;
- }
if (!ok) {
array.splice(0, i + 1);
i = 0;
- } else {
- rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
- rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
}
}
}
@@ -5247,30 +6848,23 @@ window.CodeMirror = (function() {
rebaseHistArray(hist.undone, from, to, diff);
}
- // EVENT OPERATORS
+ // EVENT UTILITIES
- function stopMethod() {e_stop(this);}
- // Ensure an event has a stop method.
- function addStop(event) {
- if (!event.stop) event.stop = stopMethod;
- return event;
- }
+ // Due to the fact that we still support jurassic IE versions, some
+ // compatibility wrappers are needed.
- function e_preventDefault(e) {
+ var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
if (e.preventDefault) e.preventDefault();
else e.returnValue = false;
- }
- function e_stopPropagation(e) {
+ };
+ var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
if (e.stopPropagation) e.stopPropagation();
else e.cancelBubble = true;
- }
+ };
function e_defaultPrevented(e) {
return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
}
- function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
- CodeMirror.e_stop = e_stop;
- CodeMirror.e_preventDefault = e_preventDefault;
- CodeMirror.e_stopPropagation = e_stopPropagation;
+ var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
function e_target(e) {return e.target || e.srcElement;}
function e_button(e) {
@@ -5286,7 +6880,10 @@ window.CodeMirror = (function() {
// EVENT HANDLING
- function on(emitter, type, f) {
+ // Lightweight event framework. on/off also work on DOM nodes,
+ // registering native DOM handlers.
+
+ var on = CodeMirror.on = function(emitter, type, f) {
if (emitter.addEventListener)
emitter.addEventListener(type, f, false);
else if (emitter.attachEvent)
@@ -5296,9 +6893,9 @@ window.CodeMirror = (function() {
var arr = map[type] || (map[type] = []);
arr.push(f);
}
- }
+ };
- function off(emitter, type, f) {
+ var off = CodeMirror.off = function(emitter, type, f) {
if (emitter.removeEventListener)
emitter.removeEventListener(type, f, false);
else if (emitter.detachEvent)
@@ -5309,15 +6906,22 @@ window.CodeMirror = (function() {
for (var i = 0; i < arr.length; ++i)
if (arr[i] == f) { arr.splice(i, 1); break; }
}
- }
+ };
- function signal(emitter, type /*, values...*/) {
+ var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
if (!arr) return;
var args = Array.prototype.slice.call(arguments, 2);
for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
- }
+ };
+ // Often, we want to signal events at a point where we are in the
+ // middle of some work, but don't want the handler to start calling
+ // other methods on the editor, which might be in an inconsistent
+ // state or simply not expect any other events to happen.
+ // signalLater looks whether there are any handlers, and schedules
+ // them to be executed when the last operation ends, or, if no
+ // operation is active, when a timeout fires.
var delayedCallbacks, delayedCallbackDepth = 0;
function signalLater(emitter, type /*, values...*/) {
var arr = emitter._handlers && emitter._handlers[type];
@@ -5333,11 +6937,6 @@ window.CodeMirror = (function() {
delayedCallbacks.push(bnd(arr[i]));
}
- function signalDOMEvent(cm, e, override) {
- signal(cm, override || e.type, cm, e);
- return e_defaultPrevented(e) || e.codemirrorIgnore;
- }
-
function fireDelayed() {
--delayedCallbackDepth;
var delayed = delayedCallbacks;
@@ -5345,13 +6944,29 @@ window.CodeMirror = (function() {
for (var i = 0; i < delayed.length; ++i) delayed[i]();
}
+ // The DOM events that CodeMirror handles can be overridden by
+ // registering a (non-DOM) handler on the editor for the event name,
+ // and preventDefault-ing the event in that handler.
+ function signalDOMEvent(cm, e, override) {
+ signal(cm, override || e.type, cm, e);
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
+ }
+
+ function signalCursorActivity(cm) {
+ var arr = cm._handlers && cm._handlers.cursorActivity;
+ if (!arr) return;
+ var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
+ for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
+ set.push(arr[i]);
+ }
+
function hasHandler(emitter, type) {
var arr = emitter._handlers && emitter._handlers[type];
return arr && arr.length > 0;
}
- CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
-
+ // Add on and off methods to a constructor's prototype, to make
+ // registering events on such objects more convenient.
function eventMixin(ctor) {
ctor.prototype.on = function(type, f) {on(this, type, f);};
ctor.prototype.off = function(type, f) {off(this, type, f);};
@@ -5366,23 +6981,47 @@ window.CodeMirror = (function() {
// handling this'.
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
+ // Reused option objects for setSelection & friends
+ var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
+
function Delayed() {this.id = null;}
- Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
+ Delayed.prototype.set = function(ms, f) {
+ clearTimeout(this.id);
+ this.id = setTimeout(f, ms);
+ };
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
- function countColumn(string, end, tabSize, startIndex, startValue) {
+ var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
- for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
- if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
- else ++n;
+ for (var i = startIndex || 0, n = startValue || 0;;) {
+ var nextTab = string.indexOf("\t", i);
+ if (nextTab < 0 || nextTab >= end)
+ return n + (end - i);
+ n += nextTab - i;
+ n += tabSize - (n % tabSize);
+ i = nextTab + 1;
+ }
+ };
+
+ // The inverse of countColumn -- find the offset that corresponds to
+ // a particular column.
+ function findColumn(string, goal, tabSize) {
+ for (var pos = 0, col = 0;;) {
+ var nextTab = string.indexOf("\t", pos);
+ if (nextTab == -1) nextTab = string.length;
+ var skipped = nextTab - pos;
+ if (nextTab == string.length || col + skipped >= goal)
+ return pos + Math.min(skipped, goal - col);
+ col += nextTab - pos;
+ col += tabSize - (col % tabSize);
+ pos = nextTab + 1;
+ if (col >= goal) return pos;
}
- return n;
}
- CodeMirror.countColumn = countColumn;
var spaceStrs = [""];
function spaceStr(n) {
@@ -5393,52 +7032,60 @@ window.CodeMirror = (function() {
function lst(arr) { return arr[arr.length-1]; }
- function selectInput(node) {
- if (ios) { // Mobile Safari apparently has a bug where select() is broken.
- node.selectionStart = 0;
- node.selectionEnd = node.value.length;
- } else {
- // Suppress mysterious IE10 errors
- try { node.select(); }
- catch(_e) {}
- }
- }
+ var selectInput = function(node) { node.select(); };
+ if (ios) // Mobile Safari apparently has a bug where select() is broken.
+ selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
+ else if (ie) // Suppress mysterious IE10 errors
+ selectInput = function(node) { try { node.select(); } catch(_e) {} };
- function indexOf(collection, elt) {
- if (collection.indexOf) return collection.indexOf(elt);
- for (var i = 0, e = collection.length; i < e; ++i)
- if (collection[i] == elt) return i;
+ function indexOf(array, elt) {
+ for (var i = 0; i < array.length; ++i)
+ if (array[i] == elt) return i;
return -1;
}
+ if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
+ function map(array, f) {
+ var out = [];
+ for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
+ return out;
+ }
+ if ([].map) map = function(array, f) { return array.map(f); };
function createObj(base, props) {
- function Obj() {}
- Obj.prototype = base;
- var inst = new Obj();
+ var inst;
+ if (Object.create) {
+ inst = Object.create(base);
+ } else {
+ var ctor = function() {};
+ ctor.prototype = base;
+ inst = new ctor();
+ }
if (props) copyObj(props, inst);
return inst;
- }
+ };
- function copyObj(obj, target) {
+ function copyObj(obj, target, overwrite) {
if (!target) target = {};
- for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
+ for (var prop in obj)
+ if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
+ target[prop] = obj[prop];
return target;
}
- function emptyArray(size) {
- for (var a = [], i = 0; i < size; ++i) a.push(undefined);
- return a;
- }
-
function bind(f) {
var args = Array.prototype.slice.call(arguments, 1);
return function(){return f.apply(null, args);};
}
- var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
- function isWordChar(ch) {
+ var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
+ var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
return /\w/.test(ch) || ch > "\x80" &&
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
+ };
+ function isWordChar(ch, helper) {
+ if (!helper) return isWordCharBasic(ch);
+ if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
+ return helper.test(ch);
}
function isEmpty(obj) {
@@ -5446,7 +7093,13 @@ window.CodeMirror = (function() {
return true;
}
- var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
+ // Extending unicode characters. A series of a non-extending char +
+ // any number of extending chars is treated as a single unit as far
+ // as editing and measuring is concerned. This is not fully correct,
+ // since some scripts/fonts/browsers also treat other configurations
+ // of code points as a group.
+ var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
+ function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
// DOM UTILITIES
@@ -5454,11 +7107,27 @@ window.CodeMirror = (function() {
var e = document.createElement(tag);
if (className) e.className = className;
if (style) e.style.cssText = style;
- if (typeof content == "string") setTextContent(e, content);
+ if (typeof content == "string") e.appendChild(document.createTextNode(content));
else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
return e;
}
+ var range;
+ if (document.createRange) range = function(node, start, end) {
+ var r = document.createRange();
+ r.setEnd(node, end);
+ r.setStart(node, start);
+ return r;
+ };
+ else range = function(node, start, end) {
+ var r = document.body.createTextRange();
+ r.moveToElementText(node.parentNode);
+ r.collapse(true);
+ r.moveEnd("character", end);
+ r.moveStart("character", start);
+ return r;
+ };
+
function removeChildren(e) {
for (var count = e.childNodes.length; count > 0; --count)
e.removeChild(e.firstChild);
@@ -5469,17 +7138,72 @@ window.CodeMirror = (function() {
return removeChildren(parent).appendChild(e);
}
- function setTextContent(e, str) {
- if (ie_lt9) {
- e.innerHTML = "";
- e.appendChild(document.createTextNode(str));
- } else e.textContent = str;
+ function contains(parent, child) {
+ if (parent.contains)
+ return parent.contains(child);
+ while (child = child.parentNode)
+ if (child == parent) return true;
}
- function getRect(node) {
- return node.getBoundingClientRect();
+ function activeElt() { return document.activeElement; }
+ // Older versions of IE throws unspecified error when touching
+ // document.activeElement in some cases (during loading, in iframe)
+ if (ie_upto10) activeElt = function() {
+ try { return document.activeElement; }
+ catch(e) { return document.body; }
+ };
+
+ function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); }
+ function rmClass(node, cls) {
+ var test = classTest(cls);
+ if (test.test(node.className)) node.className = node.className.replace(test, "");
+ }
+ function addClass(node, cls) {
+ if (!classTest(cls).test(node.className)) node.className += " " + cls;
+ }
+ function joinClasses(a, b) {
+ var as = a.split(" ");
+ for (var i = 0; i < as.length; i++)
+ if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
+ return b;
+ }
+
+ // WINDOW-WIDE EVENTS
+
+ // These must be handled carefully, because naively registering a
+ // handler for each editor will cause the editors to never be
+ // garbage collected.
+
+ function forEachCodeMirror(f) {
+ if (!document.body.getElementsByClassName) return;
+ var byClass = document.body.getElementsByClassName("CodeMirror");
+ for (var i = 0; i < byClass.length; i++) {
+ var cm = byClass[i].CodeMirror;
+ if (cm) f(cm);
+ }
+ }
+
+ var globalsRegistered = false;
+ function ensureGlobalHandlers() {
+ if (globalsRegistered) return;
+ registerGlobalHandlers();
+ globalsRegistered = true;
+ }
+ function registerGlobalHandlers() {
+ // When the window resizes, we need to refresh active editors.
+ var resizeTimer;
+ on(window, "resize", function() {
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
+ resizeTimer = null;
+ knownScrollbarWidth = null;
+ forEachCodeMirror(onResize);
+ }, 100);
+ });
+ // When the window loses focus, we want to show the editor as blurred
+ on(window, "blur", function() {
+ forEachCodeMirror(onBlur);
+ });
}
- CodeMirror.replaceGetRect = function(f) { getRect = f; };
// FEATURE DETECTION
@@ -5487,41 +7211,11 @@ window.CodeMirror = (function() {
var dragAndDrop = function() {
// There is *some* kind of drag-and-drop support in IE6-8, but I
// couldn't get it to work yet.
- if (ie_lt9) return false;
+ if (ie_upto8) return false;
var div = elt('div');
return "draggable" in div || "dragDrop" in div;
}();
- // For a reason I have yet to figure out, some browsers disallow
- // word wrapping between certain characters *only* if a new inline
- // element is started between them. This makes it hard to reliably
- // measure the position of things, since that requires inserting an
- // extra span. This terribly fragile set of tests matches the
- // character combinations that suffer from this phenomenon on the
- // various browsers.
- function spanAffectsWrapping() { return false; }
- if (gecko) // Only for "$'"
- spanAffectsWrapping = function(str, i) {
- return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
- };
- else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
- spanAffectsWrapping = function(str, i) {
- return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
- };
- else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
- spanAffectsWrapping = function(str, i) {
- var code = str.charCodeAt(i - 1);
- return code >= 8208 && code <= 8212;
- };
- else if (webkit)
- spanAffectsWrapping = function(str, i) {
- if (i > 1 && str.charCodeAt(i - 1) == 45) {
- if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
- if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
- }
- return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
- };
-
var knownScrollbarWidth;
function scrollbarWidth(measure) {
if (knownScrollbarWidth != null) return knownScrollbarWidth;
@@ -5538,15 +7232,26 @@ window.CodeMirror = (function() {
var test = elt("span", "\u200b");
removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
if (measure.firstChild.offsetHeight != 0)
- zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_upto7;
}
if (zwspSupported) return elt("span", "\u200b");
else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
}
+ // Feature-detect IE's crummy client rect reporting for bidi text
+ var badBidiRects;
+ function hasBadBidiRects(measure) {
+ if (badBidiRects != null) return badBidiRects;
+ var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
+ var r0 = range(txt, 0, 1).getBoundingClientRect();
+ if (r0.left == r0.right) return false;
+ var r1 = range(txt, 1, 2).getBoundingClientRect();
+ return badBidiRects = (r1.right - r0.right < 3);
+ }
+
// See if "".split is the broken IE version, if so, provide an
// alternative way to split lines.
- var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
+ var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
var pos = 0, result = [], l = string.length;
while (pos <= l) {
var nl = string.indexOf("\n", pos);
@@ -5563,7 +7268,6 @@ window.CodeMirror = (function() {
}
return result;
} : function(string){return string.split(/\r\n?|\n/);};
- CodeMirror.splitLines = splitLines;
var hasSelection = window.getSelection ? function(te) {
try { return te.selectionStart != te.selectionEnd; }
@@ -5579,22 +7283,22 @@ window.CodeMirror = (function() {
var e = elt("div");
if ("oncopy" in e) return true;
e.setAttribute("oncopy", "return;");
- return typeof e.oncopy == 'function';
+ return typeof e.oncopy == "function";
})();
- // KEY NAMING
+ // KEY NAMES
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
- 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
- 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
- 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
CodeMirror.keyNames = keyNames;
(function() {
// Number keys
- for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
// Alphabetic keys
for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
// Function keys
@@ -5628,19 +7332,21 @@ window.CodeMirror = (function() {
function lineStart(cm, lineN) {
var line = getLine(cm.doc, lineN);
- var visual = visualLine(cm.doc, line);
+ var visual = visualLine(line);
if (visual != line) lineN = lineNo(visual);
var order = getOrder(visual);
var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
return Pos(lineN, ch);
}
function lineEnd(cm, lineN) {
- var merged, line;
- while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
- lineN = merged.find().to.line;
+ var merged, line = getLine(cm.doc, lineN);
+ while (merged = collapsedSpanAtEnd(line)) {
+ line = merged.find(1, true).line;
+ lineN = null;
+ }
var order = getOrder(line);
var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
- return Pos(lineN, ch);
+ return Pos(lineN == null ? lineNo(line) : lineN, ch);
}
function compareBidiLevel(order, a, b) {
@@ -5651,38 +7357,37 @@ window.CodeMirror = (function() {
}
var bidiOther;
function getBidiPartAt(order, pos) {
+ bidiOther = null;
for (var i = 0, found; i < order.length; ++i) {
var cur = order[i];
- if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
- if (cur.from == pos || cur.to == pos) {
+ if (cur.from < pos && cur.to > pos) return i;
+ if ((cur.from == pos || cur.to == pos)) {
if (found == null) {
found = i;
} else if (compareBidiLevel(order, cur.level, order[found].level)) {
- bidiOther = found;
+ if (cur.from != cur.to) bidiOther = found;
return i;
} else {
- bidiOther = i;
+ if (cur.from != cur.to) bidiOther = i;
return found;
}
}
}
- bidiOther = null;
return found;
}
function moveInLine(line, pos, dir, byUnit) {
if (!byUnit) return pos + dir;
do pos += dir;
- while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
+ while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
return pos;
}
- // This is somewhat involved. It is needed in order to move
- // 'visually' through bi-directional text -- i.e., pressing left
- // should make the cursor go left, even when in RTL text. The
- // tricky part is the 'jumps', where RTL and LTR text touch each
- // other. This often requires the cursor offset to move more than
- // one unit, in order to visually move one unit.
+ // This is needed in order to move 'visually' through bi-directional
+ // text -- i.e., pressing left should make the cursor go left, even
+ // when in RTL text. The tricky part is the 'jumps', where RTL and
+ // LTR text touch each other. This often requires the cursor offset
+ // to move more than one unit, in order to visually move one unit.
function moveVisually(line, start, dir, byUnit) {
var bidi = getOrder(line);
if (!bidi) return moveLogically(line, start, dir, byUnit);
@@ -5708,7 +7413,7 @@ window.CodeMirror = (function() {
function moveLogically(line, start, dir, byUnit) {
var target = start + dir;
- if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
+ if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
return target < 0 || target > line.text.length ? null : target;
}
@@ -5737,14 +7442,16 @@ window.CodeMirror = (function() {
// objects) in the order in which they occur visually.
var bidiOrdering = (function() {
// Character types for codepoints 0 to 0xff
- var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
// Character types for codepoints 0x600 to 0x6ff
- var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
function charType(code) {
- if (code <= 0xff) return lowTypes.charAt(code);
+ if (code <= 0xf7) return lowTypes.charAt(code);
else if (0x590 <= code && code <= 0x5f4) return "R";
- else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
- else if (0x700 <= code && code <= 0x8ac) return "r";
+ else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
+ else if (0x6ee <= code && code <= 0x8ac) return "r";
+ else if (0x2000 <= code && code <= 0x200b) return "w";
+ else if (code == 0x200c) return "b";
else return "L";
}
@@ -5753,6 +7460,11 @@ window.CodeMirror = (function() {
// Browsers seem to always treat the boundaries of block elements as being L.
var outerType = "L";
+ function BidiSpan(level, from, to) {
+ this.level = level;
+ this.from = from; this.to = to;
+ }
+
return function(str) {
if (!bidiRE.test(str)) return false;
var len = str.length, types = [];
@@ -5800,7 +7512,7 @@ window.CodeMirror = (function() {
if (type == ",") types[i] = "N";
else if (type == "%") {
for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
- var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
+ var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
@@ -5825,7 +7537,7 @@ window.CodeMirror = (function() {
if (isNeutral.test(types[i])) {
for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
var before = (i ? types[i-1] : outerType) == "L";
- var after = (end < len - 1 ? types[end] : outerType) == "L";
+ var after = (end < len ? types[end] : outerType) == "L";
var replace = before || after ? "L" : "R";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
@@ -5842,32 +7554,32 @@ window.CodeMirror = (function() {
if (countsAsLeft.test(types[i])) {
var start = i;
for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
- order.push({from: start, to: i, level: 0});
+ order.push(new BidiSpan(0, start, i));
} else {
var pos = i, at = order.length;
for (++i; i < len && types[i] != "L"; ++i) {}
for (var j = pos; j < i;) {
if (countsAsNum.test(types[j])) {
- if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
+ if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
var nstart = j;
for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
- order.splice(at, 0, {from: nstart, to: j, level: 2});
+ order.splice(at, 0, new BidiSpan(2, nstart, j));
pos = j;
} else ++j;
}
- if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
+ if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
}
}
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length;
- order.unshift({from: 0, to: m[0].length, level: 0});
+ order.unshift(new BidiSpan(0, 0, m[0].length));
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length;
- order.push({from: len - m[0].length, to: len, level: 0});
+ order.push(new BidiSpan(0, len - m[0].length, len));
}
if (order[0].level != lst(order).level)
- order.push({from: len, to: len, level: order[0].level});
+ order.push(new BidiSpan(order[0].level, len, len));
return order;
};
@@ -5875,7 +7587,7 @@ window.CodeMirror = (function() {
// THE END
- CodeMirror.version = "3.16.1";
+ CodeMirror.version = "4.1.1";
return CodeMirror;
-})();
+});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/coffeescript.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/coffeescript.js
index 509d9207bb7..e8bfe48a248 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/coffeescript.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/coffeescript.js
@@ -2,346 +2,353 @@
* Link to the project's GitHub page:
* https://github.com/pickhardt/coffeescript-codemirror-mode
*/
-CodeMirror.defineMode('coffeescript', function(conf) {
- var ERRORCLASS = 'error';
-
- function wordRegexp(words) {
- return new RegExp("^((" + words.join(")|(") + "))\\b");
- }
-
- var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]");
- var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\},:`=;\\.]');
- var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))");
- var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
- var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))");
- var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*");
- var properties = new RegExp("^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*");
-
- var wordOperators = wordRegexp(['and', 'or', 'not',
- 'is', 'isnt', 'in',
- 'instanceof', 'typeof']);
- var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else',
- 'switch', 'try', 'catch', 'finally', 'class'];
- var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete',
- 'do', 'in', 'of', 'new', 'return', 'then',
- 'this', 'throw', 'when', 'until'];
-
- var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
-
- indentKeywords = wordRegexp(indentKeywords);
-
-
- var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])");
- var regexPrefixes = new RegExp("^(/{3}|/)");
- var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no'];
- var constants = wordRegexp(commonConstants);
-
- // Tokenizers
- function tokenBase(stream, state) {
- // Handle scope changes
- if (stream.sol()) {
- var scopeOffset = state.scopes[0].offset;
- if (stream.eatSpace()) {
- var lineOffset = stream.indentation();
- if (lineOffset > scopeOffset) {
- return 'indent';
- } else if (lineOffset < scopeOffset) {
- return 'dedent';
- }
- return null;
- } else {
- if (scopeOffset > 0) {
- dedent(stream, state);
- }
- }
+CodeMirror.defineMode("coffeescript", function(conf) {
+ var ERRORCLASS = "error";
+
+ function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+ }
+
+ var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/;
+ var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
+ var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
+ var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
+
+ var wordOperators = wordRegexp(["and", "or", "not",
+ "is", "isnt", "in",
+ "instanceof", "typeof"]);
+ var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
+ "switch", "try", "catch", "finally", "class"];
+ var commonKeywords = ["break", "by", "continue", "debugger", "delete",
+ "do", "in", "of", "new", "return", "then",
+ "this", "throw", "when", "until"];
+
+ var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
+
+ indentKeywords = wordRegexp(indentKeywords);
+
+
+ var stringPrefixes = /^('{3}|\"{3}|['\"])/;
+ var regexPrefixes = /^(\/{3}|\/)/;
+ var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
+ var constants = wordRegexp(commonConstants);
+
+ // Tokenizers
+ function tokenBase(stream, state) {
+ // Handle scope changes
+ if (stream.sol()) {
+ if (state.scope.align === null) state.scope.align = false;
+ var scopeOffset = state.scope.offset;
+ if (stream.eatSpace()) {
+ var lineOffset = stream.indentation();
+ if (lineOffset > scopeOffset && state.scope.type == "coffee") {
+ return "indent";
+ } else if (lineOffset < scopeOffset) {
+ return "dedent";
}
- if (stream.eatSpace()) {
- return null;
- }
-
- var ch = stream.peek();
-
- // Handle docco title comment (single line)
- if (stream.match("####")) {
- stream.skipToEnd();
- return 'comment';
- }
-
- // Handle multi line comments
- if (stream.match("###")) {
- state.tokenize = longComment;
- return state.tokenize(stream, state);
+ return null;
+ } else {
+ if (scopeOffset > 0) {
+ dedent(stream, state);
}
+ }
+ }
+ if (stream.eatSpace()) {
+ return null;
+ }
- // Single line comment
- if (ch === '#') {
- stream.skipToEnd();
- return 'comment';
- }
+ var ch = stream.peek();
- // Handle number literals
- if (stream.match(/^-?[0-9\.]/, false)) {
- var floatLiteral = false;
- // Floats
- if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
- floatLiteral = true;
- }
- if (stream.match(/^-?\d+\.\d*/)) {
- floatLiteral = true;
- }
- if (stream.match(/^-?\.\d+/)) {
- floatLiteral = true;
- }
-
- if (floatLiteral) {
- // prevent from getting extra . on 1..
- if (stream.peek() == "."){
- stream.backUp(1);
- }
- return 'number';
- }
- // Integers
- var intLiteral = false;
- // Hex
- if (stream.match(/^-?0x[0-9a-f]+/i)) {
- intLiteral = true;
- }
- // Decimal
- if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
- intLiteral = true;
- }
- // Zero by itself with no other piece of number.
- if (stream.match(/^-?0(?![\dx])/i)) {
- intLiteral = true;
- }
- if (intLiteral) {
- return 'number';
- }
- }
+ // Handle docco title comment (single line)
+ if (stream.match("####")) {
+ stream.skipToEnd();
+ return "comment";
+ }
- // Handle strings
- if (stream.match(stringPrefixes)) {
- state.tokenize = tokenFactory(stream.current(), 'string');
- return state.tokenize(stream, state);
- }
- // Handle regex literals
- if (stream.match(regexPrefixes)) {
- if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division
- state.tokenize = tokenFactory(stream.current(), 'string-2');
- return state.tokenize(stream, state);
- } else {
- stream.backUp(1);
- }
- }
+ // Handle multi line comments
+ if (stream.match("###")) {
+ state.tokenize = longComment;
+ return state.tokenize(stream, state);
+ }
- // Handle operators and delimiters
- if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
- return 'punctuation';
- }
- if (stream.match(doubleOperators)
- || stream.match(singleOperators)
- || stream.match(wordOperators)) {
- return 'operator';
- }
- if (stream.match(singleDelimiters)) {
- return 'punctuation';
- }
+ // Single line comment
+ if (ch === "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
- if (stream.match(constants)) {
- return 'atom';
+ // Handle number literals
+ if (stream.match(/^-?[0-9\.]/, false)) {
+ var floatLiteral = false;
+ // Floats
+ if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\d+\.\d*/)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\.\d+/)) {
+ floatLiteral = true;
+ }
+
+ if (floatLiteral) {
+ // prevent from getting extra . on 1..
+ if (stream.peek() == "."){
+ stream.backUp(1);
}
+ return "number";
+ }
+ // Integers
+ var intLiteral = false;
+ // Hex
+ if (stream.match(/^-?0x[0-9a-f]+/i)) {
+ intLiteral = true;
+ }
+ // Decimal
+ if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
+ intLiteral = true;
+ }
+ // Zero by itself with no other piece of number.
+ if (stream.match(/^-?0(?![\dx])/i)) {
+ intLiteral = true;
+ }
+ if (intLiteral) {
+ return "number";
+ }
+ }
- if (stream.match(keywords)) {
- return 'keyword';
- }
+ // Handle strings
+ if (stream.match(stringPrefixes)) {
+ state.tokenize = tokenFactory(stream.current(), "string");
+ return state.tokenize(stream, state);
+ }
+ // Handle regex literals
+ if (stream.match(regexPrefixes)) {
+ if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
+ state.tokenize = tokenFactory(stream.current(), "string-2");
+ return state.tokenize(stream, state);
+ } else {
+ stream.backUp(1);
+ }
+ }
- if (stream.match(identifiers)) {
- return 'variable';
- }
+ // Handle operators and delimiters
+ if (stream.match(operators) || stream.match(wordOperators)) {
+ return "operator";
+ }
+ if (stream.match(delimiters)) {
+ return "punctuation";
+ }
- if (stream.match(properties)) {
- return 'property';
- }
+ if (stream.match(constants)) {
+ return "atom";
+ }
- // Handle non-detected items
- stream.next();
- return ERRORCLASS;
+ if (stream.match(keywords)) {
+ return "keyword";
}
- function tokenFactory(delimiter, outclass) {
- var singleline = delimiter.length == 1;
- return function(stream, state) {
- while (!stream.eol()) {
- stream.eatWhile(/[^'"\/\\]/);
- if (stream.eat('\\')) {
- stream.next();
- if (singleline && stream.eol()) {
- return outclass;
- }
- } else if (stream.match(delimiter)) {
- state.tokenize = tokenBase;
- return outclass;
- } else {
- stream.eat(/['"\/]/);
- }
- }
- if (singleline) {
- if (conf.mode.singleLineStringErrors) {
- outclass = ERRORCLASS;
- } else {
- state.tokenize = tokenBase;
- }
- }
- return outclass;
- };
+ if (stream.match(identifiers)) {
+ return "variable";
}
- function longComment(stream, state) {
- while (!stream.eol()) {
- stream.eatWhile(/[^#]/);
- if (stream.match("###")) {
- state.tokenize = tokenBase;
- break;
- }
- stream.eatWhile("#");
- }
- return "comment";
+ if (stream.match(properties)) {
+ return "property";
}
- function indent(stream, state, type) {
- type = type || 'coffee';
- var indentUnit = 0;
- if (type === 'coffee') {
- for (var i = 0; i < state.scopes.length; i++) {
- if (state.scopes[i].type === 'coffee') {
- indentUnit = state.scopes[i].offset + conf.indentUnit;
- break;
- }
- }
+ // Handle non-detected items
+ stream.next();
+ return ERRORCLASS;
+ }
+
+ function tokenFactory(delimiter, outclass) {
+ var singleline = delimiter.length == 1;
+ return function(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"\/\\]/);
+ if (stream.eat("\\")) {
+ stream.next();
+ if (singleline && stream.eol()) {
+ return outclass;
+ }
+ } else if (stream.match(delimiter)) {
+ state.tokenize = tokenBase;
+ return outclass;
} else {
- indentUnit = stream.column() + stream.current().length;
+ stream.eat(/['"\/]/);
}
- state.scopes.unshift({
- offset: indentUnit,
- type: type
- });
- }
-
- function dedent(stream, state) {
- if (state.scopes.length == 1) return;
- if (state.scopes[0].type === 'coffee') {
- var _indent = stream.indentation();
- var _indent_index = -1;
- for (var i = 0; i < state.scopes.length; ++i) {
- if (_indent === state.scopes[i].offset) {
- _indent_index = i;
- break;
- }
- }
- if (_indent_index === -1) {
- return true;
- }
- while (state.scopes[0].offset !== _indent) {
- state.scopes.shift();
- }
- return false;
+ }
+ if (singleline) {
+ if (conf.mode.singleLineStringErrors) {
+ outclass = ERRORCLASS;
} else {
- state.scopes.shift();
- return false;
+ state.tokenize = tokenBase;
}
+ }
+ return outclass;
+ };
+ }
+
+ function longComment(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^#]/);
+ if (stream.match("###")) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ stream.eatWhile("#");
}
-
- function tokenLexer(stream, state) {
- var style = state.tokenize(stream, state);
- var current = stream.current();
-
- // Handle '.' connected identifiers
- if (current === '.') {
- style = state.tokenize(stream, state);
- current = stream.current();
- if (style === 'variable') {
- return 'variable';
- } else {
- return ERRORCLASS;
- }
- }
-
- // Handle scope changes.
- if (current === 'return') {
- state.dedent += 1;
- }
- if (((current === '->' || current === '=>') &&
- !state.lambda &&
- state.scopes[0].type == 'coffee' &&
- stream.peek() === '')
- || style === 'indent') {
- indent(stream, state);
- }
- var delimiter_index = '[({'.indexOf(current);
- if (delimiter_index !== -1) {
- indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1));
- }
- if (indentKeywords.exec(current)){
- indent(stream, state);
- }
- if (current == 'then'){
- dedent(stream, state);
- }
-
-
- if (style === 'dedent') {
- if (dedent(stream, state)) {
- return ERRORCLASS;
- }
- }
- delimiter_index = '])}'.indexOf(current);
- if (delimiter_index !== -1) {
- if (dedent(stream, state)) {
- return ERRORCLASS;
- }
- }
- if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') {
- if (state.scopes.length > 1) state.scopes.shift();
- state.dedent -= 1;
+ return "comment";
+ }
+
+ function indent(stream, state, type) {
+ type = type || "coffee";
+ var offset = 0, align = false, alignOffset = null;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (scope.type === "coffee") {
+ offset = scope.offset + conf.indentUnit;
+ break;
+ }
+ }
+ if (type !== "coffee") {
+ align = null;
+ alignOffset = stream.column() + stream.current().length;
+ } else if (state.scope.align) {
+ state.scope.align = false;
+ }
+ state.scope = {
+ offset: offset,
+ type: type,
+ prev: state.scope,
+ align: align,
+ alignOffset: alignOffset
+ };
+ }
+
+ function dedent(stream, state) {
+ if (!state.scope.prev) return;
+ if (state.scope.type === "coffee") {
+ var _indent = stream.indentation();
+ var matched = false;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (_indent === scope.offset) {
+ matched = true;
+ break;
}
-
- return style;
+ }
+ if (!matched) {
+ return true;
+ }
+ while (state.scope.prev && state.scope.offset !== _indent) {
+ state.scope = state.scope.prev;
+ }
+ return false;
+ } else {
+ state.scope = state.scope.prev;
+ return false;
+ }
+ }
+
+ function tokenLexer(stream, state) {
+ var style = state.tokenize(stream, state);
+ var current = stream.current();
+
+ // Handle "." connected identifiers
+ if (current === ".") {
+ style = state.tokenize(stream, state);
+ current = stream.current();
+ if (/^\.[\w$]+$/.test(current)) {
+ return "variable";
+ } else {
+ return ERRORCLASS;
+ }
}
- var external = {
- startState: function(basecolumn) {
- return {
- tokenize: tokenBase,
- scopes: [{offset:basecolumn || 0, type:'coffee'}],
- lastToken: null,
- lambda: false,
- dedent: 0
- };
- },
-
- token: function(stream, state) {
- var style = tokenLexer(stream, state);
-
- state.lastToken = {style:style, content: stream.current()};
-
- if (stream.eol() && stream.lambda) {
- state.lambda = false;
- }
-
- return style;
- },
+ // Handle scope changes.
+ if (current === "return") {
+ state.dedent += 1;
+ }
+ if (((current === "->" || current === "=>") &&
+ !state.lambda &&
+ !stream.peek())
+ || style === "indent") {
+ indent(stream, state);
+ }
+ var delimiter_index = "[({".indexOf(current);
+ if (delimiter_index !== -1) {
+ indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
+ }
+ if (indentKeywords.exec(current)){
+ indent(stream, state);
+ }
+ if (current == "then"){
+ dedent(stream, state);
+ }
- indent: function(state) {
- if (state.tokenize != tokenBase) {
- return 0;
- }
- return state.scopes[0].offset;
- },
+ if (style === "dedent") {
+ if (dedent(stream, state)) {
+ return ERRORCLASS;
+ }
+ }
+ delimiter_index = "])}".indexOf(current);
+ if (delimiter_index !== -1) {
+ while (state.scope.type == "coffee" && state.scope.prev)
+ state.scope = state.scope.prev;
+ if (state.scope.type == current)
+ state.scope = state.scope.prev;
+ }
+ if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") {
+ if (state.scope.prev) state.scope = state.scope.prev;
+ state.dedent -= 1;
+ }
- lineComment: "#"
- };
- return external;
+ return style;
+ }
+
+ var external = {
+ startState: function(basecolumn) {
+ return {
+ tokenize: tokenBase,
+ scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
+ lastToken: null,
+ lambda: false,
+ dedent: 0
+ };
+ },
+
+ token: function(stream, state) {
+ var fillAlign = state.scope.align === null && state.scope;
+ if (fillAlign && stream.sol()) fillAlign.align = false;
+
+ var style = tokenLexer(stream, state);
+ if (fillAlign && style && style != "comment") fillAlign.align = true;
+
+ state.lastToken = {style:style, content: stream.current()};
+
+ if (stream.eol() && stream.lambda) {
+ state.lambda = false;
+ }
+
+ return style;
+ },
+
+ indent: function(state, text) {
+ if (state.tokenize != tokenBase) return 0;
+ var scope = state.scope;
+ var closer = text && "])}".indexOf(text.charAt(0)) > -1;
+ if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
+ var closes = closer && scope.type === text.charAt(0);
+ if (scope.align)
+ return scope.alignOffset - (closes ? 1 : 0);
+ else
+ return (closes ? scope.prev : scope).offset;
+ },
+
+ lineComment: "#",
+ fold: "indent"
+ };
+ return external;
});
-CodeMirror.defineMIME('text/x-coffeescript', 'coffeescript');
+CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/comment.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/comment.js
index 5975b0bf69c..1eb9a05c5d4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/comment.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/comment.js
@@ -1,4 +1,11 @@
-(function() {
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
"use strict";
var noOptions = {};
@@ -11,8 +18,21 @@
}
CodeMirror.commands.toggleComment = function(cm) {
- var from = cm.getCursor("start"), to = cm.getCursor("end");
- cm.uncomment(from, to) || cm.lineComment(from, to);
+ var minLine = Infinity, ranges = cm.listSelections(), mode = null;
+ for (var i = ranges.length - 1; i >= 0; i--) {
+ var from = ranges[i].from(), to = ranges[i].to();
+ if (from.line >= minLine) continue;
+ if (to.line >= minLine) to = Pos(minLine, 0);
+ minLine = from.line;
+ if (mode == null) {
+ if (cm.uncomment(from, to)) mode = "un";
+ else { cm.lineComment(from, to); mode = "line"; }
+ } else if (mode == "un") {
+ cm.uncomment(from, to);
+ } else {
+ cm.lineComment(from, to);
+ }
+ }
};
CodeMirror.defineExtension("lineComment", function(from, to, options) {
@@ -146,4 +166,4 @@
});
return true;
});
-})();
+});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/css.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/css.js
index 6ad37f4828b..d8c30cf33d6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/css.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/css.js
@@ -1,11 +1,9 @@
-CodeMirror.defineMode("css", function(config) {
- return CodeMirror.getMode(config, "text/css");
-});
-
-CodeMirror.defineMode("css-base", function(config, parserConfig) {
+CodeMirror.defineMode("css", function(config, parserConfig) {
"use strict";
- var indentUnit = config.indentUnit,
+ if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
+ var indentUnit = config.indentUnit || config.tabSize || 2,
hooks = parserConfig.hooks || {},
atMediaTypes = parserConfig.atMediaTypes || {},
atMediaFeatures = parserConfig.atMediaFeatures || {},
@@ -39,7 +37,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
}
- else if (/\d/.test(ch)) {
+ else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
}
@@ -252,7 +250,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
// Push/pop context stack
if (type == "{") {
if (context == "@media" || context == "@mediaType") {
- state.stack.pop();
state.stack[state.stack.length-1] = "@media{";
}
else {
@@ -261,35 +258,57 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
}
else if (type == "}") {
- var lastState = state.stack[state.stack.length - 1];
- if (lastState == "interpolation") style = "operator";
- state.stack.pop();
- if (context == "propertyValue") state.stack.pop();
+ if (context == "interpolation") style = "operator";
+ // Pop off end of array until { is reached
+ while(state.stack.length){
+ var removed = state.stack.pop();
+ if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){
+ break;
+ }
+ }
}
else if (type == "interpolation") state.stack.push("interpolation");
else if (type == "@media") state.stack.push("@media");
else if (type == "@import") state.stack.push("@import");
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
- state.stack.push("@mediaType");
- else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
- else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
- else if (context == "@mediaType(" && type == ")") state.stack.pop();
+ state.stack[state.stack.length-1] = "@mediaType";
+ else if (context == "@mediaType" && stream.current() == ",")
+ state.stack[state.stack.length-1] = "@media";
+ else if (type == "(") {
+ if (context == "@media" || context == "@mediaType") {
+ // Make sure @mediaType is used to avoid error on {
+ state.stack[state.stack.length-1] = "@mediaType";
+ state.stack.push("@mediaType(");
+ }
+ else state.stack.push("(");
+ }
+ else if (type == ")") {
+ // Pop off end of array until ( is reached
+ while(state.stack.length){
+ var removed = state.stack.pop();
+ if(removed.indexOf("(") > -1){
+ break;
+ }
+ }
+ }
else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
else if (context == "propertyValue" && type == ";") state.stack.pop();
else if (context == "@import" && type == ";") state.stack.pop();
+
return state.lastToken = style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
- n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
+ n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
return state.baseIndent + n * indentUnit;
},
electricChars: "}",
blockCommentStart: "/*",
- blockCommentEnd: "*/"
+ blockCommentEnd: "*/",
+ fold: "brace"
};
});
@@ -350,8 +369,8 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
- "float", "float-offset", "font", "font-feature-settings", "font-family",
- "font-kerning", "font-language-override", "font-size", "font-size-adjust",
+ "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
+ "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
@@ -375,25 +394,27 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
- "presentation-level", "punctuation-trim", "quotes", "rendering-intent",
- "resize", "rest", "rest-after", "rest-before", "richness", "right",
- "rotation", "rotation-point", "ruby-align", "ruby-overhang",
- "ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
+ "presentation-level", "punctuation-trim", "quotes", "region-break-after",
+ "region-break-before", "region-break-inside", "region-fragment",
+ "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
+ "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
+ "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size",
+ "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
- "text-indent", "text-justify", "text-outline", "text-shadow",
- "text-space-collapse", "text-transform", "text-underline-position",
+ "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
+ "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
- "word-spacing", "word-wrap", "z-index",
+ "word-spacing", "word-wrap", "z-index", "zoom",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
@@ -416,7 +437,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
- "gold", "goldenrod", "gray", "green", "greenyellow", "honeydew",
+ "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
@@ -439,22 +460,22 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
- "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
- "backwards", "baseline", "below", "bidi-override", "binary", "bengali",
- "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
- "both", "bottom", "bounding-box", "break-all", "break-word", "button", "button-bevel",
+ "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
+ "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
+ "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
+ "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
- "col-resize", "collapse", "compact", "condensed", "contain", "content",
+ "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari",
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
- "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
+ "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
@@ -470,7 +491,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
- "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
+ "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
"landscape", "lao", "large", "larger", "left", "level", "lighter",
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
@@ -489,11 +510,11 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
- "outside", "overlay", "overline", "padding", "padding-box", "painted",
- "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
- "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
- "radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
- "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
+ "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
+ "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
+ "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
+ "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
+ "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
@@ -564,7 +585,7 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
return false;
}
},
- name: "css-base"
+ name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
@@ -575,6 +596,12 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
valueKeywords: valueKeywords,
allowNested: true,
hooks: {
+ ":": function(stream) {
+ if (stream.match(/\s*{/)) {
+ return [null, "{"];
+ }
+ return false;
+ },
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.peek() == ":") {
@@ -582,6 +609,11 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
return ["variable", "variable"];
},
+ ",": function(stream, state) {
+ if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) {
+ return ["operator", ";"];
+ }
+ },
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
@@ -602,6 +634,6 @@ CodeMirror.defineMode("css-base", function(config, parserConfig) {
}
}
},
- name: "css-base"
+ name: "css"
});
})();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/headlesscodemirror.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/headlesscodemirror.js
index 7caca5cfa4f..67c7866b76a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/headlesscodemirror.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/headlesscodemirror.js
@@ -1,83 +1,154 @@
+// Content of the function is equal to runmode-standalone.js file
+// from CodeMirror distribution
(function(window) {
- window.CodeMirror = {};
+window.CodeMirror = {};
- function splitLines(string){ return string.split(/\r?\n|\r/); };
+(function() {
+"use strict";
- function StringStream(string) {
- this.pos = this.start = 0;
- this.string = string;
+function splitLines(string){ return string.split(/\r?\n|\r/); };
+
+function StringStream(string) {
+ this.pos = this.start = 0;
+ this.string = string;
+ this.lineStart = 0;
+}
+StringStream.prototype = {
+ eol: function() {return this.pos >= this.string.length;},
+ sol: function() {return this.pos == 0;},
+ peek: function() {return this.string.charAt(this.pos) || null;},
+ next: function() {
+ if (this.pos < this.string.length)
+ return this.string.charAt(this.pos++);
+ },
+ eat: function(match) {
+ var ch = this.string.charAt(this.pos);
+ if (typeof match == "string") var ok = ch == match;
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
+ if (ok) {++this.pos; return ch;}
+ },
+ eatWhile: function(match) {
+ var start = this.pos;
+ while (this.eat(match)){}
+ return this.pos > start;
+ },
+ eatSpace: function() {
+ var start = this.pos;
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+ return this.pos > start;
+ },
+ skipToEnd: function() {this.pos = this.string.length;},
+ skipTo: function(ch) {
+ var found = this.string.indexOf(ch, this.pos);
+ if (found > -1) {this.pos = found; return true;}
+ },
+ backUp: function(n) {this.pos -= n;},
+ column: function() {return this.start - this.lineStart;},
+ indentation: function() {return 0;},
+ match: function(pattern, consume, caseInsensitive) {
+ if (typeof pattern == "string") {
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+ var substr = this.string.substr(this.pos, pattern.length);
+ if (cased(substr) == cased(pattern)) {
+ if (consume !== false) this.pos += pattern.length;
+ return true;
+ }
+ } else {
+ var match = this.string.slice(this.pos).match(pattern);
+ if (match && match.index > 0) return null;
+ if (match && consume !== false) this.pos += match[0].length;
+ return match;
+ }
+ },
+ current: function(){return this.string.slice(this.start, this.pos);},
+ hideFirstChars: function(n, inner) {
+ this.lineStart += n;
+ try { return inner(); }
+ finally { this.lineStart -= n; }
}
- StringStream.prototype = {
- eol: function() {return this.pos >= this.string.length;},
- sol: function() {return this.pos == 0;},
- peek: function() {return this.string.charAt(this.pos) || null;},
- next: function() {
- if (this.pos < this.string.length)
- return this.string.charAt(this.pos++);
- },
- eat: function(match) {
- var ch = this.string.charAt(this.pos);
- if (typeof match == "string") var ok = ch == match;
- else var ok = ch && (match.test ? match.test(ch) : match(ch));
- if (ok) {++this.pos; return ch;}
- },
- eatWhile: function(match) {
- var start = this.pos;
- while (this.eat(match)){}
- return this.pos > start;
- },
- eatSpace: function() {
- var start = this.pos;
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
- return this.pos > start;
- },
- skipToEnd: function() {this.pos = this.string.length;},
- skipTo: function(ch) {
- var found = this.string.indexOf(ch, this.pos);
- if (found > -1) {this.pos = found; return true;}
- },
- backUp: function(n) {this.pos -= n;},
- column: function() {return this.start;},
- indentation: function() {return 0;},
- match: function(pattern, consume, caseInsensitive) {
- if (typeof pattern == "string") {
- var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
- var substr = this.string.substr(this.pos, pattern.length);
- if (cased(substr) == cased(pattern)) {
- if (consume !== false) this.pos += pattern.length;
- return true;
+};
+CodeMirror.StringStream = StringStream;
+
+CodeMirror.startState = function (mode, a1, a2) {
+ return mode.startState ? mode.startState(a1, a2) : true;
+};
+
+var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+CodeMirror.defineMode = function (name, mode) { modes[name] = mode; };
+CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
+CodeMirror.resolveMode = function(spec) {
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+ spec = mimeModes[spec];
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+ spec = mimeModes[spec.name];
+ }
+ if (typeof spec == "string") return {name: spec};
+ else return spec || {name: "null"};
+};
+CodeMirror.getMode = function (options, spec) {
+ spec = CodeMirror.resolveMode(spec);
+ var mfactory = modes[spec.name];
+ if (!mfactory) throw new Error("Unknown mode: " + spec);
+ return mfactory(options, spec);
+};
+CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
+CodeMirror.defineMode("null", function() {
+ return {token: function(stream) {stream.skipToEnd();}};
+});
+CodeMirror.defineMIME("text/plain", "null");
+
+CodeMirror.runMode = function (string, modespec, callback, options) {
+ var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
+
+ if (callback.nodeType == 1) {
+ var tabSize = (options && options.tabSize) || 4;
+ var node = callback, col = 0;
+ node.innerHTML = "";
+ callback = function (text, style) {
+ if (text == "\n") {
+ node.appendChild(document.createElement("br"));
+ col = 0;
+ return;
+ }
+ var content = "";
+ // replace tabs
+ for (var pos = 0; ;) {
+ var idx = text.indexOf("\t", pos);
+ if (idx == -1) {
+ content += text.slice(pos);
+ col += text.length - pos;
+ break;
+ } else {
+ col += idx - pos;
+ content += text.slice(pos, idx);
+ var size = tabSize - col % tabSize;
+ col += size;
+ for (var i = 0; i < size; ++i) content += " ";
+ pos = idx + 1;
}
+ }
+
+ if (style) {
+ var sp = node.appendChild(document.createElement("span"));
+ sp.className = "cm-" + style.replace(/ +/g, " cm-");
+ sp.appendChild(document.createTextNode(content));
} else {
- var match = this.string.slice(this.pos).match(pattern);
- if (match && match.index > 0) return null;
- if (match && consume !== false) this.pos += match[0].length;
- return match;
+ node.appendChild(document.createTextNode(content));
}
- },
- current: function(){return this.string.slice(this.start, this.pos);}
- };
- CodeMirror.StringStream = StringStream;
+ };
+ }
- CodeMirror.startState = function (mode, a1, a2) {
- return mode.startState ? mode.startState(a1, a2) : true;
- };
+ var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
+ for (var i = 0, e = lines.length; i < e; ++i) {
+ if (i) callback("\n");
+ var stream = new CodeMirror.StringStream(lines[i]);
+ while (!stream.eol()) {
+ var style = mode.token(stream, state);
+ callback(stream.current(), style, i, stream.start, state);
+ stream.start = stream.pos;
+ }
+ }
+};
+})();
- var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
- CodeMirror.defineMode = function (name, mode) { modes[name] = mode; };
- CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
- CodeMirror.defineMode("null", function() {
- return {token: function(stream) {stream.skipToEnd();}};
- });
- CodeMirror.defineMIME("text/plain", "null");
- CodeMirror.getMode = function (options, spec) {
- if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
- spec = mimeModes[spec];
- if (typeof spec == "string")
- var mname = spec, config = {};
- else if (spec != null)
- var mname = spec.name, config = spec;
- var mfactory = modes[mname];
- if (!mfactory) throw new Error("Unknown mode: " + spec);
- return mfactory(options, config || {});
- };
-}(this));
+}(this))
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/htmlmixed.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/htmlmixed.js
index ec0c21d24ad..b59ef37edbe 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/htmlmixed.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/htmlmixed.js
@@ -44,7 +44,7 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
stream.backUp(cur.length);
- if (!stream.match(pat, false)) stream.match(cur[0]);
+ if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/javascript.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
index fabe1c42b9a..f27c06346c6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/javascript.js
@@ -2,6 +2,7 @@
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
+ var statementIndent = parserConfig.statementIndent;
var jsonMode = parserConfig.json;
var isTS = parserConfig.typescript;
@@ -20,7 +21,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
- "this": kw("this")
+ "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
};
// Extend the 'normal' keywords with the TypeScript language extensions
@@ -29,7 +31,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var tsKeywords = {
// object-like things
"interface": kw("interface"),
- "class": kw("class"),
"extends": kw("extends"),
"constructor": kw("constructor"),
@@ -39,8 +40,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"protected": kw("protected"),
"static": kw("static"),
- "super": kw("super"),
-
// types
"string": type, "number": type, "bool": type, "any": type
};
@@ -55,11 +54,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
- function chain(stream, state, f) {
- state.tokenize = f;
- return f(stream, state);
- }
-
function nextUntilUnescaped(stream, end) {
var escaped = false, next;
while ((next = stream.next()) != null) {
@@ -77,49 +71,51 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
type = tp; content = cont;
return style;
}
-
- function jsTokenBase(stream, state) {
+ function tokenBase(stream, state) {
var ch = stream.next();
- if (ch == '"' || ch == "'")
- return chain(stream, state, jsTokenString(ch));
- else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
+ return ret("number", "number");
+ } else if (ch == "." && stream.match("..")) {
+ return ret("spread", "meta");
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
- else if (ch == "0" && stream.eat(/x/i)) {
+ } else if (ch == "=" && stream.eat(">")) {
+ return ret("=>");
+ } else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
- }
- else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
+ } else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
- }
- else if (ch == "/") {
+ } else if (ch == "/") {
if (stream.eat("*")) {
- return chain(stream, state, jsTokenComment);
- }
- else if (stream.eat("/")) {
+ state.tokenize = tokenComment;
+ return tokenComment(stream, state);
+ } else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
- }
- else if (state.lastType == "operator" || state.lastType == "keyword c" ||
- /^[\[{}\(,;:]$/.test(state.lastType)) {
+ } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
nextUntilUnescaped(stream, "/");
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
return ret("regexp", "string-2");
- }
- else {
+ } else {
stream.eatWhile(isOperatorChar);
return ret("operator", null, stream.current());
}
- }
- else if (ch == "#") {
+ } else if (ch == "`") {
+ state.tokenize = tokenQuasi;
+ return tokenQuasi(stream, state);
+ } else if (ch == "#") {
stream.skipToEnd();
return ret("error", "error");
- }
- else if (isOperatorChar.test(ch)) {
+ } else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", null, stream.current());
- }
- else {
+ } else {
stream.eatWhile(/[\w\$_]/);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
@@ -127,19 +123,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
}
- function jsTokenString(quote) {
+ function tokenString(quote) {
return function(stream, state) {
if (!nextUntilUnescaped(stream, quote))
- state.tokenize = jsTokenBase;
+ state.tokenize = tokenBase;
return ret("string", "string");
};
}
- function jsTokenComment(stream, state) {
+ function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
- state.tokenize = jsTokenBase;
+ state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
@@ -147,6 +143,50 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("comment", "comment");
}
+ function tokenQuasi(stream, state) {
+ var escaped = false, next;
+ while ((next = stream.next()) != null) {
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ return ret("quasi", "string-2", stream.current());
+ }
+
+ var brackets = "([{}])";
+ // This is a crude lookahead trick to try and notice that we're
+ // parsing the argument patterns for a fat-arrow function before we
+ // actually hit the arrow token. It only works if the arrow is on
+ // the same line as the arguments and there's no strange noise
+ // (comments) in between. Fallback is to only notice when we hit the
+ // arrow, and not declare the arguments as locals for the arrow
+ // body.
+ function findFatArrow(stream, state) {
+ if (state.fatArrowAt) state.fatArrowAt = null;
+ var arrow = stream.string.indexOf("=>", stream.start);
+ if (arrow < 0) return;
+
+ var depth = 0, sawSomething = false;
+ for (var pos = arrow - 1; pos >= 0; --pos) {
+ var ch = stream.string.charAt(pos);
+ var bracket = brackets.indexOf(ch);
+ if (bracket >= 0 && bracket < 3) {
+ if (!depth) { ++pos; break; }
+ if (--depth == 0) break;
+ } else if (bracket >= 3 && bracket < 6) {
+ ++depth;
+ } else if (/[$\w]/.test(ch)) {
+ sawSomething = true;
+ } else if (sawSomething && !depth) {
+ ++pos;
+ break;
+ }
+ }
+ if (sawSomething && !depth) state.fatArrowAt = pos;
+ }
+
// Parser
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
@@ -163,6 +203,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
+ for (var cx = state.context; cx; cx = cx.prev) {
+ for (var v = cx.vars; v; v = v.next)
+ if (v.name == varname) return true;
+ }
}
function parseJS(state, style, type, content, stream) {
@@ -209,7 +253,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
- state.globalVars = {name: varname, next: state.globalVars};
+ if (parserConfig.globalVars)
+ state.globalVars = {name: varname, next: state.globalVars};
}
}
@@ -226,8 +271,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function pushlex(type, info) {
var result = function() {
- var state = cx.state;
- state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
+ var state = cx.state, indent = state.indented;
+ if (state.lexical.type == "stat") indent = state.lexical.indented;
+ state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
return result;
@@ -250,61 +296,100 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
};
}
- function statement(type) {
- if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
+ function statement(type, value) {
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
- if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse(cx.state.indented));
+ if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
if (type == "function") return cont(functiondef);
- if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
- poplex, statement, poplex);
+ if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex);
if (type == "variable") return cont(pushlex("stat"), maybelabel);
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
- block, poplex, poplex);
+ block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
- statement, poplex, popcontext);
+ statement, poplex, popcontext);
+ if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
+ if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
+ if (type == "export") return cont(pushlex("form"), afterExport, poplex);
+ if (type == "import") return cont(pushlex("form"), afterImport, poplex);
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
- return expressionInner(type, maybeoperatorComma);
+ return expressionInner(type, false);
}
function expressionNoComma(type) {
- return expressionInner(type, maybeoperatorNoComma);
+ return expressionInner(type, true);
}
- function expressionInner(type, maybeop) {
+ function expressionInner(type, noComma) {
+ if (cx.state.fatArrowAt == cx.stream.start) {
+ var body = noComma ? arrowBodyNoComma : arrowBody;
+ if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("=>"), body, popcontext);
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
+ }
+
+ var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef);
- if (type == "keyword c") return cont(maybeexpression);
- if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
- if (type == "operator") return cont(expression);
- if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);
- if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop);
+ if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
+ if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
+ if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComprehension, poplex, maybeop);
+ if (type == "{") return cont(commasep(objprop, "}"), maybeop);
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
+ function maybeexpressionNoComma(type) {
+ if (type.match(/[;\}\)\],]/)) return pass();
+ return pass(expressionNoComma);
+ }
function maybeoperatorComma(type, value) {
- if (type == ",") return pass();
- return maybeoperatorNoComma(type, value, maybeoperatorComma);
+ if (type == ",") return cont(expression);
+ return maybeoperatorNoComma(type, value, false);
}
- function maybeoperatorNoComma(type, value, me) {
- if (!me) me = maybeoperatorNoComma;
+ function maybeoperatorNoComma(type, value, noComma) {
+ var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
+ var expr = noComma == false ? expression : expressionNoComma;
+ if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
- if (value == "?") return cont(expression, expect(":"), expression);
- return cont(expression);
+ if (value == "?") return cont(expression, expect(":"), expr);
+ return cont(expr);
}
+ if (type == "quasi") { cx.cc.push(me); return quasi(value); }
if (type == ";") return;
- if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
+ if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me);
if (type == ".") return cont(property, me);
- if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, me);
+ if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
+ }
+ function quasi(value) {
+ if (!value) debugger;
+ if (value.slice(value.length - 2) != "${") return cont();
+ return cont(expression, continueQuasi);
+ }
+ function continueQuasi(type) {
+ if (type == "}") {
+ cx.marked = "string-2";
+ cx.state.tokenize = tokenQuasi;
+ return cont();
+ }
+ }
+ function arrowBody(type) {
+ findFatArrow(cx.stream, cx.state);
+ if (type == "{") return pass(statement);
+ return pass(expression);
+ }
+ function arrowBodyNoComma(type) {
+ findFatArrow(cx.stream, cx.state);
+ if (type == "{") return pass(statement);
+ return pass(expressionNoComma);
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
@@ -319,16 +404,21 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "get" || value == "set") return cont(getterSetter);
} else if (type == "number" || type == "string") {
cx.marked = type + " property";
+ } else if (type == "[") {
+ return cont(expression, expect("]"), afterprop);
}
- if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma);
+ if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
}
function getterSetter(type) {
- if (type == ":") return cont(expression);
- if (type != "variable") return cont(expect(":"), expression);
+ if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
- function commasep(what, end) {
+ function afterprop(type) {
+ if (type == ":") return cont(expressionNoComma);
+ if (type == "(") return pass(functiondef);
+ }
+ function commasep(what, end, info) {
function proceed(type) {
if (type == ",") {
var lex = cx.state.lexical;
@@ -340,7 +430,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
return function(type) {
if (type == end) return cont();
- else return pass(what, proceed);
+ if (info === false) return pass(what, proceed);
+ return pass(pushlex(end, info), what, proceed, poplex);
};
}
function block(type) {
@@ -348,73 +439,121 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return pass(statement, block);
}
function maybetype(type) {
- if (type == ":") return cont(typedef);
- return pass();
+ if (isTS && type == ":") return cont(typedef);
}
function typedef(type) {
if (type == "variable"){cx.marked = "variable-3"; return cont();}
- return pass();
}
- function vardef1(type, value) {
- if (type == "variable") {
+ function vardef() {
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
+ }
+ function pattern(type, value) {
+ if (type == "variable") { register(value); return cont(); }
+ if (type == "[") return cont(commasep(pattern, "]"));
+ if (type == "{") return cont(commasep(proppattern, "}"));
+ }
+ function proppattern(type, value) {
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
- return isTS ? cont(maybetype, vardef2) : cont(vardef2);
+ return cont(maybeAssign);
}
- return pass();
+ if (type == "variable") cx.marked = "property";
+ return cont(expect(":"), pattern, maybeAssign);
}
- function vardef2(type, value) {
- if (value == "=") return cont(expressionNoComma, vardef2);
- if (type == ",") return cont(vardef1);
+ function maybeAssign(_type, value) {
+ if (value == "=") return cont(expressionNoComma);
}
- function maybeelse(indent) {
- return function(type, value) {
- if (type == "keyword b" && value == "else") {
- cx.state.lexical = new JSLexical(indent, 0, "form", null, cx.state.lexical);
- return cont(statement, poplex);
- }
- return pass();
- };
+ function vardefCont(type) {
+ if (type == ",") return cont(vardef);
+ }
+ function maybeelse(type, value) {
+ if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
+ }
+ function forspec(type) {
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"));
}
function forspec1(type) {
- if (type == "var") return cont(vardef1, expect(";"), forspec2);
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
if (type == ";") return cont(forspec2);
- if (type == "variable") return cont(formaybein);
+ if (type == "variable") return cont(formaybeinof);
return pass(expression, expect(";"), forspec2);
}
- function formaybein(_type, value) {
- if (value == "in") return cont(expression);
+ function formaybeinof(_type, value) {
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
}
function forspec2(type, value) {
if (type == ";") return cont(forspec3);
- if (value == "in") return cont(expression);
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return pass(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type != ")") cont(expression);
}
function functiondef(type, value) {
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
- if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
+ if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext);
+ }
+ function funarg(type) {
+ if (type == "spread") return cont(funarg);
+ return pass(pattern, maybetype);
+ }
+ function className(type, value) {
+ if (type == "variable") {register(value); return cont(classNameAfter);}
+ }
+ function classNameAfter(_type, value) {
+ if (value == "extends") return cont(expression);
+ }
+ function objlit(type) {
+ if (type == "{") return cont(commasep(objprop, "}"));
+ }
+ function afterModule(type, value) {
+ if (type == "string") return cont(statement);
+ if (type == "variable") { register(value); return cont(maybeFrom); }
+ }
+ function afterExport(_type, value) {
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+ return pass(statement);
}
- function funarg(type, value) {
- if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
+ function afterImport(type) {
+ if (type == "string") return cont();
+ return pass(importSpec, maybeFrom);
+ }
+ function importSpec(type, value) {
+ if (type == "{") return cont(commasep(importSpec, "}"));
+ if (type == "variable") register(value);
+ return cont();
+ }
+ function maybeFrom(_type, value) {
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
+ }
+ function maybeArrayComprehension(type) {
+ if (type == "for") return pass(comprehension);
+ if (type == ",") return cont(commasep(expressionNoComma, "]", false));
+ return pass(commasep(expressionNoComma, "]", false));
+ }
+ function comprehension(type) {
+ if (type == "for") return cont(forspec, comprehension);
+ if (type == "if") return cont(expression, comprehension);
}
// Interface
return {
startState: function(basecolumn) {
- return {
- tokenize: jsTokenBase,
- lastType: null,
+ var state = {
+ tokenize: tokenBase,
+ lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
- globalVars: parserConfig.globalVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: 0
};
+ if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
+ return state;
},
token: function(stream, state) {
@@ -422,8 +561,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
+ findFatArrow(stream, state);
}
- if (state.tokenize != jsTokenComment && stream.eatSpace()) return null;
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
@@ -431,22 +571,26 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
},
indent: function(state, textAfter) {
- if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
- if (state.tokenize != jsTokenBase) return 0;
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
+ if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+ // Kludge to prevent 'maybelse' from blocking lexical scope pops
+ for (var i = state.cc.length - 1; i >= 0; --i) {
+ var c = state.cc[i];
+ if (c == poplex) lexical = lexical.prev;
+ else if (c != maybeelse) break;
+ }
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+ if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
+ lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
- if (parserConfig.statementIndent != null) {
- if (type == ")" && lexical.prev && lexical.prev.type == "stat") lexical = lexical.prev;
- if (lexical.type == "stat") return lexical.indented + parserConfig.statementIndent;
- }
- if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
- return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
- else if (lexical.info == "switch" && !closing)
+ return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
+ else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
@@ -456,7 +600,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
+ fold: "brace",
+ helperType: jsonMode ? "json" : "javascript",
jsonMode: jsonMode
};
});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/markselection.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/markselection.js
index c97776e492d..ae0d3931438 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/markselection.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/markselection.js
@@ -4,7 +4,14 @@
// selected text the CSS class given as option value, or
// "CodeMirror-selectedtext" when the value is not a string.
-(function() {
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) {
@@ -34,10 +41,7 @@
var CHUNK_SIZE = 8;
var Pos = CodeMirror.Pos;
-
- function cmp(pos1, pos2) {
- return pos1.line - pos2.line || pos1.ch - pos2.ch;
- }
+ var cmp = CodeMirror.cmpPos;
function coverRange(cm, from, to, addAt) {
if (cmp(from, to) == 0) return;
@@ -63,13 +67,16 @@
function reset(cm) {
clear(cm);
- var from = cm.getCursor("start"), to = cm.getCursor("end");
- coverRange(cm, from, to);
+ var ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++)
+ coverRange(cm, ranges[i].from(), ranges[i].to());
}
function update(cm) {
+ if (!cm.somethingSelected()) return clear(cm);
+ if (cm.listSelections().length > 1) return reset(cm);
+
var from = cm.getCursor("start"), to = cm.getCursor("end");
- if (cmp(from, to) == 0) return clear(cm);
var array = cm.state.markedSelection;
if (!array.length) return coverRange(cm, from, to);
@@ -105,4 +112,4 @@
}
}
}
-})();
+});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/matchbrackets.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/matchbrackets.js
index 131fe831fdc..b889fa3ae57 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/matchbrackets.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/matchbrackets.js
@@ -1,72 +1,96 @@
-(function() {
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
(document.documentMode == null || document.documentMode < 8);
var Pos = CodeMirror.Pos;
var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
- function findMatchingBracket(cm, where, strict) {
- var state = cm.state.matchBrackets;
- var maxScanLen = (state && state.maxScanLineLength) || 10000;
- var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1;
+ function findMatchingBracket(cm, where, strict, config) {
+ var line = cm.getLineHandle(where.line), pos = where.ch - 1;
var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
if (!match) return null;
- var forward = match.charAt(1) == ">", d = forward ? 1 : -1;
- if (strict && forward != (pos == cur.ch)) return null;
- var style = cm.getTokenTypeAt(Pos(cur.line, pos + 1));
+ var dir = match.charAt(1) == ">" ? 1 : -1;
+ if (strict && (dir > 0) != (pos == where.ch)) return null;
+ var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
- var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
- function scan(line, lineNo, start) {
- if (!line.text) return;
- var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1;
- if (line.text.length > maxScanLen) return null;
- if (start != null) pos = start + d;
- for (; pos != end; pos += d) {
- var ch = line.text.charAt(pos);
- if (re.test(ch) && cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style) {
+ var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
+ return {from: Pos(where.line, pos), to: found && found.pos,
+ match: found && found.ch == match.charAt(0), forward: dir > 0};
+ }
+
+ // bracketRegex is used to specify which type of bracket to scan
+ // should be a regexp, e.g. /[[\]]/
+ //
+ // Note: If "where" is on an open bracket, then this bracket is ignored.
+ function scanForBracket(cm, where, dir, style, config) {
+ var maxScanLen = (config && config.maxScanLineLength) || 10000;
+ var maxScanLines = (config && config.maxScanLines) || 500;
+
+ var stack = [];
+ var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
+ var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
+ : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
+ for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
+ var line = cm.getLine(lineNo);
+ if (!line) continue;
+ var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
+ if (line.length > maxScanLen) continue;
+ if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
+ for (; pos != end; pos += dir) {
+ var ch = line.charAt(pos);
+ if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
var match = matching[ch];
- if (match.charAt(1) == ">" == forward) stack.push(ch);
- else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
- else if (!stack.length) return {pos: pos, match: true};
+ if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
+ else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
+ else stack.pop();
}
}
}
- for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {
- if (i == cur.line) found = scan(line, i, pos);
- else found = scan(cm.getLineHandle(i), i);
- if (found) break;
- }
- return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos),
- match: found && found.match, forward: forward};
}
- function matchBrackets(cm, autoclear) {
+ function matchBrackets(cm, autoclear, config) {
// Disable brace matching in long lines, since it'll cause hugely slow updates
var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
- var found = findMatchingBracket(cm);
- if (!found || cm.getLine(found.from.line).length > maxHighlightLen ||
- found.to && cm.getLine(found.to.line).length > maxHighlightLen)
- return;
+ var marks = [], ranges = cm.listSelections();
+ for (var i = 0; i < ranges.length; i++) {
+ var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
+ if (match && cm.getLine(match.from.line).length <= maxHighlightLen &&
+ match.to && cm.getLine(match.to.line).length <= maxHighlightLen) {
+ var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
+ marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
+ if (match.to)
+ marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
+ }
+ }
+
+ if (marks.length) {
+ // Kludge to work around the IE bug from issue #1193, where text
+ // input stops going to the textare whever this fires.
+ if (ie_lt8 && cm.state.focused) cm.display.input.focus();
- var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
- var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style});
- var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style});
- // Kludge to work around the IE bug from issue #1193, where text
- // input stops going to the textare whever this fires.
- if (ie_lt8 && cm.state.focused) cm.display.input.focus();
- var clear = function() {
- cm.operation(function() { one.clear(); two && two.clear(); });
- };
- if (autoclear) setTimeout(clear, 800);
- else return clear;
+ var clear = function() {
+ cm.operation(function() {
+ for (var i = 0; i < marks.length; i++) marks[i].clear();
+ });
+ };
+ if (autoclear) setTimeout(clear, 800);
+ else return clear;
+ }
}
var currentlyHighlighted = null;
function doMatchBrackets(cm) {
cm.operation(function() {
if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
- if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false);
+ currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
});
}
@@ -80,7 +104,10 @@
});
CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
- CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){
- return findMatchingBracket(this, pos, strict);
+ CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
+ return findMatchingBracket(this, pos, strict, config);
+ });
+ CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
+ return scanForBracket(this, pos, dir, style, config);
});
-})();
+});
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/php.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/php.js
index fa0db5b1fe9..3555b8b1456 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/php.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/php.js
@@ -18,10 +18,10 @@
"for foreach function global goto if implements interface instanceof namespace " +
"new or private protected public static switch throw trait try use var while xor " +
"die echo empty exit eval include include_once isset list require require_once return " +
- "print unset __halt_compiler self static parent"),
- blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
- atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__"),
- builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport echo print global static exit array empty eval isset unset die include require include_once require_once"),
+ "print unset __halt_compiler self static parent yield insteadof finally"),
+ blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
+ atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__"),
+ builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once"),
multiLineStrings: true,
hooks: {
"$": function(stream) {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/python.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/python.js
index b623972b881..802c2dd4ac6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/python.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/python.js
@@ -36,6 +36,12 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
var py3 = {'builtins': ['ascii', 'bytes', 'exec', 'print'],
'keywords': ['nonlocal', 'False', 'True', 'None']};
+ if(parserConf.extra_keywords != undefined){
+ commonkeywords = commonkeywords.concat(parserConf.extra_keywords);
+ }
+ if(parserConf.extra_builtins != undefined){
+ commonBuiltins = commonBuiltins.concat(parserConf.extra_builtins);
+ }
if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
commonkeywords = commonkeywords.concat(py3.keywords);
commonBuiltins = commonBuiltins.concat(py3.builtins);
@@ -145,6 +151,9 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
}
if (stream.match(identifiers)) {
+ if (state.lastToken == 'def' || state.lastToken == 'class') {
+ return 'def';
+ }
return 'variable';
}
@@ -252,7 +261,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
// Handle '.' connected identifiers
if (current === '.') {
style = stream.match(identifiers, false) ? null : ERRORCLASS;
- if (style === null && state.lastToken === 'meta') {
+ if (style === null && state.lastStyle === 'meta') {
// Apply 'meta' style to '.' connected identifiers when
// appropriate.
style = 'meta';
@@ -266,7 +275,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
}
if ((style === 'variable' || style === 'builtin')
- && state.lastToken === 'meta') {
+ && state.lastStyle === 'meta') {
style = 'meta';
}
@@ -307,6 +316,7 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
return {
tokenize: tokenBase,
scopes: [{offset:basecolumn || 0, type:'py'}],
+ lastStyle: null,
lastToken: null,
lambda: false,
dedent: 0
@@ -316,12 +326,16 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
token: function(stream, state) {
var style = tokenLexer(stream, state);
- state.lastToken = style;
+ state.lastStyle = style;
- if (stream.eol() && stream.lambda) {
- state.lambda = false;
+ var current = stream.current();
+ if (current && style) {
+ state.lastToken = current;
}
+ if (stream.eol() && state.lambda) {
+ state.lambda = false;
+ }
return style;
},
@@ -333,9 +347,22 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
return state.scopes[0].offset;
},
- lineComment: "#"
+ lineComment: "#",
+ fold: "indent"
};
return external;
});
CodeMirror.defineMIME("text/x-python", "python");
+
+(function() {
+ "use strict";
+ var words = function(str){return str.split(' ');};
+
+ CodeMirror.defineMIME("text/x-cython", {
+ name: "python",
+ extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
+ "extern gil include nogil property public"+
+ "readonly struct union DEF IF ELIF ELSE")
+ });
+})();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cm/xml.js b/chromium/third_party/WebKit/Source/devtools/front_end/cm/xml.js
index 53285c848c6..4f49e07faf5 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cm/xml.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/cm/xml.js
@@ -76,7 +76,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
tagName = "";
var c;
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
- if (!tagName) return "error";
+ if (!tagName) return "tag error";
type = isClose ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag";
@@ -109,7 +109,9 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
type = "equals";
return null;
} else if (ch == "<") {
- return "error";
+ state.tokenize = inText;
+ var next = state.tokenize(stream, state);
+ return next ? next + " error" : "error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
@@ -298,7 +300,9 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
}
}
state.startOfLine = false;
- return setStyle || style;
+ if (setStyle)
+ style = setStyle == "error" ? style + " error" : setStyle;
+ return style;
},
indent: function(state, textAfter, fullLine) {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Color.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Color.js
index 7d37c51f9e9..84d7685385a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Color.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Color.js
@@ -493,6 +493,7 @@ WebInspector.Color.Nicknames = {
"darkcyan": [0,139,139],
"darkgoldenrod": [184,134,11],
"darkgray": [169,169,169],
+ "darkgrey": [169,169,169],
"darkgreen": [0,100,0],
"darkkhaki": [189,183,107],
"darkmagenta": [139,0,139],
@@ -504,11 +505,13 @@ WebInspector.Color.Nicknames = {
"darkseagreen": [143,188,143],
"darkslateblue": [72,61,139],
"darkslategray": [47,79,79],
+ "darkslategrey": [47,79,79],
"darkturquoise": [0,206,209],
"darkviolet": [148,0,211],
"deeppink": [255,20,147],
"deepskyblue": [0,191,255],
"dimgray": [105,105,105],
+ "dimgrey": [105,105,105],
"dodgerblue": [30,144,255],
"firebrick": [178,34,34],
"floralwhite": [255,250,240],
@@ -518,6 +521,7 @@ WebInspector.Color.Nicknames = {
"gold": [255,215,0],
"goldenrod": [218,165,32],
"gray": [128,128,128],
+ "grey": [128,128,128],
"green": [0,128,0],
"greenyellow": [173,255,47],
"honeydew": [240,255,240],
@@ -535,12 +539,14 @@ WebInspector.Color.Nicknames = {
"lightcyan": [224,255,255],
"lightgoldenrodyellow":[250,250,210],
"lightgreen": [144,238,144],
+ "lightgray": [211,211,211],
"lightgrey": [211,211,211],
"lightpink": [255,182,193],
"lightsalmon": [255,160,122],
"lightseagreen": [32,178,170],
"lightskyblue": [135,206,250],
"lightslategray": [119,136,153],
+ "lightslategrey": [119,136,153],
"lightsteelblue": [176,196,222],
"lightyellow": [255,255,224],
"lime": [0,255,0],
@@ -593,6 +599,7 @@ WebInspector.Color.Nicknames = {
"skyblue": [135,206,235],
"slateblue": [106,90,205],
"slategray": [112,128,144],
+ "slategrey": [112,128,144],
"snow": [255,250,250],
"springgreen": [0,255,127],
"steelblue": [70,130,180],
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CompletionDictionary.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/CompletionDictionary.js
index 89a89ecdcdf..861ac9f4517 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CompletionDictionary.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/CompletionDictionary.js
@@ -60,7 +60,9 @@ WebInspector.CompletionDictionary.prototype = {
* @param {string} word
* @return {number}
*/
- wordCount: function(word) { }
+ wordCount: function(word) { },
+
+ reset: function() { }
}
/**
@@ -126,5 +128,10 @@ WebInspector.SampleCompletionDictionary.prototype = {
wordCount: function(word)
{
return this._words[word] ? this._words[word] : 0;
+ },
+
+ reset: function()
+ {
+ this._words = {};
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMExtension.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/DOMExtension.js
index 82bf8009948..e6bfd54a6e7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMExtension.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/DOMExtension.js
@@ -31,7 +31,11 @@
*/
/**
+ * @param {number} offset
+ * @param {string} stopCharacters
+ * @param {!Node} stayWithinNode
* @param {string=} direction
+ * @return {!Range}
*/
Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
{
@@ -120,11 +124,15 @@ Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, di
return result;
}
+/**
+ * @param {!Node=} stayWithin
+ * @return {?Node}
+ */
Node.prototype.traverseNextTextNode = function(stayWithin)
{
var node = this.traverseNextNode(stayWithin);
if (!node)
- return;
+ return null;
while (node && node.nodeType !== Node.TEXT_NODE)
node = node.traverseNextNode(stayWithin);
@@ -132,6 +140,10 @@ Node.prototype.traverseNextTextNode = function(stayWithin)
return node;
}
+/**
+ * @param {number} offset
+ * @return {!{container: !Node, offset: number}}
+ */
Node.prototype.rangeBoundaryForOffset = function(offset)
{
var node = this.traverseNextTextNode(this);
@@ -152,38 +164,36 @@ Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
}
/**
- * @param {string} className
- * @param {*} enable
- */
-Element.prototype.enableStyleClass = function(className, enable)
-{
- if (enable)
- this.classList.add(className);
- else
- this.classList.remove(className);
-}
-
-/**
* @param {number|undefined} x
* @param {number|undefined} y
+ * @param {!Element=} relativeTo
*/
-Element.prototype.positionAt = function(x, y)
+Element.prototype.positionAt = function(x, y, relativeTo)
{
+ var shift = {x: 0, y: 0};
+ if (relativeTo)
+ shift = relativeTo.boxInWindow(this.ownerDocument.defaultView);
+
if (typeof x === "number")
- this.style.setProperty("left", x + "px");
+ this.style.setProperty("left", (shift.x + x) + "px");
else
this.style.removeProperty("left");
if (typeof y === "number")
- this.style.setProperty("top", y + "px");
+ this.style.setProperty("top", (shift.y + y) + "px");
else
this.style.removeProperty("top");
}
+/**
+ * @return {boolean}
+ */
Element.prototype.isScrolledToBottom = function()
{
- // This code works only for 0-width border
- return this.scrollTop + this.clientHeight === this.scrollHeight;
+ // This code works only for 0-width border.
+ // Both clientHeight and scrollHeight are rounded to integer values, so we tolerate
+ // one pixel error.
+ return Math.abs(this.scrollTop + this.clientHeight - this.scrollHeight) <= 1;
}
/**
@@ -201,13 +211,76 @@ function removeSubsequentNodes(fromNode, toNode)
/**
* @constructor
- * @param {number} width
- * @param {number} height
+ * @param {!Size} minimum
+ * @param {?Size=} preferred
+ */
+function Constraints(minimum, preferred)
+{
+ /**
+ * @type {!Size}
+ */
+ this.minimum = minimum;
+
+ /**
+ * @type {!Size}
+ */
+ this.preferred = preferred || minimum;
+
+ if (this.minimum.width > this.preferred.width || this.minimum.height > this.preferred.height)
+ throw new Error("Minimum size is greater than preferred.");
+}
+
+/**
+ * @param {?Constraints} constraints
+ * @return {boolean}
+ */
+Constraints.prototype.isEqual = function(constraints)
+{
+ return !!constraints && this.minimum.isEqual(constraints.minimum) && this.preferred.isEqual(constraints.preferred);
+}
+
+/**
+ * @param {!Constraints|number} value
+ * @return {!Constraints}
+ */
+Constraints.prototype.widthToMax = function(value)
+{
+ if (typeof value === "number")
+ return new Constraints(this.minimum.widthToMax(value), this.preferred.widthToMax(value));
+ return new Constraints(this.minimum.widthToMax(value.minimum), this.preferred.widthToMax(value.preferred));
+}
+
+/**
+ * @param {!Constraints|number} value
+ * @return {!Constraints}
+ */
+Constraints.prototype.addWidth = function(value)
+{
+ if (typeof value === "number")
+ return new Constraints(this.minimum.addWidth(value), this.preferred.addWidth(value));
+ return new Constraints(this.minimum.addWidth(value.minimum), this.preferred.addWidth(value.preferred));
+}
+
+/**
+ * @param {!Constraints|number} value
+ * @return {!Constraints}
*/
-function Size(width, height)
+Constraints.prototype.heightToMax = function(value)
{
- this.width = width;
- this.height = height;
+ if (typeof value === "number")
+ return new Constraints(this.minimum.heightToMax(value), this.preferred.heightToMax(value));
+ return new Constraints(this.minimum.heightToMax(value.minimum), this.preferred.heightToMax(value.preferred));
+}
+
+/**
+ * @param {!Constraints|number} value
+ * @return {!Constraints}
+ */
+Constraints.prototype.addHeight = function(value)
+{
+ if (typeof value === "number")
+ return new Constraints(this.minimum.addHeight(value), this.preferred.addHeight(value));
+ return new Constraints(this.minimum.addHeight(value.minimum), this.preferred.addHeight(value.preferred));
}
/**
@@ -236,15 +309,25 @@ Element.prototype.containsEventPoint = function(event)
box.top < event.y && event.y < box.bottom;
}
+/**
+ * @param {!Array.<string>} nameArray
+ * @return {?Node}
+ */
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
- for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
- for (var i = 0; i < nameArray.length; ++i)
+ for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) {
+ for (var i = 0; i < nameArray.length; ++i) {
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
+ }
+ }
return null;
}
+/**
+ * @param {string} nodeName
+ * @return {?Node}
+ */
Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
@@ -253,15 +336,21 @@ Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
/**
* @param {string} className
* @param {!Element=} stayWithin
+ * @return {?Element}
*/
Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin)
{
- for (var node = this; node && node !== stayWithin && node !== this.ownerDocument; node = node.parentNode)
+ for (var node = this; node && node !== stayWithin && node !== this.ownerDocument; node = node.parentNode) {
if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className))
- return node;
+ return /** @type {!Element} */ (node);
+ }
return null;
}
+/**
+ * @param {string} query
+ * @return {?Node}
+ */
Element.prototype.query = function(query)
{
return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
@@ -273,6 +362,21 @@ Element.prototype.removeChildren = function()
this.textContent = "";
}
+Element.prototype.appendChildren = function(children)
+{
+ for (var i = 0; i < children.length; ++i)
+ this.appendChild(children[i]);
+}
+
+Element.prototype.setChildren = function(children)
+{
+ this.removeChildren();
+ this.appendChildren(children);
+}
+
+/**
+ * @return {boolean}
+ */
Element.prototype.isInsertionCaretInside = function()
{
var selection = window.getSelection();
@@ -285,6 +389,7 @@ Element.prototype.isInsertionCaretInside = function()
/**
* @param {string} elementName
* @param {string=} className
+ * @return {!Element}
*/
Document.prototype.createElementWithClass = function(elementName, className)
{
@@ -295,7 +400,9 @@ Document.prototype.createElementWithClass = function(elementName, className)
}
/**
+ * @param {string} elementName
* @param {string=} className
+ * @return {!Element}
*/
Element.prototype.createChild = function(elementName, className)
{
@@ -308,6 +415,7 @@ DocumentFragment.prototype.createChild = Element.prototype.createChild;
/**
* @param {string} text
+ * @return {!Text}
*/
Element.prototype.createTextChild = function(text)
{
@@ -335,12 +443,18 @@ Element.prototype.totalOffsetTop = function()
}
+/**
+ * @return {!{left: number, top: number}}
+ */
Element.prototype.totalOffset = function()
{
var rect = this.getBoundingClientRect();
return { left: rect.left, top: rect.top };
}
+/**
+ * @return {!{left: number, top: number}}
+ */
Element.prototype.scrollOffset = function()
{
var curLeft = 0;
@@ -368,6 +482,34 @@ function AnchorBox(x, y, width, height)
}
/**
+ * @param {!AnchorBox} box
+ * @return {!AnchorBox}
+ */
+AnchorBox.prototype.relativeTo = function(box)
+{
+ return new AnchorBox(
+ this.x - box.x, this.y - box.y, this.width, this.height);
+}
+
+/**
+ * @param {!Element} element
+ * @return {!AnchorBox}
+ */
+AnchorBox.prototype.relativeToElement = function(element)
+{
+ return this.relativeTo(element.boxInWindow(element.ownerDocument.defaultView));
+}
+
+/**
+ * @param {?AnchorBox} anchorBox
+ * @return {boolean}
+ */
+AnchorBox.prototype.equals = function(anchorBox)
+{
+ return !!anchorBox && this.x === anchorBox.x && this.y === anchorBox.y && this.width === anchorBox.width && this.height === anchorBox.height;
+}
+
+/**
* @param {!Window} targetWindow
* @return {!AnchorBox}
*/
@@ -390,7 +532,7 @@ Element.prototype.offsetRelativeToWindow = function(targetWindow)
}
/**
- * @param {!Window} targetWindow
+ * @param {!Window=} targetWindow
* @return {!AnchorBox}
*/
Element.prototype.boxInWindow = function(targetWindow)
@@ -443,6 +585,11 @@ Event.prototype.consume = function(preventDefault)
this.handled = true;
}
+/**
+ * @param {number=} start
+ * @param {number=} end
+ * @return {!Text}
+ */
Text.prototype.select = function(start, end)
{
start = start || 0;
@@ -460,6 +607,9 @@ Text.prototype.select = function(start, end)
return this;
}
+/**
+ * @return {?number}
+ */
Element.prototype.selectionLeftOffset = function()
{
// Calculate selection offset relative to the current element.
@@ -482,6 +632,10 @@ Element.prototype.selectionLeftOffset = function()
return leftOffset;
}
+/**
+ * @param {?Node} node
+ * @return {boolean}
+ */
Node.prototype.isAncestor = function(node)
{
if (!node)
@@ -496,21 +650,37 @@ Node.prototype.isAncestor = function(node)
return false;
}
+/**
+ * @param {?Node} descendant
+ * @return {boolean}
+ */
Node.prototype.isDescendant = function(descendant)
{
return !!descendant && descendant.isAncestor(this);
}
+/**
+ * @param {?Node} node
+ * @return {boolean}
+ */
Node.prototype.isSelfOrAncestor = function(node)
{
return !!node && (node === this || this.isAncestor(node));
}
+/**
+ * @param {?Node} node
+ * @return {boolean}
+ */
Node.prototype.isSelfOrDescendant = function(node)
{
return !!node && (node === this || this.isDescendant(node));
}
+/**
+ * @param {!Node=} stayWithin
+ * @return {?Node}
+ */
Node.prototype.traverseNextNode = function(stayWithin)
{
var node = this.firstChild;
@@ -533,6 +703,10 @@ Node.prototype.traverseNextNode = function(stayWithin)
return node.nextSibling;
}
+/**
+ * @param {!Node=} stayWithin
+ * @return {?Node}
+ */
Node.prototype.traversePreviousNode = function(stayWithin)
{
if (stayWithin && this === stayWithin)
@@ -545,6 +719,30 @@ Node.prototype.traversePreviousNode = function(stayWithin)
return this.parentNode;
}
+/**
+ * @param {*} text
+ * @param {string=} placeholder
+ * @return {boolean} true if was truncated
+ */
+Node.prototype.setTextContentTruncatedIfNeeded = function(text, placeholder)
+{
+ // Huge texts in the UI reduce rendering performance drastically.
+ // Moreover, Blink/WebKit uses <unsigned short> internally for storing text content
+ // length, so texts longer than 65535 are inherently displayed incorrectly.
+ const maxTextContentLength = 65535;
+
+ if (typeof text === "string" && text.length > maxTextContentLength) {
+ this.textContent = typeof placeholder === "string" ? placeholder : text.trimEnd(maxTextContentLength);
+ return true;
+ }
+
+ this.textContent = text;
+ return false;
+}
+
+/**
+ * @return {boolean}
+ */
function isEnterKey(event) {
// Check if in IME.
return event.keyCode !== 229 && event.keyIdentifier === "Enter";
@@ -554,45 +752,3 @@ function consumeEvent(e)
{
e.consume();
}
-
-/**
- * Mutation observers leak memory. Keep track of them and disconnect
- * on unload.
- * @constructor
- * @param {function(!Array.<!WebKitMutation>)} handler
- */
-function NonLeakingMutationObserver(handler)
-{
- this._observer = new WebKitMutationObserver(handler);
- NonLeakingMutationObserver._instances.push(this);
- if (!NonLeakingMutationObserver._unloadListener) {
- NonLeakingMutationObserver._unloadListener = function() {
- while (NonLeakingMutationObserver._instances.length)
- NonLeakingMutationObserver._instances[NonLeakingMutationObserver._instances.length - 1].disconnect();
- };
- window.addEventListener("unload", NonLeakingMutationObserver._unloadListener, false);
- }
-}
-
-NonLeakingMutationObserver._instances = [];
-
-NonLeakingMutationObserver.prototype = {
- /**
- * @param {!Element} element
- * @param {!Object} config
- */
- observe: function(element, config)
- {
- if (this._observer)
- this._observer.observe(element, config);
- },
-
- disconnect: function()
- {
- if (this._observer)
- this._observer.disconnect();
- NonLeakingMutationObserver._instances.remove(this);
- delete this._observer;
- }
-}
-
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Geometry.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
index 609a3994fff..bc6612fa973 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Geometry.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Geometry.js
@@ -120,6 +120,33 @@ WebInspector.Geometry.crossProduct = function(u, v)
/**
* @param {!WebInspector.Geometry.Vector} u
* @param {!WebInspector.Geometry.Vector} v
+ * @return {!WebInspector.Geometry.Vector}
+ */
+WebInspector.Geometry.subtract = function(u, v)
+{
+ var x = u.x - v.x;
+ var y = u.y - v.y;
+ var z = u.z - v.z;
+ return new WebInspector.Geometry.Vector(x, y, z);
+}
+
+/**
+ * @param {!WebInspector.Geometry.Vector} v
+ * @param {!CSSMatrix} m
+ * @return {!WebInspector.Geometry.Vector}
+ */
+WebInspector.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m)
+{
+ var t = v.x * m.m14 + v.y * m.m24 + v.z * m.m34 + m.m44;
+ var x = (v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41) / t;
+ var y = (v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42) / t;
+ var z = (v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43) / t;
+ return new WebInspector.Geometry.Vector(x, y, z);
+}
+
+/**
+ * @param {!WebInspector.Geometry.Vector} u
+ * @param {!WebInspector.Geometry.Vector} v
* @return {number}
*/
WebInspector.Geometry.calculateAngle = function(u, v)
@@ -143,3 +170,59 @@ WebInspector.Geometry.radToDeg = function(rad)
return rad * 180 / Math.PI;
}
+
+/**
+ * @constructor
+ * @param {number} width
+ * @param {number} height
+ */
+function Size(width, height)
+{
+ this.width = width;
+ this.height = height;
+}
+
+/**
+ * @param {?Size} size
+ * @return {boolean}
+ */
+Size.prototype.isEqual = function(size)
+{
+ return !!size && this.width === size.width && this.height === size.height;
+};
+
+/**
+ * @param {!Size|number} size
+ * @return {!Size}
+ */
+Size.prototype.widthToMax = function(size)
+{
+ return new Size(Math.max(this.width, (typeof size === "number" ? size : size.width)), this.height);
+};
+
+/**
+ * @param {!Size|number} size
+ * @return {!Size}
+ */
+Size.prototype.addWidth = function(size)
+{
+ return new Size(this.width + (typeof size === "number" ? size : size.width), this.height);
+};
+
+/**
+ * @param {!Size|number} size
+ * @return {!Size}
+ */
+Size.prototype.heightToMax = function(size)
+{
+ return new Size(this.width, Math.max(this.height, (typeof size === "number" ? size : size.height)));
+};
+
+/**
+ * @param {!Size|number} size
+ * @return {!Size}
+ */
+Size.prototype.addHeight = function(size)
+{
+ return new Size(this.width, this.height + (typeof size === "number" ? size : size.height));
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/MessageSink.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/MessageSink.js
new file mode 100644
index 00000000000..6d6bf4eedf1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/MessageSink.js
@@ -0,0 +1,79 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.MessageSink = function()
+{
+ /** @type {!Array.<!WebInspector.MessageSink.Message>} */
+ this._messages = [];
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.MessageSink.Events = {
+ MessageAdded: "messageAdded"
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.MessageSink.MessageLevel = {
+ Log: "log",
+ Warning: "warning",
+ Error: "error"
+}
+
+/**
+ * @constructor
+ * @param {string} text
+ * @param {!WebInspector.MessageSink.MessageLevel} level
+ * @param {number} timestamp
+ * @param {boolean} show
+ */
+WebInspector.MessageSink.Message = function(text, level, timestamp, show)
+{
+ this.text = text;
+ this.level = level;
+ this.timestamp = (typeof timestamp === "number") ? timestamp : Date.now();
+ this.show = show;
+}
+
+WebInspector.MessageSink.prototype = {
+ /**
+ * @param {string} text
+ * @param {!WebInspector.MessageSink.MessageLevel=} level
+ * @param {boolean=} show
+ */
+ addMessage: function(text, level, show)
+ {
+ var message = new WebInspector.MessageSink.Message(text, level || WebInspector.MessageSink.MessageLevel.Log, Date.now(), show || false);
+ this._messages.push(message);
+ this.dispatchEventToListeners(WebInspector.MessageSink.Events.MessageAdded, message);
+ },
+
+ /**
+ * @param {string} text
+ * @param {boolean=} show
+ */
+ addErrorMessage: function(text, show)
+ {
+ this.addMessage(text, WebInspector.MessageSink.MessageLevel.Error, show);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.MessageSink.Message>}
+ */
+ messages: function()
+ {
+ return this._messages;
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+WebInspector.messageSink = new WebInspector.MessageSink();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/ModuleManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/ModuleManager.js
new file mode 100644
index 00000000000..874ef83565f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/ModuleManager.js
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {!Array.<!WebInspector.ModuleManager.ModuleDescriptor>} descriptors
+ */
+WebInspector.ModuleManager = function(descriptors)
+{
+ /**
+ * @type {!Array.<!WebInspector.ModuleManager.Module>}
+ */
+ this._modules = [];
+ /**
+ * @type {!Object.<string, !WebInspector.ModuleManager.Module>}
+ */
+ this._modulesMap = {};
+ /**
+ * @type {!Array.<!WebInspector.ModuleManager.Extension>}
+ */
+ this._extensions = [];
+
+ /**
+ * @type {!Object.<string, !function(new:Object)>}
+ */
+ this._cachedTypeClasses = {};
+
+ /**
+ * @type {!Object.<string, !WebInspector.ModuleManager.ModuleDescriptor>}
+ */
+ this._descriptorsMap = {};
+ for (var i = 0; i < descriptors.length; ++i)
+ this._descriptorsMap[descriptors[i]["name"]] = descriptors[i];
+}
+
+WebInspector.ModuleManager.prototype = {
+ /**
+ * @param {!Array.<string>} configuration
+ */
+ registerModules: function(configuration)
+ {
+ for (var i = 0; i < configuration.length; ++i)
+ this.registerModule(configuration[i]);
+ },
+
+ /**
+ * @param {string} moduleName
+ */
+ registerModule: function(moduleName)
+ {
+ if (!this._descriptorsMap[moduleName]) {
+ var content = loadResource(moduleName + "/module.json");
+ if (!content)
+ throw new Error("Module is not defined: " + moduleName + " " + new Error().stack);
+ var module = /** @type {!WebInspector.ModuleManager.ModuleDescriptor} */ (self.eval("(" + content + ")"));
+ module["name"] = moduleName;
+ this._descriptorsMap[moduleName] = module;
+ }
+ var module = new WebInspector.ModuleManager.Module(this, this._descriptorsMap[moduleName]);
+ this._modules.push(module);
+ this._modulesMap[moduleName] = module;
+ },
+
+ /**
+ * @param {string} moduleName
+ */
+ loadModule: function(moduleName)
+ {
+ this._modulesMap[moduleName]._load();
+ },
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @param {?function(function(new:Object)):boolean} predicate
+ * @return {boolean}
+ */
+ _checkExtensionApplicability: function(extension, predicate)
+ {
+ if (!predicate)
+ return false;
+ var contextTypes = /** @type {!Array.<string>|undefined} */ (extension.descriptor().contextTypes);
+ if (!contextTypes)
+ return true;
+ for (var i = 0; i < contextTypes.length; ++i) {
+ var contextType = this._resolve(contextTypes[i]);
+ var isMatching = !!contextType && predicate(contextType);
+ if (isMatching)
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @param {?Object} context
+ * @return {boolean}
+ */
+ isExtensionApplicableToContext: function(extension, context)
+ {
+ if (!context)
+ return true;
+ return this._checkExtensionApplicability(extension, isInstanceOf);
+
+ /**
+ * @param {!Function} targetType
+ * @return {boolean}
+ */
+ function isInstanceOf(targetType)
+ {
+ return context instanceof targetType;
+ }
+ },
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @param {!Set.<!Function>=} currentContextTypes
+ * @return {boolean}
+ */
+ isExtensionApplicableToContextTypes: function(extension, currentContextTypes)
+ {
+ if (!extension.descriptor().contextTypes)
+ return true;
+
+ return this._checkExtensionApplicability(extension, currentContextTypes ? isContextTypeKnown : null);
+
+ /**
+ * @param {!Function} targetType
+ * @return {boolean}
+ */
+ function isContextTypeKnown(targetType)
+ {
+ return currentContextTypes.contains(targetType);
+ }
+ },
+
+ /**
+ * @param {string|!Function} type
+ * @param {?Object=} context
+ * @return {!Array.<!WebInspector.ModuleManager.Extension>}
+ */
+ extensions: function(type, context)
+ {
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @return {boolean}
+ */
+ function filter(extension)
+ {
+ if (extension._type !== type && extension._typeClass() !== type)
+ return false;
+ return !context || extension.isApplicable(context);
+ }
+ return this._extensions.filter(filter);
+ },
+
+ /**
+ * @param {string|!Function} type
+ * @param {?Object=} context
+ * @return {?WebInspector.ModuleManager.Extension}
+ */
+ extension: function(type, context)
+ {
+ return this.extensions(type, context)[0] || null;
+ },
+
+ /**
+ * @param {string|!Function} type
+ * @param {?Object=} context
+ * @return {!Array.<!Object>}
+ */
+ instances: function(type, context)
+ {
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @return {?Object}
+ */
+ function instantiate(extension)
+ {
+ return extension.instance();
+ }
+ return this.extensions(type, context).filter(instantiate).map(instantiate);
+ },
+
+ /**
+ * @param {string|!Function} type
+ * @param {?Object=} context
+ * @return {?Object}
+ */
+ instance: function(type, context)
+ {
+ var extension = this.extension(type, context);
+ return extension ? extension.instance() : null;
+ },
+
+ /**
+ * @param {string|!Function} type
+ * @param {string} nameProperty
+ * @param {string} orderProperty
+ * @return {function(string, string):number}
+ */
+ orderComparator: function(type, nameProperty, orderProperty)
+ {
+ var extensions = this.extensions(type);
+ var orderForName = {};
+ for (var i = 0; i < extensions.length; ++i) {
+ var descriptor = extensions[i].descriptor();
+ orderForName[descriptor[nameProperty]] = descriptor[orderProperty];
+ }
+
+ /**
+ * @param {string} name1
+ * @param {string} name2
+ * @return {number}
+ */
+ function result(name1, name2)
+ {
+ if (name1 in orderForName && name2 in orderForName)
+ return orderForName[name1] - orderForName[name2];
+ if (name1 in orderForName)
+ return -1;
+ if (name2 in orderForName)
+ return 1;
+ return name1.compareTo(name2);
+ }
+ return result;
+ },
+
+ /**
+ * @return {?function(new:Object)}
+ */
+ _resolve: function(typeName)
+ {
+ if (!this._cachedTypeClasses[typeName]) {
+ var path = typeName.split(".");
+ var object = window;
+ for (var i = 0; object && (i < path.length); ++i)
+ object = object[path[i]];
+ if (object)
+ this._cachedTypeClasses[typeName] = /** @type function(new:Object) */(object);
+ }
+ return this._cachedTypeClasses[typeName];
+ }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.ModuleManager.ModuleDescriptor = function()
+{
+ /**
+ * @type {string}
+ */
+ this.name;
+
+ /**
+ * @type {!Array.<!WebInspector.ModuleManager.ExtensionDescriptor>}
+ */
+ this.extensions;
+
+ /**
+ * @type {!Array.<string>|undefined}
+ */
+ this.dependencies;
+
+ /**
+ * @type {!Array.<string>}
+ */
+ this.scripts;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.ModuleManager.ExtensionDescriptor = function()
+{
+ /**
+ * @type {string}
+ */
+ this.type;
+
+ /**
+ * @type {string|undefined}
+ */
+ this.className;
+
+ /**
+ * @type {!Array.<string>|undefined}
+ */
+ this.contextTypes;
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.ModuleManager} manager
+ * @param {!WebInspector.ModuleManager.ModuleDescriptor} descriptor
+ */
+WebInspector.ModuleManager.Module = function(manager, descriptor)
+{
+ this._manager = manager;
+ this._descriptor = descriptor;
+ this._name = descriptor.name;
+ var extensions = /** @type {?Array.<!WebInspector.ModuleManager.ExtensionDescriptor>}*/ (descriptor.extensions);
+ for (var i = 0; extensions && i < extensions.length; ++i)
+ this._manager._extensions.push(new WebInspector.ModuleManager.Extension(this, extensions[i]));
+ this._loaded = false;
+}
+
+WebInspector.ModuleManager.Module.prototype = {
+ /**
+ * @return {string}
+ */
+ name: function()
+ {
+ return this._name;
+ },
+
+ _load: function()
+ {
+ if (this._loaded)
+ return;
+
+ if (this._isLoading) {
+ var oldStackTraceLimit = Error.stackTraceLimit;
+ Error.stackTraceLimit = 50;
+ console.assert(false, "Module " + this._name + " is loaded from itself: " + new Error().stack);
+ Error.stackTraceLimit = oldStackTraceLimit;
+ return;
+ }
+
+ this._isLoading = true;
+ var dependencies = this._descriptor.dependencies;
+ for (var i = 0; dependencies && i < dependencies.length; ++i)
+ this._manager.loadModule(dependencies[i]);
+ var scripts = this._descriptor.scripts;
+ for (var i = 0; scripts && i < scripts.length; ++i)
+ loadScript(this._name + "/" + scripts[i]);
+ this._isLoading = false;
+ this._loaded = true;
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.ModuleManager.Module} module
+ * @param {!WebInspector.ModuleManager.ExtensionDescriptor} descriptor
+ */
+WebInspector.ModuleManager.Extension = function(module, descriptor)
+{
+ this._module = module;
+ this._descriptor = descriptor;
+
+ this._type = descriptor.type;
+ this._hasTypeClass = !!this._type.startsWith("@");
+
+ /**
+ * @type {?string}
+ */
+ this._className = descriptor.className || null;
+}
+
+WebInspector.ModuleManager.Extension.prototype = {
+ /**
+ * @return {!Object}
+ */
+ descriptor: function()
+ {
+ return this._descriptor;
+ },
+
+ /**
+ * @return {!WebInspector.ModuleManager.Module}
+ */
+ module: function()
+ {
+ return this._module;
+ },
+
+ /**
+ * @return {?function(new:Object)}
+ */
+ _typeClass: function()
+ {
+ if (!this._hasTypeClass)
+ return null;
+ return this._module._manager._resolve(this._type.substring(1));
+ },
+
+ /**
+ * @param {?Object} context
+ * @return {boolean}
+ */
+ isApplicable: function(context)
+ {
+ return this._module._manager.isExtensionApplicableToContext(this, context);
+ },
+
+ /**
+ * @return {?Object}
+ */
+ instance: function()
+ {
+ if (!this._className)
+ return null;
+
+ if (!this._instance) {
+ this._module._load();
+
+ var constructorFunction = window.eval(this._className);
+ if (!(constructorFunction instanceof Function))
+ return null;
+
+ this._instance = new constructorFunction();
+ }
+ return this._instance;
+ }
+}
+
+/**
+ * @interface
+ */
+WebInspector.Renderer = function()
+{
+}
+
+WebInspector.Renderer.prototype = {
+ /**
+ * @param {!Object} object
+ * @return {?Element}
+ */
+ render: function(object) {}
+}
+
+/**
+ * @interface
+ */
+WebInspector.Revealer = function()
+{
+}
+
+/**
+ * @param {?Object} revealable
+ * @param {number=} lineNumber
+ */
+WebInspector.Revealer.reveal = function(revealable, lineNumber)
+{
+ if (!revealable)
+ return;
+ var revealer = WebInspector.moduleManager.instance(WebInspector.Revealer, revealable);
+ if (revealer)
+ revealer.reveal(revealable, lineNumber);
+}
+
+WebInspector.Revealer.prototype = {
+ /**
+ * @param {!Object} object
+ */
+ reveal: function(object) {}
+}
+
+WebInspector.moduleManager = new WebInspector.ModuleManager(allDescriptors);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Object.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Object.js
index 9544e0d8f11..20268738297 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Object.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Object.js
@@ -61,10 +61,8 @@ WebInspector.Object.prototype = {
return;
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
- if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
- listeners.splice(i, 1);
- else if (!listener && thisObject && listeners[i].thisObject === thisObject)
- listeners.splice(i, 1);
+ if (listeners[i].listener === listener && listeners[i].thisObject === thisObject)
+ listeners.splice(i--, 1);
}
if (!listeners.length)
@@ -147,6 +145,51 @@ WebInspector.Event.prototype = {
}
/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.Lock = function()
+{
+ this._count = 0; // Reentrant.
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.Lock.Events = {
+ StateChanged: "StateChanged"
+}
+
+WebInspector.Lock.prototype = {
+ /**
+ * @return {boolean}
+ */
+ isAcquired: function()
+ {
+ return !!this._count;
+ },
+
+ acquire: function()
+ {
+ if (++this._count === 1)
+ this.dispatchEventToListeners(WebInspector.Lock.Events.StateChanged);
+ },
+
+ release: function()
+ {
+ --this._count;
+ if (this._count < 0) {
+ console.error("WebInspector.Lock acquire/release calls are unbalanced " + new Error().stack);
+ return;
+ }
+ if (!this._count)
+ this.dispatchEventToListeners(WebInspector.Lock.Events.StateChanged);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
* @interface
*/
WebInspector.EventTarget = function()
@@ -183,5 +226,3 @@ WebInspector.EventTarget.prototype = {
*/
dispatchEventToListeners: function(eventType, eventData) { },
}
-
-WebInspector.notifications = new WebInspector.Object();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ParsedURL.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js
index 046094dd170..6f5d66f245f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ParsedURL.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/ParsedURL.js
@@ -111,8 +111,11 @@ WebInspector.ParsedURL.splitURL = function(url)
}
var result = [origin];
var splittedPath = folderPath.split("/");
- for (var i = 1; i < splittedPath.length; ++i)
+ for (var i = 1; i < splittedPath.length; ++i) {
+ if (!splittedPath[i])
+ continue;
result.push(splittedPath[i]);
+ }
result.push(name);
return result;
}
@@ -229,15 +232,16 @@ WebInspector.ParsedURL.prototype = {
return this.url;
this._displayName = this.lastPathComponent;
- if (!this._displayName && this.host)
- this._displayName = this.host + "/";
- if (!this._displayName && this.url)
- this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
+ if (!this._displayName)
+ this._displayName = (this.host || "") + "/";
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
},
+ /**
+ * @return {string}
+ */
dataURLDisplayName: function()
{
if (this._dataURLDisplayName)
@@ -248,11 +252,17 @@ WebInspector.ParsedURL.prototype = {
return this._dataURLDisplayName;
},
+ /**
+ * @return {boolean}
+ */
isAboutBlank: function()
{
return this.url === "about:blank";
},
+ /**
+ * @return {boolean}
+ */
isDataURL: function()
{
return this.scheme === "data";
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/Platform.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Platform.js
new file mode 100644
index 00000000000..5e11b794306
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Platform.js
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @return {string}
+ */
+WebInspector.platform = function()
+{
+ if (!WebInspector._platform)
+ WebInspector._platform = InspectorFrontendHost.platform();
+ return WebInspector._platform;
+}
+
+/**
+ * @return {boolean}
+ */
+WebInspector.isMac = function()
+{
+ if (typeof WebInspector._isMac === "undefined")
+ WebInspector._isMac = WebInspector.platform() === "mac";
+
+ return WebInspector._isMac;
+}
+
+/**
+ * @return {boolean}
+ */
+WebInspector.isWin = function()
+{
+ if (typeof WebInspector._isWin === "undefined")
+ WebInspector._isWin = WebInspector.platform() === "windows";
+
+ return WebInspector._isWin;
+}
+
+WebInspector.PlatformFlavor = {
+ WindowsVista: "windows-vista",
+ MacTiger: "mac-tiger",
+ MacLeopard: "mac-leopard",
+ MacSnowLeopard: "mac-snowleopard",
+ MacLion: "mac-lion"
+}
+
+/**
+ * @return {string}
+ */
+WebInspector.platformFlavor = function()
+{
+ function detectFlavor()
+ {
+ const userAgent = navigator.userAgent;
+
+ if (WebInspector.platform() === "windows") {
+ var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
+ if (match && match[1] >= 6)
+ return WebInspector.PlatformFlavor.WindowsVista;
+ return null;
+ } else if (WebInspector.platform() === "mac") {
+ var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
+ if (!match || match[1] != 10)
+ return WebInspector.PlatformFlavor.MacSnowLeopard;
+ switch (Number(match[2])) {
+ case 4:
+ return WebInspector.PlatformFlavor.MacTiger;
+ case 5:
+ return WebInspector.PlatformFlavor.MacLeopard;
+ case 6:
+ return WebInspector.PlatformFlavor.MacSnowLeopard;
+ case 7:
+ return WebInspector.PlatformFlavor.MacLion;
+ case 8: // Matches the default version
+ case 9: // Matches the default version
+ default:
+ return "";
+ }
+ }
+ }
+
+ if (!WebInspector._platformFlavor)
+ WebInspector._platformFlavor = detectFlavor();
+
+ return WebInspector._platformFlavor;
+}
+
+/**
+ * @return {string}
+ */
+WebInspector.port = function()
+{
+ if (!WebInspector._port)
+ WebInspector._port = InspectorFrontendHost.port();
+
+ return WebInspector._port;
+}
+
+/**
+ * @return {string}
+ */
+WebInspector.fontFamily = function()
+{
+ if (WebInspector._fontFamily)
+ return WebInspector._fontFamily;
+ switch (WebInspector.platform()) {
+ case "linux":
+ WebInspector._fontFamily = "Ubuntu, Arial, sans-serif";
+ break;
+ case "mac":
+ WebInspector._fontFamily = "'Lucida Grande', sans-serif";
+ break;
+ case "windows":
+ WebInspector._fontFamily = "'Segoe UI', Tahoma, sans-serif";
+ break;
+ }
+ return WebInspector._fontFamily;
+}
+
+/**
+ * @return {string}
+ */
+WebInspector.monospaceFontFamily = function()
+{
+ if (WebInspector._monospaceFontFamily)
+ return WebInspector._monospaceFontFamily;
+ switch (WebInspector.platform()) {
+ case "linux":
+ WebInspector._monospaceFontFamily = "dejavu sans mono, monospace";
+ break;
+ case "mac":
+ WebInspector._monospaceFontFamily = "Menlo, monospace";
+ break;
+ case "windows":
+ WebInspector._monospaceFontFamily = "Consolas, monospace";
+ break;
+ }
+ return WebInspector._monospaceFontFamily;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Progress.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Progress.js
index ce709eb5aa6..7e01366c489 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Progress.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Progress.js
@@ -37,7 +37,8 @@ WebInspector.Progress = function()
}
WebInspector.Progress.Events = {
- Canceled: "Canceled"
+ Canceled: "Canceled",
+ Done: "Done"
}
WebInspector.Progress.prototype = {
@@ -95,8 +96,10 @@ WebInspector.CompositeProgress = function(parent)
WebInspector.CompositeProgress.prototype = {
_childDone: function()
{
- if (++this._childrenDone === this._children.length)
- this._parent.done();
+ if (++this._childrenDone !== this._children.length)
+ return;
+ this.dispatchEventToListeners(WebInspector.Progress.Events.Done);
+ this._parent.done();
},
_parentCanceled: function()
@@ -109,6 +112,7 @@ WebInspector.CompositeProgress.prototype = {
/**
* @param {number=} weight
+ * @return {!WebInspector.SubProgress}
*/
createSubProgress: function(weight)
{
@@ -169,6 +173,7 @@ WebInspector.SubProgress.prototype = {
{
this.setWorked(this._totalWork);
this._composite._childDone();
+ this.dispatchEventToListeners(WebInspector.Progress.Events.Done);
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Settings.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Settings.js
index 9b390ad1bd9..b1d7b42e1fb 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Settings.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Settings.js
@@ -28,22 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-var Preferences = {
- maxInlineTextChildLength: 80,
- minConsoleHeight: 25,
- minSidebarWidth: 100,
- minSidebarHeight: 75,
- minElementsSidebarWidth: 200,
- minElementsSidebarHeight: 200,
- minScriptsSidebarWidth: 200,
- applicationTitle: "Developer Tools - %s",
- experimentsEnabled: false
-}
-
var Capabilities = {
- canInspectWorkers: false,
- canScreencast: false
+ isMainFrontend: false,
+ canProfilePower: false,
}
/**
@@ -61,6 +48,7 @@ WebInspector.Settings = function()
this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
+ this.consoleTimestampsEnabled = this.createSetting("consoleTimestampsEnabled", false);
this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
@@ -74,21 +62,9 @@ WebInspector.Settings = function()
this.jsSourceMapsEnabled = this.createSetting("sourceMapsEnabled", true);
this.cssSourceMapsEnabled = this.createSetting("cssSourceMapsEnabled", true);
this.cacheDisabled = this.createSetting("cacheDisabled", false);
- this.overrideUserAgent = this.createSetting("overrideUserAgent", false);
- this.userAgent = this.createSetting("userAgent", "");
- this.overrideDeviceMetrics = this.createSetting("overrideDeviceMetrics", false);
- this.deviceMetrics = this.createSetting("deviceMetrics", "");
- this.deviceFitWindow = this.createSetting("deviceFitWindow", true);
- this.emulateViewport = this.createSetting("emulateViewport", false);
- this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
- this.showShadowDOM = this.createSetting("showShadowDOM", false);
- this.zoomLevel = this.createSetting("zoomLevel", 0);
+ this.showUAShadowDOM = this.createSetting("showUAShadowDOM", false);
this.savedURLs = this.createSetting("savedURLs", {});
this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
- this.overrideGeolocation = this.createSetting("overrideGeolocation", false);
- this.geolocationOverride = this.createSetting("geolocationOverride", "");
- this.overrideDeviceOrientation = this.createSetting("overrideDeviceOrientation", false);
- this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
this.showAdvancedHeapSnapshotProperties = this.createSetting("showAdvancedHeapSnapshotProperties", false);
this.highResolutionCpuProfiling = this.createSetting("highResolutionCpuProfiling", false);
this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
@@ -96,28 +72,25 @@ WebInspector.Settings = function()
this.textEditorAutoDetectIndent = this.createSetting("textEditorAutoIndentIndent", true);
this.textEditorAutocompletion = this.createSetting("textEditorAutocompletion", true);
this.textEditorBracketMatching = this.createSetting("textEditorBracketMatching", true);
- this.lastDockState = this.createSetting("lastDockState", "");
this.cssReloadEnabled = this.createSetting("cssReloadEnabled", false);
- this.timelineCaptureStacks = this.createSetting("timelineCaptureStacks", true);
+ this.timelineLiveUpdate = this.createSetting("timelineLiveUpdate", true);
this.showMetricsRulers = this.createSetting("showMetricsRulers", false);
- this.overrideCSSMedia = this.createSetting("overrideCSSMedia", false);
- this.emulatedCSSMedia = this.createSetting("emulatedCSSMedia", "print");
this.workerInspectorWidth = this.createSetting("workerInspectorWidth", 600);
this.workerInspectorHeight = this.createSetting("workerInspectorHeight", 600);
this.messageURLFilters = this.createSetting("messageURLFilters", {});
this.networkHideDataURL = this.createSetting("networkHideDataURL", false);
+ this.networkResourceTypeFilters = this.createSetting("networkResourceTypeFilters", {});
this.messageLevelFilters = this.createSetting("messageLevelFilters", {});
this.splitVerticallyWhenDockedToRight = this.createSetting("splitVerticallyWhenDockedToRight", true);
this.visiblePanels = this.createSetting("visiblePanels", {});
this.shortcutPanelSwitch = this.createSetting("shortcutPanelSwitch", false);
this.showWhitespacesInEditor = this.createSetting("showWhitespacesInEditor", false);
this.skipStackFramesSwitch = this.createSetting("skipStackFramesSwitch", false);
- this.skipStackFramesPattern = this.createSetting("skipStackFramesPattern", "");
- this.screencastEnabled = this.createSetting("screencastEnabled", false);
- this.screencastSidebarWidth = this.createSetting("screencastSidebarWidth", 300);
- this.showEmulationViewInDrawer = this.createSetting("showEmulationViewInDrawer", true);
- this.showRenderingViewInDrawer = this.createSetting("showRenderingViewInDrawer", true);
+ this.skipStackFramesPattern = this.createRegExpSetting("skipStackFramesPattern", "");
+ this.pauseOnExceptionEnabled = this.createSetting("pauseOnExceptionEnabled", false);
+ this.pauseOnCaughtException = this.createSetting("pauseOnCaughtException", false);
this.enableAsyncStackTraces = this.createSetting("enableAsyncStackTraces", false);
+ this.showMediaQueryInspector = this.createSetting("showMediaQueryInspector", false);
}
WebInspector.Settings.prototype = {
@@ -135,6 +108,19 @@ WebInspector.Settings.prototype = {
/**
* @param {string} key
+ * @param {string} defaultValue
+ * @param {string=} regexFlags
+ * @return {!WebInspector.Setting}
+ */
+ createRegExpSetting: function(key, defaultValue, regexFlags)
+ {
+ if (!this._registry[key])
+ this._registry[key] = new WebInspector.RegExpSetting(key, defaultValue, this._eventSupport, window.localStorage, regexFlags);
+ return this._registry[key];
+ },
+
+ /**
+ * @param {string} key
* @param {*} defaultValue
* @param {function(*, function(string, ...))} setterCallback
* @return {!WebInspector.Setting}
@@ -144,15 +130,25 @@ WebInspector.Settings.prototype = {
if (!this._registry[key])
this._registry[key] = new WebInspector.BackendSetting(key, defaultValue, this._eventSupport, window.localStorage, setterCallback);
return this._registry[key];
+ },
+
+ initializeBackendSettings: function()
+ {
+ this.showPaintRects = WebInspector.settings.createBackendSetting("showPaintRects", false, PageAgent.setShowPaintRects.bind(PageAgent));
+ this.showDebugBorders = WebInspector.settings.createBackendSetting("showDebugBorders", false, PageAgent.setShowDebugBorders.bind(PageAgent));
+ this.continuousPainting = WebInspector.settings.createBackendSetting("continuousPainting", false, PageAgent.setContinuousPaintingEnabled.bind(PageAgent));
+ this.showFPSCounter = WebInspector.settings.createBackendSetting("showFPSCounter", false, PageAgent.setShowFPSCounter.bind(PageAgent));
+ this.showScrollBottleneckRects = WebInspector.settings.createBackendSetting("showScrollBottleneckRects", false, PageAgent.setShowScrollBottleneckRects.bind(PageAgent));
}
}
/**
* @constructor
* @param {string} name
- * @param {*} defaultValue
+ * @param {V} defaultValue
* @param {!WebInspector.Object} eventSupport
* @param {?Storage} storage
+ * @template V
*/
WebInspector.Setting = function(name, defaultValue, eventSupport, storage)
{
@@ -186,6 +182,9 @@ WebInspector.Setting.prototype = {
return this._name;
},
+ /**
+ * @return {V}
+ */
get: function()
{
if (typeof this._value !== "undefined")
@@ -220,6 +219,46 @@ WebInspector.Setting.prototype = {
* @constructor
* @extends {WebInspector.Setting}
* @param {string} name
+ * @param {string} defaultValue
+ * @param {!WebInspector.Object} eventSupport
+ * @param {?Storage} storage
+ * @param {string=} regexFlags
+ */
+WebInspector.RegExpSetting = function(name, defaultValue, eventSupport, storage, regexFlags)
+{
+ WebInspector.Setting.call(this, name, defaultValue, eventSupport, storage);
+ this._regexFlags = regexFlags;
+}
+
+WebInspector.RegExpSetting.prototype = {
+ set: function(value)
+ {
+ delete this._regex;
+ WebInspector.Setting.prototype.set.call(this, value);
+ },
+
+ /**
+ * @return {?RegExp}
+ */
+ asRegExp: function()
+ {
+ if (typeof this._regex !== "undefined")
+ return this._regex;
+ this._regex = null;
+ try {
+ this._regex = new RegExp(this.get(), this._regexFlags || "");
+ } catch (e) {
+ }
+ return this._regex;
+ },
+
+ __proto__: WebInspector.Setting.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Setting}
+ * @param {string} name
* @param {*} defaultValue
* @param {!WebInspector.Object} eventSupport
* @param {?Storage} storage
@@ -244,7 +283,7 @@ WebInspector.BackendSetting.prototype = {
function callback(error)
{
if (error) {
- WebInspector.log("Error applying setting " + this._name + ": " + error);
+ WebInspector.messageSink.addErrorMessage("Error applying setting " + this._name + ": " + error);
this._eventSupport.dispatchEventToListeners(this._name, this._value);
return;
}
@@ -254,29 +293,41 @@ WebInspector.BackendSetting.prototype = {
},
__proto__: WebInspector.Setting.prototype
-};
+}
/**
* @constructor
+ * @param {boolean} experimentsEnabled
*/
-WebInspector.ExperimentsSettings = function()
+WebInspector.ExperimentsSettings = function(experimentsEnabled)
{
+ this._experimentsEnabled = experimentsEnabled;
this._setting = WebInspector.settings.createSetting("experiments", {});
this._experiments = [];
this._enabledForTest = {};
// Add currently running experiments here.
- this.asyncStackTraces = this._createExperiment("asyncStackTraces", "Enable support for async stack traces");
- this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
- this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection");
- this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support");
- this.frameworksDebuggingSupport = this._createExperiment("frameworksDebuggingSupport", "Enable frameworks debugging support");
- this.layersPanel = this._createExperiment("layersPanel", "Show Layers panel");
- this.stepIntoSelection = this._createExperiment("stepIntoSelection", "Show step-in candidates while debugging.");
- this.doNotOpenDrawerOnEsc = this._createExperiment("doNotOpenDrawerWithEsc", "Do not open drawer on Esc");
- this.showEditorInDrawer = this._createExperiment("showEditorInDrawer", "Show editor in drawer");
- this.gpuTimeline = this._createExperiment("gpuTimeline", "Show GPU data on timeline");
this.applyCustomStylesheet = this._createExperiment("applyCustomStylesheet", "Allow custom UI themes");
+ this.canvasInspection = this._createExperiment("canvasInspection ", "Canvas inspection");
+ this.devicesPanel = this._createExperiment("devicesPanel", "Devices panel", true);
+ this.disableAgentsWhenProfile = this._createExperiment("disableAgentsWhenProfile", "Disable other agents and UI when profiler is active", true);
+ this.dockToLeft = this._createExperiment("dockToLeft", "Dock to left", true);
+ this.editorInDrawer = this._createExperiment("showEditorInDrawer", "Editor in drawer", true);
+ this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
+ this.frameworksDebuggingSupport = this._createExperiment("frameworksDebuggingSupport", "JavaScript frameworks debugging");
+ this.gpuTimeline = this._createExperiment("gpuTimeline", "GPU data on timeline", true);
+ this.heapAllocationProfiler = this._createExperiment("allocationProfiler", "Heap allocation profiler");
+ this.heapSnapshotStatistics = this._createExperiment("heapSnapshotStatistics", "Heap snapshot statistics", true);
+ this.layersPanel = this._createExperiment("layersPanel", "Layers panel", true);
+ this.networkConditions = this._createExperiment("networkConditions", "Network conditions", true);
+ this.responsiveDesign = this._createExperiment("responsiveDesign", "Responsive design");
+ this.timelineFlameChart = this._createExperiment("timelineFlameChart", "Timeline flame chart");
+ this.timelineOnTraceEvents = this._createExperiment("timelineOnTraceEvents", "Timeline on trace events", true);
+ this.timelinePowerProfiler = this._createExperiment("timelinePowerProfiler", "Timeline power profiler");
+ this.timelineTracingMode = this._createExperiment("timelineTracingMode", "Timeline tracing mode");
+ this.timelineJSCPUProfile = this._createExperiment("timelineJSCPUProfile", "Timeline with JS sampling");
+ this.timelineNoLiveUpdate = this._createExperiment("timelineNoLiveUpdate", "Timeline w/o live update", true);
+ this.workersInMainWindow = this._createExperiment("workersInMainWindow", "Workers in main window", true);
this._cleanUpSetting();
}
@@ -295,17 +346,18 @@ WebInspector.ExperimentsSettings.prototype = {
*/
get experimentsEnabled()
{
- return Preferences.experimentsEnabled || ("experiments" in WebInspector.queryParamsObject);
+ return this._experimentsEnabled;
},
/**
* @param {string} experimentName
* @param {string} experimentTitle
+ * @param {boolean=} hidden
* @return {!WebInspector.Experiment}
*/
- _createExperiment: function(experimentName, experimentTitle)
+ _createExperiment: function(experimentName, experimentTitle, hidden)
{
- var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
+ var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle, !!hidden);
this._experiments.push(experiment);
return experiment;
},
@@ -363,11 +415,13 @@ WebInspector.ExperimentsSettings.prototype = {
* @param {!WebInspector.ExperimentsSettings} experimentsSettings
* @param {string} name
* @param {string} title
+ * @param {boolean} hidden
*/
-WebInspector.Experiment = function(experimentsSettings, name, title)
+WebInspector.Experiment = function(experimentsSettings, name, title, hidden)
{
this._name = name;
this._title = title;
+ this._hidden = hidden;
this._experimentsSettings = experimentsSettings;
}
@@ -391,6 +445,14 @@ WebInspector.Experiment.prototype = {
/**
* @return {boolean}
*/
+ get hidden()
+ {
+ return this._hidden;
+ },
+
+ /**
+ * @return {boolean}
+ */
isEnabled: function()
{
return this._experimentsSettings.isEnabled(this._name);
@@ -401,7 +463,7 @@ WebInspector.Experiment.prototype = {
*/
setEnabled: function(enabled)
{
- return this._experimentsSettings.setEnabled(this._name, enabled);
+ this._experimentsSettings.setEnabled(this._name, enabled);
},
enableForTest: function()
@@ -417,7 +479,7 @@ WebInspector.VersionController = function()
{
}
-WebInspector.VersionController.currentVersion = 4;
+WebInspector.VersionController.currentVersion = 8;
WebInspector.VersionController.prototype = {
updateVersion: function()
@@ -468,6 +530,142 @@ WebInspector.VersionController.prototype = {
WebInspector.settings.showAdvancedHeapSnapshotProperties.set(advancedMode);
},
+ _updateVersionFrom4To5: function()
+ {
+ if (!window.localStorage)
+ return;
+ var settingNames = {
+ "FileSystemViewSidebarWidth": "fileSystemViewSplitViewState",
+ "canvasProfileViewReplaySplitLocation": "canvasProfileViewReplaySplitViewState",
+ "canvasProfileViewSplitLocation": "canvasProfileViewSplitViewState",
+ "elementsSidebarWidth": "elementsPanelSplitViewState",
+ "StylesPaneSplitRatio": "stylesPaneSplitViewState",
+ "heapSnapshotRetainersViewSize": "heapSnapshotSplitViewState",
+ "InspectorView.splitView": "InspectorView.splitViewState",
+ "InspectorView.screencastSplitView": "InspectorView.screencastSplitViewState",
+ "Inspector.drawerSplitView": "Inspector.drawerSplitViewState",
+ "layerDetailsSplitView": "layerDetailsSplitViewState",
+ "networkSidebarWidth": "networkPanelSplitViewState",
+ "sourcesSidebarWidth": "sourcesPanelSplitViewState",
+ "scriptsPanelNavigatorSidebarWidth": "sourcesPanelNavigatorSplitViewState",
+ "sourcesPanelSplitSidebarRatio": "sourcesPanelDebuggerSidebarSplitViewState",
+ "timeline-details": "timelinePanelDetailsSplitViewState",
+ "timeline-split": "timelinePanelRecorsSplitViewState",
+ "timeline-view": "timelinePanelTimelineStackSplitViewState",
+ "auditsSidebarWidth": "auditsPanelSplitViewState",
+ "layersSidebarWidth": "layersPanelSplitViewState",
+ "profilesSidebarWidth": "profilesPanelSplitViewState",
+ "resourcesSidebarWidth": "resourcesPanelSplitViewState"
+ };
+ for (var oldName in settingNames) {
+ var newName = settingNames[oldName];
+ var oldNameH = oldName + "H";
+
+ var newValue = null;
+ var oldSetting = WebInspector.settings.createSetting(oldName, undefined).get();
+ if (oldSetting) {
+ newValue = newValue || {};
+ newValue.vertical = {};
+ newValue.vertical.size = oldSetting;
+ delete window.localStorage[oldName];
+ }
+ var oldSettingH = WebInspector.settings.createSetting(oldNameH, undefined).get();
+ if (oldSettingH) {
+ newValue = newValue || {};
+ newValue.horizontal = {};
+ newValue.horizontal.size = oldSettingH;
+ delete window.localStorage[oldNameH];
+ }
+ var newSetting = WebInspector.settings.createSetting(newName, {});
+ if (newValue)
+ newSetting.set(newValue);
+ }
+ },
+
+ _updateVersionFrom5To6: function()
+ {
+ if (!window.localStorage)
+ return;
+
+ var settingNames = {
+ "debuggerSidebarHidden": "sourcesPanelSplitViewState",
+ "navigatorHidden": "sourcesPanelNavigatorSplitViewState",
+ "WebInspector.Drawer.showOnLoad": "Inspector.drawerSplitViewState"
+ };
+
+ for (var oldName in settingNames) {
+ var newName = settingNames[oldName];
+
+ var oldSetting = WebInspector.settings.createSetting(oldName, undefined).get();
+ var invert = "WebInspector.Drawer.showOnLoad" === oldName;
+ var hidden = !!oldSetting !== invert;
+ delete window.localStorage[oldName];
+ var showMode = hidden ? "OnlyMain" : "Both";
+
+ var newSetting = WebInspector.settings.createSetting(newName, null);
+ var newValue = newSetting.get() || {};
+ newValue.vertical = newValue.vertical || {};
+ newValue.vertical.showMode = showMode;
+ newValue.horizontal = newValue.horizontal || {};
+ newValue.horizontal.showMode = showMode;
+ newSetting.set(newValue);
+ }
+ },
+
+ _updateVersionFrom6To7: function()
+ {
+ if (!window.localStorage)
+ return;
+
+ var settingNames = {
+ "sourcesPanelNavigatorSplitViewState": "sourcesPanelNavigatorSplitViewState",
+ "elementsPanelSplitViewState": "elementsPanelSplitViewState",
+ "canvasProfileViewReplaySplitViewState": "canvasProfileViewReplaySplitViewState",
+ "editorInDrawerSplitViewState": "editorInDrawerSplitViewState",
+ "stylesPaneSplitViewState": "stylesPaneSplitViewState",
+ "sourcesPanelDebuggerSidebarSplitViewState": "sourcesPanelDebuggerSidebarSplitViewState"
+ };
+
+ for (var name in settingNames) {
+ if (!(name in window.localStorage))
+ continue;
+ var setting = WebInspector.settings.createSetting(name, undefined);
+ var value = setting.get();
+ if (!value)
+ continue;
+ // Zero out saved percentage sizes, and they will be restored to defaults.
+ if (value.vertical && value.vertical.size && value.vertical.size < 1)
+ value.vertical.size = 0;
+ if (value.horizontal && value.horizontal.size && value.horizontal.size < 1)
+ value.horizontal.size = 0;
+ setting.set(value);
+ }
+ },
+
+ _updateVersionFrom7To8: function()
+ {
+ var settingName = "deviceMetrics";
+ if (!window.localStorage || !(settingName in window.localStorage))
+ return;
+ var setting = WebInspector.settings.createSetting(settingName, undefined);
+ var value = setting.get();
+ if (!value)
+ return;
+
+ var components = value.split("x");
+ if (components.length >= 3) {
+ var width = parseInt(components[0], 10);
+ var height = parseInt(components[1], 10);
+ var deviceScaleFactor = parseFloat(components[2]);
+ if (deviceScaleFactor) {
+ components[0] = "" + Math.round(width / deviceScaleFactor);
+ components[1] = "" + Math.round(height / deviceScaleFactor);
+ }
+ }
+ value = components.join("x");
+ setting.set(value);
+ },
+
/**
* @param {!WebInspector.Setting} breakpointsSetting
* @param {number} maxBreakpointsCount
@@ -481,5 +679,87 @@ WebInspector.VersionController.prototype = {
}
}
-WebInspector.settings = new WebInspector.Settings();
-WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();
+/**
+ * @type {!WebInspector.Settings}
+ */
+WebInspector.settings;
+
+/**
+ * @type {!WebInspector.ExperimentsSettings}
+ */
+WebInspector.experimentsSettings;
+
+// These methods are added for backwards compatibility with Devtools CodeSchool extension.
+// DO NOT REMOVE
+
+/**
+ * @constructor
+ */
+WebInspector.PauseOnExceptionStateSetting = function()
+{
+ WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._enabledChanged, this);
+ WebInspector.settings.pauseOnCaughtException.addChangeListener(this._pauseOnCaughtChanged, this);
+ this._name = "pauseOnExceptionStateString";
+ this._eventSupport = new WebInspector.Object();
+ this._value = this._calculateValue();
+}
+
+WebInspector.PauseOnExceptionStateSetting.prototype = {
+ /**
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ addChangeListener: function(listener, thisObject)
+ {
+ this._eventSupport.addEventListener(this._name, listener, thisObject);
+ },
+
+ /**
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ removeChangeListener: function(listener, thisObject)
+ {
+ this._eventSupport.removeEventListener(this._name, listener, thisObject);
+ },
+
+ /**
+ * @return {string}
+ */
+ get: function()
+ {
+ return this._value;
+ },
+
+ /**
+ * @return {string}
+ */
+ _calculateValue: function()
+ {
+ if (!WebInspector.settings.pauseOnExceptionEnabled.get())
+ return "none";
+ // The correct code here would be
+ // return WebInspector.settings.pauseOnCaughtException.get() ? "all" : "uncaught";
+ // But the CodeSchool DevTools relies on the fact that we used to enable pausing on ALL extensions by default, so we trick it here.
+ return "all";
+ },
+
+ _enabledChanged: function(event)
+ {
+ this._fireChangedIfNeeded();
+ },
+
+ _pauseOnCaughtChanged: function(event)
+ {
+ this._fireChangedIfNeeded();
+ },
+
+ _fireChangedIfNeeded: function()
+ {
+ var newValue = this._calculateValue();
+ if (newValue === this._value)
+ return;
+ this._value = newValue;
+ this._eventSupport.dispatchEventToListeners(this._name, this._value);
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TextRange.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/TextRange.js
index 01b093e10e5..3639fb8ec63 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TextRange.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/TextRange.js
@@ -43,6 +43,11 @@ WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
this.endColumn = endColumn;
}
+/**
+ * @param {number} line
+ * @param {number} column
+ * @return {!WebInspector.TextRange}
+ */
WebInspector.TextRange.createFromLocation = function(line, column)
{
return new WebInspector.TextRange(line, column, line, column);
@@ -57,6 +62,16 @@ WebInspector.TextRange.fromObject = function(serializedTextRange)
return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
}
+/**
+ * @param {!WebInspector.TextRange} range1
+ * @param {!WebInspector.TextRange} range2
+ * @return {number}
+ */
+WebInspector.TextRange.comparator = function(range1, range2)
+{
+ return range1.compareTo(range2);
+}
+
WebInspector.TextRange.prototype = {
/**
* @return {boolean}
@@ -89,6 +104,16 @@ WebInspector.TextRange.prototype = {
},
/**
+ * @param {!WebInspector.TextRange} range
+ * @return {boolean}
+ */
+ follows: function(range)
+ {
+ return (range.endLine === this.startLine && range.endColumn <= this.startColumn)
+ || range.endLine < this.startLine;
+ },
+
+ /**
* @return {number}
*/
get linesCount()
@@ -96,6 +121,9 @@ WebInspector.TextRange.prototype = {
return this.endLine - this.startLine;
},
+ /**
+ * @return {!WebInspector.TextRange}
+ */
collapseToEnd: function()
{
return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
@@ -104,6 +132,14 @@ WebInspector.TextRange.prototype = {
/**
* @return {!WebInspector.TextRange}
*/
+ collapseToStart: function()
+ {
+ return new WebInspector.TextRange(this.startLine, this.startColumn, this.startLine, this.startColumn);
+ },
+
+ /**
+ * @return {!WebInspector.TextRange}
+ */
normalize: function()
{
if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
@@ -151,6 +187,16 @@ WebInspector.TextRange.prototype = {
},
/**
+ * @param {!WebInspector.TextRange} other
+ * @return {boolean}
+ */
+ equal: function(other)
+ {
+ return this.startLine === other.startLine && this.endLine === other.endLine &&
+ this.startColumn === other.startColumn && this.endColumn === other.endColumn;
+ },
+
+ /**
* @param {number} lineOffset
* @return {!WebInspector.TextRange}
*/
@@ -159,6 +205,32 @@ WebInspector.TextRange.prototype = {
return new WebInspector.TextRange(this.startLine + lineOffset, this.startColumn, this.endLine + lineOffset, this.endColumn);
},
+ /**
+ * @param {!WebInspector.TextRange} originalRange
+ * @param {!WebInspector.TextRange} editedRange
+ * @return {!WebInspector.TextRange}
+ */
+ rebaseAfterTextEdit: function(originalRange, editedRange)
+ {
+ console.assert(originalRange.startLine === editedRange.startLine);
+ console.assert(originalRange.startColumn === editedRange.startColumn);
+ var rebase = this.clone();
+ if (!this.follows(originalRange))
+ return rebase;
+ var lineDelta = editedRange.endLine - originalRange.endLine;
+ var columnDelta = editedRange.endColumn - originalRange.endColumn;
+ rebase.startLine += lineDelta;
+ rebase.endLine += lineDelta;
+ if (rebase.startLine === editedRange.endLine)
+ rebase.startColumn += columnDelta;
+ if (rebase.endLine === editedRange.endLine)
+ rebase.endColumn += columnDelta;
+ return rebase;
+ },
+
+ /**
+ * @return {string}
+ */
toString: function()
{
return JSON.stringify(this);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/Throttler.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/Throttler.js
new file mode 100644
index 00000000000..398e03fd2c7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/Throttler.js
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @param {number} timeout
+ */
+WebInspector.Throttler = function(timeout)
+{
+ this._timeout = timeout;
+ this._isRunningProcess = false;
+ this._asSoonAsPossible = false;
+ /** @type {?function(!WebInspector.Throttler.FinishCallback)} */
+ this._process = null;
+}
+
+WebInspector.Throttler.prototype = {
+ _processCompleted: function()
+ {
+ this._isRunningProcess = false;
+ if (this._process)
+ this._innerSchedule(false);
+ },
+
+ _onTimeout: function()
+ {
+ delete this._processTimeout;
+ this._asSoonAsPossible = false;
+ this._isRunningProcess = true;
+
+ // Process might issue synchronous calls to this throttler.
+ var process = this._process;
+ this._process = null;
+ process(this._processCompleted.bind(this));
+ },
+
+ /**
+ * @param {function(!WebInspector.Throttler.FinishCallback)} process
+ * @param {boolean=} asSoonAsPossible
+ */
+ schedule: function(process, asSoonAsPossible)
+ {
+ // Deliberately skip previous process.
+ this._process = process;
+ var force = !!asSoonAsPossible && !this._asSoonAsPossible;
+ this._asSoonAsPossible = this._asSoonAsPossible || !!asSoonAsPossible;
+
+ this._innerSchedule(force);
+ },
+
+ /**
+ * @param {boolean} force
+ */
+ _innerSchedule: function(force)
+ {
+ if (this._isRunningProcess)
+ return;
+ if (this._processTimeout && !force)
+ return;
+ if (this._processTimeout)
+ this._clearTimeout(this._processTimeout);
+
+ var timeout = this._asSoonAsPossible ? 0 : this._timeout;
+ this._processTimeout = this._setTimeout(this._onTimeout.bind(this), timeout);
+ },
+
+ /**
+ * @param {number} timeoutId
+ */
+ _clearTimeout: function(timeoutId)
+ {
+ clearTimeout(timeoutId);
+ },
+
+ /**
+ * @param {function()} operation
+ * @param {number} timeout
+ * @return {number}
+ */
+ _setTimeout: function(operation, timeout)
+ {
+ return setTimeout(operation, timeout);
+ }
+}
+
+/** @typedef {function()} */
+WebInspector.Throttler.FinishCallback;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/UIString.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/UIString.js
index d676f25a174..d676f25a174 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/UIString.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/UIString.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/UserMetrics.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/UserMetrics.js
index 0c436adbcca..bbfecd097a1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/UserMetrics.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/UserMetrics.js
@@ -37,19 +37,6 @@ WebInspector.UserMetrics = function()
var actionCode = WebInspector.UserMetrics._ActionCodes[actionName];
this[actionName] = new WebInspector.UserMetrics._Recorder(actionCode);
}
-
- function settingChanged(trueCode, falseCode, event)
- {
- if (event.data)
- InspectorFrontendHost.recordSettingChanged(trueCode);
- else
- InspectorFrontendHost.recordSettingChanged(falseCode);
- }
-
- WebInspector.settings.domWordWrap.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOn, WebInspector.UserMetrics._SettingCodes.ElementsDOMWrapOff));
- WebInspector.settings.monitoringXHREnabled.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROn, WebInspector.UserMetrics._SettingCodes.ConsoleMonitorXHROff));
- WebInspector.settings.preserveConsoleLog.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOn, WebInspector.UserMetrics._SettingCodes.ConsolePreserveLogOff));
- WebInspector.settings.resourcesLargeRows.addChangeListener(settingChanged.bind(this, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOn, WebInspector.UserMetrics._SettingCodes.NetworkShowLargeRowsOff));
}
// Codes below are used to collect UMA histograms in the Chromium port.
@@ -67,17 +54,6 @@ WebInspector.UserMetrics._ActionCodes = {
ConsoleEvaluated: 8
}
-WebInspector.UserMetrics._SettingCodes = {
- ElementsDOMWrapOn: 1,
- ElementsDOMWrapOff: 2,
- ConsoleMonitorXHROn: 3,
- ConsoleMonitorXHROff: 4,
- ConsolePreserveLogOn: 5,
- ConsolePreserveLogOff: 6,
- NetworkShowLargeRowsOn: 7,
- NetworkShowLargeRowsOff: 8
-}
-
WebInspector.UserMetrics._PanelCodes = {
elements: 1,
resources: 2,
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/WebInspector.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/WebInspector.js
new file mode 100644
index 00000000000..73b4e80c905
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/WebInspector.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+window.WebInspector = {
+ _queryParamsObject: {}
+}
+
+WebInspector.Events = {
+ InspectorLoaded: "InspectorLoaded"
+}
+
+/**
+ * @param {string} name
+ * @return {?string}
+ */
+WebInspector.queryParam = function(name)
+{
+ return WebInspector._queryParamsObject.hasOwnProperty(name) ? WebInspector._queryParamsObject[name] : null;
+}
+
+{(function parseQueryParameters()
+{
+ var queryParams = window.location.search;
+ if (!queryParams)
+ return;
+ var params = queryParams.substring(1).split("&");
+ for (var i = 0; i < params.length; ++i) {
+ var pair = params[i].split("=");
+ WebInspector._queryParamsObject[pair[0]] = pair[1];
+ }
+
+ // Patch settings from the URL param (for tests).
+ var settingsParam = WebInspector.queryParam("settings");
+ if (settingsParam) {
+ try {
+ var settings = JSON.parse(window.decodeURI(settingsParam));
+ for (var key in settings)
+ window.localStorage[key] = settings[key];
+ } catch(e) {
+ // Ignore malformed settings.
+ }
+ }
+})();}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/common/modules.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/modules.js
new file mode 100644
index 00000000000..eeca510dd23
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/modules.js
@@ -0,0 +1 @@
+var allDescriptors = [];
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/utilities.js b/chromium/third_party/WebKit/Source/devtools/front_end/common/utilities.js
index 6ad96c6d079..fdb81dfb2c4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/utilities.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/common/utilities.js
@@ -53,6 +53,16 @@ Object.values = function(obj)
}
/**
+ * @param {number} m
+ * @param {number} n
+ * @return {number}
+ */
+function mod(m, n)
+{
+ return ((m % n) + n) % n;
+}
+
+/**
* @param {string} string
* @return {!Array.<number>}
*/
@@ -80,6 +90,29 @@ String.prototype.lineEndings = function()
}
/**
+ * @return {number}
+ */
+String.prototype.lineCount = function()
+{
+ var lineEndings = this.lineEndings();
+ return lineEndings.length;
+}
+
+/**
+ * @return {string}
+ */
+String.prototype.lineAt = function(lineNumber)
+{
+ var lineEndings = this.lineEndings();
+ var lineStart = lineNumber > 0 ? lineEndings[lineNumber - 1] + 1 : 0;
+ var lineEnd = lineEndings[lineNumber];
+ var lineContent = this.substring(lineStart, lineEnd);
+ if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === "\r")
+ lineContent = lineContent.substring(0, lineContent.length - 1);
+ return lineContent;
+}
+
+/**
* @param {string} chars
* @return {string}
*/
@@ -111,7 +144,7 @@ String.prototype.escapeCharacters = function(chars)
*/
String.regexSpecialCharacters = function()
{
- return "^[]{}()\\.$*+?|-,";
+ return "^[]{}()\\.^$*+?|-,";
}
/**
@@ -232,6 +265,17 @@ String.prototype.endsWith = function(substring)
}
/**
+ * @return {number}
+ */
+String.prototype.hashCode = function()
+{
+ var result = 0;
+ for (var i = 0; i < this.length; ++i)
+ result = result * 3 + this.charCodeAt(i);
+ return result;
+}
+
+/**
* @param {string} a
* @param {string} b
* @return {number}
@@ -336,28 +380,60 @@ Date.prototype.toISO8601Compact = function()
leadZero(this.getSeconds());
}
+/**
+ * @return {string}
+ */
+ Date.prototype.toConsoleTime = function()
+{
+ /**
+ * @param {number} x
+ * @return {string}
+ */
+ function leadZero2(x)
+ {
+ return (x > 9 ? "" : "0") + x;
+ }
+
+ /**
+ * @param {number} x
+ * @return {string}
+ */
+ function leadZero3(x)
+ {
+ return (Array(4 - x.toString().length)).join('0') + x;
+ }
+
+ return this.getFullYear() + "-" +
+ leadZero2(this.getMonth() + 1) + "-" +
+ leadZero2(this.getDate()) + " " +
+ leadZero2(this.getHours()) + ":" +
+ leadZero2(this.getMinutes()) + ":" +
+ leadZero2(this.getSeconds()) + "." +
+ leadZero3(this.getMilliseconds());
+}
+
Object.defineProperty(Array.prototype, "remove",
{
/**
* @param {!T} value
- * @param {boolean=} onlyFirst
+ * @param {boolean=} firstOnly
* @this {Array.<!T>}
* @template T
*/
- value: function(value, onlyFirst)
+ value: function(value, firstOnly)
{
- if (onlyFirst) {
- var index = this.indexOf(value);
- if (index !== -1)
- this.splice(index, 1);
+ var index = this.indexOf(value);
+ if (index === -1)
+ return;
+ if (firstOnly) {
+ this.splice(index, 1);
return;
}
-
- var length = this.length;
- for (var i = 0; i < length; ++i) {
- if (this[i] === value)
- this.splice(i, 1);
+ for (var i = index + 1, n = this.length; i < n; ++i) {
+ if (this[i] !== value)
+ this[index++] = this[i];
}
+ this.length = index;
}
});
@@ -376,6 +452,19 @@ Object.defineProperty(Array.prototype, "keySet",
}
});
+Object.defineProperty(Array.prototype, "pushAll",
+{
+ /**
+ * @param {!Array.<!T>} array
+ * @this {Array.<!T>}
+ * @template T
+ */
+ value: function(array)
+ {
+ Array.prototype.push.apply(this, array);
+ }
+});
+
Object.defineProperty(Array.prototype, "rotate",
{
/**
@@ -393,8 +482,29 @@ Object.defineProperty(Array.prototype, "rotate",
}
});
+Object.defineProperty(Array.prototype, "sortNumbers",
+{
+ /**
+ * @this {Array.<number>}
+ */
+ value: function()
+ {
+ /**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+ function numericComparator(a, b)
+ {
+ return a - b;
+ }
+
+ this.sort(numericComparator);
+ }
+});
+
Object.defineProperty(Uint32Array.prototype, "sort", {
- value: Array.prototype.sort
+ value: Array.prototype.sort
});
(function() {
@@ -552,24 +662,28 @@ Object.defineProperty(Array.prototype, "lowerBound",
/**
* Return index of the leftmost element that is equal or greater
* than the specimen object. If there's no such element (i.e. all
- * elements are smaller than the specimen) returns array.length.
+ * elements are smaller than the specimen) returns right bound.
* The function works for sorted array.
+ * When specified, |left| (inclusive) and |right| (exclusive) indices
+ * define the search window.
*
* @param {!T} object
* @param {function(!T,!S):number=} comparator
+ * @param {number=} left
+ * @param {number=} right
* @return {number}
* @this {Array.<!S>}
* @template T,S
*/
- value: function(object, comparator)
+ value: function(object, comparator, left, right)
{
function defaultComparator(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
}
comparator = comparator || defaultComparator;
- var l = 0;
- var r = this.length;
+ var l = left || 0;
+ var r = right !== undefined ? right : this.length;
while (l < r) {
var m = (l + r) >> 1;
if (comparator(object, this[m]) > 0)
@@ -586,24 +700,28 @@ Object.defineProperty(Array.prototype, "upperBound",
/**
* Return index of the leftmost element that is greater
* than the specimen object. If there's no such element (i.e. all
- * elements are smaller than the specimen) returns array.length.
+ * elements are smaller or equal to the specimen) returns right bound.
* The function works for sorted array.
+ * When specified, |left| (inclusive) and |right| (exclusive) indices
+ * define the search window.
*
* @param {!T} object
* @param {function(!T,!S):number=} comparator
+ * @param {number=} left
+ * @param {number=} right
* @return {number}
* @this {Array.<!S>}
* @template T,S
*/
- value: function(object, comparator)
+ value: function(object, comparator, left, right)
{
function defaultComparator(a, b)
{
return a < b ? -1 : (a > b ? 1 : 0);
}
comparator = comparator || defaultComparator;
- var l = 0;
- var r = this.length;
+ var l = left || 0;
+ var r = right !== undefined ? right : this.length;
while (l < r) {
var m = (l + r) >> 1;
if (comparator(object, this[m]) >= 0)
@@ -615,6 +733,18 @@ Object.defineProperty(Array.prototype, "upperBound",
}
});
+Object.defineProperty(Uint32Array.prototype, "lowerBound", {
+ value: Array.prototype.lowerBound
+});
+
+Object.defineProperty(Uint32Array.prototype, "upperBound", {
+ value: Array.prototype.upperBound
+});
+
+Object.defineProperty(Float64Array.prototype, "lowerBound", {
+ value: Array.prototype.lowerBound
+});
+
Object.defineProperty(Array.prototype, "binaryIndexOf",
{
/**
@@ -667,6 +797,7 @@ Object.defineProperty(Array.prototype, "peekLast",
* @param {!Array.<T>} array1
* @param {!Array.<T>} array2
* @param {function(T,T):number} comparator
+ * @param {boolean} mergeNotIntersect
* @return {!Array.<T>}
* @template T
*/
@@ -675,29 +806,20 @@ function mergeOrIntersect(array1, array2, comparator, mergeNotIntersect)
var result = [];
var i = 0;
var j = 0;
- while (i < array1.length || j < array2.length) {
- if (i === array1.length) {
- result = result.concat(array2.slice(j));
- j = array2.length;
- } else if (j === array2.length) {
- result = result.concat(array1.slice(i));
- i = array1.length;
- } else {
- var compareValue = comparator(array1[i], array2[j])
- if (compareValue < 0) {
- if (mergeNotIntersect)
- result.push(array1[i]);
- ++i;
- } else if (compareValue > 0) {
- if (mergeNotIntersect)
- result.push(array2[j]);
- ++j;
- } else {
- result.push(array1[i]);
- ++i;
- ++j;
- }
- }
+ while (i < array1.length && j < array2.length) {
+ var compareValue = comparator(array1[i], array2[j]);
+ if (mergeNotIntersect || !compareValue)
+ result.push(compareValue <= 0 ? array1[i] : array2[j]);
+ if (compareValue <= 0)
+ i++;
+ if (compareValue >= 0)
+ j++;
+ }
+ if (mergeNotIntersect) {
+ while (i < array1.length)
+ result.push(array1[i++]);
+ while (j < array2.length)
+ result.push(array2[j++]);
}
return result;
}
@@ -761,6 +883,11 @@ String.sprintf = function(format, var_arg)
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
}
+/**
+ * @param {string} format
+ * @param {!Object.<string, function(string, ...):*>} formatters
+ * @return {!Array.<!Object>}
+ */
String.tokenizeFormatString = function(format, formatters)
{
var tokens = [];
@@ -786,6 +913,13 @@ String.tokenizeFormatString = function(format, formatters)
addStringToken(format.substring(index, precentIndex));
index = precentIndex + 1;
+ if (format[index] === "%") {
+ // %% escape sequence.
+ addStringToken("%");
+ ++index;
+ continue;
+ }
+
if (isDigit(format[index])) {
// The first character is a number, it might be a substitution index.
var number = parseInt(format.substring(index), 10);
@@ -831,11 +965,17 @@ String.tokenizeFormatString = function(format, formatters)
}
String.standardFormatters = {
+ /**
+ * @return {number}
+ */
d: function(substitution)
{
return !isNaN(substitution) ? substitution : 0;
},
+ /**
+ * @return {number}
+ */
f: function(substitution, token)
{
if (substitution && token.precision > -1)
@@ -843,6 +983,9 @@ String.standardFormatters = {
return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
},
+ /**
+ * @return {string}
+ */
s: function(substitution)
{
return substitution;
@@ -859,6 +1002,15 @@ String.vsprintf = function(format, substitutions)
return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
}
+/**
+ * @param {string} format
+ * @param {?Array.<string>} substitutions
+ * @param {!Object.<string, function(string, ...):string>} formatters
+ * @param {!T} initialValue
+ * @param {function(T, string): T|undefined} append
+ * @return {!{formattedResult: T, unusedSubstitutions: ?Array.<string>}};
+ * @template T
+ */
String.format = function(format, substitutions, formatters, initialValue, append)
{
if (!format || !substitutions || !substitutions.length)
@@ -1023,6 +1175,18 @@ var Set = function()
this._size = 0;
}
+/**
+ * @param {!Array.<!T>} array
+ * @return {!Set.<T>}
+ * @template T
+ */
+Set.fromArray = function(array)
+{
+ var result = new Set();
+ array.forEach(function(item) { result.add(item); });
+ return result;
+}
+
Set.prototype = {
/**
* @param {!T} item
@@ -1056,7 +1220,7 @@ Set.prototype = {
/**
* @return {!Array.<!T>}
*/
- items: function()
+ values: function()
{
var result = new Array(this._size);
var i = 0;
@@ -1069,7 +1233,7 @@ Set.prototype = {
* @param {!T} item
* @return {boolean}
*/
- hasItem: function(item)
+ contains: function(item)
{
return !!this._set[item.__identifier];
},
@@ -1229,6 +1393,7 @@ StringMap.prototype = {
/**
* @param {string} key
+ * @return {T|undefined}
*/
remove: function(key)
{
@@ -1274,6 +1439,7 @@ StringMap.prototype = {
/**
* @param {string} key
+ * @return {T|undefined}
*/
get: function(key)
{
@@ -1314,14 +1480,164 @@ StringMap.prototype = {
}
/**
+ * @constructor
+ * @extends {StringMap.<Set.<!T>>}
+ * @template T
+ */
+var StringMultimap = function()
+{
+ StringMap.call(this);
+}
+
+StringMultimap.prototype = {
+ /**
+ * @param {string} key
+ * @param {T} value
+ */
+ put: function(key, value)
+ {
+ if (key === "__proto__") {
+ if (!this._hasProtoKey) {
+ ++this._size;
+ this._hasProtoKey = true;
+ /** @type {!Set.<T>} */
+ this._protoValue = new Set();
+ }
+ this._protoValue.add(value);
+ return;
+ }
+ if (!Object.prototype.hasOwnProperty.call(this._map, key)) {
+ ++this._size;
+ this._map[key] = new Set();
+ }
+ this._map[key].add(value);
+ },
+
+ /**
+ * @param {string} key
+ * @return {!Set.<!T>}
+ */
+ get: function(key)
+ {
+ var result = StringMap.prototype.get.call(this, key);
+ if (!result)
+ result = new Set();
+ return result;
+ },
+
+ /**
+ * @param {string} key
+ * @param {T} value
+ */
+ remove: function(key, value)
+ {
+ var values = this.get(key);
+ values.remove(value);
+ if (!values.size())
+ StringMap.prototype.remove.call(this, key)
+ },
+
+ /**
+ * @param {string} key
+ */
+ removeAll: function(key)
+ {
+ StringMap.prototype.remove.call(this, key);
+ },
+
+ /**
+ * @return {!Array.<!T>}
+ */
+ values: function()
+ {
+ var result = [];
+ var keys = this.keys();
+ for (var i = 0; i < keys.length; ++i)
+ result.pushAll(this.get(keys[i]).values());
+ return result;
+ },
+
+ __proto__: StringMap.prototype
+}
+
+/**
+ * @constructor
+ */
+var StringSet = function()
+{
+ /** @type {!StringMap.<boolean>} */
+ this._map = new StringMap();
+}
+
+/**
+ * @param {!Array.<string>} array
+ * @return {!StringSet}
+ */
+StringSet.fromArray = function(array)
+{
+ var result = new StringSet();
+ array.forEach(function(item) { result.add(item); });
+ return result;
+}
+
+StringSet.prototype = {
+ /**
+ * @param {string} value
+ */
+ add: function(value)
+ {
+ this._map.put(value, true);
+ },
+
+ /**
+ * @param {string} value
+ * @return {boolean}
+ */
+ remove: function(value)
+ {
+ return !!this._map.remove(value);
+ },
+
+ /**
+ * @return {!Array.<string>}
+ */
+ values: function()
+ {
+ return this._map.keys();
+ },
+
+ /**
+ * @param {string} value
+ * @return {boolean}
+ */
+ contains: function(value)
+ {
+ return this._map.contains(value);
+ },
+
+ /**
+ * @return {number}
+ */
+ size: function()
+ {
+ return this._map.size();
+ },
+
+ clear: function()
+ {
+ this._map.clear();
+ }
+}
+
+/**
* @param {string} url
* @param {boolean=} async
* @param {function(?string)=} callback
* @return {?string}
*/
-function loadXHR(url, async, callback)
+function loadXHR(url, async, callback)
{
- function onReadyStateChanged()
+ function onReadyStateChanged()
{
if (xhr.readyState !== XMLHttpRequest.DONE)
return;
@@ -1331,7 +1647,7 @@ function loadXHR(url, async, callback)
return;
}
- callback(null);
+ callback(null);
}
var xhr = new XMLHttpRequest();
@@ -1341,77 +1657,40 @@ function loadXHR(url, async, callback)
xhr.send(null);
if (!async) {
- if (xhr.status === 200)
+ if (xhr.status === 200)
return xhr.responseText;
return null;
}
return null;
}
+var _importedScripts = {};
+
/**
- * @constructor
+ * @param {string} url
+ * @return {string}
*/
-function StringPool()
+function loadResource(url)
{
- this.reset();
-}
-
-StringPool.prototype = {
- /**
- * @param {string} string
- * @return {string}
- */
- intern: function(string)
- {
- // Do not mess with setting __proto__ to anything but null, just handle it explicitly.
- if (string === "__proto__")
- return "__proto__";
- var result = this._strings[string];
- if (result === undefined) {
- this._strings[string] = string;
- result = string;
- }
- return result;
- },
-
- reset: function()
- {
- this._strings = Object.create(null);
- },
-
- /**
- * @param {!Object} obj
- * @param {number=} depthLimit
- */
- internObjectStrings: function(obj, depthLimit)
- {
- if (typeof depthLimit !== "number")
- depthLimit = 100;
- else if (--depthLimit < 0)
- throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?";
-
- for (var field in obj) {
- switch (typeof obj[field]) {
- case "string":
- obj[field] = this.intern(obj[field]);
- break;
- case "object":
- this.internObjectStrings(obj[field], depthLimit);
- break;
- }
- }
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, false);
+ var stack = new Error().stack;
+ try {
+ xhr.send(null);
+ } catch (e) {
+ console.error(url + " -> " + stack);
+ throw e;
}
+ return xhr.responseText;
}
-var _importedScripts = {};
-
/**
* This function behavior depends on the "debug_devtools" flag value.
* - In debug mode it loads scripts synchronously via xhr request.
* - In release mode every occurrence of "importScript" in the js files
- * that have been white listed in the build system gets replaced with
+ * that have been whitelisted in the build system gets replaced with
* the script source code on the compilation phase.
- * The build system will throw an exception if it found importScript call
+ * The build system will throw an exception if it finds an importScript() call
* in other files.
*
* To load scripts lazily in release mode call "loadScript" function.
@@ -1419,18 +1698,27 @@ var _importedScripts = {};
*/
function importScript(scriptName)
{
- if (_importedScripts[scriptName])
+ var sourceURL = self._importScriptPathPrefix + scriptName;
+ if (_importedScripts[sourceURL])
return;
- var xhr = new XMLHttpRequest();
- _importedScripts[scriptName] = true;
- xhr.open("GET", scriptName, false);
- xhr.send(null);
- if (!xhr.responseText)
- throw "empty response arrived for script '" + scriptName + "'";
- var sourceURL = WebInspector.ParsedURL.completeURL(window.location.href, scriptName);
- window.eval(xhr.responseText + "\n//# sourceURL=" + sourceURL);
+ _importedScripts[sourceURL] = true;
+ var scriptSource = loadResource(sourceURL);
+ if (!scriptSource)
+ throw "empty response arrived for script '" + sourceURL + "'";
+ var oldPrefix = self._importScriptPathPrefix;
+ self._importScriptPathPrefix += scriptName.substring(0, scriptName.lastIndexOf("/") + 1);
+ try {
+ self.eval(scriptSource + "\n//# sourceURL=" + sourceURL);
+ } finally {
+ self._importScriptPathPrefix = oldPrefix;
+ }
}
+(function() {
+ var baseUrl = location.origin + location.pathname;
+ self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1);
+})();
+
var loadScript = importScript;
/**
@@ -1443,9 +1731,8 @@ function CallbackBarrier()
CallbackBarrier.prototype = {
/**
- * @param {function(!T)=} userCallback
- * @return {function(!T=)}
- * @template T
+ * @param {function(...)=} userCallback
+ * @return {function(...)}
*/
createCallback: function(userCallback)
{
@@ -1479,3 +1766,10 @@ CallbackBarrier.prototype = {
this._outgoingCallback();
}
}
+
+/**
+ * @param {*} value
+ */
+function suppressUnused(value)
+{
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CookiesTable.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/CookiesTable.js
index 6d88f3425aa..a829d0e5f31 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CookiesTable.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/CookiesTable.js
@@ -30,15 +30,14 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {boolean} expandable
* @param {function()=} refreshCallback
* @param {function()=} selectedCallback
*/
WebInspector.CookiesTable = function(expandable, refreshCallback, selectedCallback)
{
- WebInspector.View.call(this);
- this.element.className = "fill";
+ WebInspector.VBox.call(this);
var readOnly = expandable;
this._refreshCallback = refreshCallback;
@@ -252,7 +251,7 @@ WebInspector.CookiesTable.prototype = {
if (cookie.maxAge())
data.expires = Number.secondsToString(parseInt(cookie.maxAge(), 10));
else if (cookie.expires())
- data.expires = new Date(cookie.expires()).toGMTString();
+ data.expires = new Date(cookie.expires()).toISOString();
else
data.expires = WebInspector.UIString("Session");
}
@@ -283,5 +282,5 @@ WebInspector.CookiesTable.prototype = {
this._refreshCallback();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMBreakpointsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
index 33a9e17ee88..51c3c1ec3fb 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMBreakpointsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
@@ -31,6 +31,7 @@
/**
* @constructor
* @extends {WebInspector.NativeBreakpointsSidebarPane}
+ * @implements {WebInspector.TargetManager.Observer}
*/
WebInspector.DOMBreakpointsSidebarPane = function()
{
@@ -53,11 +54,28 @@ WebInspector.DOMBreakpointsSidebarPane = function()
this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
+ WebInspector.targetManager.observeTargets(this);
}
WebInspector.DOMBreakpointsSidebarPane.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
+ target.domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
+ target.domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
+ },
+
_inspectedURLChanged: function(event)
{
this._breakpointElements = {};
@@ -103,46 +121,59 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
}
},
- createBreakpointHitStatusMessage: function(auxData, callback)
+ /**
+ * @param {!WebInspector.DebuggerPausedDetails} details
+ * @param {function(!Element)} callback
+ */
+ createBreakpointHitStatusMessage: function(details, callback)
{
+ var auxData = /** @type {!Object} */ (details.auxData);
+ var domModel = details.target().domModel;
if (auxData.type === this._breakpointTypes.SubtreeModified) {
- var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
+ var targetNodeObject = details.target().runtimeModel.createRemoteObject(auxData["targetNode"]);
targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
- } else
- this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
+ } else {
+ this._doCreateBreakpointHitStatusMessage(auxData, domModel.nodeForId(auxData.nodeId), null, callback);
+ }
/**
- * @param {?DOMAgent.NodeId} targetNodeId
+ * @param {?WebInspector.DOMNode} targetNode
* @this {WebInspector.DOMBreakpointsSidebarPane}
*/
- function didPushNodeToFrontend(targetNodeId)
+ function didPushNodeToFrontend(targetNode)
{
- if (targetNodeId)
+ if (targetNode)
targetNodeObject.release();
- this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
+ this._doCreateBreakpointHitStatusMessage(auxData, domModel.nodeForId(auxData.nodeId), targetNode, callback);
}
},
- _doCreateBreakpointHitStatusMessage: function(auxData, targetNodeId, callback)
+ /**
+ * @param {!Object} auxData
+ * @param {?WebInspector.DOMNode} node
+ * @param {?WebInspector.DOMNode} targetNode
+ * @param {function(!Element)} callback
+ */
+ _doCreateBreakpointHitStatusMessage: function(auxData, node, targetNode, callback)
{
var message;
var typeLabel = this._breakpointTypeLabels[auxData.type];
- var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
+ var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
var substitutions = [typeLabel, linkifiedNode];
- var targetNode = "";
- if (targetNodeId)
- targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);
+ var targetNodeLink = "";
+ if (targetNode)
+ targetNodeLink = WebInspector.DOMPresentationUtils.linkifyNodeReference(targetNode);
if (auxData.type === this._breakpointTypes.SubtreeModified) {
if (auxData.insertion) {
- if (targetNodeId !== auxData.nodeId) {
+ if (targetNode !== node) {
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
- substitutions.push(targetNode);
+ substitutions.push(targetNodeLink);
} else
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
} else {
message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
- substitutions.push(targetNode);
+ substitutions.push(targetNodeLink);
}
} else
message = "Paused on a \"%s\" breakpoint set on %s.";
@@ -208,7 +239,7 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
var labelElement = document.createElement("span");
element.appendChild(labelElement);
- var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
+ var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
linkifiedNode.classList.add("monospace");
labelElement.appendChild(linkifiedNode);
@@ -317,7 +348,10 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
WebInspector.settings.domBreakpoints.set(breakpoints);
},
- restoreBreakpoints: function()
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ restoreBreakpoints: function(target)
{
var pathToBreakpoints = {};
@@ -328,7 +362,7 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
*/
function didPushNodeByPathToFrontend(path, nodeId)
{
- var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null;
+ var node = nodeId ? target.domModel.nodeForId(nodeId) : null;
if (!node)
return;
@@ -345,7 +379,7 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
var path = breakpoint.path;
if (!pathToBreakpoints[path]) {
pathToBreakpoints[path] = [];
- WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
+ target.domModel.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
pathToBreakpoints[path].push(breakpoint);
}
@@ -353,6 +387,7 @@ WebInspector.DOMBreakpointsSidebarPane.prototype = {
/**
* @param {!WebInspector.Panel} panel
+ * @return {!WebInspector.DOMBreakpointsSidebarPane.Proxy}
*/
createProxy: function(panel)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMPresentationUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
index d412f9d04e6..ac9ad80af30 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMPresentationUtils.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
@@ -90,36 +90,36 @@ WebInspector.DOMPresentationUtils.createSpansForNodeTitle = function(container,
container.createChild("span", "webkit-html-attribute-name").textContent = match[3];
}
+/**
+ * @param {?WebInspector.DOMNode} node
+ * @return {!Node}
+ */
WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
{
+ if (!node)
+ return document.createTextNode(WebInspector.UIString("<node>"));
+
var link = document.createElement("span");
link.className = "node-link";
WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
- link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
- link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, "", undefined), false);
- link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);
+ link.addEventListener("click", node.reveal.bind(node), false);
+ link.addEventListener("mouseover", node.highlight.bind(node, undefined, undefined), false);
+ link.addEventListener("mouseout", node.domModel().hideDOMNodeHighlight.bind(node.domModel()), false);
return link;
}
-WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
-{
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
- return document.createTextNode(WebInspector.UIString("<node>"));
- return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
-}
-
/**
* @param {string} imageURL
+ * @param {!WebInspector.Target} target
* @param {boolean} showDimensions
* @param {function(!Element=)} userCallback
* @param {!Object=} precomputedDimensions
*/
-WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
+WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(target, imageURL, showDimensions, userCallback, precomputedDimensions)
{
- var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
+ var resource = target.resourceTreeModel.resourceForURL(imageURL);
if (!resource) {
userCallback();
return;
@@ -164,15 +164,29 @@ WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL,
* @param {boolean=} justSelector
* @return {string}
*/
-WebInspector.DOMPresentationUtils.appropriateSelectorFor = function(node, justSelector)
+WebInspector.DOMPresentationUtils.fullQualifiedSelector = function(node, justSelector)
+{
+ if (node.nodeType() !== Node.ELEMENT_NODE)
+ return node.localName() || node.nodeName().toLowerCase();
+ return WebInspector.DOMPresentationUtils.cssPath(node, justSelector);
+}
+
+/**
+ * @param {!WebInspector.DOMNode} node
+ * @return {string}
+ */
+WebInspector.DOMPresentationUtils.simpleSelector = function(node)
{
var lowerCaseName = node.localName() || node.nodeName().toLowerCase();
if (node.nodeType() !== Node.ELEMENT_NODE)
return lowerCaseName;
if (lowerCaseName === "input" && node.getAttribute("type") && !node.getAttribute("id") && !node.getAttribute("class"))
return lowerCaseName + "[type=\"" + node.getAttribute("type") + "\"]";
-
- return WebInspector.DOMPresentationUtils.cssPath(node, justSelector);
+ if (node.getAttribute("id"))
+ return lowerCaseName + "#" + node.getAttribute("id");
+ if (node.getAttribute("class"))
+ return (lowerCaseName === "div" ? "" : lowerCaseName) + "." + node.getAttribute("class").trim().replace(/\s+/g, ".");
+ return lowerCaseName;
}
/**
@@ -188,7 +202,7 @@ WebInspector.DOMPresentationUtils.cssPath = function(node, optimized)
var steps = [];
var contextNode = node;
while (contextNode) {
- var step = WebInspector.DOMPresentationUtils._cssPathValue(contextNode, optimized);
+ var step = WebInspector.DOMPresentationUtils._cssPathStep(contextNode, !!optimized, contextNode === node);
if (!step)
break; // Error - bail out early.
steps.push(step);
@@ -203,10 +217,11 @@ WebInspector.DOMPresentationUtils.cssPath = function(node, optimized)
/**
* @param {!WebInspector.DOMNode} node
- * @param {boolean=} optimized
+ * @param {boolean} optimized
+ * @param {boolean} isTargetNode
* @return {?WebInspector.DOMNodePathStep}
*/
-WebInspector.DOMPresentationUtils._cssPathValue = function(node, optimized)
+WebInspector.DOMPresentationUtils._cssPathStep = function(node, optimized, isTargetNode)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
@@ -312,11 +327,15 @@ WebInspector.DOMPresentationUtils._cssPathValue = function(node, optimized)
var needsClassNames = false;
var needsNthChild = false;
var ownIndex = -1;
+ var elementIndex = -1;
var siblings = parent.children();
for (var i = 0; (ownIndex === -1 || !needsNthChild) && i < siblings.length; ++i) {
var sibling = siblings[i];
+ if (sibling.nodeType() !== Node.ELEMENT_NODE)
+ continue;
+ elementIndex += 1;
if (sibling === node) {
- ownIndex = i;
+ ownIndex = elementIndex;
continue;
}
if (needsNthChild)
@@ -347,6 +366,8 @@ WebInspector.DOMPresentationUtils._cssPathValue = function(node, optimized)
}
var result = nodeName;
+ if (isTargetNode && nodeName.toLowerCase() === "input" && node.getAttribute("type") && !node.getAttribute("id") && !node.getAttribute("class"))
+ result += "[type=\"" + node.getAttribute("type") + "\"]";
if (needsNthChild) {
result += ":nth-child(" + (ownIndex + 1) + ")";
} else if (needsClassNames) {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/DockController.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/DockController.js
new file mode 100644
index 00000000000..24179082f47
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/DockController.js
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {boolean} canDock
+ */
+WebInspector.DockController = function(canDock)
+{
+ this._canDock = canDock;
+ if (!canDock) {
+ this._dockSide = WebInspector.DockController.State.Undocked;
+ this._updateUI();
+ return;
+ }
+
+ WebInspector.settings.currentDockState = WebInspector.settings.createSetting("currentDockState", "");
+ WebInspector.settings.lastDockState = WebInspector.settings.createSetting("lastDockState", "");
+}
+
+WebInspector.DockController.State = {
+ DockedToBottom: "bottom",
+ DockedToRight: "right",
+ DockedToLeft: "left",
+ Undocked: "undocked"
+}
+
+// Use BeforeDockSideChanged to do something before all the UI bits are updated,
+// DockSideChanged to update UI, and AfterDockSideChanged to perform actions
+// after frontend is docked/undocked in the browser.
+WebInspector.DockController.Events = {
+ BeforeDockSideChanged: "BeforeDockSideChanged",
+ DockSideChanged: "DockSideChanged",
+ AfterDockSideChanged: "AfterDockSideChanged"
+}
+
+WebInspector.DockController.prototype = {
+ initialize: function()
+ {
+ if (!this._canDock)
+ return;
+
+ this._states = [WebInspector.DockController.State.DockedToBottom, WebInspector.DockController.State.Undocked, WebInspector.DockController.State.DockedToRight];
+ this._titles = [WebInspector.UIString("Dock to main window."), WebInspector.UIString("Undock into separate window."), WebInspector.UIString("Dock to main window.")];
+ if (WebInspector.experimentsSettings.dockToLeft.isEnabled()) {
+ this._states.push(WebInspector.DockController.State.DockedToLeft);
+ this._titles.push(WebInspector.UIString("Dock to main window."));
+ }
+ var initialState = WebInspector.settings.currentDockState.get();
+ initialState = this._states.indexOf(initialState) >= 0 ? initialState : this._states[0];
+ this._dockSideChanged(initialState);
+ },
+
+ /**
+ * @return {string}
+ */
+ dockSide: function()
+ {
+ return this._dockSide;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ canDock: function()
+ {
+ return this._canDock;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isVertical: function()
+ {
+ return this._dockSide === WebInspector.DockController.State.DockedToRight || this._dockSide === WebInspector.DockController.State.DockedToLeft;
+ },
+
+ /**
+ * @param {string} dockSide
+ */
+ _dockSideChanged: function(dockSide)
+ {
+ if (this._dockSide === dockSide)
+ return;
+
+ var eventData = { from: this._dockSide, to: dockSide };
+ this.dispatchEventToListeners(WebInspector.DockController.Events.BeforeDockSideChanged, eventData);
+ InspectorFrontendHost.setIsDocked(dockSide !== WebInspector.DockController.State.Undocked, this._setIsDockedResponse.bind(this, eventData));
+ this._dockSide = dockSide;
+ this._updateUI();
+ this.dispatchEventToListeners(WebInspector.DockController.Events.DockSideChanged, eventData);
+ },
+
+ /**
+ * @param {{from: string, to: string}} eventData
+ */
+ _setIsDockedResponse: function(eventData)
+ {
+ this.dispatchEventToListeners(WebInspector.DockController.Events.AfterDockSideChanged, eventData);
+ },
+
+ _updateUI: function()
+ {
+ var body = document.body;
+ switch (this._dockSide) {
+ case WebInspector.DockController.State.DockedToBottom:
+ body.classList.remove("undocked");
+ body.classList.remove("dock-to-right");
+ body.classList.remove("dock-to-left");
+ body.classList.add("dock-to-bottom");
+ break;
+ case WebInspector.DockController.State.DockedToRight:
+ body.classList.remove("undocked");
+ body.classList.add("dock-to-right");
+ body.classList.remove("dock-to-left");
+ body.classList.remove("dock-to-bottom");
+ break;
+ case WebInspector.DockController.State.DockedToLeft:
+ body.classList.remove("undocked");
+ body.classList.remove("dock-to-right");
+ body.classList.add("dock-to-left");
+ body.classList.remove("dock-to-bottom");
+ break;
+ case WebInspector.DockController.State.Undocked:
+ body.classList.add("undocked");
+ body.classList.remove("dock-to-right");
+ body.classList.remove("dock-to-left");
+ body.classList.remove("dock-to-bottom");
+ break;
+ }
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.StatusBarButton.Provider}
+ */
+WebInspector.DockController.ButtonProvider = function()
+{
+}
+
+WebInspector.DockController.ButtonProvider.prototype = {
+ /**
+ * @return {?WebInspector.StatusBarButton}
+ */
+ button: function()
+ {
+ if (!WebInspector.dockController.canDock())
+ return null;
+
+ if (!this._dockToggleButton) {
+ this._dockToggleButton = new WebInspector.StatusBarStatesSettingButton(
+ "dock-status-bar-item",
+ WebInspector.dockController._states,
+ WebInspector.dockController._titles,
+ WebInspector.dockController.dockSide(),
+ WebInspector.settings.currentDockState,
+ WebInspector.settings.lastDockState,
+ WebInspector.dockController._dockSideChanged.bind(WebInspector.dockController));
+ }
+ return this._dockToggleButton;
+ }
+}
+
+/**
+ * @type {!WebInspector.DockController}
+ */
+WebInspector.dockController;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/Drawer.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/Drawer.js
new file mode 100644
index 00000000000..de59615a16d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/Drawer.js
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.SplitView} splitView
+ */
+WebInspector.Drawer = function(splitView)
+{
+ WebInspector.VBox.call(this);
+ this.element.id = "drawer-contents";
+
+ this._splitView = splitView;
+ splitView.hideDefaultResizer();
+ this.show(splitView.sidebarElement());
+
+ this._drawerEditorSplitView = new WebInspector.SplitView(true, true, "editorInDrawerSplitViewState", 0.5, 0.5);
+ this._drawerEditorSplitView.hideSidebar();
+ this._drawerEditorSplitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._drawerEditorSplitViewShowModeChanged, this);
+ this._drawerEditorShownSetting = WebInspector.settings.createSetting("drawerEditorShown", true);
+ this._drawerEditorSplitView.show(this.element);
+
+ this._toggleDrawerButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show drawer."), "console-status-bar-item");
+ this._toggleDrawerButton.addEventListener("click", this.toggle, this);
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.element.id = "drawer-tabbed-pane";
+ this._tabbedPane.closeableTabs = false;
+ this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+ new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "drawer-view");
+
+ this._toggleDrawerEditorButton = this._drawerEditorSplitView.createShowHideSidebarButton("editor in drawer", "drawer-editor-show-hide-button");
+ this._tabbedPane.element.appendChild(this._toggleDrawerEditorButton.element);
+ if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
+ this.setDrawerEditorAvailable(false);
+
+ splitView.installResizer(this._tabbedPane.headerElement());
+ this._lastSelectedViewSetting = WebInspector.settings.createSetting("WebInspector.Drawer.lastSelectedView", "console");
+ this._tabbedPane.show(this._drawerEditorSplitView.mainElement());
+}
+
+WebInspector.Drawer.prototype = {
+ /**
+ * @return {!Element}
+ */
+ toggleButtonElement: function()
+ {
+ return this._toggleDrawerButton.element;
+ },
+
+ /**
+ * @param {string} id
+ */
+ closeView: function(id)
+ {
+ this._tabbedPane.closeTab(id);
+ },
+
+ /**
+ * @param {string} id
+ * @param {boolean=} immediate
+ */
+ showView: function(id, immediate)
+ {
+ if (!this._tabbedPane.hasTab(id)) {
+ // Hidden tab.
+ this._innerShow(immediate);
+ return;
+ }
+ this._innerShow(immediate);
+ this._tabbedPane.selectTab(id, true);
+ // In case this id is already selected, anyways persist it as the last saved value.
+ this._lastSelectedViewSetting.set(id);
+ },
+
+ /**
+ * @param {string} id
+ * @param {string} title
+ * @param {!WebInspector.View} view
+ */
+ showCloseableView: function(id, title, view)
+ {
+ if (!this._tabbedPane.hasTab(id)) {
+ this._tabbedPane.appendTab(id, title, view, undefined, false, true);
+ } else {
+ this._tabbedPane.changeTabView(id, view);
+ this._tabbedPane.changeTabTitle(id, title);
+ }
+ this._innerShow();
+ this._tabbedPane.selectTab(id, true);
+ },
+
+ showDrawer: function()
+ {
+ this.showView(this._lastSelectedViewSetting.get());
+ },
+
+ wasShown: function()
+ {
+ this.showView(this._lastSelectedViewSetting.get());
+ this._toggleDrawerButton.toggled = true;
+ this._toggleDrawerButton.title = WebInspector.UIString("Hide drawer.");
+ this._ensureDrawerEditorExistsIfNeeded();
+ },
+
+ willHide: function()
+ {
+ this._toggleDrawerButton.toggled = false;
+ this._toggleDrawerButton.title = WebInspector.UIString("Show drawer.");
+ },
+
+ /**
+ * @param {boolean=} immediate
+ */
+ _innerShow: function(immediate)
+ {
+ if (this.isShowing())
+ return;
+
+ this._splitView.showBoth(!immediate);
+
+ if (this._visibleView())
+ this._visibleView().focus();
+ },
+
+ closeDrawer: function()
+ {
+ if (!this.isShowing())
+ return;
+
+ WebInspector.restoreFocusFromElement(this.element);
+ this._splitView.hideSidebar(true);
+ },
+
+ /**
+ * @return {?WebInspector.View} view
+ */
+ _visibleView: function()
+ {
+ return this._tabbedPane.visibleView;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _tabSelected: function(event)
+ {
+ var tabId = this._tabbedPane.selectedTabId;
+ if (tabId && event.data["isUserGesture"] && !this._tabbedPane.isTabCloseable(tabId))
+ this._lastSelectedViewSetting.set(tabId);
+ },
+
+ toggle: function()
+ {
+ if (this._toggleDrawerButton.toggled)
+ this.closeDrawer();
+ else
+ this.showDrawer();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ visible: function()
+ {
+ return this._toggleDrawerButton.toggled;
+ },
+
+ /**
+ * @return {?string}
+ */
+ selectedViewId: function()
+ {
+ return this._tabbedPane.selectedTabId;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _drawerEditorSplitViewShowModeChanged: function(event)
+ {
+ var mode = /** @type {string} */ (event.data);
+ var shown = mode === WebInspector.SplitView.ShowMode.Both;
+
+ if (this._isHidingDrawerEditor)
+ return;
+
+ this._drawerEditorShownSetting.set(shown);
+
+ if (!shown)
+ return;
+
+ this._ensureDrawerEditor();
+ this._drawerEditor.view().show(this._drawerEditorSplitView.sidebarElement());
+ },
+
+ initialPanelShown: function()
+ {
+ this._initialPanelWasShown = true;
+ this._ensureDrawerEditorExistsIfNeeded();
+ },
+
+ _ensureDrawerEditorExistsIfNeeded: function()
+ {
+ if (!this._initialPanelWasShown || !this.isShowing() || !this._drawerEditorShownSetting.get() || !WebInspector.experimentsSettings.editorInDrawer.isEnabled())
+ return;
+ this._ensureDrawerEditor();
+ },
+
+ _ensureDrawerEditor: function()
+ {
+ if (this._drawerEditor)
+ return;
+ this._drawerEditor = WebInspector.moduleManager.instance(WebInspector.DrawerEditor);
+ this._drawerEditor.installedIntoDrawer();
+ },
+
+ /**
+ * @param {boolean} available
+ */
+ setDrawerEditorAvailable: function(available)
+ {
+ if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
+ available = false;
+ this._toggleDrawerEditorButton.element.classList.toggle("hidden", !available);
+ },
+
+ showDrawerEditor: function()
+ {
+ if (!WebInspector.experimentsSettings.editorInDrawer.isEnabled())
+ return;
+
+ this._splitView.showBoth();
+ this._drawerEditorSplitView.showBoth();
+ },
+
+ hideDrawerEditor: function()
+ {
+ this._isHidingDrawerEditor = true;
+ this._drawerEditorSplitView.hideSidebar();
+ this._isHidingDrawerEditor = false;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isDrawerEditorShown: function()
+ {
+ return this._drawerEditorShownSetting.get();
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @interface
+ */
+WebInspector.Drawer.ViewFactory = function()
+{
+}
+
+WebInspector.Drawer.ViewFactory.prototype = {
+ /**
+ * @return {!WebInspector.View}
+ */
+ createView: function() {}
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Drawer.ViewFactory}
+ * @param {function(new:T)} constructor
+ * @template T
+ */
+WebInspector.Drawer.SingletonViewFactory = function(constructor)
+{
+ this._constructor = constructor;
+}
+
+WebInspector.Drawer.SingletonViewFactory.prototype = {
+ /**
+ * @return {!WebInspector.View}
+ */
+ createView: function()
+ {
+ if (!this._instance)
+ this._instance = /** @type {!WebInspector.View} */(new this._constructor());
+ return this._instance;
+ }
+}
+
+/**
+ * @interface
+ */
+WebInspector.DrawerEditor = function()
+{
+}
+
+WebInspector.DrawerEditor.prototype = {
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function() { },
+
+ installedIntoDrawer: function() { },
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/ExecutionContextSelector.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/ExecutionContextSelector.js
new file mode 100644
index 00000000000..b9c7773696f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/ExecutionContextSelector.js
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.TargetManager.Observer}
+ */
+WebInspector.ExecutionContextSelector = function()
+{
+ WebInspector.targetManager.observeTargets(this);
+ WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this);
+ WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChanged, this);
+}
+
+WebInspector.ExecutionContextSelector.prototype = {
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ if (!WebInspector.context.flavor(WebInspector.Target))
+ WebInspector.context.setFlavor(WebInspector.Target, target);
+
+ target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
+ target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
+ target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.Target);
+ if (currentExecutionContext && currentExecutionContext.target() === target)
+ this._currentExecutionContextGone();
+
+ var targets = WebInspector.targetManager.targets();
+ if (WebInspector.context.flavor(WebInspector.Target) === target && targets.length)
+ WebInspector.context.setFlavor(WebInspector.Target, targets[0]);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _executionContextChanged: function(event)
+ {
+ var newContext = /** @type {?WebInspector.ExecutionContext} */ (event.data);
+ if (newContext)
+ WebInspector.context.setFlavor(WebInspector.Target, newContext.target());
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _targetChanged: function(event)
+ {
+ var newTarget = /** @type {?WebInspector.Target} */(event.data);
+ var currentContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+
+ if (!newTarget || (currentContext && currentContext.target() === newTarget))
+ return;
+
+ var executionContexts = newTarget.runtimeModel.executionContexts();
+ if (!executionContexts.length)
+ return;
+
+ var newContext = executionContexts[0];
+ for (var i = 1; i < executionContexts.length; ++i) {
+ if (executionContexts[i].isMainWorldContext)
+ newContext = executionContexts[i];
+ }
+ WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onExecutionContextCreated: function(event)
+ {
+ var executionContext = /** @type {!WebInspector.ExecutionContext}*/ (event.data);
+ if (!WebInspector.context.flavor(WebInspector.ExecutionContext))
+ WebInspector.context.setFlavor(WebInspector.ExecutionContext, executionContext);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onExecutionContextDestroyed: function(event)
+ {
+ var executionContext = /** @type {!WebInspector.ExecutionContext}*/ (event.data);
+ if (WebInspector.context.flavor(WebInspector.ExecutionContext) === executionContext)
+ this._currentExecutionContextGone();
+ },
+
+ _currentExecutionContextGone: function()
+ {
+ var targets = WebInspector.targetManager.targets();
+ var newContext = null;
+ for (var i = 0; i < targets.length; ++i) {
+ var executionContexts = targets[i].runtimeModel.executionContexts();
+ if (executionContexts.length) {
+ newContext = executionContexts[0];
+ break;
+ }
+ }
+ WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext);
+ }
+
+}
+
+/**
+ * @param {!Element} proxyElement
+ * @param {!Range} wordRange
+ * @param {boolean} force
+ * @param {function(!Array.<string>, number=)} completionsReadyCallback
+ */
+WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext = function(proxyElement, wordRange, force, completionsReadyCallback)
+{
+ var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (!executionContext) {
+ completionsReadyCallback([]);
+ return;
+ }
+
+ // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
+ var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, " =:[({;,!+-*/&|^<>", proxyElement, "backward");
+ var expressionString = expressionRange.toString();
+ var prefix = wordRange.toString();
+ executionContext.completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/ExtensionServerProxy.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/ExtensionServerProxy.js
new file mode 100644
index 00000000000..7c21d630fdf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/ExtensionServerProxy.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @interface
+ */
+WebInspector.ExtensionServerAPI = function() { }
+
+WebInspector.ExtensionServerAPI.prototype = {
+ /**
+ * @param {!Array.<!ExtensionDescriptor>} descriptors
+ */
+ addExtensions: function(descriptors) { }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.ExtensionServerProxy = function()
+{
+}
+
+WebInspector.ExtensionServerProxy._ensureExtensionServer = function()
+{
+ if (!WebInspector.extensionServer)
+ WebInspector.extensionServer = WebInspector.moduleManager.instance(WebInspector.ExtensionServerAPI);
+},
+
+WebInspector.ExtensionServerProxy.prototype = {
+ setFrontendReady: function()
+ {
+ this._frontendReady = true;
+ this._pushExtensionsToServer();
+ },
+
+ _addExtensions: function(extensions)
+ {
+ if (extensions.length === 0)
+ return;
+
+ console.assert(!this._pendingExtensions);
+ this._pendingExtensions = extensions;
+ this._pushExtensionsToServer();
+ },
+
+ _pushExtensionsToServer: function()
+ {
+ if (!this._frontendReady || !this._pendingExtensions)
+ return;
+ WebInspector.ExtensionServerProxy._ensureExtensionServer();
+ WebInspector.extensionServer.addExtensions(this._pendingExtensions);
+ delete this._pendingExtensions;
+ }
+}
+
+WebInspector.extensionServerProxy = new WebInspector.ExtensionServerProxy();
+
+WebInspector.addExtensions = function(extensions)
+{
+ WebInspector.extensionServerProxy._addExtensions(extensions);
+}
+
+WebInspector.setInspectedTabId = function(tabId)
+{
+ WebInspector._inspectedTabId = tabId;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FilterBar.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/FilterBar.js
index c2bbb739d5d..e4f1585aa08 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FilterBar.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/FilterBar.js
@@ -39,7 +39,7 @@ WebInspector.FilterBar = function()
this._element.className = "hbox";
this._filterButton = new WebInspector.StatusBarButton(WebInspector.UIString("Filter"), "filters-toggle", 3);
- this._filterButton.element.addEventListener("mousedown", this._handleFilterButtonClick.bind(this), false);
+ this._filterButton.element.addEventListener("click", this._handleFilterButtonClick.bind(this), false);
this._filters = [];
}
@@ -56,6 +56,15 @@ WebInspector.FilterBar.FilterBarState = {
WebInspector.FilterBar.prototype = {
/**
+ * @param {string} name
+ */
+ setName: function(name)
+ {
+ this._stateSetting = WebInspector.settings.createSetting("filterBar-" + name + "-toggled", false);
+ this._setState(this._stateSetting.get());
+ },
+
+ /**
* @return {!WebInspector.StatusBarButton}
*/
filterButton: function()
@@ -123,9 +132,31 @@ WebInspector.FilterBar.prototype = {
*/
_handleFilterButtonClick: function(event)
{
- this._filtersShown = !this._filtersShown;
+ this._setState(!this._filtersShown);
+ },
+
+ /**
+ * @param {boolean} filtersShown
+ */
+ _setState: function(filtersShown)
+ {
+ if (this._filtersShown === filtersShown)
+ return;
+
+ this._filtersShown = filtersShown;
+ if (this._stateSetting)
+ this._stateSetting.set(filtersShown);
+
this._updateFilterButton();
this.dispatchEventToListeners(WebInspector.FilterBar.Events.FiltersToggled, this._filtersShown);
+ if (this._filtersShown) {
+ for (var i = 0; i < this._filters.length; ++i) {
+ if (this._filters[i] instanceof WebInspector.TextFilterUI) {
+ var textFilterUI = /** @type {!WebInspector.TextFilterUI} */ (this._filters[i]);
+ textFilterUI.focus();
+ }
+ }
+ }
},
clear: function()
@@ -164,8 +195,9 @@ WebInspector.FilterUI.prototype = {
/**
* @constructor
- * @implements {WebInspector.FilterUI}
* @extends {WebInspector.Object}
+ * @implements {WebInspector.FilterUI}
+ * @implements {WebInspector.SuggestBoxDelegate}
* @param {boolean=} supportRegex
*/
WebInspector.TextFilterUI = function(supportRegex)
@@ -176,12 +208,19 @@ WebInspector.TextFilterUI = function(supportRegex)
this._filterElement = document.createElement("div");
this._filterElement.className = "filter-text-filter";
- this._filterInputElement = this._filterElement.createChild("input", "search-replace toolbar-replace-control");
+ this._filterInputElement = /** @type {!HTMLInputElement} */ (this._filterElement.createChild("input", "search-replace toolbar-replace-control"));
this._filterInputElement.placeholder = WebInspector.UIString("Filter");
this._filterInputElement.id = "filter-input-field";
this._filterInputElement.addEventListener("mousedown", this._onFilterFieldManualFocus.bind(this), false); // when the search field is manually selected
this._filterInputElement.addEventListener("input", this._onInput.bind(this), false);
- this._filterInputElement.addEventListener("change", this._onInput.bind(this), false);
+ this._filterInputElement.addEventListener("change", this._onChange.bind(this), false);
+ this._filterInputElement.addEventListener("keydown", this._onInputKeyDown.bind(this), true);
+ this._filterInputElement.addEventListener("blur", this._onBlur.bind(this), true);
+
+ /** @type {?WebInspector.TextFilterUI.SuggestionBuilder} */
+ this._suggestionBuilder = null;
+
+ this._suggestBox = new WebInspector.SuggestBox(this);
if (this._supportRegex) {
this._filterElement.classList.add("supports-regex");
@@ -227,7 +266,7 @@ WebInspector.TextFilterUI.prototype = {
setValue: function(value)
{
this._filterInputElement.value = value;
- this._valueChanged();
+ this._valueChanged(false);
},
/**
@@ -247,14 +286,72 @@ WebInspector.TextFilterUI.prototype = {
},
/**
- * @param {!WebInspector.Event} event
+ * @param {?Event} event
*/
- _onInput: function(event)
+ _onBlur: function(event)
{
- this._valueChanged();
+ this._cancelSuggestion();
},
- _valueChanged: function() {
+ _cancelSuggestion: function()
+ {
+ if (this._suggestionBuilder && this._suggestBox.visible) {
+ this._suggestionBuilder.unapplySuggestion(this._filterInputElement);
+ this._suggestBox.hide();
+ }
+ },
+
+ _onInput: function()
+ {
+ this._valueChanged(true);
+ },
+
+ _onChange: function()
+ {
+ this._valueChanged(false);
+ },
+
+ focus: function()
+ {
+ this._filterInputElement.focus();
+ },
+
+ /**
+ * @param {?WebInspector.TextFilterUI.SuggestionBuilder} suggestionBuilder
+ */
+ setSuggestionBuilder: function(suggestionBuilder)
+ {
+ this._cancelSuggestion();
+ this._suggestionBuilder = suggestionBuilder;
+ },
+
+ _updateSuggestions: function()
+ {
+ if (!this._suggestionBuilder)
+ return;
+ var suggestions = this._suggestionBuilder.buildSuggestions(this._filterInputElement);
+ if (suggestions && suggestions.length) {
+ if (this._suppressSuggestion)
+ delete this._suppressSuggestion;
+ else
+ this._suggestionBuilder.applySuggestion(this._filterInputElement, suggestions[0], true);
+ var anchorBox = this._filterInputElement.boxInWindow().relativeTo(new AnchorBox(-3, 0));
+ this._suggestBox.updateSuggestions(anchorBox, suggestions, 0, true, "");
+ } else {
+ this._suggestBox.hide();
+ }
+ },
+
+ /**
+ * @param {boolean} showSuggestions
+ */
+ _valueChanged: function(showSuggestions)
+ {
+ if (showSuggestions)
+ this._updateSuggestions();
+ else
+ this._suggestBox.hide();
+
var filterQuery = this.value();
this._regex = null;
@@ -271,18 +368,99 @@ WebInspector.TextFilterUI.prototype = {
}
}
+ this._dispatchFilterChanged();
+ },
+
+ _dispatchFilterChanged: function()
+ {
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
+ /**
+ * @param {?Event} event
+ * @return {boolean}
+ */
+ _onInputKeyDown: function(event)
+ {
+ var handled = false;
+ if (event.keyIdentifier === "U+0008") { // Backspace
+ this._suppressSuggestion = true;
+ } else if (this._suggestBox.visible()) {
+ if (event.keyIdentifier === "U+001B") { // Esc
+ this._cancelSuggestion();
+ handled = true;
+ } else if (event.keyIdentifier === "U+0009") { // Tab
+ this._suggestBox.acceptSuggestion();
+ this._valueChanged(true);
+ handled = true;
+ } else {
+ handled = this._suggestBox.keyPressed(/** @type {!KeyboardEvent} */ (event));
+ }
+ }
+ if (handled)
+ event.consume(true);
+ return handled;
+ },
+
+ /**
+ * @override
+ * @param {string} suggestion
+ * @param {boolean=} isIntermediateSuggestion
+ */
+ applySuggestion: function(suggestion, isIntermediateSuggestion)
+ {
+ if (!this._suggestionBuilder)
+ return;
+ this._suggestionBuilder.applySuggestion(this._filterInputElement, suggestion, !!isIntermediateSuggestion);
+ if (isIntermediateSuggestion)
+ this._dispatchFilterChanged();
+ },
+
+ /** @override */
+ acceptSuggestion: function()
+ {
+ this._filterInputElement.scrollLeft = this._filterInputElement.scrollWidth;
+ this._valueChanged(true);
+ },
+
__proto__: WebInspector.Object.prototype
}
/**
+ * @interface
+ */
+WebInspector.TextFilterUI.SuggestionBuilder = function()
+{
+}
+
+WebInspector.TextFilterUI.SuggestionBuilder.prototype = {
+ /**
+ * @param {!HTMLInputElement} input
+ * @return {?Array.<string>}
+ */
+ buildSuggestions: function(input) { },
+
+ /**
+ * @param {!HTMLInputElement} input
+ * @param {string} suggestion
+ * @param {boolean} isIntermediate
+ */
+ applySuggestion: function(input, suggestion, isIntermediate) { },
+
+ /**
+ * @param {!HTMLInputElement} input
+ */
+ unapplySuggestion: function(input) { }
+}
+
+/**
* @constructor
- * @implements {WebInspector.FilterUI}
* @extends {WebInspector.Object}
+ * @implements {WebInspector.FilterUI}
+ * @param {!Array.<!WebInspector.NamedBitSetFilterUI.Item>} items
+ * @param {!WebInspector.Setting=} setting
*/
-WebInspector.NamedBitSetFilterUI = function()
+WebInspector.NamedBitSetFilterUI = function(items, setting)
{
this._filtersElement = document.createElement("div");
this._filtersElement.className = "filter-bitset-filter status-bar-item";
@@ -290,11 +468,24 @@ WebInspector.NamedBitSetFilterUI = function()
this._allowedTypes = {};
this._typeFilterElements = {};
- this.addBit(WebInspector.NamedBitSetFilterUI.ALL_TYPES, WebInspector.UIString("All"));
+ this._addBit(WebInspector.NamedBitSetFilterUI.ALL_TYPES, WebInspector.UIString("All"));
this._filtersElement.createChild("div", "filter-bitset-filter-divider");
- this._toggleTypeFilter(WebInspector.NamedBitSetFilterUI.ALL_TYPES, false);
+
+ for (var i = 0; i < items.length; ++i)
+ this._addBit(items[i].name, items[i].label);
+
+ if (setting) {
+ this._setting = setting;
+ setting.addChangeListener(this._settingChanged.bind(this));
+ this._settingChanged();
+ } else {
+ this._toggleTypeFilter(WebInspector.NamedBitSetFilterUI.ALL_TYPES, false);
+ }
}
+/** @typedef {{name: string, label: string}} */
+WebInspector.NamedBitSetFilterUI.Item;
+
WebInspector.NamedBitSetFilterUI.ALL_TYPES = "all";
WebInspector.NamedBitSetFilterUI.prototype = {
@@ -307,17 +498,6 @@ WebInspector.NamedBitSetFilterUI.prototype = {
},
/**
- * @param {!WebInspector.Setting} setting
- */
- bindSetting: function(setting)
- {
- console.assert(!this._setting);
- this._setting = setting;
- setting.addChangeListener(this._settingChanged.bind(this));
- this._settingChanged();
- },
-
- /**
* @return {!Element}
*/
element: function()
@@ -352,7 +532,7 @@ WebInspector.NamedBitSetFilterUI.prototype = {
this._allowedTypes[WebInspector.NamedBitSetFilterUI.ALL_TYPES] = true;
}
for (var typeName in this._typeFilterElements)
- this._typeFilterElements[typeName].enableStyleClass("selected", this._allowedTypes[typeName]);
+ this._typeFilterElements[typeName].classList.toggle("selected", this._allowedTypes[typeName]);
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
@@ -360,7 +540,7 @@ WebInspector.NamedBitSetFilterUI.prototype = {
* @param {string} name
* @param {string} label
*/
- addBit: function(name, label)
+ _addBit: function(name, label)
{
var typeFilterElement = this._filtersElement.createChild("li", name);
typeFilterElement.typeName = name;
@@ -370,7 +550,7 @@ WebInspector.NamedBitSetFilterUI.prototype = {
},
/**
- * @param {!Event} e
+ * @param {?Event} e
*/
_onTypeFilterClicked: function(e)
{
@@ -408,7 +588,7 @@ WebInspector.NamedBitSetFilterUI.prototype = {
* @constructor
* @implements {WebInspector.FilterUI}
* @extends {WebInspector.Object}
- * @param {!Array.<{value: *, label: string, title: string}>} options
+ * @param {!Array.<!{value: *, label: string, title: string}>} options
*/
WebInspector.ComboBoxFilterUI = function(options)
{
@@ -456,6 +636,22 @@ WebInspector.ComboBoxFilterUI.prototype = {
},
/**
+ * @param {number} index
+ */
+ setSelectedIndex: function(index)
+ {
+ this._filterComboBox.setSelectedIndex(index);
+ },
+
+ /**
+ * @return {number}
+ */
+ selectedIndex: function(index)
+ {
+ return this._filterComboBox.selectedIndex();
+ },
+
+ /**
* @param {?Event} event
*/
_filterChanged: function(event)
@@ -519,9 +715,18 @@ WebInspector.CheckboxFilterUI.prototype = {
return this._checked;
},
+ /**
+ * @param {boolean} state
+ */
+ setState: function(state)
+ {
+ this._checked = state;
+ this._update();
+ },
+
_update: function()
{
- this._checkElement.enableStyleClass("checkbox-filter-checkbox-checked", this._checked);
+ this._checkElement.classList.toggle("checkbox-filter-checkbox-checked", this._checked);
this.dispatchEventToListeners(WebInspector.FilterUI.Events.FilterChanged, null);
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/FilterSuggestionBuilder.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/FilterSuggestionBuilder.js
new file mode 100644
index 00000000000..4919bd1d7d3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/FilterSuggestionBuilder.js
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @implements {WebInspector.TextFilterUI.SuggestionBuilder}
+ * @param {!Array.<string>} keys
+ */
+WebInspector.FilterSuggestionBuilder = function(keys)
+{
+ this._keys = keys;
+ this._valueSets = {};
+ this._valueLists = {};
+}
+
+WebInspector.FilterSuggestionBuilder.prototype = {
+ /**
+ * @param {!HTMLInputElement} input
+ * @return {?Array.<string>}
+ */
+ buildSuggestions: function(input)
+ {
+ var text = input.value;
+ var end = input.selectionEnd;
+ if (end != text.length)
+ return null;
+
+ var start = input.selectionStart;
+ text = text.substring(0, start);
+ var prefixIndex = text.lastIndexOf(" ") + 1;
+
+ var prefix = text.substring(prefixIndex);
+ if (!prefix)
+ return [];
+
+ var valueDelimiterIndex = prefix.indexOf(":");
+
+ var suggestions = [];
+ if (valueDelimiterIndex === -1) {
+ for (var j = 0; j < this._keys.length; ++j) {
+ if (this._keys[j].startsWith(prefix))
+ suggestions.push(this._keys[j] + ":");
+ }
+ } else {
+ var key = prefix.substring(0, valueDelimiterIndex);
+ var value = prefix.substring(valueDelimiterIndex + 1);
+ var items = this._values(key);
+ for (var i = 0; i < items.length; ++i) {
+ if (items[i].startsWith(value) && (items[i] !== value))
+ suggestions.push(key + ":" + items[i]);
+ }
+ }
+ return suggestions;
+ },
+
+ /**
+ * @param {!HTMLInputElement} input
+ * @param {string} suggestion
+ * @param {boolean} isIntermediate
+ */
+ applySuggestion: function(input, suggestion, isIntermediate)
+ {
+ var text = input.value;
+
+ var start = input.selectionStart;
+ text = text.substring(0, start);
+ var prefixIndex = text.lastIndexOf(" ") + 1;
+
+ text = text.substring(0, prefixIndex) + suggestion;
+ input.value = text;
+ if (!isIntermediate)
+ start = text.length;
+ input.setSelectionRange(start, text.length);
+ },
+
+ /**
+ * @param {!HTMLInputElement} input
+ */
+ unapplySuggestion: function(input)
+ {
+ var start = input.selectionStart;
+ var end = input.selectionEnd;
+ var text = input.value;
+ if (start !== end && end === text.length)
+ input.value = text.substring(0, start);
+ },
+
+ /**
+ * @param {string} key
+ * @return {!Array.<string>}
+ */
+ _values: function(key)
+ {
+ var result = this._valueLists[key];
+ if (!result)
+ return [];
+
+ result.sort();
+ return result;
+ },
+
+ /**
+ * @param {string} key
+ * @param {?string=} value
+ */
+ addItem: function(key, value)
+ {
+ if (!value)
+ return;
+
+ var set = this._valueSets[key];
+ var list = this._valueLists[key];
+ if (!set) {
+ set = {};
+ this._valueSets[key] = set;
+ list = [];
+ this._valueLists[key] = list;
+ }
+
+ if (set[value])
+ return;
+
+ set[value] = true;
+ list.push(value);
+ },
+
+ /**
+ * @param {string} query
+ * @return {{text: !Array.<string>, filters: !Object.<string, string>}}
+ */
+ parseQuery: function(query)
+ {
+ var filters = {};
+ var text = [];
+ var i = 0;
+ var j = 0;
+ var part;
+ while (true) {
+ var colonIndex = query.indexOf(":", i);
+ if (colonIndex == -1) {
+ part = query.substring(j);
+ if (part)
+ text.push(part);
+ break;
+ }
+ var spaceIndex = query.lastIndexOf(" ", colonIndex);
+ var key = query.substring(spaceIndex + 1, colonIndex);
+ if (this._keys.indexOf(key) == -1) {
+ i = colonIndex + 1;
+ continue;
+ }
+ part = spaceIndex > j ? query.substring(j, spaceIndex) : "";
+ if (part)
+ text.push(part);
+ var nextSpace = query.indexOf(" ", colonIndex + 1);
+ if (nextSpace == -1) {
+ filters[key] = query.substring(colonIndex + 1);
+ break;
+ }
+ filters[key] = query.substring(colonIndex + 1, nextSpace);
+ i = nextSpace + 1;
+ j = i;
+ }
+ return {text: text, filters: filters};
+ }
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/FlameChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/FlameChart.js
new file mode 100644
index 00000000000..f818b5b8e18
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/FlameChart.js
@@ -0,0 +1,967 @@
+/**
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @interface
+ */
+WebInspector.FlameChartDelegate = function() { }
+
+WebInspector.FlameChartDelegate.prototype = {
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ requestWindowTimes: function(startTime, endTime) { }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HBox}
+ * @param {!WebInspector.FlameChartDataProvider} dataProvider
+ * @param {!WebInspector.FlameChartDelegate} flameChartDelegate
+ * @param {boolean} isTopDown
+ */
+WebInspector.FlameChart = function(dataProvider, flameChartDelegate, isTopDown)
+{
+ WebInspector.HBox.call(this);
+ this.element.classList.add("flame-chart-main-pane");
+ this._flameChartDelegate = flameChartDelegate;
+ this._isTopDown = isTopDown;
+
+ this._calculator = new WebInspector.FlameChart.Calculator();
+
+ this._canvas = this.element.createChild("canvas");
+ this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), false);
+ this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), false);
+ this._canvas.addEventListener("click", this._onClick.bind(this), false);
+ WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind(this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "move", null);
+
+ this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll");
+ this._vScrollContent = this._vScrollElement.createChild("div");
+ this._vScrollElement.addEventListener("scroll", this._scheduleUpdate.bind(this), false);
+
+ this._entryInfo = this.element.createChild("div", "profile-entry-info");
+ this._highlightElement = this.element.createChild("div", "flame-chart-highlight-element");
+ this._selectedElement = this.element.createChild("div", "flame-chart-selected-element");
+
+ this._dataProvider = dataProvider;
+
+ this._windowLeft = 0.0;
+ this._windowRight = 1.0;
+ this._windowWidth = 1.0;
+ this._timeWindowLeft = 0;
+ this._timeWindowRight = Infinity;
+ this._barHeight = dataProvider.barHeight();
+ this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight;
+ this._minWidth = 1;
+ this._paddingLeft = this._dataProvider.paddingLeft();
+ this._markerPadding = 2;
+ this._markerRadius = this._barHeight / 2 - this._markerPadding;
+ this._highlightedEntryIndex = -1;
+ this._selectedEntryIndex = -1;
+ this._textWidth = {};
+}
+
+WebInspector.FlameChart.DividersBarHeight = 20;
+
+/**
+ * @interface
+ */
+WebInspector.FlameChartDataProvider = function()
+{
+}
+
+/** @typedef {!{
+ entryLevels: (!Array.<number>|!Uint8Array),
+ entryTotalTimes: (!Array.<number>|!Float32Array),
+ entryStartTimes: (!Array.<number>|!Float64Array)
+ }}
+ */
+WebInspector.FlameChart.TimelineData;
+
+WebInspector.FlameChartDataProvider.prototype = {
+ /**
+ * @return {number}
+ */
+ barHeight: function() { },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {?Array.<number>}
+ */
+ dividerOffsets: function(startTime, endTime) { },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function() { },
+
+ /**
+ * @return {number}
+ */
+ totalTime: function() { },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function() { },
+
+ /**
+ * @return {?WebInspector.FlameChart.TimelineData}
+ */
+ timelineData: function() { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?Array.<!{title: string, text: string}>}
+ */
+ prepareHighlightedEntryInfo: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ canJumpToEntry: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryTitle: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryFont: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryColor: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @param {!CanvasRenderingContext2D} context
+ * @param {?string} text
+ * @param {number} barX
+ * @param {number} barY
+ * @param {number} barWidth
+ * @param {number} barHeight
+ * @param {function(number):number} timeToPosition
+ * @return {boolean}
+ */
+ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, timeToPosition) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ forceDecoration: function(entryIndex) { },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ textColor: function(entryIndex) { },
+
+ /**
+ * @return {number}
+ */
+ textBaseline: function() { },
+
+ /**
+ * @return {number}
+ */
+ textPadding: function() { },
+
+ /**
+ * @return {?{startTime: number, endTime: number}}
+ */
+ highlightTimeRange: function(entryIndex) { },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function() { },
+}
+
+WebInspector.FlameChart.Events = {
+ EntrySelected: "EntrySelected"
+}
+
+
+/**
+ * @constructor
+ * @param {!{min: number, max: number, count: number}|number=} hueSpace
+ * @param {!{min: number, max: number, count: number}|number=} satSpace
+ * @param {!{min: number, max: number, count: number}|number=} lightnessSpace
+ */
+WebInspector.FlameChart.ColorGenerator = function(hueSpace, satSpace, lightnessSpace)
+{
+ this._hueSpace = hueSpace || { min: 0, max: 360, count: 20 };
+ this._satSpace = satSpace || 67;
+ this._lightnessSpace = lightnessSpace || 80;
+ this._colors = {};
+}
+
+WebInspector.FlameChart.ColorGenerator.prototype = {
+ /**
+ * @param {string} id
+ * @param {string|!CanvasGradient} color
+ */
+ setColorForID: function(id, color)
+ {
+ this._colors[id] = color;
+ },
+
+ /**
+ * @param {string} id
+ * @return {string}
+ */
+ colorForID: function(id)
+ {
+ var color = this._colors[id];
+ if (!color) {
+ color = this._generateColorForID(id);
+ this._colors[id] = color;
+ }
+ return color;
+ },
+
+ /**
+ * @param {string} id
+ * @return {string}
+ */
+ _generateColorForID: function(id)
+ {
+ var hash = id.hashCode();
+ var h = this._indexToValueInSpace(hash, this._hueSpace);
+ var s = this._indexToValueInSpace(hash, this._satSpace);
+ var l = this._indexToValueInSpace(hash, this._lightnessSpace);
+ return "hsl(" + h + ", " + s + "%, " + l + "%)";
+ },
+
+ /**
+ * @param {number} index
+ * @param {!{min: number, max: number, count: number}|number} space
+ * @return {number}
+ */
+ _indexToValueInSpace: function(index, space)
+ {
+ if (typeof space === "number")
+ return space;
+ index %= space.count;
+ return space.min + Math.floor(index / space.count * (space.max - space.min));
+ }
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineGrid.Calculator}
+ */
+WebInspector.FlameChart.Calculator = function()
+{
+ this._paddingLeft = 0;
+}
+
+WebInspector.FlameChart.Calculator.prototype = {
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return this._paddingLeft;
+ },
+
+ /**
+ * @param {!WebInspector.FlameChart} mainPane
+ */
+ _updateBoundaries: function(mainPane)
+ {
+ this._totalTime = mainPane._dataProvider.totalTime();
+ this._zeroTime = mainPane._dataProvider.minimumBoundary();
+ this._minimumBoundaries = this._zeroTime + mainPane._windowLeft * this._totalTime;
+ this._maximumBoundaries = this._zeroTime + mainPane._windowRight * this._totalTime;
+ this._paddingLeft = mainPane._paddingLeft;
+ this._width = mainPane._canvas.width / window.devicePixelRatio - this._paddingLeft;
+ this._timeToPixel = this._width / this.boundarySpan();
+ },
+
+ /**
+ * @param {number} time
+ * @return {number}
+ */
+ computePosition: function(time)
+ {
+ return Math.round((time - this._minimumBoundaries) * this._timeToPixel + this._paddingLeft);
+ },
+
+ /**
+ * @param {number} value
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatTime: function(value, precision)
+ {
+ return Number.preciseMillisToString(value - this._zeroTime, precision);
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumBoundary: function()
+ {
+ return this._maximumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ zeroTime: function()
+ {
+ return this._zeroTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ boundarySpan: function()
+ {
+ return this._maximumBoundaries - this._minimumBoundaries;
+ }
+}
+
+WebInspector.FlameChart.prototype = {
+ _resetCanvas: function()
+ {
+ var ratio = window.devicePixelRatio;
+ this._canvas.width = this._offsetWidth * ratio;
+ this._canvas.height = this._offsetHeight * ratio;
+ this._canvas.style.width = this._offsetWidth + "px";
+ this._canvas.style.height = this._offsetHeight + "px";
+ },
+
+ /**
+ * @return {?WebInspector.FlameChart.TimelineData}
+ */
+ _timelineData: function()
+ {
+ var timelineData = this._dataProvider.timelineData();
+ if (timelineData !== this._rawTimelineData || timelineData.entryStartTimes.length !== this._rawTimelineDataLength)
+ this._processTimelineData(timelineData);
+ return this._rawTimelineData;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._timeWindowLeft = startTime;
+ this._timeWindowRight = endTime;
+ this._scheduleUpdate();
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ */
+ _startCanvasDragging: function(event)
+ {
+ if (!this._timelineData() || this._timeWindowRight === Infinity)
+ return false;
+ this._isDragging = true;
+ this._maxDragOffset = 0;
+ this._dragStartPointX = event.pageX;
+ this._dragStartPointY = event.pageY;
+ this._dragStartScrollTop = this._vScrollElement.scrollTop;
+ this._dragStartWindowLeft = this._timeWindowLeft;
+ this._dragStartWindowRight = this._timeWindowRight;
+ this._canvas.style.cursor = "";
+
+ return true;
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ */
+ _canvasDragging: function(event)
+ {
+ var pixelShift = this._dragStartPointX - event.pageX;
+ var pixelScroll = this._dragStartPointY - event.pageY;
+ this._vScrollElement.scrollTop = this._dragStartScrollTop + pixelScroll;
+ var windowShift = pixelShift / this._totalPixels;
+ var windowTime = this._windowWidth * this._totalTime;
+ var timeShift = windowTime * pixelShift / this._pixelWindowWidth;
+ timeShift = Number.constrain(
+ timeShift,
+ this._minimumBoundary - this._dragStartWindowLeft,
+ this._minimumBoundary + this._totalTime - this._dragStartWindowRight
+ );
+ var windowLeft = this._dragStartWindowLeft + timeShift;
+ var windowRight = this._dragStartWindowRight + timeShift;
+ this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight);
+ this._maxDragOffset = Math.max(this._maxDragOffset, Math.abs(pixelShift));
+ },
+
+ _endCanvasDragging: function()
+ {
+ this._isDragging = false;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseMove: function(event)
+ {
+ if (this._isDragging)
+ return;
+ var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offsetY);
+
+ if (this._highlightedEntryIndex === entryIndex)
+ return;
+
+ if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex))
+ this._canvas.style.cursor = "default";
+ else
+ this._canvas.style.cursor = "pointer";
+
+ this._highlightedEntryIndex = entryIndex;
+
+ this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
+ this._entryInfo.removeChildren();
+
+ if (this._highlightedEntryIndex === -1)
+ return;
+
+ if (!this._isDragging) {
+ var entryInfo = this._dataProvider.prepareHighlightedEntryInfo(this._highlightedEntryIndex);
+ if (entryInfo)
+ this._entryInfo.appendChild(this._buildEntryInfo(entryInfo));
+ }
+ },
+
+ _onClick: function()
+ {
+ // onClick comes after dragStart and dragEnd events.
+ // So if there was drag (mouse move) in the middle of that events
+ // we skip the click. Otherwise we jump to the sources.
+ const clickThreshold = 5;
+ if (this._maxDragOffset > clickThreshold)
+ return;
+ if (this._highlightedEntryIndex === -1)
+ return;
+ this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, this._highlightedEntryIndex);
+ },
+
+ /**
+ * @param {?Event} e
+ */
+ _onMouseWheel: function(e)
+ {
+ var scrollIsThere = this._totalHeight > this._offsetHeight;
+ var windowLeft = this._timeWindowLeft ? this._timeWindowLeft : this._dataProvider.minimumBoundary();
+ var windowRight = this._timeWindowRight !== Infinity ? this._timeWindowRight : this._dataProvider.minimumBoundary() + this._dataProvider.totalTime();
+
+ var panHorizontally = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) && !e.shiftKey;
+ var panVertically = scrollIsThere && ((e.wheelDeltaY && !e.shiftKey) || (Math.abs(e.wheelDeltaX) === 120 && !e.shiftKey));
+ if (panVertically) {
+ this._vScrollElement.scrollTop -= e.wheelDeltaY / 120 * this._offsetHeight / 8;
+ } else if (panHorizontally) {
+ var shift = -e.wheelDeltaX * this._pixelToTime;
+ shift = Number.constrain(shift, this._minimumBoundary - windowLeft, this._totalTime + this._minimumBoundary - windowRight);
+ windowLeft += shift;
+ windowRight += shift;
+ } else { // Zoom.
+ const mouseWheelZoomSpeed = 1 / 120;
+ var zoom = Math.pow(1.2, -(e.wheelDeltaY || e.wheelDeltaX) * mouseWheelZoomSpeed) - 1;
+ var cursorTime = this._cursorTime(e.offsetX);
+ windowLeft += (windowLeft - cursorTime) * zoom;
+ windowRight += (windowRight - cursorTime) * zoom;
+ }
+ windowLeft = Number.constrain(windowLeft, this._minimumBoundary, this._totalTime + this._minimumBoundary);
+ windowRight = Number.constrain(windowRight, this._minimumBoundary, this._totalTime + this._minimumBoundary);
+ this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight);
+
+ // Block swipe gesture.
+ e.consume(true);
+ },
+
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ _cursorTime: function(x)
+ {
+ return (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTime + this._minimumBoundary;
+ },
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @return {number}
+ */
+ _coordinatesToEntryIndex: function(x, y)
+ {
+ y += this._scrollTop;
+ var timelineData = this._timelineData();
+ if (!timelineData)
+ return -1;
+ var cursorTime = this._cursorTime(x);
+ var cursorLevel;
+ var offsetFromLevel;
+ if (this._isTopDown) {
+ cursorLevel = Math.floor((y - WebInspector.FlameChart.DividersBarHeight) / this._barHeight);
+ offsetFromLevel = y - WebInspector.FlameChart.DividersBarHeight - cursorLevel * this._barHeight;
+ } else {
+ cursorLevel = Math.floor((this._canvas.height / window.devicePixelRatio - y) / this._barHeight);
+ offsetFromLevel = this._canvas.height / window.devicePixelRatio - cursorLevel * this._barHeight;
+ }
+ var entryStartTimes = timelineData.entryStartTimes;
+ var entryTotalTimes = timelineData.entryTotalTimes;
+ var entryIndexes = this._timelineLevels[cursorLevel];
+ if (!entryIndexes || !entryIndexes.length)
+ return -1;
+
+ function comparator(time, entryIndex)
+ {
+ return time - entryStartTimes[entryIndex];
+ }
+ var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparator) - 1, 0);
+
+ /**
+ * @this {WebInspector.FlameChart}
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ function checkEntryHit(entryIndex)
+ {
+ if (entryIndex === undefined)
+ return false;
+ var startTime = entryStartTimes[entryIndex];
+ var duration = entryTotalTimes[entryIndex];
+ if (isNaN(duration)) {
+ var dx = (startTime - cursorTime) / this._pixelToTime;
+ var dy = this._barHeight / 2 - offsetFromLevel;
+ return dx * dx + dy * dy < this._markerRadius * this._markerRadius;
+ }
+ var endTime = startTime + duration;
+ var barThreshold = 3 * this._pixelToTime;
+ return startTime - barThreshold < cursorTime && cursorTime < endTime + barThreshold;
+ }
+
+ var entryIndex = entryIndexes[indexOnLevel];
+ if (checkEntryHit.call(this, entryIndex))
+ return entryIndex;
+ entryIndex = entryIndexes[indexOnLevel + 1];
+ if (checkEntryHit.call(this, entryIndex))
+ return entryIndex;
+ return -1;
+ },
+
+ /**
+ * @param {number} height
+ * @param {number} width
+ */
+ _draw: function(width, height)
+ {
+ var timelineData = this._timelineData();
+ if (!timelineData)
+ return;
+
+ var context = this._canvas.getContext("2d");
+ context.save();
+ var ratio = window.devicePixelRatio;
+ context.scale(ratio, ratio);
+
+ var timeWindowRight = this._timeWindowRight;
+ var timeWindowLeft = this._timeWindowLeft;
+ var timeToPixel = this._timeToPixel;
+ var pixelWindowLeft = this._pixelWindowLeft;
+ var paddingLeft = this._paddingLeft;
+ var minWidth = this._minWidth;
+ var entryTotalTimes = timelineData.entryTotalTimes;
+ var entryStartTimes = timelineData.entryStartTimes;
+ var entryLevels = timelineData.entryLevels;
+
+ var titleIndices = new Uint32Array(timelineData.entryTotalTimes);
+ var nextTitleIndex = 0;
+ var markerIndices = new Uint32Array(timelineData.entryTotalTimes);
+ var nextMarkerIndex = 0;
+ var textPadding = this._dataProvider.textPadding();
+ this._minTextWidth = 2 * textPadding + this._measureWidth(context, "\u2026");
+ var minTextWidth = this._minTextWidth;
+
+ var barHeight = this._barHeight;
+
+ var timeToPosition = this._timeToPosition.bind(this);
+ var textBaseHeight = this._baseHeight + barHeight - this._dataProvider.textBaseline();
+ var colorBuckets = {};
+ var minVisibleBarLevel = Math.max(Math.floor((this._scrollTop - this._baseHeight) / barHeight), 0);
+ var maxVisibleBarLevel = Math.min(Math.floor((this._scrollTop - this._baseHeight + height) / barHeight), this._dataProvider.maxStackDepth());
+
+ context.translate(0, -this._scrollTop);
+
+ function comparator(time, entryIndex)
+ {
+ return time - entryStartTimes[entryIndex];
+ }
+
+ for (var level = minVisibleBarLevel; level <= maxVisibleBarLevel; ++level) {
+ // Entries are ordered by start time within a level, so find the last visible entry.
+ var levelIndexes = this._timelineLevels[level];
+ var rightIndexOnLevel = levelIndexes.lowerBound(timeWindowRight, comparator) - 1;
+ var lastDrawOffset = Infinity;
+ for (var entryIndexOnLevel = rightIndexOnLevel; entryIndexOnLevel >= 0; --entryIndexOnLevel) {
+ var entryIndex = levelIndexes[entryIndexOnLevel];
+ var entryStartTime = entryStartTimes[entryIndex];
+ var entryOffsetRight = entryStartTime + (isNaN(entryTotalTimes[entryIndex]) ? 0 : entryTotalTimes[entryIndex]);
+ if (entryOffsetRight <= timeWindowLeft)
+ break;
+
+ var barX = this._timeToPosition(entryStartTime);
+ if (barX >= lastDrawOffset)
+ continue;
+ var barRight = Math.min(this._timeToPosition(entryOffsetRight), lastDrawOffset);
+ lastDrawOffset = barX;
+
+ var color = this._dataProvider.entryColor(entryIndex);
+ var bucket = colorBuckets[color];
+ if (!bucket) {
+ bucket = [];
+ colorBuckets[color] = bucket;
+ }
+ bucket.push(entryIndex);
+ }
+ }
+
+ var colors = Object.keys(colorBuckets);
+ // We don't use for-in here because it couldn't be optimized.
+ for (var c = 0; c < colors.length; ++c) {
+ var color = colors[c];
+ context.fillStyle = color;
+ context.strokeStyle = color;
+ var indexes = colorBuckets[color];
+
+ // First fill the boxes.
+ context.beginPath();
+ for (var i = 0; i < indexes.length; ++i) {
+ var entryIndex = indexes[i];
+ var entryStartTime = entryStartTimes[entryIndex];
+ var barX = this._timeToPosition(entryStartTime);
+ var barRight = this._timeToPosition(entryStartTime + entryTotalTimes[entryIndex]);
+ var barWidth = Math.max(barRight - barX, minWidth);
+ var barLevel = entryLevels[entryIndex];
+ var barY = this._levelToHeight(barLevel);
+ if (isNaN(entryTotalTimes[entryIndex])) {
+ context.moveTo(barX + this._markerRadius, barY + barHeight / 2);
+ context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2);
+ markerIndices[nextMarkerIndex++] = entryIndex;
+ } else {
+ context.rect(barX, barY, barWidth, barHeight);
+ if (barWidth > minTextWidth || this._dataProvider.forceDecoration(entryIndex))
+ titleIndices[nextTitleIndex++] = entryIndex;
+ }
+ }
+ context.fill();
+ }
+
+ context.strokeStyle = "rgb(0, 0, 0)";
+ context.beginPath();
+ for (var m = 0; m < nextMarkerIndex; ++m) {
+ var entryIndex = markerIndices[m];
+ var entryStartTime = entryStartTimes[entryIndex];
+ var barX = this._timeToPosition(entryStartTime);
+ var barLevel = entryLevels[entryIndex];
+ var barY = this._levelToHeight(barLevel);
+ context.moveTo(barX + this._markerRadius, barY + barHeight / 2);
+ context.arc(barX, barY + barHeight / 2, this._markerRadius, 0, Math.PI * 2);
+ }
+ context.stroke();
+
+ context.textBaseline = "alphabetic";
+
+ for (var i = 0; i < nextTitleIndex; ++i) {
+ var entryIndex = titleIndices[i];
+ var entryStartTime = entryStartTimes[entryIndex];
+ var barX = this._timeToPosition(entryStartTime);
+ var barRight = this._timeToPosition(entryStartTime + entryTotalTimes[entryIndex]);
+ var barWidth = Math.max(barRight - barX, minWidth);
+ var barLevel = entryLevels[entryIndex];
+ var barY = this._levelToHeight(barLevel);
+ var text = this._dataProvider.entryTitle(entryIndex);
+ if (text && text.length) {
+ context.font = this._dataProvider.entryFont(entryIndex);
+ text = this._prepareText(context, text, barWidth - 2 * textPadding);
+ }
+
+ if (this._dataProvider.decorateEntry(entryIndex, context, text, barX, barY, barWidth, barHeight, timeToPosition))
+ continue;
+ if (!text || !text.length)
+ continue;
+
+ context.fillStyle = this._dataProvider.textColor(entryIndex);
+ context.fillText(text, barX + textPadding, textBaseHeight - barLevel * this._barHeightDelta);
+ }
+ context.restore();
+
+ var offsets = this._dataProvider.dividerOffsets(this._calculator.minimumBoundary(), this._calculator.maximumBoundary());
+ WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets);
+
+ this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
+ this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
+ },
+
+ /**
+ * @param {?WebInspector.FlameChart.TimelineData} timelineData
+ */
+ _processTimelineData: function(timelineData)
+ {
+ if (!timelineData) {
+ this._timelineLevels = null;
+ this._rawTimelineData = null;
+ this._rawTimelineDataLength = 0;
+ return;
+ }
+
+ var entryCounters = new Uint32Array(this._dataProvider.maxStackDepth() + 1);
+ for (var i = 0; i < timelineData.entryLevels.length; ++i)
+ ++entryCounters[timelineData.entryLevels[i]];
+ var levelIndexes = new Array(entryCounters.length);
+ for (var i = 0; i < levelIndexes.length; ++i) {
+ levelIndexes[i] = new Uint32Array(entryCounters[i]);
+ entryCounters[i] = 0;
+ }
+ for (var i = 0; i < timelineData.entryLevels.length; ++i) {
+ var level = timelineData.entryLevels[i];
+ levelIndexes[level][entryCounters[level]++] = i;
+ }
+ this._timelineLevels = levelIndexes;
+ this._rawTimelineData = timelineData;
+ this._rawTimelineDataLength = timelineData.entryStartTimes.length;
+ },
+
+ /**
+ * @param {number} entryIndex
+ */
+ setSelectedEntry: function(entryIndex)
+ {
+ this._selectedEntryIndex = entryIndex;
+ this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
+ },
+
+ _updateElementPosition: function(element, entryIndex)
+ {
+ if (element.parentElement)
+ element.remove();
+ if (entryIndex === -1)
+ return;
+ var timeRange = this._dataProvider.highlightTimeRange(entryIndex);
+ if (!timeRange)
+ return;
+ var timelineData = this._timelineData();
+ var barX = this._timeToPosition(timeRange.startTime);
+ var barRight = this._timeToPosition(timeRange.endTime);
+ if (barRight === 0 || barX === this._canvas.width)
+ return;
+ var barWidth = Math.max(barRight - barX, this._minWidth);
+ var barY = this._levelToHeight(timelineData.entryLevels[entryIndex]) - this._scrollTop;
+ var style = element.style;
+ style.left = barX + "px";
+ style.top = barY + "px";
+ style.width = barWidth + "px";
+ style.height = this._barHeight + "px";
+ this.element.appendChild(element);
+ },
+
+ /**
+ * @param {number} time
+ */
+ _timeToPosition: function(time)
+ {
+ var value = Math.floor((time - this._minimumBoundary) * this._timeToPixel) - this._pixelWindowLeft + this._paddingLeft;
+ return Math.min(this._canvas.width, Math.max(0, value));
+ },
+
+ _levelToHeight: function(level)
+ {
+ return this._baseHeight - level * this._barHeightDelta;
+ },
+
+ _buildEntryInfo: function(entryInfo)
+ {
+ var infoTable = document.createElement("table");
+ infoTable.className = "info-table";
+ for (var i = 0; i < entryInfo.length; ++i) {
+ var row = infoTable.createChild("tr");
+ var titleCell = row.createChild("td");
+ titleCell.textContent = entryInfo[i].title;
+ titleCell.className = "title";
+ var textCell = row.createChild("td");
+ textCell.textContent = entryInfo[i].text;
+ }
+ return infoTable;
+ },
+
+ /**
+ * @param {!CanvasRenderingContext2D} context
+ * @param {string} title
+ * @param {number} maxSize
+ * @return {string}
+ */
+ _prepareText: function(context, title, maxSize)
+ {
+ var titleWidth = this._measureWidth(context, title);
+ if (maxSize >= titleWidth)
+ return title;
+
+ var l = 2;
+ var r = title.length;
+ while (l < r) {
+ var m = (l + r) >> 1;
+ if (this._measureWidth(context, title.trimMiddle(m)) <= maxSize)
+ l = m + 1;
+ else
+ r = m;
+ }
+ title = title.trimMiddle(r - 1);
+ return title !== "\u2026" ? title : "";
+ },
+
+ /**
+ * @param {!CanvasRenderingContext2D} context
+ * @param {string} text
+ * @return {number}
+ */
+ _measureWidth: function(context, text)
+ {
+ if (text.length > 20)
+ return context.measureText(text).width;
+
+ var font = context.font;
+ var textWidths = this._textWidth[font];
+ if (!textWidths) {
+ textWidths = {};
+ this._textWidth[font] = textWidths;
+ }
+ var width = textWidths[text];
+ if (!width) {
+ width = context.measureText(text).width;
+ textWidths[text] = width;
+ }
+ return width;
+ },
+
+ _updateBoundaries: function()
+ {
+ this._totalTime = this._dataProvider.totalTime();
+ this._minimumBoundary = this._dataProvider.minimumBoundary();
+
+ if (this._timeWindowRight !== Infinity) {
+ this._windowLeft = (this._timeWindowLeft - this._minimumBoundary) / this._totalTime;
+ this._windowRight = (this._timeWindowRight - this._minimumBoundary) / this._totalTime;
+ this._windowWidth = this._windowRight - this._windowLeft;
+ } else {
+ this._windowLeft = 0;
+ this._windowRight = 1;
+ this._windowWidth = 1;
+ }
+
+ this._pixelWindowWidth = this._offsetWidth - this._paddingLeft;
+ this._totalPixels = Math.floor(this._pixelWindowWidth / this._windowWidth);
+ this._pixelWindowLeft = Math.floor(this._totalPixels * this._windowLeft);
+ this._pixelWindowRight = Math.floor(this._totalPixels * this._windowRight);
+
+ this._timeToPixel = this._totalPixels / this._totalTime;
+ this._pixelToTime = this._totalTime / this._totalPixels;
+ this._paddingLeftTime = this._paddingLeft / this._timeToPixel;
+
+ this._baseHeight = this._isTopDown ? WebInspector.FlameChart.DividersBarHeight : this._offsetHeight - this._barHeight;
+
+ this._totalHeight = this._levelToHeight(this._dataProvider.maxStackDepth() + 1);
+ this._vScrollContent.style.height = this._totalHeight + "px";
+ this._scrollTop = this._vScrollElement.scrollTop;
+ this._updateScrollBar();
+ },
+
+ onResize: function()
+ {
+ this._updateScrollBar();
+ this._scheduleUpdate();
+ },
+
+ _updateScrollBar: function()
+ {
+ var showScroll = this._totalHeight > this._offsetHeight;
+ this._vScrollElement.classList.toggle("hidden", !showScroll);
+ this._offsetWidth = this.element.offsetWidth - (WebInspector.isMac() ? 0 : this._vScrollElement.offsetWidth);
+ this._offsetHeight = this.element.offsetHeight;
+ },
+
+ _scheduleUpdate: function()
+ {
+ if (this._updateTimerId)
+ return;
+ this._updateTimerId = requestAnimationFrame(this.update.bind(this));
+ },
+
+ update: function()
+ {
+ this._updateTimerId = 0;
+ if (!this._timelineData())
+ return;
+ this._resetCanvas();
+ this._updateBoundaries();
+ this._calculator._updateBoundaries(this);
+ this._draw(this._offsetWidth, this._offsetHeight);
+ },
+
+ reset: function()
+ {
+ this._highlightedEntryIndex = -1;
+ this._selectedEntryIndex = -1;
+ this._textWidth = {};
+ this.update();
+ },
+
+ __proto__: WebInspector.HBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HandlerRegistry.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js
index 1ae71e73290..5779c0a56de 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HandlerRegistry.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/HandlerRegistry.js
@@ -31,7 +31,6 @@
/**
* @constructor
* @extends {WebInspector.Object}
- * @implements {WebInspector.ContextMenu.Provider}
*/
WebInspector.HandlerRegistry = function(setting)
{
@@ -39,7 +38,6 @@ WebInspector.HandlerRegistry = function(setting)
this._handlers = {};
this._setting = setting;
this._activeHandler = this._setting.get();
- WebInspector.ContextMenu.registerProvider(this);
}
WebInspector.HandlerRegistry.prototype = {
@@ -61,6 +59,7 @@ WebInspector.HandlerRegistry.prototype = {
/**
* @param {!Object} data
+ * @return {boolean}
*/
dispatch: function(data)
{
@@ -70,6 +69,7 @@ WebInspector.HandlerRegistry.prototype = {
/**
* @param {string} name
* @param {!Object} data
+ * @return {boolean}
*/
dispatchToHandler: function(name, data)
{
@@ -90,17 +90,15 @@ WebInspector.HandlerRegistry.prototype = {
this.dispatchEventToListeners(WebInspector.HandlerRegistry.EventTypes.HandlersUpdated);
},
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
+ /**
+ * @param {string} url
*/
- appendApplicableItems: function(event, contextMenu, target)
+ _openInNewTab: function(url)
{
- this._appendContentProviderItems(contextMenu, target);
- this._appendHrefItems(contextMenu, target);
+ InspectorFrontendHost.openInNewTab(url);
},
- /**
+ /**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
@@ -112,7 +110,7 @@ WebInspector.HandlerRegistry.prototype = {
if (!contentProvider.contentURL())
return;
- contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, contentProvider.contentURL(), false));
+ contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, contentProvider.contentURL()));
// Skip 0th handler, as it's 'Use default panel' one.
for (var i = 1; i < this.handlerNames.length; ++i) {
var handler = this.handlerNames[i];
@@ -137,13 +135,12 @@ WebInspector.HandlerRegistry.prototype = {
function doSave(forceSaveAs, content)
{
var url = contentProvider.contentURL();
- WebInspector.fileManager.save(url, content, forceSaveAs);
+ WebInspector.fileManager.save(url, /** @type {string} */ (content), forceSaveAs);
WebInspector.fileManager.close(url);
}
/**
* @param {boolean} forceSaveAs
- * @this {WebInspector.HandlerRegistry}
*/
function save(forceSaveAs)
{
@@ -152,15 +149,15 @@ WebInspector.HandlerRegistry.prototype = {
uiSourceCode.saveToFileSystem(forceSaveAs);
return;
}
- contentProvider.requestContent(doSave.bind(this, forceSaveAs));
+ contentProvider.requestContent(doSave.bind(null, forceSaveAs));
}
contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(this, false));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(this, true));
+ contextMenu.appendItem(WebInspector.UIString("Save"), save.bind(null, false));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save as..." : "Save As..."), save.bind(null, true));
},
- /**
+ /**
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
@@ -179,9 +176,18 @@ WebInspector.HandlerRegistry.prototype = {
return;
// Add resource-related actions.
- contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, resourceURL, false));
+ contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), this._openInNewTab.bind(this, resourceURL));
+
+ function openInResourcesPanel(resourceURL)
+ {
+ var resource = WebInspector.resourceForURL(resourceURL);
+ if (resource)
+ WebInspector.Revealer.reveal(resource);
+ else
+ InspectorFrontendHost.openInNewTab(resourceURL);
+ }
if (WebInspector.resourceForURL(resourceURL))
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), WebInspector.openResource.bind(null, resourceURL, true));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in Resources panel" : "Open Link in Resources Panel"), openInResourcesPanel.bind(null, resourceURL));
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), InspectorFrontendHost.copyText.bind(InspectorFrontendHost, resourceURL));
},
@@ -229,6 +235,72 @@ WebInspector.HandlerSelector.prototype =
}
}
+/**
+ * @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ */
+WebInspector.HandlerRegistry.ContextMenuProvider = function()
+{
+}
+
+WebInspector.HandlerRegistry.ContextMenuProvider.prototype = {
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ WebInspector.openAnchorLocationRegistry._appendContentProviderItems(contextMenu, target);
+ WebInspector.openAnchorLocationRegistry._appendHrefItems(contextMenu, target);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Linkifier.LinkHandler}
+ */
+WebInspector.HandlerRegistry.LinkHandler = function()
+{
+}
+
+WebInspector.HandlerRegistry.LinkHandler.prototype = {
+ /**
+ * @param {string} url
+ * @param {number=} lineNumber
+ * @return {boolean}
+ */
+ handleLink: function(url, lineNumber)
+ {
+ return WebInspector.openAnchorLocationRegistry.dispatch({ url: url, lineNumber: lineNumber});
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.UISettingDelegate}
+ */
+WebInspector.HandlerRegistry.OpenAnchorLocationSettingDelegate = function()
+{
+ WebInspector.UISettingDelegate.call(this);
+}
+
+WebInspector.HandlerRegistry.OpenAnchorLocationSettingDelegate.prototype = {
+ /**
+ * @override
+ * @return {?Element}
+ */
+ settingElement: function()
+ {
+ if (!WebInspector.openAnchorLocationRegistry.handlerNames.length)
+ return null;
+
+ var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
+ return WebInspector.SettingsUI.createCustomSetting(WebInspector.UIString("Open links in"), handlerSelector.element);
+ },
+
+ __proto__: WebInspector.UISettingDelegate.prototype
+}
/**
* @type {!WebInspector.HandlerRegistry}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HelpScreen.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/HelpScreen.js
index 4865301135b..e820ea1b0af 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HelpScreen.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/HelpScreen.js
@@ -31,15 +31,15 @@
/**
* @constructor
* @param {string=} title
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.HelpScreen = function(title)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.markAsRoot();
this.registerRequiredCSS("helpScreen.css");
- this.element.className = "help-window-outer";
+ this.element.classList.add("help-window-outer");
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.element.tabIndex = 0;
@@ -88,7 +88,8 @@ WebInspector.HelpScreen.prototype = {
if (visibleHelpScreen)
visibleHelpScreen.hide();
WebInspector.HelpScreen._visibleScreen = this;
- this.show(WebInspector.inspectorView.devtoolsElement());
+ WebInspector.GlassPane.DefaultFocusedViewStack.unshift(this);
+ this.show(WebInspector.inspectorView.element);
this.focus();
},
@@ -98,6 +99,7 @@ WebInspector.HelpScreen.prototype = {
return;
WebInspector.HelpScreen._visibleScreen = null;
+ WebInspector.GlassPane.DefaultFocusedViewStack.shift();
WebInspector.restoreFocusFromElement(this.element);
this.detach();
@@ -124,33 +126,41 @@ WebInspector.HelpScreen.prototype = {
}
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
* @constructor
- * @param {string=} title
- * @param {string=} message
* @extends {WebInspector.HelpScreen}
*/
-WebInspector.HelpScreenUntilReload = function(title, message)
+WebInspector.RemoteDebuggingTerminatedScreen = function(reason)
{
- WebInspector.HelpScreen.call(this, title);
+ WebInspector.HelpScreen.call(this, WebInspector.UIString("Detached from the target"));
var p = this.contentElement.createChild("p");
p.classList.add("help-section");
- p.textContent = message;
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
+ p.createChild("span").textContent = WebInspector.UIString("Remote debugging has been terminated with reason: ");
+ p.createChild("span", "error-message").textContent = reason;
+ p.createChild("br");
+ p.createChild("span").textContent = WebInspector.UIString("Please re-attach to the new target.");
}
-WebInspector.HelpScreenUntilReload.prototype = {
- /**
- * @override
- */
- willHide: function()
- {
- WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
- WebInspector.HelpScreen.prototype.willHide.call(this);
- },
+WebInspector.RemoteDebuggingTerminatedScreen.prototype = {
+ __proto__: WebInspector.HelpScreen.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HelpScreen}
+ */
+WebInspector.WorkerTerminatedScreen = function()
+{
+ WebInspector.HelpScreen.call(this, WebInspector.UIString("Inspected worker terminated"));
+ var p = this.contentElement.createChild("p");
+ p.classList.add("help-section");
+ p.textContent = WebInspector.UIString("Inspected worker has terminated. Once it restarts we will attach to it automatically.");
+}
+
+WebInspector.WorkerTerminatedScreen.prototype = {
__proto__: WebInspector.HelpScreen.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectElementModeController.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectElementModeController.js
index 1ba844187e5..02146f17778 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/InspectElementModeController.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectElementModeController.js
@@ -31,20 +31,25 @@
*/
WebInspector.InspectElementModeController = function()
{
- this.toggleSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
- this.toggleSearchButton.addEventListener("click", this.toggleSearch, this);
+ this._toggleSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
this._shortcut = WebInspector.InspectElementModeController.createShortcut();
}
+/**
+ * @return {!WebInspector.KeyboardShortcut.Descriptor}
+ */
WebInspector.InspectElementModeController.createShortcut = function()
{
return WebInspector.KeyboardShortcut.makeDescriptor("c", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift);
}
WebInspector.InspectElementModeController.prototype = {
+ /**
+ * @return {boolean}
+ */
enabled: function()
{
- return this.toggleSearchButton.toggled;
+ return this._toggleSearchButton.toggled;
},
disable: function()
@@ -56,32 +61,55 @@ WebInspector.InspectElementModeController.prototype = {
toggleSearch: function()
{
var enabled = !this.enabled();
+ this._toggleSearchButton.toggled = enabled;
- /**
- * @param {?Protocol.Error} error
- * @this {WebInspector.InspectElementModeController}
- */
- function callback(error)
- {
- if (!error)
- this.toggleSearchButton.toggled = enabled;
- }
- WebInspector.domAgent.setInspectModeEnabled(enabled, WebInspector.settings.showShadowDOM.get(), callback.bind(this));
- },
+ var targets = WebInspector.targetManager.targets();
+ for (var i = 0; i < targets.length; ++i)
+ targets[i].domModel.setInspectModeEnabled(enabled, WebInspector.settings.showUAShadowDOM.get());
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.InspectElementModeController.ToggleSearchActionDelegate = function()
+{
+}
+WebInspector.InspectElementModeController.ToggleSearchActionDelegate.prototype = {
/**
- * @param {!KeyboardEvent} event
* @return {boolean}
*/
- handleShortcut: function(event)
+ handleAction: function()
{
- if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) !== this._shortcut.key)
+ if (!WebInspector.inspectElementModeController)
return false;
- this.toggleSearch();
- event.consume(true);
+ WebInspector.inspectElementModeController.toggleSearch();
return true;
}
}
-/** @type {!WebInspector.InspectElementModeController} */
-WebInspector.inspectElementModeController;
+/**
+ * @constructor
+ * @implements {WebInspector.StatusBarButton.Provider}
+ */
+WebInspector.InspectElementModeController.ToggleButtonProvider = function()
+{
+}
+
+WebInspector.InspectElementModeController.ToggleButtonProvider.prototype = {
+ /**
+ * @return {?WebInspector.StatusBarButton}
+ */
+ button: function()
+ {
+ if (!WebInspector.inspectElementModeController)
+ return null;
+
+ return WebInspector.inspectElementModeController._toggleSearchButton;
+ }
+}
+
+/** @type {?WebInspector.InspectElementModeController} */
+WebInspector.inspectElementModeController = null;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectedPagePlaceholder.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectedPagePlaceholder.js
new file mode 100644
index 00000000000..f2112e03516
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectedPagePlaceholder.js
@@ -0,0 +1,123 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ */
+WebInspector.InspectedPagePlaceholder = function()
+{
+ WebInspector.View.call(this);
+ this.element.classList.add("white-background");
+ WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._scheduleUpdate, this);
+ this._margins = { top: 0, right: 0, bottom: 0, left: 0 };
+ this.restoreMinimumSizeAndMargins();
+};
+
+WebInspector.InspectedPagePlaceholder.Events = {
+ Update: "Update"
+};
+
+WebInspector.InspectedPagePlaceholder.MarginValue = 3;
+
+WebInspector.InspectedPagePlaceholder.prototype = {
+ _findMargins: function()
+ {
+ var margins = { top: 0, right: 0, bottom: 0, left: 0 };
+
+ if (this._useMargins) {
+ var adjacent = { top: true, right: true, bottom: true, left: true };
+ var view = this;
+ while (view.parentView()) {
+ var parent = view.parentView();
+ // This view assumes it's always inside the main split view element, not a sidebar.
+ // Every parent which is not a split view, must be of the same size as this view.
+ if (parent instanceof WebInspector.SplitView) {
+ var side = parent.sidebarSide();
+ if (adjacent[side] && !parent.hasCustomResizer() && parent.isResizable())
+ margins[side] = WebInspector.InspectedPagePlaceholder.MarginValue;
+ adjacent[side] = false;
+ }
+ view = parent;
+ }
+ }
+
+ if (this._margins.top !== margins.top || this._margins.left !== margins.left || this._margins.right !== margins.right || this._margins.bottom !== margins.bottom) {
+ this._margins = margins;
+ this._scheduleUpdate();
+ }
+ },
+
+ onResize: function()
+ {
+ this._findMargins();
+ this._scheduleUpdate();
+ },
+
+ _scheduleUpdate: function()
+ {
+ if (this._updateId)
+ window.cancelAnimationFrame(this._updateId);
+ this._updateId = window.requestAnimationFrame(this.update.bind(this));
+ },
+
+ /**
+ * @return {!Size}
+ */
+ dipPageSize: function()
+ {
+ var rect = this._dipPageRect();
+ return new Size(Math.round(rect.width), Math.round(rect.height));
+ },
+
+ /**
+ * @return {!Size}
+ */
+ cssElementSize: function()
+ {
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var rect = this.element.getBoundingClientRect();
+ var width = rect.width - (this._margins.left + this._margins.right) / zoomFactor;
+ var height = rect.height - (this._margins.top + this._margins.bottom) / zoomFactor;
+ return new Size(width, height);
+ },
+
+ restoreMinimumSizeAndMargins: function()
+ {
+ this._useMargins = true;
+ this.setMinimumSize(50, 50);
+ this._findMargins();
+ },
+
+ clearMinimumSizeAndMargins: function()
+ {
+ this._useMargins = false;
+ this.setMinimumSize(1, 1);
+ this._findMargins();
+ },
+
+ _dipPageRect: function()
+ {
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var rect = this.element.getBoundingClientRect();
+ var bodyRect = document.body.getBoundingClientRect();
+
+ var left = Math.max(rect.left * zoomFactor + this._margins.left, bodyRect.left * zoomFactor);
+ var top = Math.max(rect.top * zoomFactor + this._margins.top, bodyRect.top * zoomFactor);
+ var bottom = Math.min(rect.bottom * zoomFactor - this._margins.bottom, bodyRect.bottom * zoomFactor);
+ var right = Math.min(rect.right * zoomFactor - this._margins.right, bodyRect.right * zoomFactor);
+
+ return { x: left, y: top, width: right - left, height: bottom - top };
+ },
+
+ update: function()
+ {
+ delete this._updateId;
+ var rect = this._dipPageRect();
+ var bounds = { x: Math.round(rect.x), y: Math.round(rect.y), height: Math.max(1, Math.round(rect.height)), width: Math.max(1, Math.round(rect.width)) };
+ this.dispatchEventToListeners(WebInspector.InspectedPagePlaceholder.Events.Update, bounds);
+ },
+
+ __proto__: WebInspector.View.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorView.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectorView.js
index a29a798a8fa..799c24b9c50 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/InspectorView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/InspectorView.js
@@ -30,34 +30,27 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.InspectorView = function()
{
- WebInspector.View.call(this);
- this.markAsRoot();
- this.element.classList.add("fill", "vbox", "inspector-view");
- this.element.setAttribute("spellcheck", false);
-
- this._splitView = new WebInspector.SplitView(false, "InspectorView.splitView", 300, 300);
- this._splitView.setSecondIsSidebar(true);
- this._splitView.setSidebarElementConstraints(150, 50);
- this._splitView.setMainElementConstraints(50, 50);
- WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._updateSplitView.bind(this));
-
- this._splitView.element.id = "inspector-split-view";
- this._splitView.show(this.element);
-
- this._overlayView = new WebInspector.ViewWithResizeCallback(this._onOverlayResized.bind(this));
- this._overlayView.show(this._splitView.mainElement);
+ WebInspector.VBox.call(this);
+ WebInspector.Dialog.setModalHostView(this);
+ WebInspector.GlassPane.DefaultFocusedViewStack.unshift(this);
+ this.setMinimumSize(180, 72);
- this._devtoolsElement = this._splitView.sidebarElement;
- this._devtoolsElement.classList.add("vbox");
+ // DevTools sidebar is a vertical split of panels tabbed pane and a drawer.
+ this._drawerSplitView = new WebInspector.SplitView(false, true, "Inspector.drawerSplitViewState", 200, 200);
+ this._drawerSplitView.hideSidebar();
+ this._drawerSplitView.enableShowModeSaving();
+ this._drawerSplitView.show(this.element);
this._tabbedPane = new WebInspector.TabbedPane();
- this._tabbedPane.setRetainTabsOrder(true);
- this._tabbedPane.show(this._devtoolsElement);
+ this._tabbedPane.setRetainTabOrder(true, WebInspector.moduleManager.orderComparator(WebInspector.Panel, "name", "order"));
+ this._tabbedPane.show(this._drawerSplitView.mainElement());
+ this._drawer = new WebInspector.Drawer(this._drawerSplitView);
+ // Patch tabbed pane header with toolbar actions.
this._toolbarElement = document.createElement("div");
this._toolbarElement.className = "toolbar toolbar-background";
var headerElement = this._tabbedPane.headerElement();
@@ -67,12 +60,27 @@ WebInspector.InspectorView = function()
this._toolbarElement.appendChild(headerElement);
this._rightToolbarElement = this._toolbarElement.createChild("div", "toolbar-controls-right");
+ if (WebInspector.experimentsSettings.devicesPanel.isEnabled()) {
+ this._remoteDeviceCountElement = this._rightToolbarElement.createChild("div", "hidden");
+ this._remoteDeviceCountElement.addEventListener("click", this.showViewInDrawer.bind(this, "devices", true), false);
+ this._remoteDeviceCountElement.id = "remote-device-count";
+ WebInspector.inspectorFrontendEventSink.addEventListener(WebInspector.InspectorView.Events.DeviceCountChanged, this._onDeviceCountChanged, this);
+ }
+
this._errorWarningCountElement = this._rightToolbarElement.createChild("div", "hidden");
this._errorWarningCountElement.id = "error-warning-count";
- this._drawer = new WebInspector.Drawer(this);
+ this._closeButtonToolbarItem = document.createElementWithClass("div", "toolbar-close-button-item");
+ var closeButtonElement = this._closeButtonToolbarItem.createChild("div", "close-button");
+ closeButtonElement.addEventListener("click", InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost), true);
+ this._rightToolbarElement.appendChild(this._closeButtonToolbarItem);
+
this.appendToRightToolbar(this._drawer.toggleButtonElement());
+ this._panels = {};
+ // Used by tests.
+ WebInspector["panels"] = this._panels;
+
this._history = [];
this._historyIterator = -1;
document.addEventListener("keydown", this._keyDown.bind(this), false);
@@ -84,10 +92,29 @@ WebInspector.InspectorView = function()
this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
this._lastActivePanelSetting = WebInspector.settings.createSetting("lastActivePanel", "elements");
- this._updateSplitView();
+ this._loadPanelDesciptors();
+};
+
+WebInspector.InspectorView.Events = {
+ DeviceCountChanged: "DeviceCountChanged"
}
WebInspector.InspectorView.prototype = {
+ _loadPanelDesciptors: function()
+ {
+ WebInspector.startBatchUpdate();
+ WebInspector.moduleManager.extensions(WebInspector.Panel).forEach(processPanelExtensions.bind(this));
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @this {!WebInspector.InspectorView}
+ */
+ function processPanelExtensions(extension)
+ {
+ this.addPanel(new WebInspector.ModuleManagerExtensionPanelDescriptor(extension));
+ }
+ WebInspector.endBatchUpdate();
+ },
+
/**
* @param {!Element} element
*/
@@ -101,23 +128,7 @@ WebInspector.InspectorView.prototype = {
*/
appendToRightToolbar: function(element)
{
- this._rightToolbarElement.appendChild(element);
- },
-
- /**
- * @return {!WebInspector.Drawer}
- */
- drawer: function()
- {
- return this._drawer;
- },
-
- /**
- * @return {!Element}
- */
- devtoolsElement: function()
- {
- return this._devtoolsElement;
+ this._rightToolbarElement.insertBefore(element, this._closeButtonToolbarItem);
},
/**
@@ -134,6 +145,15 @@ WebInspector.InspectorView.prototype = {
/**
* @param {string} panelName
+ * @return {boolean}
+ */
+ hasPanel: function(panelName)
+ {
+ return !!this._panelDescriptors[panelName];
+ },
+
+ /**
+ * @param {string} panelName
* @return {?WebInspector.Panel}
*/
panel: function(panelName)
@@ -142,7 +162,10 @@ WebInspector.InspectorView.prototype = {
var panelOrder = this._tabbedPane.allTabs();
if (!panelDescriptor && panelOrder.length)
panelDescriptor = this._panelDescriptors[panelOrder[0]];
- return panelDescriptor ? panelDescriptor.panel() : null;
+ var panel = panelDescriptor ? panelDescriptor.panel() : null;
+ if (panel)
+ this._panels[panelName] = panel;
+ return panel;
},
/**
@@ -169,13 +192,42 @@ WebInspector.InspectorView.prototype = {
{
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
this._tabSelected();
- this._drawer.showOnLoadIfNecessary();
+ this._drawer.initialPanelShown();
+ },
+
+ showDrawerEditor: function()
+ {
+ this._drawer.showDrawerEditor();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isDrawerEditorShown: function()
+ {
+ return this._drawer.isDrawerEditorShown();
+ },
+
+ hideDrawerEditor: function()
+ {
+ this._drawer.hideDrawerEditor();
+ },
+
+ /**
+ * @param {boolean} available
+ */
+ setDrawerEditorAvailable: function(available)
+ {
+ this._drawer.setDrawerEditorAvailable(available);
},
_tabSelected: function()
{
var panelName = this._tabbedPane.selectedTabId;
+ if (!panelName)
+ return;
var panel = this._panelDescriptors[this._tabbedPane.selectedTabId].panel();
+ this._panels[panelName] = panel;
this._tabbedPane.changeTabView(panelName, panel);
this._currentPanel = panel;
@@ -202,7 +254,7 @@ WebInspector.InspectorView.prototype = {
*/
closeViewInDrawer: function(id)
{
- return this._drawer.closeView(id);
+ this._drawer.closeView(id);
},
/**
@@ -215,34 +267,30 @@ WebInspector.InspectorView.prototype = {
this._drawer.showCloseableView(id, title, view);
},
- /**
- * @param {string} id
- * @param {string} title
- * @param {!WebInspector.ViewFactory} factory
- */
- registerViewInDrawer: function(id, title, factory)
+ showDrawer: function()
{
- this._drawer.registerView(id, title, factory);
+ this._drawer.showDrawer();
},
/**
- * @param {string} id
+ * @return {boolean}
*/
- unregisterViewInDrawer: function(id)
+ drawerVisible: function()
{
- this._drawer.unregisterView(id);
+ return this._drawer.isShowing();
},
/**
* @param {string} id
+ * @param {boolean=} immediate
*/
- showViewInDrawer: function(id)
+ showViewInDrawer: function(id, immediate)
{
- this._drawer.showView(id);
+ this._drawer.showView(id, immediate);
},
/**
- * @return {string}
+ * @return {?string}
*/
selectedViewInDrawer: function()
{
@@ -251,7 +299,7 @@ WebInspector.InspectorView.prototype = {
closeDrawer: function()
{
- this._drawer.hide();
+ this._drawer.closeDrawer();
},
/**
@@ -289,7 +337,8 @@ WebInspector.InspectorView.prototype = {
if (panelIndex !== -1) {
var panelName = this._tabbedPane.allTabs()[panelIndex];
if (panelName) {
- this.showPanel(panelName);
+ if (!WebInspector.Dialog.currentInstance())
+ this.showPanel(panelName);
event.consume(true);
}
return;
@@ -309,67 +358,49 @@ WebInspector.InspectorView.prototype = {
_keyDownInternal: function(event)
{
- if (this._openBracketIdentifiers[event.keyIdentifier]) {
- var isRotateLeft = !event.shiftKey && !event.altKey;
- if (isRotateLeft) {
- var panelOrder = this._tabbedPane.allTabs();
- var index = panelOrder.indexOf(this.currentPanel().name);
- index = (index === 0) ? panelOrder.length - 1 : index - 1;
- this.showPanel(panelOrder[index]);
- event.consume(true);
- return;
- }
+ var direction = 0;
- var isGoBack = event.altKey;
- if (isGoBack && this._canGoBackInHistory()) {
- this._goBackInHistory();
- event.consume(true);
- }
- return;
- }
+ if (this._openBracketIdentifiers[event.keyIdentifier])
+ direction = -1;
- if (this._closeBracketIdentifiers[event.keyIdentifier]) {
- var isRotateRight = !event.shiftKey && !event.altKey;
- if (isRotateRight) {
- var panelOrder = this._tabbedPane.allTabs();
- var index = panelOrder.indexOf(this.currentPanel().name);
- index = (index + 1) % panelOrder.length;
- this.showPanel(panelOrder[index]);
- event.consume(true);
- return;
- }
+ if (this._closeBracketIdentifiers[event.keyIdentifier])
+ direction = 1;
- var isGoForward = event.altKey;
- if (isGoForward && this._canGoForwardInHistory()) {
- this._goForwardInHistory();
- event.consume(true);
- }
+ if (!direction)
+ return;
+
+ if (!event.shiftKey && !event.altKey) {
+ if (!WebInspector.Dialog.currentInstance())
+ this._changePanelInDirection(direction);
+ event.consume(true);
return;
}
- },
- _canGoBackInHistory: function()
- {
- return this._historyIterator > 0;
+ if (event.altKey && this._moveInHistory(direction))
+ event.consume(true)
},
- _goBackInHistory: function()
+ _changePanelInDirection: function(direction)
{
- this._inHistory = true;
- this.setCurrentPanel(WebInspector.panels[this._history[--this._historyIterator]]);
- delete this._inHistory;
+ var panelOrder = this._tabbedPane.allTabs();
+ var index = panelOrder.indexOf(this.currentPanel().name);
+ index = (index + panelOrder.length + direction) % panelOrder.length;
+ this.showPanel(panelOrder[index]);
},
- _canGoForwardInHistory: function()
+ _moveInHistory: function(move)
{
- return this._historyIterator < this._history.length - 1;
- },
+ var newIndex = this._historyIterator + move;
+ if (newIndex >= this._history.length || newIndex < 0)
+ return false;
- _goForwardInHistory: function()
- {
this._inHistory = true;
- this.setCurrentPanel(WebInspector.panels[this._history[++this._historyIterator]]);
+ this._historyIterator = newIndex;
+ if (!WebInspector.Dialog.currentInstance())
+ this.setCurrentPanel(this._panels[this._history[this._historyIterator]]);
delete this._inHistory;
+
+ return true;
},
_pushToHistory: function(panelName)
@@ -385,42 +416,26 @@ WebInspector.InspectorView.prototype = {
onResize: function()
{
- // FIXME: make drawer a view.
- this.doResize();
- this._drawer.resize();
- },
-
- _updateSplitView: function()
- {
- var dockSide = WebInspector.dockController.dockSide();
- if (WebInspector.queryParamsObject["overlayContents"] && dockSide !== WebInspector.DockController.State.Undocked) {
- this._splitView.showBoth();
- var vertical = dockSide === WebInspector.DockController.State.DockedToRight;
- this._splitView.setVertical(vertical);
- if (vertical) {
- this._splitView.uninstallResizer(this._tabbedPane.headerElement());
- this._splitView.installResizer(this._splitView.resizerElement());
- } else {
- this._splitView.uninstallResizer(this._splitView.resizerElement());
- this._splitView.installResizer(this._tabbedPane.headerElement());
- }
- } else {
- this._splitView.showOnlySecond();
- }
+ WebInspector.Dialog.modalHostRepositioned();
},
- _onOverlayResized: function()
+ /**
+ * @return {!Element}
+ */
+ topResizerElement: function()
{
- var dockSide = WebInspector.dockController.dockSide();
- if (WebInspector.queryParamsObject["overlayContents"] && dockSide !== WebInspector.DockController.State.Undocked) {
- // Leave 3px room for resizer.
- var bottom = this._splitView.isVertical() ? 0 : this._splitView.sidebarSize();
- var right = this._splitView.isVertical() ? this._splitView.sidebarSize() + 3 : 0;
- InspectorFrontendHost.setContentsInsets(0, 0, bottom, right);
- }
+ return this._tabbedPane.headerElement();
+ },
- // FIXME: make drawer a view.
- this._drawer.resize();
+ _createImagedCounterElementIfNeeded: function(parent, count, id, styleName)
+ {
+ if (!count)
+ return;
+
+ var imageElement = parent.createChild("div", styleName);
+ var counterElement = parent.createChild("span");
+ counterElement.id = id;
+ counterElement.textContent = count;
},
/**
@@ -429,58 +444,117 @@ WebInspector.InspectorView.prototype = {
*/
setErrorAndWarningCounts: function(errors, warnings)
{
- if (!errors && !warnings) {
- this._errorWarningCountElement.classList.add("hidden");
- this._tabbedPane.headerResized();
+ if (this._errors === errors && this._warnings === warnings)
return;
- }
-
- this._errorWarningCountElement.classList.remove("hidden");
+ this._errors = errors;
+ this._warnings = warnings;
+ this._errorWarningCountElement.classList.toggle("hidden", !errors && !warnings);
this._errorWarningCountElement.removeChildren();
- if (errors) {
- var errorImageElement = this._errorWarningCountElement.createChild("div", "error-icon-small");
- var errorElement = this._errorWarningCountElement.createChild("span");
- errorElement.id = "error-count";
- errorElement.textContent = errors;
- }
-
- if (warnings) {
- var warningsImageElement = this._errorWarningCountElement.createChild("div", "warning-icon-small");
- var warningsElement = this._errorWarningCountElement.createChild("span");
- warningsElement.id = "warning-count";
- warningsElement.textContent = warnings;
- }
+ this._createImagedCounterElementIfNeeded(this._errorWarningCountElement, errors, "error-count", "error-icon-small");
+ this._createImagedCounterElementIfNeeded(this._errorWarningCountElement, warnings, "warning-count", "warning-icon-small");
- if (errors) {
- if (warnings) {
- if (errors == 1) {
- if (warnings == 1)
- this._errorWarningCountElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings);
- else
- this._errorWarningCountElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings);
- } else if (warnings == 1)
- this._errorWarningCountElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings);
- else
- this._errorWarningCountElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings);
- } else if (errors == 1)
- this._errorWarningCountElement.title = WebInspector.UIString("%d error", errors);
- else
- this._errorWarningCountElement.title = WebInspector.UIString("%d errors", errors);
- } else if (warnings == 1)
- this._errorWarningCountElement.title = WebInspector.UIString("%d warning", warnings);
- else if (warnings)
- this._errorWarningCountElement.title = WebInspector.UIString("%d warnings", warnings);
- else
- this._errorWarningCountElement.title = null;
+ var errorString = errors ? WebInspector.UIString("%d error%s", errors, errors > 1 ? "s" : "") : "";
+ var warningString = warnings ? WebInspector.UIString("%d warning%s", warnings, warnings > 1 ? "s" : "") : "";
+ var commaString = errors && warnings ? ", " : "";
+ this._errorWarningCountElement.title = errorString + commaString + warningString;
+ this._tabbedPane.headerResized();
+ },
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onDeviceCountChanged: function(event)
+ {
+ var count = /** @type {number} */ (event.data);
+ if (count === this.deviceCount_)
+ return;
+ this.deviceCount_ = count;
+ this._remoteDeviceCountElement.classList.toggle("hidden", !count);
+ this._remoteDeviceCountElement.removeChildren();
+ this._createImagedCounterElementIfNeeded(this._remoteDeviceCountElement, count, "device-count", "device-icon-small");
+ this._remoteDeviceCountElement.title = WebInspector.UIString(((count > 1) ? "%d devices found" : "%d device found"), count);
this._tabbedPane.headerResized();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
};
/**
* @type {!WebInspector.InspectorView}
*/
WebInspector.inspectorView;
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.InspectorView.DrawerToggleActionDelegate = function()
+{
+}
+
+WebInspector.InspectorView.DrawerToggleActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ if (WebInspector.inspectorView.drawerVisible()) {
+ WebInspector.inspectorView.closeDrawer();
+ return true;
+ }
+ WebInspector.inspectorView.showDrawer();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.RootView = function()
+{
+ WebInspector.VBox.call(this);
+ this.markAsRoot();
+ this.element.classList.add("root-view");
+ this.element.setAttribute("spellcheck", false);
+ window.addEventListener("resize", this.doResize.bind(this), true);
+ this._onScrollBound = this._onScroll.bind(this);
+};
+
+WebInspector.RootView.prototype = {
+ attachToBody: function()
+ {
+ this.doResize();
+ this.show(document.body);
+ },
+
+ _onScroll: function()
+ {
+ // If we didn't have enough space at the start, we may have wrong scroll offsets.
+ if (document.body.scrollTop !== 0)
+ document.body.scrollTop = 0;
+ if (document.body.scrollLeft !== 0)
+ document.body.scrollLeft = 0;
+ },
+
+ doResize: function()
+ {
+ var size = this.constraints().minimum;
+ var zoom = WebInspector.zoomManager.zoomFactor();
+ var right = Math.min(0, window.innerWidth - size.width / zoom);
+ this.element.style.right = right + "px";
+ var bottom = Math.min(0, window.innerHeight - size.height / zoom);
+ this.element.style.bottom = bottom + "px";
+
+ if (window.innerWidth < size.width || window.innerHeight < size.height)
+ window.addEventListener("scroll", this._onScrollBound, false);
+ else
+ window.removeEventListener("scroll", this._onScrollBound, false);
+
+ WebInspector.VBox.prototype.doResize.call(this);
+ this._onScroll();
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NativeBreakpointsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/NativeBreakpointsSidebarPane.js
index 6e723c47321..6e723c47321 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NativeBreakpointsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/NativeBreakpointsSidebarPane.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ObjectPopoverHelper.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js
index b963706d996..9253777f1dd 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ObjectPopoverHelper.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js
@@ -62,18 +62,17 @@ WebInspector.ObjectPopoverHelper.prototype = {
_showObjectPopover: function(element, popover)
{
/**
+ * @param {!WebInspector.Target} target
* @param {!Element} anchorElement
* @param {!Element} popoverContentElement
- * @param {?Protocol.Error} error
- * @param {!DebuggerAgent.FunctionDetails} response
+ * @param {?DebuggerAgent.FunctionDetails} response
* @this {WebInspector.ObjectPopoverHelper}
*/
- function didGetDetails(anchorElement, popoverContentElement, error, response)
+ function didGetDetails(target, anchorElement, popoverContentElement, response)
{
- if (error) {
- console.error(error);
+ if (!response)
return;
- }
+
var container = document.createElement("div");
container.className = "inline-block";
@@ -82,7 +81,7 @@ WebInspector.ObjectPopoverHelper.prototype = {
functionName.textContent = response.functionName || WebInspector.UIString("(anonymous function)");
this._linkifier = new WebInspector.Linkifier();
- var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (response.location);
+ var rawLocation = WebInspector.DebuggerModel.Location.fromPayload(target, response.location);
var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link");
if (link)
title.appendChild(link);
@@ -117,15 +116,17 @@ WebInspector.ObjectPopoverHelper.prototype = {
popoverContentElement.style.whiteSpace = "pre";
popoverContentElement.textContent = description;
if (result.type === "function") {
- DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this, anchorElement, popoverContentElement));
+ result.functionDetails(didGetDetails.bind(this, result.target(), anchorElement, popoverContentElement));
return;
}
if (result.type === "string")
popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\"";
popover.show(popoverContentElement, anchorElement);
} else {
- if (result.subtype === "node")
+ if (result.subtype === "node") {
result.highlightAsDOMNode();
+ this._resultHighlightedAsDOM = result;
+ }
popoverContentElement = document.createElement("div");
this._titleElement = document.createElement("div");
this._titleElement.className = "source-frame-popover-title monospace";
@@ -153,7 +154,10 @@ WebInspector.ObjectPopoverHelper.prototype = {
_onHideObjectPopover: function()
{
- WebInspector.domAgent.hideDOMNodeHighlight();
+ if (this._resultHighlightedAsDOM) {
+ this._resultHighlightedAsDOM.target().domModel.hideDOMNodeHighlight();
+ delete this._resultHighlightedAsDOM;
+ }
if (this._linkifier) {
this._linkifier.reset();
delete this._linkifier;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ObjectPropertiesSection.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
index 0146ba3c056..444f20361c2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ObjectPropertiesSection.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/ObjectPropertiesSection.js
@@ -138,6 +138,10 @@ WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, pro
return 1;
if (b === "__proto__")
return -1;
+ if (propertyA.symbol && !propertyB.symbol)
+ return 1;
+ if (propertyB.symbol && !propertyA.symbol)
+ return -1;
return String.naturalOrderComparator(a, b);
}
@@ -161,11 +165,12 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
{
var propertyValue = /** @type {!WebInspector.RemoteObject} */ (this.property.value);
console.assert(propertyValue);
- return WebInspector.ObjectPropertyTreeElement.populate(this, propertyValue);
+ WebInspector.ObjectPropertyTreeElement.populate(this, propertyValue);
},
/**
* @override
+ * @return {boolean}
*/
ondblclick: function(event)
{
@@ -194,6 +199,8 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.nameElement.classList.add("dimmed");
if (this.property.isAccessorProperty())
this.nameElement.classList.add("properties-accessor-property-name");
+ if (this.property.symbol)
+ this.nameElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.symbol), false);
var separatorElement = document.createElement("span");
separatorElement.className = "separator";
@@ -203,18 +210,20 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.valueElement = document.createElement("span");
this.valueElement.className = "value";
var description = this.property.value.description;
- // Render \n as a nice unicode cr symbol.
+ var valueText;
if (this.property.wasThrown) {
- this.valueElement.textContent = "[Exception: " + description + "]";
+ valueText = "[Exception: " + description + "]";
} else if (this.property.value.type === "string" && typeof description === "string") {
- this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
+ // Render \n as a nice unicode cr symbol.
+ valueText = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
this.valueElement._originalTextContent = "\"" + description + "\"";
} else if (this.property.value.type === "function" && typeof description === "string") {
- this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
+ valueText = /.*/.exec(description)[0].replace(/ +$/g, "");
this.valueElement._originalTextContent = description;
} else if (this.property.value.type !== "object" || this.property.value.subtype !== "node") {
- this.valueElement.textContent = description;
+ valueText = description;
}
+ this.valueElement.setTextContentTruncatedIfNeeded(valueText || "");
if (this.property.wasThrown)
this.valueElement.classList.add("error");
@@ -284,31 +293,40 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.parent.shouldRefreshChildren = true;
},
+ /**
+ * @return {boolean}
+ */
renderPromptAsBlock: function()
{
return false;
},
/**
- * @param {!Event=} event
+ * @return {{element: !Element, value: (string|undefined)}}
*/
- elementAndValueToEdit: function(event)
+ elementAndValueToEdit: function()
{
- return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
+ return {
+ element: this.valueElement,
+ value: (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined
+ };
},
+ /**
+ * @param {!Event=} event
+ */
startEditing: function(event)
{
- var elementAndValueToEdit = this.elementAndValueToEdit(event);
- var elementToEdit = elementAndValueToEdit[0];
- var valueToEdit = elementAndValueToEdit[1];
+ var elementAndValueToEdit = this.elementAndValueToEdit();
+ var elementToEdit = elementAndValueToEdit.element;
+ var valueToEdit = elementAndValueToEdit.value;
if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
return;
// Edit original source.
if (typeof valueToEdit !== "undefined")
- elementToEdit.textContent = valueToEdit;
+ elementToEdit.setTextContentTruncatedIfNeeded(valueToEdit, WebInspector.UIString("<string is too large to edit>"));
var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };
@@ -317,7 +335,7 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.listItemElement.classList.add("editing-sub-part");
- this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());
+ this._prompt = new WebInspector.ObjectPropertyPrompt(this.renderPromptAsBlock());
/**
* @this {WebInspector.ObjectPropertyTreeElement}
@@ -359,29 +377,39 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
editingCommitted: function(element, userInput, previousContent, context)
{
- if (userInput === previousContent)
- return this.editingCancelled(element, context); // nothing changed, so cancel
+ if (userInput === previousContent) {
+ this.editingCancelled(element, context); // nothing changed, so cancel
+ return;
+ }
this.editingEnded(context);
- this.applyExpression(userInput, true);
+ this.applyExpression(userInput);
},
_promptKeyDown: function(context, event)
{
if (isEnterKey(event)) {
event.consume(true);
- return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
+ this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
+ return;
}
if (event.keyIdentifier === "U+001B") { // Esc
event.consume();
- return this.editingCancelled(null, context);
+ this.editingCancelled(null, context);
+ return;
}
},
- applyExpression: function(expression, updateInterface)
+ /**
+ * @param {string} expression
+ */
+ applyExpression: function(expression)
{
expression = expression.trim();
- var expressionLength = expression.length;
+ if (expression)
+ this.property.parentObject.setPropertyValue(this.property.name, expression, callback.bind(this));
+ else
+ this.property.parentObject.deleteProperty(this.property.name, callback.bind(this));
/**
* @param {?Protocol.Error} error
@@ -389,13 +417,12 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
*/
function callback(error)
{
- if (!updateInterface)
- return;
-
- if (error)
+ if (error) {
this.update();
+ return;
+ }
- if (!expressionLength) {
+ if (!expression) {
// The property was deleted, so remove this tree element.
this.parent.removeChild(this);
} else {
@@ -403,9 +430,11 @@ WebInspector.ObjectPropertyTreeElement.prototype = {
this.updateSiblings();
}
};
- this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this));
},
+ /**
+ * @return {string|undefined}
+ */
propertyPath: function()
{
if ("_cachedPropertyPath" in this)
@@ -587,16 +616,13 @@ WebInspector.FunctionScopeMainTreeElement.prototype = {
return;
/**
- * @param {?Protocol.Error} error
- * @param {!DebuggerAgent.FunctionDetails} response
+ * @param {?DebuggerAgent.FunctionDetails} response
* @this {WebInspector.FunctionScopeMainTreeElement}
*/
- function didGetDetails(error, response)
+ function didGetDetails(response)
{
- if (error) {
- console.error(error);
+ if (!response)
return;
- }
this.removeChildren();
var scopeChain = response.scopeChain;
@@ -634,20 +660,22 @@ WebInspector.FunctionScopeMainTreeElement.prototype = {
continue;
}
- var scopeRef = isTrueObject ? undefined : new WebInspector.ScopeRef(i, undefined, this._remoteObject.objectId);
- var remoteObject = WebInspector.ScopeRemoteObject.fromPayload(scope.object, scopeRef);
+ var runtimeModel = this._remoteObject.target().runtimeModel;
if (isTrueObject) {
- var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
+ var remoteObject = runtimeModel.createRemoteObject(scope.object);
+ var property = new WebInspector.RemoteObjectProperty(title, remoteObject);
+ property.writable = false;
property.parentObject = null;
this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
} else {
+ var scopeRef = new WebInspector.ScopeRef(i, undefined, this._remoteObject.objectId);
+ var remoteObject = runtimeModel.createScopeRemoteObject(scope.object, scopeRef);
var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
this.appendChild(scopeTreeElement);
}
}
-
}
- DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
+ this._remoteObject.functionDetails(didGetDetails.bind(this));
},
__proto__: TreeElement.prototype
@@ -656,6 +684,8 @@ WebInspector.FunctionScopeMainTreeElement.prototype = {
/**
* @constructor
* @extends {TreeElement}
+ * @param {string} title
+ * @param {?string} subtitle
* @param {!WebInspector.RemoteObject} remoteObject
*/
WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
@@ -671,7 +701,7 @@ WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
WebInspector.ScopeTreeElement.prototype = {
onpopulate: function()
{
- return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
+ WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
},
__proto__: TreeElement.prototype
@@ -720,9 +750,10 @@ WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, obj
*/
WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel)
{
- object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], callback.bind(this));
+ object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], callback);
/**
+ * @suppressReceiverCheck
* @this {Object}
* @param {number=} fromIndex // must declare optional
* @param {number=} toIndex // must declare optional
@@ -822,6 +853,7 @@ WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement
object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._sparseIterationThreshold}], processArrayFragment.bind(this));
/**
+ * @suppressReceiverCheck
* @this {Object}
* @param {number=} fromIndex // must declare optional
* @param {number=} toIndex // must declare optional
@@ -884,7 +916,10 @@ WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(tre
{
object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this));
- /** @this {Object} */
+ /**
+ * @suppressReceiverCheck
+ * @this {Object}
+ */
function buildObjectFragment()
{
var result = Object.create(this.__proto__);
@@ -960,10 +995,10 @@ WebInspector.ArrayGroupingTreeElement.prototype = {
* @extends {WebInspector.TextPrompt}
* @param {boolean=} renderAsBlock
*/
-WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
+WebInspector.ObjectPropertyPrompt = function(renderAsBlock)
{
- WebInspector.TextPrompt.call(this, WebInspector.runtimeModel.completionsForTextPrompt.bind(WebInspector.runtimeModel));
- this.setSuggestBoxEnabled("generic-suggest");
+ WebInspector.TextPrompt.call(this, WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);
+ this.setSuggestBoxEnabled(true);
if (renderAsBlock)
this.renderAsBlock();
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/OverviewGrid.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/OverviewGrid.js
index 7fdce6c0f06..4d8db240f38 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/OverviewGrid.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/OverviewGrid.js
@@ -252,8 +252,8 @@ WebInspector.OverviewGrid.Window.prototype = {
{
if (!this._enabled)
return false;
- this._offsetLeft = event.pageX - event.offsetX;
- var position = event.pageX - this._offsetLeft;
+ this._offsetLeft = this._parentElement.totalOffsetLeft();
+ var position = event.x - this._offsetLeft;
this._overviewWindowSelector = new WebInspector.OverviewGrid.WindowSelector(this._parentElement, position);
return true;
},
@@ -263,7 +263,7 @@ WebInspector.OverviewGrid.Window.prototype = {
*/
_windowSelectorDragging: function(event)
{
- this._overviewWindowSelector._updatePosition(event.pageX - this._offsetLeft);
+ this._overviewWindowSelector._updatePosition(event.x - this._offsetLeft);
event.preventDefault();
},
@@ -272,7 +272,7 @@ WebInspector.OverviewGrid.Window.prototype = {
*/
_endWindowSelectorDragging: function(event)
{
- var window = this._overviewWindowSelector._close(event.pageX - this._offsetLeft);
+ var window = this._overviewWindowSelector._close(event.x - this._offsetLeft);
delete this._overviewWindowSelector;
if (window.end === window.start) { // Click, not drag.
var middle = window.end;
@@ -459,18 +459,6 @@ WebInspector.OverviewGrid.WindowSelector = function(parent, position)
}
WebInspector.OverviewGrid.WindowSelector.prototype = {
- _createSelectorElement: function(parent, left, width, height)
- {
- var selectorElement = document.createElement("div");
- selectorElement.className = "overview-grid-window-selector";
- selectorElement.style.left = left + "px";
- selectorElement.style.width = width + "px";
- selectorElement.style.top = "0px";
- selectorElement.style.height = height + "px";
- parent.appendChild(selectorElement);
- return selectorElement;
- },
-
_close: function(position)
{
position = Math.max(0, Math.min(position, this._width));
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Panel.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/Panel.js
index f8b6ad02014..fc099898e48 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Panel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/Panel.js
@@ -27,21 +27,18 @@
*/
/**
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @constructor
*/
WebInspector.Panel = function(name)
{
- WebInspector.View.call(this);
- WebInspector.panels[name] = this;
+ WebInspector.VBox.call(this);
this.element.classList.add("panel");
this.element.classList.add(name);
this._panelName = name;
this._shortcuts = /** !Object.<number, function(Event=):boolean> */ ({});
-
- WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined);
}
// Should by in sync with style declarations.
@@ -57,9 +54,12 @@ WebInspector.Panel.prototype = {
{
},
+ /**
+ * @return {!Element}
+ */
defaultFocusedElement: function()
{
- return this.sidebarTreeElement || this.element;
+ return this.element;
},
/**
@@ -86,78 +86,8 @@ WebInspector.Panel.prototype = {
},
/**
- * @param {!Element=} parentElement
- * @param {string=} position
- * @param {number=} defaultWidth
- * @param {number=} defaultHeight
- */
- createSidebarView: function(parentElement, position, defaultWidth, defaultHeight)
- {
- if (this.splitView)
- return;
-
- if (!parentElement)
- parentElement = this.element;
-
- this.splitView = new WebInspector.SidebarView(position, this._sidebarWidthSettingName(), defaultWidth, defaultHeight);
- this.splitView.show(parentElement);
- this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this.sidebarResized.bind(this));
-
- this.sidebarElement = this.splitView.sidebarElement;
- },
-
- /**
- * @param {!Element=} parentElement
- * @param {string=} position
- * @param {number=} defaultWidth
+ * @return {!Array.<!Element>}
*/
- createSidebarViewWithTree: function(parentElement, position, defaultWidth)
- {
- if (this.splitView)
- return;
-
- this.createSidebarView(parentElement, position);
-
- this.sidebarTreeElement = document.createElement("ol");
- this.sidebarTreeElement.className = "sidebar-tree";
- this.splitView.sidebarElement.appendChild(this.sidebarTreeElement);
- this.splitView.sidebarElement.classList.add("sidebar");
-
- this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
- this.sidebarTree.panel = this;
- },
-
- _sidebarWidthSettingName: function()
- {
- return this._panelName + "SidebarWidth";
- },
-
- // Should be implemented by ancestors.
-
- get statusBarItems()
- {
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- sidebarResized: function(event)
- {
- },
-
- statusBarResized: function()
- {
- },
-
- /**
- * @param {!Element} anchor
- * @return {boolean}
- */
- showAnchorLocation: function(anchor)
- {
- return false;
- },
-
elementsToRestoreScrollPositionsFor: function()
{
return [];
@@ -205,30 +135,100 @@ WebInspector.Panel.prototype = {
this._shortcuts[keys[i].key] = handler;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
- * @constructor
+ * @extends {WebInspector.Panel}
* @param {string} name
- * @param {string} title
- * @param {string=} className
- * @param {string=} scriptName
- * @param {!WebInspector.Panel=} panel
+ * @param {number=} defaultWidth
+ * @constructor
*/
-WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel)
+WebInspector.PanelWithSidebarTree = function(name, defaultWidth)
+{
+ WebInspector.Panel.call(this, name);
+
+ this._panelSplitView = new WebInspector.SplitView(true, false, this._panelName + "PanelSplitViewState", defaultWidth || 200);
+ this._panelSplitView.show(this.element);
+
+ var sidebarView = new WebInspector.VBox();
+ sidebarView.setMinimumSize(100, 25);
+ sidebarView.show(this._panelSplitView.sidebarElement());
+
+ this._sidebarElement = sidebarView.element;
+ this._sidebarElement.classList.add("sidebar");
+ var sidebarTreeElement = this._sidebarElement.createChild("ol", "sidebar-tree");
+ this.sidebarTree = new TreeOutline(sidebarTreeElement);
+}
+
+WebInspector.PanelWithSidebarTree.prototype = {
+ /**
+ * @return {!Element}
+ */
+ sidebarElement: function()
+ {
+ return this._sidebarElement;
+ },
+
+ /**
+ * @return {!Element} element
+ */
+ mainElement: function()
+ {
+ return this._panelSplitView.mainElement();
+ },
+
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this.sidebarTree.element || this.element;
+ },
+
+ __proto__: WebInspector.Panel.prototype
+}
+
+/**
+ * @interface
+ */
+WebInspector.PanelDescriptor = function()
{
- this._name = name;
- this._title = title;
- this._className = className;
- this._scriptName = scriptName;
- this._panel = panel;
}
WebInspector.PanelDescriptor.prototype = {
/**
* @return {string}
*/
+ name: function() {},
+
+ /**
+ * @return {string}
+ */
+ title: function() {},
+
+ /**
+ * @return {!WebInspector.Panel}
+ */
+ panel: function() {}
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @implements {WebInspector.PanelDescriptor}
+ */
+WebInspector.ModuleManagerExtensionPanelDescriptor = function(extension)
+{
+ this._name = extension.descriptor()["name"];
+ this._title = WebInspector.UIString(extension.descriptor()["title"]);
+ this._extension = extension;
+}
+
+WebInspector.ModuleManagerExtensionPanelDescriptor.prototype = {
+ /**
+ * @return {string}
+ */
name: function()
{
return this._name;
@@ -247,21 +247,6 @@ WebInspector.PanelDescriptor.prototype = {
*/
panel: function()
{
- if (this._panel)
- return this._panel;
- if (!this._isCreatingPanel) {
- var oldStackTraceLimit = Error.stackTraceLimit;
- Error.stackTraceLimit = 50;
- console.assert(!this._isCreatingPanel, "PanelDescriptor.panel() is called from inside itself: " + new Error().stack);
- Error.stackTraceLimit = oldStackTraceLimit;
- }
- if (this._scriptName)
- loadScript(this._scriptName);
- this._isCreatingPanel = true;
- this._panel = new WebInspector[this._className];
- delete this._isCreatingPanel;
- return this._panel;
- },
-
- registerShortcuts: function() {}
+ return /** @type {!WebInspector.Panel} */ (this._extension.instance());
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSection.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/PropertiesSection.js
index 9a6d4cf3362..9a6d4cf3362 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSection.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/PropertiesSection.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SearchableView.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/SearchableView.js
index a5b390f9e24..a647c778549 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SearchableView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/SearchableView.js
@@ -31,20 +31,17 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.Searchable} searchable
*/
WebInspector.SearchableView = function(searchable)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._searchProvider = searchable;
-
- this.element.classList.add("vbox");
- this.element.style.flex = "auto";
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
- this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden");
+ this._footerElementContainer = this.element.createChild("div", "search-bar status-bar hidden");
this._footerElementContainer.style.order = 100;
this._footerElement = this._footerElementContainer.createChild("table", "toolbar-search");
@@ -85,7 +82,7 @@ WebInspector.SearchableView = function(searchable)
this._findButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._findButtonElement.textContent = WebInspector.UIString("Find");
this._findButtonElement.tabIndex = -1;
- this._findButtonElement.addEventListener("click", this._onNextButtonSearch.bind(this), false);
+ this._findButtonElement.addEventListener("click", this._onFindClick.bind(this), false);
this._replaceButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceButtonElement.textContent = WebInspector.UIString("Replace");
@@ -96,9 +93,8 @@ WebInspector.SearchableView = function(searchable)
// Column 3
this._prevButtonElement = this._firstRowElement.createChild("td").createChild("button", "hidden");
this._prevButtonElement.textContent = WebInspector.UIString("Previous");
- this._prevButtonElement.disabled = true;
this._prevButtonElement.tabIndex = -1;
- this._prevButtonElement.addEventListener("click", this._onPrevButtonSearch.bind(this), false);
+ this._prevButtonElement.addEventListener("click", this._onPreviousClick.bind(this), false);
this._replaceAllButtonElement = this._secondRowElement.createChild("td").createChild("button");
this._replaceAllButtonElement.textContent = WebInspector.UIString("Replace All");
@@ -109,12 +105,14 @@ WebInspector.SearchableView = function(searchable)
this._replaceCheckboxElement = this._replaceElement.createChild("input");
this._replaceCheckboxElement.type = "checkbox";
- this._replaceCheckboxElement.id = "search-replace-trigger";
+ this._uniqueId = ++WebInspector.SearchableView._lastUniqueId;
+ var replaceCheckboxId = "search-replace-trigger" + this._uniqueId;
+ this._replaceCheckboxElement.id = replaceCheckboxId;
this._replaceCheckboxElement.addEventListener("change", this._updateSecondRowVisibility.bind(this), false);
this._replaceLabelElement = this._replaceElement.createChild("label");
this._replaceLabelElement.textContent = WebInspector.UIString("Replace");
- this._replaceLabelElement.setAttribute("for", "search-replace-trigger");
+ this._replaceLabelElement.setAttribute("for", replaceCheckboxId);
// Column 5
var cancelButtonElement = this._firstRowElement.createChild("td").createChild("button");
@@ -126,6 +124,11 @@ WebInspector.SearchableView = function(searchable)
this._registerShortcuts();
}
+WebInspector.SearchableView._lastUniqueId = 0;
+
+/**
+ * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
+ */
WebInspector.SearchableView.findShortcuts = function()
{
if (WebInspector.SearchableView._findShortcuts)
@@ -136,6 +139,9 @@ WebInspector.SearchableView.findShortcuts = function()
return WebInspector.SearchableView._findShortcuts;
}
+/**
+ * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
+ */
WebInspector.SearchableView.cancelSearchShortcuts = function()
{
if (WebInspector.SearchableView._cancelSearchShortcuts)
@@ -144,33 +150,53 @@ WebInspector.SearchableView.cancelSearchShortcuts = function()
return WebInspector.SearchableView._cancelSearchShortcuts;
}
+/**
+ * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
+ */
WebInspector.SearchableView.findNextShortcut = function()
{
if (WebInspector.SearchableView._findNextShortcut)
return WebInspector.SearchableView._findNextShortcut;
WebInspector.SearchableView._findNextShortcut = [];
- if (!WebInspector.isMac())
- WebInspector.SearchableView._findNextShortcut.push(WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta));
+ if (WebInspector.isMac())
+ WebInspector.SearchableView._findNextShortcut.push(WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Meta));
return WebInspector.SearchableView._findNextShortcut;
}
+/**
+ * @return {!Array.<!WebInspector.KeyboardShortcut.Descriptor>}
+ */
WebInspector.SearchableView.findPreviousShortcuts = function()
{
if (WebInspector.SearchableView._findPreviousShortcuts)
return WebInspector.SearchableView._findPreviousShortcuts;
WebInspector.SearchableView._findPreviousShortcuts = [];
- if (!WebInspector.isMac())
- WebInspector.SearchableView._findPreviousShortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift));
+ if (WebInspector.isMac())
+ WebInspector.SearchableView._findPreviousShortcuts.push(WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Shift));
return WebInspector.SearchableView._findPreviousShortcuts;
}
WebInspector.SearchableView.prototype = {
/**
- * @param {!KeyboardEvent} event
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ var children = this.children();
+ for (var i = 0; i < children.length; ++i) {
+ var element = children[i].defaultFocusedElement();
+ if (element)
+ return element;
+ }
+ return WebInspector.View.prototype.defaultFocusedElement.call(this);
+ },
+
+ /**
+ * @param {?Event} event
*/
_onKeyDown: function(event)
{
- var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(/**@type {!KeyboardEvent}*/(event));
var handler = this._shortcuts[shortcutKey];
if (handler && handler(event))
event.consume(true);
@@ -206,11 +232,11 @@ WebInspector.SearchableView.prototype = {
},
/**
- * @param {boolean} canReplace
+ * @param {boolean} replaceable
*/
- setCanReplace: function(canReplace)
+ setReplaceable: function(replaceable)
{
- this._canReplace = canReplace;
+ this._replaceable = replaceable;
},
/**
@@ -230,6 +256,9 @@ WebInspector.SearchableView.prototype = {
this._updateSearchMatchesCountAndCurrentMatchIndex(this._searchProvider.currentSearchMatches, currentMatchIndex);
},
+ /**
+ * @return {boolean}
+ */
isSearchVisible: function()
{
return this._searchIsVisible;
@@ -238,12 +267,13 @@ WebInspector.SearchableView.prototype = {
closeSearch: function()
{
this.cancelSearch();
- WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
+ if (WebInspector.currentFocusElement().isDescendant(this._footerElementContainer))
+ this.focus();
},
_toggleSearchBar: function(toggled)
{
- this._footerElementContainer.enableStyleClass("hidden", !toggled);
+ this._footerElementContainer.classList.toggle("hidden", !toggled);
this.doResize();
},
@@ -269,8 +299,8 @@ WebInspector.SearchableView.prototype = {
handleFindNextShortcut: function()
{
if (!this._searchIsVisible)
- return true;
- this._searchProvider.jumpToPreviousSearchResult();
+ return false;
+ this._searchProvider.jumpToNextSearchResult();
return true;
},
@@ -280,8 +310,8 @@ WebInspector.SearchableView.prototype = {
handleFindPreviousShortcut: function()
{
if (!this._searchIsVisible)
- return true;
- this._searchProvider.jumpToNextSearchResult();
+ return false;
+ this._searchProvider.jumpToPreviousSearchResult();
return true;
},
@@ -311,7 +341,6 @@ WebInspector.SearchableView.prototype = {
_updateSearchNavigationButtonState: function(enabled)
{
this._replaceButtonElement.disabled = !enabled;
- this._prevButtonElement.disabled = !enabled;
if (enabled) {
this._searchNavigationPrevElement.classList.add("enabled");
this._searchNavigationNextElement.classList.add("enabled");
@@ -343,17 +372,17 @@ WebInspector.SearchableView.prototype = {
if (this._searchIsVisible)
this.cancelSearch();
- this._toggleSearchBar(true);
-
- this._updateReplaceVisibility();
+ var queryCandidate;
if (WebInspector.currentFocusElement() !== this._searchInputElement) {
var selection = window.getSelection();
- if (selection.rangeCount) {
- var queryCandidate = selection.toString().replace(/\r?\n.*/, "");
- if (queryCandidate)
- this._searchInputElement.value = queryCandidate;
- }
+ if (selection.rangeCount)
+ queryCandidate = selection.toString().replace(/\r?\n.*/, "");
}
+
+ this._toggleSearchBar(true);
+ this._updateReplaceVisibility();
+ if (queryCandidate)
+ this._searchInputElement.value = queryCandidate;
this._performSearch(false, false);
this._searchInputElement.focus();
this._searchInputElement.select();
@@ -362,15 +391,15 @@ WebInspector.SearchableView.prototype = {
_updateReplaceVisibility: function()
{
- this._replaceElement.enableStyleClass("hidden", !this._canReplace);
- if (!this._canReplace) {
+ this._replaceElement.classList.toggle("hidden", !this._replaceable);
+ if (!this._replaceable) {
this._replaceCheckboxElement.checked = false;
this._updateSecondRowVisibility();
}
},
/**
- * @param {!Event} event
+ * @param {?Event} event
*/
_onSearchFieldManualFocus: function(event)
{
@@ -378,21 +407,21 @@ WebInspector.SearchableView.prototype = {
},
/**
- * @param {!KeyboardEvent} event
+ * @param {?Event} event
*/
_onSearchKeyDown: function(event)
{
- if (isEnterKey(event)) {
- // FIXME: This won't start backwards search with Shift+Enter correctly.
- if (!this._currentQuery)
- this._performSearch(true, true);
- else
- this._jumpToNextSearchResult(event.shiftKey);
- }
+ if (!isEnterKey(event))
+ return;
+
+ if (!this._currentQuery)
+ this._performSearch(true, true, event.shiftKey);
+ else
+ this._jumpToNextSearchResult(event.shiftKey);
},
/**
- * @param {!KeyboardEvent} event
+ * @param {?Event} event
*/
_onReplaceKeyDown: function(event)
{
@@ -418,7 +447,6 @@ WebInspector.SearchableView.prototype = {
{
if (!this._searchNavigationNextElement.classList.contains("enabled"))
return;
- // Simulate next search on search-navigation-button click.
this._jumpToNextSearchResult();
this._searchInputElement.focus();
},
@@ -427,11 +455,28 @@ WebInspector.SearchableView.prototype = {
{
if (!this._searchNavigationPrevElement.classList.contains("enabled"))
return;
- // Simulate previous search on search-navigation-button click.
this._jumpToNextSearchResult(true);
this._searchInputElement.focus();
},
+ _onFindClick: function(event)
+ {
+ if (!this._currentQuery)
+ this._performSearch(true, true);
+ else
+ this._jumpToNextSearchResult();
+ this._searchInputElement.focus();
+ },
+
+ _onPreviousClick: function(event)
+ {
+ if (!this._currentQuery)
+ this._performSearch(true, true, true);
+ else
+ this._jumpToNextSearchResult(true);
+ this._searchInputElement.focus();
+ },
+
_clearSearch: function()
{
delete this._currentQuery;
@@ -445,8 +490,9 @@ WebInspector.SearchableView.prototype = {
/**
* @param {boolean} forceSearch
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- _performSearch: function(forceSearch, shouldJump)
+ _performSearch: function(forceSearch, shouldJump, jumpBackwards)
{
var query = this._searchInputElement.value;
if (!query || (!forceSearch && query.length < this._minimalSearchQuerySize && !this._currentQuery)) {
@@ -456,39 +502,36 @@ WebInspector.SearchableView.prototype = {
this._currentQuery = query;
this._searchProvider.currentQuery = query;
- this._searchProvider.performSearch(query, shouldJump);
+ this._searchProvider.performSearch(query, shouldJump, jumpBackwards);
},
_updateSecondRowVisibility: function()
{
- if (this._replaceCheckboxElement.checked) {
- this._footerElement.classList.add("toolbar-search-replace");
- this._secondRowElement.classList.remove("hidden");
- this._prevButtonElement.classList.remove("hidden");
- this._findButtonElement.classList.remove("hidden");
- this._replaceCheckboxElement.tabIndex = -1;
+ var secondRowVisible = this._replaceCheckboxElement.checked;
+ this._footerElementContainer.classList.toggle("replaceable", secondRowVisible);
+ this._footerElement.classList.toggle("toolbar-search-replace", secondRowVisible);
+ this._secondRowElement.classList.toggle("hidden", !secondRowVisible);
+ this._prevButtonElement.classList.toggle("hidden", !secondRowVisible);
+ this._findButtonElement.classList.toggle("hidden", !secondRowVisible);
+ this._replaceCheckboxElement.tabIndex = secondRowVisible ? -1 : 0;
+
+ if (secondRowVisible)
this._replaceInputElement.focus();
- } else {
- this._footerElement.classList.remove("toolbar-search-replace");
- this._secondRowElement.classList.add("hidden");
- this._prevButtonElement.classList.add("hidden");
- this._findButtonElement.classList.add("hidden");
- this._replaceCheckboxElement.tabIndex = 0;
+ else
this._searchInputElement.focus();
- }
this.doResize();
},
_replace: function()
{
- this._searchProvider.replaceSelectionWith(this._replaceInputElement.value);
+ /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceSelectionWith(this._replaceInputElement.value);
delete this._currentQuery;
this._performSearch(true, true);
},
_replaceAll: function()
{
- this._searchProvider.replaceAllWith(this._searchInputElement.value, this._replaceInputElement.value);
+ /** @type {!WebInspector.Replaceable} */ (this._searchProvider).replaceAllWith(this._searchInputElement.value, this._replaceInputElement.value);
},
_onInput: function(event)
@@ -501,7 +544,7 @@ WebInspector.SearchableView.prototype = {
this._performSearch(false, true);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
@@ -517,10 +560,31 @@ WebInspector.Searchable.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump) { },
+ performSearch: function(query, shouldJump, jumpBackwards) { },
jumpToNextSearchResult: function() { },
- jumpToPreviousSearchResult: function() { },
+ jumpToPreviousSearchResult: function() { }
+}
+
+/**
+ * @interface
+ */
+WebInspector.Replaceable = function()
+{
+}
+
+WebInspector.Replaceable.prototype = {
+ /**
+ * @param {string} text
+ */
+ replaceSelectionWith: function(text) { },
+
+ /**
+ * @param {string} query
+ * @param {string} replacement
+ */
+ replaceAllWith: function(query, replacement) { }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Section.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/Section.js
index 787fd8b23b9..787fd8b23b9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Section.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/Section.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/ShortcutsScreen.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/ShortcutsScreen.js
new file mode 100644
index 00000000000..19f88a79b8c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/ShortcutsScreen.js
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ */
+WebInspector.ShortcutsScreen = function()
+{
+ /** @type {!Object.<string, !WebInspector.ShortcutsSection>} */
+ this._sections = {};
+}
+
+WebInspector.ShortcutsScreen.prototype = {
+ /**
+ * @param {string} name
+ * @return {!WebInspector.ShortcutsSection}
+ */
+ section: function(name)
+ {
+ var section = this._sections[name];
+ if (!section)
+ this._sections[name] = section = new WebInspector.ShortcutsSection(name);
+ return section;
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ createShortcutsTabView: function()
+ {
+ var orderedSections = [];
+ for (var section in this._sections)
+ orderedSections.push(this._sections[section]);
+ function compareSections(a, b)
+ {
+ return a.order - b.order;
+ }
+ orderedSections.sort(compareSections);
+
+ var view = new WebInspector.View();
+
+ view.element.className = "settings-tab-container"; // Override
+ view.element.createChild("header").createChild("h3").appendChild(document.createTextNode(WebInspector.UIString("Shortcuts")));
+ var scrollPane = view.element.createChild("div", "help-container-wrapper");
+ var container = scrollPane.createChild("div");
+ container.className = "help-content help-container";
+ for (var i = 0; i < orderedSections.length; ++i)
+ orderedSections[i].renderSection(container);
+
+ var note = scrollPane.createChild("p", "help-footnote");
+ var noteLink = note.createChild("a");
+ noteLink.href = "https://developers.google.com/chrome-developer-tools/docs/shortcuts";
+ noteLink.target = "_blank";
+ noteLink.createTextChild(WebInspector.UIString("Full list of keyboard shortcuts and gestures"));
+
+ return view;
+ }
+}
+
+/**
+ * We cannot initialize it here as localized strings are not loaded yet.
+ * @type {!WebInspector.ShortcutsScreen}
+ */
+WebInspector.shortcutsScreen;
+
+/**
+ * @constructor
+ * @param {string} name
+ */
+WebInspector.ShortcutsSection = function(name)
+{
+ this.name = name;
+ this._lines = /** @type {!Array.<!{key: !Node, text: string}>} */ ([]);
+ this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
+};
+
+WebInspector.ShortcutsSection._sequenceNumber = 0;
+
+WebInspector.ShortcutsSection.prototype = {
+ /**
+ * @param {!WebInspector.KeyboardShortcut.Descriptor} key
+ * @param {string} description
+ */
+ addKey: function(key, description)
+ {
+ this._addLine(this._renderKey(key), description);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
+ * @param {string} description
+ */
+ addRelatedKeys: function(keys, description)
+ {
+ this._addLine(this._renderSequence(keys, "/"), description);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
+ * @param {string} description
+ */
+ addAlternateKeys: function(keys, description)
+ {
+ this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description);
+ },
+
+ /**
+ * @param {!Node} keyElement
+ * @param {string} description
+ */
+ _addLine: function(keyElement, description)
+ {
+ this._lines.push({ key: keyElement, text: description })
+ },
+
+ /**
+ * @param {!Element} container
+ */
+ renderSection: function(container)
+ {
+ var parent = container.createChild("div", "help-block");
+
+ var headLine = parent.createChild("div", "help-line");
+ headLine.createChild("div", "help-key-cell");
+ headLine.createChild("div", "help-section-title help-cell").textContent = this.name;
+
+ for (var i = 0; i < this._lines.length; ++i) {
+ var line = parent.createChild("div", "help-line");
+ var keyCell = line.createChild("div", "help-key-cell");
+ keyCell.appendChild(this._lines[i].key);
+ keyCell.appendChild(this._createSpan("help-key-delimiter", ":"));
+ line.createChild("div", "help-cell").textContent = this._lines[i].text;
+ }
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} sequence
+ * @param {string} delimiter
+ * @return {!Node}
+ */
+ _renderSequence: function(sequence, delimiter)
+ {
+ var delimiterSpan = this._createSpan("help-key-delimiter", delimiter);
+ return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
+ },
+
+ /**
+ * @param {!WebInspector.KeyboardShortcut.Descriptor} key
+ * @return {!Node}
+ */
+ _renderKey: function(key)
+ {
+ var keyName = key.name;
+ var plus = this._createSpan("help-combine-keys", "+");
+ return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this, "help-key")), plus);
+ },
+
+ /**
+ * @param {string} className
+ * @param {string} textContent
+ * @return {!Element}
+ */
+ _createSpan: function(className, textContent)
+ {
+ var node = document.createElement("span");
+ node.className = className;
+ node.textContent = textContent;
+ return node;
+ },
+
+ /**
+ * @param {!Array.<!Element>} nodes
+ * @param {!Element} delimiter
+ * @return {!Node}
+ */
+ _joinNodes: function(nodes, delimiter)
+ {
+ var result = document.createDocumentFragment();
+ for (var i = 0; i < nodes.length; ++i) {
+ if (i > 0)
+ result.appendChild(delimiter.cloneNode(true));
+ result.appendChild(nodes[i]);
+ }
+ return result;
+ }
+}
+
+WebInspector.ShortcutsScreen.registerShortcuts = function()
+{
+ // Elements panel
+ var elementsSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
+
+ var navigate = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateUp.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NavigateDown);
+ elementsSection.addRelatedKeys(navigate, WebInspector.UIString("Navigate elements"));
+
+ var expandCollapse = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Expand.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.Collapse);
+ elementsSection.addRelatedKeys(expandCollapse, WebInspector.UIString("Expand/collapse"));
+
+ elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.EditAttribute, WebInspector.UIString("Edit attribute"));
+ elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.HideElement, WebInspector.UIString("Hide element"));
+ elementsSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.ToggleEditAsHTML, WebInspector.UIString("Toggle edit as HTML"));
+
+ var stylesPaneSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Styles Pane"));
+
+ var nextPreviousProperty = WebInspector.ShortcutsScreen.ElementsPanelShortcuts.NextProperty.concat(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.PreviousProperty);
+ stylesPaneSection.addRelatedKeys(nextPreviousProperty, WebInspector.UIString("Next/previous property"));
+
+ stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementValue, WebInspector.UIString("Increment value"));
+ stylesPaneSection.addRelatedKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementValue, WebInspector.UIString("Decrement value"));
+
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy10, WebInspector.UIString("Increment by %f", 10));
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy10, WebInspector.UIString("Decrement by %f", 10));
+
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy100, WebInspector.UIString("Increment by %f", 100));
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy100, WebInspector.UIString("Decrement by %f", 100));
+
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.IncrementBy01, WebInspector.UIString("Increment by %f", 0.1));
+ stylesPaneSection.addAlternateKeys(WebInspector.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy01, WebInspector.UIString("Decrement by %f", 0.1));
+
+
+ // Sources panel
+ var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
+
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PauseContinue, WebInspector.UIString("Pause/Continue"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOver, WebInspector.UIString("Step over"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepInto, WebInspector.UIString("Step into"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOut, WebInspector.UIString("Step out"));
+
+ var nextAndPrevFrameKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame.concat(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame);
+ section.addRelatedKeys(nextAndPrevFrameKeys, WebInspector.UIString("Next/previous call frame"));
+
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.EvaluateSelectionInConsole, WebInspector.UIString("Evaluate selection in console"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.AddSelectionToWatch, WebInspector.UIString("Add selection to watch"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, WebInspector.UIString("Go to member"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, WebInspector.UIString("Go to line"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, WebInspector.UIString("Toggle breakpoint"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment, WebInspector.UIString("Toggle comment"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab, WebInspector.UIString("Close editor tab"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByOne, WebInspector.UIString("Increment CSS unit by 1"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByOne, WebInspector.UIString("Decrement CSS unit by 1"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByTen, WebInspector.UIString("Increment CSS unit by 10"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByTen, WebInspector.UIString("Decrement CSS unit by 10"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation, WebInspector.UIString("Jump to previous editing location"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation, WebInspector.UIString("Jump to next editing location"));
+
+ // Timeline panel
+ section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Timeline Panel"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.StartStopRecording, WebInspector.UIString("Start/stop recording"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.SaveToFile, WebInspector.UIString("Save timeline data"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.LoadFromFile, WebInspector.UIString("Load timeline data"));
+
+
+ // Profiles panel
+ section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Profiles Panel"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.ProfilesPanelShortcuts.StartStopRecording, WebInspector.UIString("Start/stop recording"));
+
+ // Layers panel
+ if (WebInspector.experimentsSettings.isEnabled("layersPanel")) {
+ section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Layers Panel"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView, WebInspector.UIString("Reset view"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, WebInspector.UIString("Zoom in"));
+ section.addAlternateKeys(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, WebInspector.UIString("Zoom out"));
+ var PanUpDown = WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanUp.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanDown);
+ section.addRelatedKeys(PanUpDown, WebInspector.UIString("Pan up/down"));
+ var PanLeftRight = WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanLeft.concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanRight);
+ section.addRelatedKeys(PanLeftRight, WebInspector.UIString("Pan left/right"));
+ var rotate = WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWX
+ .concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWX)
+ .concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWY)
+ .concat(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWY);
+ section.addRelatedKeys(rotate, WebInspector.UIString("Rotate"));
+ }
+}
+
+WebInspector.ShortcutsScreen.ElementsPanelShortcuts = {
+ NavigateUp: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
+ ],
+
+ NavigateDown: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
+ ],
+
+ Expand: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right)
+ ],
+
+ Collapse: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left)
+ ],
+
+ EditAttribute: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter)
+ ],
+
+ HideElement: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.H)
+ ],
+
+ ToggleEditAsHTML: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F2)
+ ],
+
+ NextProperty: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab)
+ ],
+
+ PreviousProperty: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Tab, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ IncrementValue: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up)
+ ],
+
+ DecrementValue: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down)
+ ],
+
+ IncrementBy10: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ DecrementBy10: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ IncrementBy100: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ DecrementBy100: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ IncrementBy01: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ DecrementBy01: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ]
+};
+
+WebInspector.ShortcutsScreen.SourcesPanelShortcuts = {
+ IncreaseCSSUnitByOne: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ DecreaseCSSUnitByOne: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ IncreaseCSSUnitByTen: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageUp, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ DecreaseCSSUnitByTen: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.PageDown, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ RunSnippet: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Enter, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ PauseContinue: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F8),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Backslash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ StepOver: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F10),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.SingleQuote, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ StepInto: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ StepOut: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.F11, WebInspector.KeyboardShortcut.Modifiers.Shift),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Semicolon, WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ EvaluateSelectionInConsole: [
+ WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl)
+ ],
+
+ AddSelectionToWatch: [
+ WebInspector.KeyboardShortcut.makeDescriptor("a", WebInspector.KeyboardShortcut.Modifiers.Shift | WebInspector.KeyboardShortcut.Modifiers.Ctrl)
+ ],
+
+ GoToMember: [
+ WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ GoToLine: [
+ WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl)
+ ],
+
+ ToggleBreakpoint: [
+ WebInspector.KeyboardShortcut.makeDescriptor("b", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ NextCallFrame: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Period, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
+ ],
+
+ PrevCallFrame: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Comma, WebInspector.KeyboardShortcut.Modifiers.Ctrl)
+ ],
+
+ ToggleComment: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Slash, WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ JumpToPreviousLocation: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ JumpToNextLocation: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus, WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ CloseEditorTab: [
+ WebInspector.KeyboardShortcut.makeDescriptor("w", WebInspector.KeyboardShortcut.Modifiers.Alt)
+ ],
+
+ Save: [
+ WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ SaveAll: [
+ WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.ShiftOrOption)
+ ],
+};
+
+WebInspector.ShortcutsScreen.TimelinePanelShortcuts = {
+ StartStopRecording: [
+ WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ SaveToFile: [
+ WebInspector.KeyboardShortcut.makeDescriptor("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ],
+
+ LoadFromFile: [
+ WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ]
+};
+
+WebInspector.ShortcutsScreen.ProfilesPanelShortcuts = {
+ StartStopRecording: [
+ WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
+ ]
+};
+
+WebInspector.ShortcutsScreen.LayersPanelShortcuts = {
+ ResetView: [
+ WebInspector.KeyboardShortcut.makeDescriptor("0")
+ ],
+
+ ZoomIn: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Plus, WebInspector.KeyboardShortcut.Modifiers.Shift),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadPlus)
+ ],
+
+ ZoomOut: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Minus, WebInspector.KeyboardShortcut.Modifiers.Shift),
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.NumpadMinus)
+ ],
+
+ PanUp: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ PanDown: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ PanLeft: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ PanRight: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right, WebInspector.KeyboardShortcut.Modifiers.Shift)
+ ],
+
+ RotateCWX: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Up),
+ ],
+
+ RotateCCWX: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Down),
+ ],
+
+ RotateCWY: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Left),
+ ],
+
+ RotateCCWY: [
+ WebInspector.KeyboardShortcut.makeDescriptor(WebInspector.KeyboardShortcut.Keys.Right),
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/TimelineGrid.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/TimelineGrid.js
new file mode 100644
index 00000000000..76471534b1b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/TimelineGrid.js
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineGrid = function()
+{
+ this.element = document.createElement("div");
+
+ this._dividersElement = this.element.createChild("div", "resources-dividers");
+
+ this._gridHeaderElement = document.createElement("div");
+ this._gridHeaderElement.id = "timeline-grid-header";
+ this._eventDividersElement = this._gridHeaderElement.createChild("div", "resources-event-dividers");
+ this._dividersLabelBarElement = this._gridHeaderElement.createChild("div", "resources-dividers-label-bar");
+ this.element.appendChild(this._gridHeaderElement);
+
+ this._leftCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-left");
+ this._rightCurtainElement = this.element.createChild("div", "timeline-cpu-curtain-right");
+}
+
+/**
+ * @param {!WebInspector.TimelineGrid.Calculator} calculator
+ * @param {number} clientWidth
+ * @return {!{offsets: !Array.<number>, precision: number}}
+ */
+WebInspector.TimelineGrid.calculateDividerOffsets = function(calculator, clientWidth)
+{
+ const minGridSlicePx = 64; // minimal distance between grid lines.
+ const gridFreeZoneAtLeftPx = 50;
+
+ var dividersCount = clientWidth / minGridSlicePx;
+ var gridSliceTime = calculator.boundarySpan() / dividersCount;
+ var pixelsPerTime = clientWidth / calculator.boundarySpan();
+
+ // Align gridSliceTime to a nearest round value.
+ // We allow spans that fit into the formula: span = (1|2|5)x10^n,
+ // e.g.: ... .1 .2 .5 1 2 5 10 20 50 ...
+ // After a span has been chosen make grid lines at multiples of the span.
+
+ var logGridSliceTime = Math.ceil(Math.log(gridSliceTime) / Math.LN10);
+ gridSliceTime = Math.pow(10, logGridSliceTime);
+ if (gridSliceTime * pixelsPerTime >= 5 * minGridSlicePx)
+ gridSliceTime = gridSliceTime / 5;
+ if (gridSliceTime * pixelsPerTime >= 2 * minGridSlicePx)
+ gridSliceTime = gridSliceTime / 2;
+
+ var firstDividerTime = Math.ceil((calculator.minimumBoundary() - calculator.zeroTime()) / gridSliceTime) * gridSliceTime + calculator.zeroTime();
+ var lastDividerTime = calculator.maximumBoundary();
+ // Add some extra space past the right boundary as the rightmost divider label text
+ // may be partially shown rather than just pop up when a new rightmost divider gets into the view.
+ if (calculator.paddingLeft() > 0)
+ lastDividerTime = lastDividerTime + minGridSlicePx / pixelsPerTime;
+ dividersCount = Math.ceil((lastDividerTime - firstDividerTime) / gridSliceTime);
+
+ var skipLeftmostDividers = calculator.paddingLeft() === 0;
+
+ if (!gridSliceTime)
+ dividersCount = 0;
+
+ var offsets = [];
+ for (var i = 0; i < dividersCount; ++i) {
+ var left = calculator.computePosition(firstDividerTime + gridSliceTime * i);
+ if (skipLeftmostDividers && left < gridFreeZoneAtLeftPx)
+ continue;
+ offsets.push(firstDividerTime + gridSliceTime * i);
+ }
+
+ return {offsets: offsets, precision: Math.max(0, -Math.floor(Math.log(gridSliceTime * 1.01) / Math.LN10))};
+}
+
+/**
+ * @param {!Object} canvas
+ * @param {!WebInspector.TimelineGrid.Calculator} calculator
+ * @param {?Array.<number>=} dividerOffsets
+ */
+WebInspector.TimelineGrid.drawCanvasGrid = function(canvas, calculator, dividerOffsets)
+{
+ var context = canvas.getContext("2d");
+ context.save();
+ var ratio = window.devicePixelRatio;
+ context.scale(ratio, ratio);
+ var printDeltas = !!dividerOffsets;
+ var width = canvas.width / window.devicePixelRatio;
+ var height = canvas.height / window.devicePixelRatio;
+ var precision = 0;
+ if (!dividerOffsets) {
+ var dividersData = WebInspector.TimelineGrid.calculateDividerOffsets(calculator, width);
+ dividerOffsets = dividersData.offsets;
+ precision = dividersData.precision;
+ }
+
+ context.fillStyle = "rgba(255, 255, 255, 0.5)";
+ context.fillRect(0, 0, width, 15);
+
+ context.fillStyle = "#333";
+ context.strokeStyle = "rgba(0, 0, 0, 0.1)";
+ context.textBaseline = "hanging";
+ context.font = (printDeltas ? "italic bold 11px " : " 11px ") + WebInspector.fontFamily();
+ context.lineWidth = 1;
+
+ context.translate(0.5, 0.5);
+ const minWidthForTitle = 60;
+ var lastPosition = 0;
+ var time = 0;
+ var lastTime = 0;
+ var paddingRight = 4;
+ var paddingTop = 3;
+ for (var i = 0; i < dividerOffsets.length; ++i) {
+ time = dividerOffsets[i];
+ var position = calculator.computePosition(time);
+ context.beginPath();
+ if (position - lastPosition > minWidthForTitle) {
+ if (!printDeltas || i !== 0) {
+ var text = printDeltas ? calculator.formatTime(calculator.zeroTime() + time - lastTime) : calculator.formatTime(time, precision);
+ var textWidth = context.measureText(text).width;
+ var textPosition = printDeltas ? (position + lastPosition - textWidth) / 2 : position - textWidth - paddingRight;
+ context.fillText(text, textPosition, paddingTop);
+ }
+ }
+ context.moveTo(position, 0);
+ context.lineTo(position, height);
+ context.stroke();
+ lastTime = time;
+ lastPosition = position;
+ }
+ context.restore();
+},
+
+WebInspector.TimelineGrid.prototype = {
+ get dividersElement()
+ {
+ return this._dividersElement;
+ },
+
+ get dividersLabelBarElement()
+ {
+ return this._dividersLabelBarElement;
+ },
+
+ removeDividers: function()
+ {
+ this._dividersElement.removeChildren();
+ this._dividersLabelBarElement.removeChildren();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineGrid.Calculator} calculator
+ * @param {?Array.<number>=} dividerOffsets
+ * @param {boolean=} printDeltas
+ * @return {boolean}
+ */
+ updateDividers: function(calculator, dividerOffsets, printDeltas)
+ {
+ var precision = 0;
+ if (!dividerOffsets) {
+ var dividersData = WebInspector.TimelineGrid.calculateDividerOffsets(calculator, this._dividersElement.clientWidth);
+ dividerOffsets = dividersData.offsets;
+ precision = dividersData.precision;
+ printDeltas = false;
+ }
+
+ var dividersElementClientWidth = this._dividersElement.clientWidth;
+
+ // Reuse divider elements and labels.
+ var divider = /** @type {?Element} */ (this._dividersElement.firstChild);
+ var dividerLabelBar = /** @type {?Element} */ (this._dividersLabelBarElement.firstChild);
+
+ const minWidthForTitle = 60;
+ var lastPosition = 0;
+ var lastTime = 0;
+ for (var i = 0; i < dividerOffsets.length; ++i) {
+ if (!divider) {
+ divider = document.createElement("div");
+ divider.className = "resources-divider";
+ this._dividersElement.appendChild(divider);
+
+ dividerLabelBar = document.createElement("div");
+ dividerLabelBar.className = "resources-divider";
+ var label = document.createElement("div");
+ label.className = "resources-divider-label";
+ dividerLabelBar._labelElement = label;
+ dividerLabelBar.appendChild(label);
+ this._dividersLabelBarElement.appendChild(dividerLabelBar);
+ }
+
+ var time = dividerOffsets[i];
+ var position = calculator.computePosition(time);
+ if (position - lastPosition > minWidthForTitle)
+ dividerLabelBar._labelElement.textContent = printDeltas ? calculator.formatTime(time - lastTime) : calculator.formatTime(time, precision);
+ else
+ dividerLabelBar._labelElement.textContent = "";
+
+ if (printDeltas)
+ dividerLabelBar._labelElement.style.width = Math.ceil(position - lastPosition) + "px";
+ else
+ dividerLabelBar._labelElement.style.removeProperty("width");
+
+ lastPosition = position;
+ lastTime = time;
+ var percentLeft = 100 * position / dividersElementClientWidth;
+ divider.style.left = percentLeft + "%";
+ dividerLabelBar.style.left = percentLeft + "%";
+
+ divider = divider.nextSibling;
+ dividerLabelBar = dividerLabelBar.nextSibling;
+ }
+
+ // Remove extras.
+ while (divider) {
+ var nextDivider = divider.nextSibling;
+ this._dividersElement.removeChild(divider);
+ divider = nextDivider;
+ }
+ while (dividerLabelBar) {
+ var nextDivider = dividerLabelBar.nextSibling;
+ this._dividersLabelBarElement.removeChild(dividerLabelBar);
+ dividerLabelBar = nextDivider;
+ }
+ return true;
+ },
+
+ addEventDivider: function(divider)
+ {
+ this._eventDividersElement.appendChild(divider);
+ },
+
+ addEventDividers: function(dividers)
+ {
+ this._gridHeaderElement.removeChild(this._eventDividersElement);
+ for (var i = 0; i < dividers.length; ++i) {
+ if (dividers[i])
+ this._eventDividersElement.appendChild(dividers[i]);
+ }
+ this._gridHeaderElement.appendChild(this._eventDividersElement);
+ },
+
+ removeEventDividers: function()
+ {
+ this._eventDividersElement.removeChildren();
+ },
+
+ hideEventDividers: function()
+ {
+ this._eventDividersElement.classList.add("hidden");
+ },
+
+ showEventDividers: function()
+ {
+ this._eventDividersElement.classList.remove("hidden");
+ },
+
+ hideDividers: function()
+ {
+ this._dividersElement.classList.add("hidden");
+ },
+
+ showDividers: function()
+ {
+ this._dividersElement.classList.remove("hidden");
+ },
+
+ hideCurtains: function()
+ {
+ this._leftCurtainElement.classList.add("hidden");
+ this._rightCurtainElement.classList.add("hidden");
+ },
+
+ /**
+ * @param {number} gapOffset
+ * @param {number} gapWidth
+ */
+ showCurtains: function(gapOffset, gapWidth)
+ {
+ this._leftCurtainElement.style.width = gapOffset + "px";
+ this._leftCurtainElement.classList.remove("hidden");
+ this._rightCurtainElement.style.left = (gapOffset + gapWidth) + "px";
+ this._rightCurtainElement.classList.remove("hidden");
+ },
+
+ setScrollAndDividerTop: function(scrollTop, dividersTop)
+ {
+ this._dividersLabelBarElement.style.top = scrollTop + "px";
+ this._eventDividersElement.style.top = scrollTop + "px";
+ this._leftCurtainElement.style.top = scrollTop + "px";
+ this._rightCurtainElement.style.top = scrollTop + "px";
+ }
+}
+
+/**
+ * @interface
+ */
+WebInspector.TimelineGrid.Calculator = function() { }
+
+WebInspector.TimelineGrid.Calculator.prototype = {
+ /**
+ * @return {number}
+ */
+ paddingLeft: function() { },
+
+ /**
+ * @param {number} time
+ * @return {number}
+ */
+ computePosition: function(time) { },
+
+ /**
+ * @param {number} time
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatTime: function(time, precision) { },
+
+ /** @return {number} */
+ minimumBoundary: function() { },
+
+ /** @return {number} */
+ zeroTime: function() { },
+
+ /** @return {number} */
+ maximumBoundary: function() { },
+
+ /** @return {number} */
+ boundarySpan: function() { }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/components/WorkerFrontendManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/components/WorkerFrontendManager.js
new file mode 100644
index 00000000000..4c94df23da9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/components/WorkerFrontendManager.js
@@ -0,0 +1,172 @@
+
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ */
+WebInspector.WorkerFrontendManager = function()
+{
+ this._workerIdToWindow = {};
+
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerAdded, this._workerAdded, this);
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerRemoved, this._workerRemoved, this);
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkersCleared, this._workersCleared, this);
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.MessageFromWorker, this._sendMessageToWorkerInspector, this);
+
+ window.addEventListener("message", this._handleMessage.bind(this), true);
+}
+
+WebInspector.WorkerFrontendManager.prototype = {
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _workerAdded: function(event)
+ {
+ var data = /** @type {{workerId: number, url: string, inspectorConnected: boolean}} */ (event.data);
+
+ if (data.inspectorConnected)
+ this._openInspectorWindow(data.workerId, true);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _workerRemoved: function(event)
+ {
+ var data = /** @type {{workerId: number, url: string}} */ (event.data);
+
+ this.closeWorkerInspector(data.workerId);
+ },
+
+ _workersCleared: function()
+ {
+ for (var workerId in this._workerIdToWindow)
+ this.closeWorkerInspector(workerId);
+ },
+
+ _handleMessage: function(event)
+ {
+ var data = /** @type {{workerId: string, command: string, message: !Object}} */ (event.data);
+ var workerId = data["workerId"];
+ workerId = parseInt(workerId, 10);
+ var command = data.command;
+ var message = data.message;
+
+ if (command == "sendMessageToBackend")
+ WorkerAgent.sendMessageToWorker(workerId, message);
+ },
+
+ _sendMessageToWorkerInspector: function(event)
+ {
+ var data = (event.data);
+
+ var workerInspectorWindow = this._workerIdToWindow[data.workerId];
+ if (workerInspectorWindow)
+ workerInspectorWindow.postMessage(data.message, "*");
+ },
+
+ openWorkerInspector: function(workerId)
+ {
+ var existingInspector = this._workerIdToWindow[workerId];
+ if (existingInspector) {
+ existingInspector.focus();
+ return;
+ }
+
+ this._openInspectorWindow(workerId, false);
+ WorkerAgent.connectToWorker(workerId);
+ },
+
+ _openInspectorWindow: function(workerId, workerIsPaused)
+ {
+ var search = window.location.search;
+ var hash = window.location.hash;
+ var url = window.location.href;
+ // Make sure hash is in rear
+ url = url.replace(hash, "");
+ url += (search ? "&dedicatedWorkerId=" : "?dedicatedWorkerId=") + workerId;
+ if (workerIsPaused)
+ url += "&workerPaused=true";
+ url = url.replace("docked=true&", "");
+ url = url.replace("can_dock=true&", "");
+ url += hash;
+ var width = WebInspector.settings.workerInspectorWidth.get();
+ var height = WebInspector.settings.workerInspectorHeight.get();
+ // Set location=0 just to make sure the front-end will be opened in a separate window, not in new tab.
+ var workerInspectorWindow = window.open(url, undefined, "location=0,width=" + width + ",height=" + height);
+ workerInspectorWindow.addEventListener("resize", this._onWorkerInspectorResize.bind(this, workerInspectorWindow), false);
+ this._workerIdToWindow[workerId] = workerInspectorWindow;
+ workerInspectorWindow.addEventListener("beforeunload", this._workerInspectorClosing.bind(this, workerId), true);
+
+ // Listen to beforeunload in detached state and to the InspectorClosing event in case of attached inspector.
+ window.addEventListener("unload", this._pageInspectorClosing.bind(this), true);
+ },
+
+ closeWorkerInspector: function(workerId)
+ {
+ var workerInspectorWindow = this._workerIdToWindow[workerId];
+ if (workerInspectorWindow)
+ workerInspectorWindow.close();
+ },
+
+ _onWorkerInspectorResize: function(workerInspectorWindow)
+ {
+ var doc = workerInspectorWindow.document;
+ WebInspector.settings.workerInspectorWidth.set(doc.width);
+ WebInspector.settings.workerInspectorHeight.set(doc.height);
+ },
+
+ _workerInspectorClosing: function(workerId, event)
+ {
+ if (event.target.location.href === "about:blank")
+ return;
+ if (this._ignoreWorkerInspectorClosing)
+ return;
+ delete this._workerIdToWindow[workerId];
+ WorkerAgent.disconnectFromWorker(workerId);
+ },
+
+ _pageInspectorClosing: function()
+ {
+ this._ignoreWorkerInspectorClosing = true;
+ for (var workerId in this._workerIdToWindow) {
+ this._workerIdToWindow[workerId].close();
+ WorkerAgent.disconnectFromWorker(parseInt(workerId, 10));
+ }
+ }
+
+}
+/**
+ * @type {?WebInspector.WorkerFrontendManager}
+ */
+WebInspector.workerFrontendManager = null;
+
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ConsolePanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsolePanel.js
index 4ac37b193ce..97ee8d8627a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ConsolePanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsolePanel.js
@@ -26,33 +26,34 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+importScript("ConsoleViewMessage.js");
+importScript("ConsoleView.js");
+
/**
* @constructor
* @extends {WebInspector.Panel}
- * @implements {WebInspector.ViewFactory}
*/
WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");
- this._view = WebInspector.consoleView;
+ this._view = WebInspector.ConsolePanel._view();
+}
+
+/**
+ * @return {!WebInspector.ConsoleView}
+ */
+WebInspector.ConsolePanel._view = function()
+{
+ if (!WebInspector.ConsolePanel._consoleView)
+ WebInspector.ConsolePanel._consoleView = new WebInspector.ConsoleView(!Capabilities.isMainFrontend);
+
+ return WebInspector.ConsolePanel._consoleView;
}
WebInspector.ConsolePanel.prototype = {
/**
- * @param {string=} id
- * @return {?WebInspector.View}
+ * @return {!Element}
*/
- createView: function(id)
- {
- if (!this._consoleViewWrapper) {
- this._consoleViewWrapper = new WebInspector.View();
- this._consoleViewWrapper.element.classList.add("fill", "console-view-wrapper");
- if (WebInspector.inspectorView.currentPanel() !== this)
- this._showViewInWrapper();
- }
- return this._consoleViewWrapper;
- },
-
defaultFocusedElement: function()
{
return this._view.defaultFocusedElement();
@@ -61,30 +62,85 @@ WebInspector.ConsolePanel.prototype = {
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
- if (WebInspector.inspectorView.drawer().visible() && WebInspector.inspectorView.selectedViewInDrawer() === "console") {
- WebInspector.inspectorView.drawer().hide(true);
- this._drawerWasVisible = true;
- }
this._view.show(this.element);
},
willHide: function()
{
- if (this._drawerWasVisible) {
- WebInspector.inspectorView.drawer().show(true);
- delete this._drawerWasVisible;
- }
-
WebInspector.Panel.prototype.willHide.call(this);
- if (this._consoleViewWrapper)
+ if (WebInspector.ConsolePanel.WrapperView._instance)
+ WebInspector.ConsolePanel.WrapperView._instance._showViewInWrapper();
+ },
+
+ __proto__: WebInspector.Panel.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.ConsolePanel.WrapperView = function()
+{
+ WebInspector.VBox.call(this);
+ this.element.classList.add("console-view-wrapper");
+
+ WebInspector.ConsolePanel.WrapperView._instance = this;
+
+ this._view = WebInspector.ConsolePanel._view();
+ // FIXME: this won't be needed once drawer becomes a view.
+ this.wasShown();
+}
+
+WebInspector.ConsolePanel.WrapperView.prototype = {
+ wasShown: function()
+ {
+ if (!WebInspector.inspectorView.currentPanel() || WebInspector.inspectorView.currentPanel().name !== "console")
this._showViewInWrapper();
},
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this._view.defaultFocusedElement();
+ },
+
+ focus: function()
+ {
+ this._view.focus();
+ },
+
_showViewInWrapper: function()
{
- this._view.show(this._consoleViewWrapper.element);
- this._consoleViewWrapper.setDefaultFocusedElement(this._view.defaultFocusedElement());
+ this._view.show(this.element);
},
- __proto__: WebInspector.Panel.prototype
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.ConsolePanel.ConsoleRevealer = function()
+{
+}
+
+WebInspector.ConsolePanel.ConsoleRevealer.prototype = {
+ /**
+ * @param {!Object} object
+ */
+ reveal: function(object)
+ {
+ if (!(object instanceof WebInspector.ConsoleModel))
+ return;
+
+ var consoleView = WebInspector.ConsolePanel._view();
+ if (consoleView.isShowing()) {
+ consoleView.focus();
+ return;
+ }
+ WebInspector.inspectorView.showViewInDrawer("console");
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
new file mode 100644
index 00000000000..4ae9cf551ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -0,0 +1,1228 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @implements {WebInspector.Searchable}
+ * @implements {WebInspector.TargetManager.Observer}
+ * @implements {WebInspector.ViewportControl.Provider}
+ * @param {boolean} hideContextSelector
+ */
+WebInspector.ConsoleView = function(hideContextSelector)
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("filter.css");
+
+ this._searchableView = new WebInspector.SearchableView(this);
+ this._searchableView.setMinimalSearchQuerySize(0);
+ this._searchableView.show(this.element);
+
+ this._contentsElement = this._searchableView.element;
+ this._contentsElement.classList.add("console-view");
+ this._visibleViewMessages = [];
+ this._urlToMessageCount = {};
+ this._hiddenByFilterCount = 0;
+
+ this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
+ this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);
+
+ this._executionContextSelector = new WebInspector.StatusBarComboBox(this._executionContextChanged.bind(this), "console-context");
+
+ /**
+ * @type {!Map.<!WebInspector.ExecutionContext, !Element>}
+ */
+ this._optionByExecutionContext = new Map();
+
+ this._filter = new WebInspector.ConsoleViewFilter(this);
+ this._filter.addEventListener(WebInspector.ConsoleViewFilter.Events.FilterChanged, this._updateMessageList.bind(this));
+
+ if (hideContextSelector)
+ this._executionContextSelector.element.classList.add("hidden");
+
+ this._filterBar = new WebInspector.FilterBar();
+
+ var statusBarElement = this._contentsElement.createChild("div", "console-status-bar");
+ statusBarElement.appendChild(this._clearConsoleButton.element);
+ statusBarElement.appendChild(this._filterBar.filterButton().element);
+ statusBarElement.appendChild(this._executionContextSelector.element);
+
+ this._filtersContainer = this._contentsElement.createChild("div", "console-filters-header hidden");
+ this._filtersContainer.appendChild(this._filterBar.filtersElement());
+ this._filterBar.addEventListener(WebInspector.FilterBar.Events.FiltersToggled, this._onFiltersToggled, this);
+ this._filterBar.setName("consoleView");
+ this._filter.addFilters(this._filterBar);
+
+ this._viewport = new WebInspector.ViewportControl(this);
+ this._viewport.setStickToBottom(true);
+ this._viewport.contentElement().classList.add("console-group");
+ this._viewport.contentElement().classList.add("console-group-messages");
+ this._contentsElement.appendChild(this._viewport.element);
+ this._messagesElement = this._viewport.element;
+ this._messagesElement.id = "console-messages";
+ this._messagesElement.classList.add("monospace");
+ this._messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
+ this._scrolledToBottom = true;
+
+ this._filterStatusMessageElement = document.createElementWithClass("div", "console-message");
+ this._messagesElement.insertBefore(this._filterStatusMessageElement, this._messagesElement.firstChild);
+ this._filterStatusTextElement = this._filterStatusMessageElement.createChild("span", "console-info");
+ this._filterStatusMessageElement.createTextChild(" ");
+ var resetFiltersLink = this._filterStatusMessageElement.createChild("span", "console-info node-link");
+ resetFiltersLink.textContent = WebInspector.UIString("Show all messages.");
+ resetFiltersLink.addEventListener("click", this._filter.reset.bind(this._filter), true);
+
+ this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
+ this._currentGroup = this._topGroup;
+
+ this._promptElement = this._messagesElement.createChild("div", "source-code");
+ this._promptElement.id = "console-prompt";
+ this._promptElement.spellcheck = false;
+ this._messagesElement.appendChild(this._promptElement);
+ this._messagesElement.appendChild(document.createElement("br"));
+
+ this._showAllMessagesCheckbox = new WebInspector.StatusBarCheckbox(WebInspector.UIString("Show all messages"));
+ this._showAllMessagesCheckbox.inputElement.checked = true;
+ this._showAllMessagesCheckbox.inputElement.addEventListener("change", this._updateMessageList.bind(this), false);
+
+ if (!WebInspector.experimentsSettings.workersInMainWindow.isEnabled())
+ this._showAllMessagesCheckbox.element.classList.add("hidden");
+
+ statusBarElement.appendChild(this._showAllMessagesCheckbox.element);
+
+ this._registerShortcuts();
+ this.registerRequiredCSS("suggestBox.css");
+
+ this._messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
+ WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged, this);
+
+ this._linkifier = new WebInspector.Linkifier();
+
+ /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
+ this._consoleMessages = [];
+
+ this._prompt = new WebInspector.TextPromptWithHistory(WebInspector.ExecutionContextSelector.completionsForTextPromptInCurrentContext);
+ this._prompt.setSuggestBoxEnabled(true);
+ this._prompt.renderAsBlock();
+ this._prompt.attach(this._promptElement);
+ this._prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
+ this._prompt.setHistoryData(WebInspector.settings.consoleHistory.get());
+ var historyData = WebInspector.settings.consoleHistory.get();
+ this._prompt.setHistoryData(historyData);
+
+ this._updateFilterStatus();
+ WebInspector.settings.consoleTimestampsEnabled.addChangeListener(this._consoleTimestampsSettingChanged, this);
+
+ this._registerWithMessageSink();
+ WebInspector.targetManager.observeTargets(this);
+ WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChangedExternally, this);
+}
+
+WebInspector.ConsoleView.prototype = {
+ /**
+ * @return {number}
+ */
+ itemCount: function()
+ {
+ return this._visibleViewMessages.length;
+ },
+
+ /**
+ * @param {number} index
+ * @return {?WebInspector.ViewportElement}
+ */
+ itemElement: function(index)
+ {
+ return this._visibleViewMessages[index];
+ },
+
+ /**
+ * @param {number} index
+ * @return {number}
+ */
+ fastHeight: function(index)
+ {
+ return this._visibleViewMessages[index].fastHeight();
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRowHeight: function()
+ {
+ return 16;
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ /**
+ * @param {!WebInspector.ConsoleMessage} message
+ * @this {WebInspector.ConsoleView}
+ */
+ function appendMessage(message)
+ {
+ var viewMessage = this._createViewMessage(message);
+ this._consoleMessageAdded(viewMessage);
+ }
+
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
+ target.consoleModel.messages.forEach(appendMessage, this);
+ this._viewport.invalidate();
+
+ target.runtimeModel.executionContexts().forEach(this._executionContextCreated, this);
+ target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
+ target.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._onConsoleMessageAdded, this);
+ target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+ target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.CommandEvaluated, this._commandEvaluated, this);
+ target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this);
+ target.runtimeModel.removeEventListener(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this);
+ },
+
+ _registerWithMessageSink: function()
+ {
+ WebInspector.messageSink.messages().forEach(this._addSinkMessage, this);
+ WebInspector.messageSink.addEventListener(WebInspector.MessageSink.Events.MessageAdded, messageAdded, this);
+
+ /**
+ * @param {!WebInspector.Event} event
+ * @this {WebInspector.ConsoleView}
+ */
+ function messageAdded(event)
+ {
+ this._addSinkMessage(/** @type {!WebInspector.MessageSink.Message} */ (event.data));
+ }
+ },
+
+ /**
+ * @param {!WebInspector.MessageSink.Message} message
+ */
+ _addSinkMessage: function(message)
+ {
+ var level = WebInspector.ConsoleMessage.MessageLevel.Debug;
+ switch (message.level) {
+ case WebInspector.MessageSink.MessageLevel.Error:
+ level = WebInspector.ConsoleMessage.MessageLevel.Error;
+ break;
+ case WebInspector.MessageSink.MessageLevel.Warning:
+ level = WebInspector.ConsoleMessage.MessageLevel.Warning;
+ break;
+ }
+
+ var consoleMessage = new WebInspector.ConsoleMessage(null, WebInspector.ConsoleMessage.MessageSource.Other, level, message.text,
+ undefined, undefined, undefined, undefined, undefined, undefined, undefined, message.timestamp);
+ this._addConsoleMessage(consoleMessage);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _consoleTimestampsSettingChanged: function(event)
+ {
+ var enabled = /** @type {boolean} */ (event.data);
+ this._updateMessageList();
+ this._consoleMessages.forEach(function(viewMessage) {
+ viewMessage.updateTimestamp(enabled);
+ });
+ },
+
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this._promptElement
+ },
+
+ _onFiltersToggled: function(event)
+ {
+ var toggled = /** @type {boolean} */ (event.data);
+ this._filtersContainer.classList.toggle("hidden", !toggled);
+ },
+
+ /**
+ * @param {!WebInspector.ExecutionContext} executionContext
+ * @return {string}
+ */
+ _titleFor: function(executionContext)
+ {
+ var result = executionContext.name;
+ if (executionContext.isMainWorldContext && executionContext.frameId) {
+ var frame = executionContext.target().resourceTreeModel.frameForId(executionContext.frameId);
+ result = frame ? frame.displayName() : result;
+ }
+
+ if (!executionContext.isMainWorldContext)
+ result = "\u00a0\u00a0\u00a0\u00a0" + result;
+
+ var maxLength = 50;
+ return result.trimMiddle(maxLength);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onExecutionContextCreated: function(event)
+ {
+ var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data);
+ this._executionContextCreated(executionContext);
+ },
+
+ /**
+ * @param {!WebInspector.ExecutionContext} executionContext
+ */
+ _executionContextCreated: function(executionContext)
+ {
+ var newOption = document.createElement("option");
+ newOption.__executionContext = executionContext;
+ newOption.text = this._titleFor(executionContext);
+ this._optionByExecutionContext.put(executionContext, newOption);
+ var sameGroupExists = false;
+ var options = this._executionContextSelector.selectElement().options;
+ var insertBeforeOption = null;
+ for (var i = 0; i < options.length; ++i) {
+ var optionContext = options[i].__executionContext;
+ var isSameGroup = executionContext.target() === optionContext.target() && executionContext.frameId === optionContext.frameId;
+ sameGroupExists |= isSameGroup;
+ if ((isSameGroup && WebInspector.ExecutionContext.comparator(optionContext, executionContext) > 0) || (sameGroupExists && !isSameGroup)) {
+ insertBeforeOption = options[i];
+ break;
+ }
+ }
+ this._executionContextSelector.selectElement().insertBefore(newOption, insertBeforeOption);
+ if (executionContext === WebInspector.context.flavor(WebInspector.ExecutionContext))
+ this._executionContextSelector.select(newOption);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onExecutionContextDestroyed: function(event)
+ {
+ var executionContext = /** @type {!WebInspector.ExecutionContext} */ (event.data);
+ var option = this._optionByExecutionContext.remove(executionContext);
+ option.remove();
+ },
+
+ _executionContextChanged: function()
+ {
+ var newContext = this._currentExecutionContext();
+ WebInspector.context.setFlavor(WebInspector.ExecutionContext, newContext);
+ this._prompt.clearAutoComplete(true);
+ if (!this._showAllMessagesCheckbox.checked())
+ this._updateMessageList();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _executionContextChangedExternally: function(event)
+ {
+ var executionContext = /** @type {?WebInspector.ExecutionContext} */ (event.data);
+ if (!executionContext)
+ return;
+
+ var options = this._executionContextSelector.selectElement().options;
+ for (var i = 0; i < options.length; ++i) {
+ if (options[i].__executionContext === executionContext)
+ this._executionContextSelector.select(options[i]);
+ }
+ },
+
+ /**
+ * @return {?WebInspector.ExecutionContext}
+ */
+ _currentExecutionContext: function()
+ {
+ var option = this._executionContextSelector.selectedOption();
+ return option ? option.__executionContext : null;
+ },
+
+ willHide: function()
+ {
+ this._prompt.hideSuggestBox();
+ this._prompt.clearAutoComplete(true);
+ },
+
+ wasShown: function()
+ {
+ this._viewport.refresh();
+ if (!this._prompt.isCaretInsidePrompt())
+ this._prompt.moveCaretToEndOfPrompt();
+ },
+
+ focus: function()
+ {
+ if (this._promptElement === WebInspector.currentFocusElement())
+ return;
+ WebInspector.setCurrentFocusElement(this._promptElement);
+ this._prompt.moveCaretToEndOfPrompt();
+ },
+
+ storeScrollPositions: function()
+ {
+ WebInspector.View.prototype.storeScrollPositions.call(this);
+ this._scrolledToBottom = this._messagesElement.isScrolledToBottom();
+ },
+
+ restoreScrollPositions: function()
+ {
+ if (this._scrolledToBottom)
+ this._immediatelyScrollIntoView();
+ else
+ WebInspector.View.prototype.restoreScrollPositions.call(this);
+ },
+
+ onResize: function()
+ {
+ this._scheduleViewportRefresh();
+ this._prompt.hideSuggestBox();
+ this.restoreScrollPositions();
+ },
+
+ _isScrollIntoViewScheduled: function()
+ {
+ return !!this._scrollIntoViewTimer;
+ },
+
+ _scheduleViewportRefresh: function()
+ {
+ if (this._scrollIntoViewTimer)
+ return;
+ /**
+ * @this {WebInspector.ConsoleView}
+ */
+ function scrollIntoView()
+ {
+ delete this._scrollIntoViewTimer;
+ this._viewport.invalidate();
+ }
+ this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 50);
+ },
+
+ _immediatelyScrollIntoView: function()
+ {
+ this._promptElement.scrollIntoView(true);
+ this._cancelScheduledScrollIntoView();
+ },
+
+ _cancelScheduledScrollIntoView: function()
+ {
+ if (!this._isScrollIntoViewScheduled())
+ return;
+ clearTimeout(this._scrollIntoViewTimer);
+ this._viewport.refresh();
+ delete this._scrollIntoViewTimer;
+ },
+
+ _updateFilterStatus: function()
+ {
+ this._filterStatusTextElement.textContent = WebInspector.UIString(this._hiddenByFilterCount === 1 ? "%d message is hidden by filters." : "%d messages are hidden by filters.", this._hiddenByFilterCount);
+ this._filterStatusMessageElement.style.display = this._hiddenByFilterCount ? "" : "none";
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleViewMessage} viewMessage
+ */
+ _consoleMessageAdded: function(viewMessage)
+ {
+ /**
+ * @param {!WebInspector.ConsoleViewMessage} viewMessage1
+ * @param {!WebInspector.ConsoleViewMessage} viewMessage2
+ * @return {number}
+ */
+ function compareTimestamps(viewMessage1, viewMessage2)
+ {
+ return WebInspector.ConsoleMessage.timestampComparator(viewMessage1.consoleMessage(), viewMessage2.consoleMessage());
+ }
+ var insertAt = insertionIndexForObjectInListSortedByFunction(viewMessage, this._consoleMessages, compareTimestamps, true);
+ this._consoleMessages.splice(insertAt, 0, viewMessage);
+
+ var message = viewMessage.consoleMessage();
+ if (this._urlToMessageCount[message.url])
+ this._urlToMessageCount[message.url]++;
+ else
+ this._urlToMessageCount[message.url] = 1;
+
+ if (this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.peekLast()))
+ return;
+
+ if (this._filter.shouldBeVisible(viewMessage))
+ this._showConsoleMessage(viewMessage)
+ else {
+ this._hiddenByFilterCount++;
+ this._updateFilterStatus();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onConsoleMessageAdded: function(event)
+ {
+ var message = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
+ this._addConsoleMessage(message);
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} message
+ */
+ _addConsoleMessage: function(message)
+ {
+ var viewMessage = this._createViewMessage(message);
+ this._consoleMessageAdded(viewMessage);
+ this._scheduleViewportRefresh();
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleViewMessage} viewMessage
+ */
+ _showConsoleMessage: function(viewMessage)
+ {
+ var lastMessage = this._visibleViewMessages.peekLast();
+ if (viewMessage.consoleMessage().type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
+ if (lastMessage && !this._currentGroup.messagesHidden())
+ lastMessage.incrementCloseGroupDecorationCount();
+ this._currentGroup = this._currentGroup.parentGroup();
+ return;
+ }
+ if (!this._currentGroup.messagesHidden()) {
+ var originatingMessage = viewMessage.consoleMessage().originatingMessage();
+ if (lastMessage && originatingMessage && lastMessage.consoleMessage() === originatingMessage)
+ lastMessage.toMessageElement().classList.add("console-adjacent-user-command-result");
+
+ this._visibleViewMessages.push(viewMessage);
+
+ if (this._searchRegex && viewMessage.matchesRegex(this._searchRegex)) {
+ this._searchResults.push(viewMessage);
+ this._searchableView.updateSearchMatchesCount(this._searchResults.length);
+ }
+ }
+
+ if (viewMessage.consoleMessage().isGroupStartMessage())
+ this._currentGroup = new WebInspector.ConsoleGroup(this._currentGroup, viewMessage);
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} message
+ * @return {!WebInspector.ConsoleViewMessage}
+ */
+ _createViewMessage: function(message)
+ {
+ var nestingLevel = this._currentGroup.nestingLevel();
+ switch (message.type) {
+ case WebInspector.ConsoleMessage.MessageType.Command:
+ return new WebInspector.ConsoleCommand(message, nestingLevel);
+ case WebInspector.ConsoleMessage.MessageType.Result:
+ return new WebInspector.ConsoleCommandResult(message, this._linkifier, nestingLevel);
+ case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
+ case WebInspector.ConsoleMessage.MessageType.StartGroup:
+ return new WebInspector.ConsoleGroupViewMessage(message, this._linkifier, nestingLevel);
+ default:
+ return new WebInspector.ConsoleViewMessage(message, this._linkifier, nestingLevel);
+ }
+ },
+
+ _consoleCleared: function()
+ {
+ this._clearCurrentSearchResultHighlight();
+ this._consoleMessages = [];
+ this._scrolledToBottom = true;
+ this._updateMessageList();
+
+ if (this._searchRegex)
+ this._searchableView.updateSearchMatchesCount(0);
+
+ this._linkifier.reset();
+ },
+
+ _handleContextMenuEvent: function(event)
+ {
+ if (event.target.enclosingNodeOrSelfWithNodeName("a"))
+ return;
+
+ var contextMenu = new WebInspector.ContextMenu(event);
+
+ function monitoringXHRItemAction()
+ {
+ WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
+ }
+ contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction, WebInspector.settings.monitoringXHREnabled.get());
+
+ function preserveLogItemAction()
+ {
+ WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
+ }
+ contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction, WebInspector.settings.preserveConsoleLog.get());
+
+ var sourceElement = event.target.enclosingNodeOrSelfWithClass("console-message-wrapper");
+ var consoleMessage = sourceElement ? sourceElement.message.consoleMessage() : null;
+
+ var filterSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Filter"));
+
+ if (consoleMessage && consoleMessage.url) {
+ var menuTitle = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Hide messages from %s" : "Hide Messages from %s", new WebInspector.ParsedURL(consoleMessage.url).displayName);
+ filterSubMenu.appendItem(menuTitle, this._filter.addMessageURLFilter.bind(this._filter, consoleMessage.url));
+ }
+
+ filterSubMenu.appendSeparator();
+ var unhideAll = filterSubMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Unhide all" : "Unhide All"), this._filter.removeMessageURLFilter.bind(this._filter));
+ filterSubMenu.appendSeparator();
+
+ var hasFilters = false;
+
+ for (var url in this._filter.messageURLFilters) {
+ filterSubMenu.appendCheckboxItem(String.sprintf("%s (%d)", new WebInspector.ParsedURL(url).displayName, this._urlToMessageCount[url]), this._filter.removeMessageURLFilter.bind(this._filter, url), true);
+ hasFilters = true;
+ }
+
+ filterSubMenu.setEnabled(hasFilters || (consoleMessage && consoleMessage.url));
+ unhideAll.setEnabled(hasFilters);
+
+ contextMenu.appendSeparator();
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));
+
+ var request = consoleMessage ? consoleMessage.request : null;
+ if (request && request.type === WebInspector.resourceTypes.XHR) {
+ contextMenu.appendSeparator();
+ contextMenu.appendItem(WebInspector.UIString("Replay XHR"), NetworkAgent.replayXHR.bind(null, request.requestId));
+ }
+
+ contextMenu.show();
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleViewMessage} lastMessage
+ * @param {?WebInspector.ConsoleViewMessage} viewMessage
+ * @return {boolean}
+ */
+ _tryToCollapseMessages: function(lastMessage, viewMessage)
+ {
+ if (!WebInspector.settings.consoleTimestampsEnabled.get() && viewMessage && !lastMessage.consoleMessage().isGroupMessage() && lastMessage.consoleMessage().isEqual(viewMessage.consoleMessage())) {
+ viewMessage.incrementRepeatCount();
+ return true;
+ }
+
+ return false;
+ },
+
+ _updateMessageList: function()
+ {
+ this._topGroup = WebInspector.ConsoleGroup.createTopGroup();
+ this._currentGroup = this._topGroup;
+ this._searchResults = [];
+ this._hiddenByFilterCount = 0;
+ for (var i = 0; i < this._visibleViewMessages.length; ++i) {
+ this._visibleViewMessages[i].resetCloseGroupDecorationCount();
+ this._visibleViewMessages[i].resetIncrementRepeatCount();
+ }
+ this._visibleViewMessages = [];
+ for (var i = 0; i < this._consoleMessages.length; ++i) {
+ var viewMessage = this._consoleMessages[i];
+ if (this._tryToCollapseMessages(viewMessage, this._visibleViewMessages.peekLast()))
+ continue;
+ if (this._filter.shouldBeVisible(viewMessage))
+ this._showConsoleMessage(viewMessage);
+ else
+ this._hiddenByFilterCount++;
+ }
+ this._updateFilterStatus();
+ this._viewport.invalidate();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _monitoringXHREnabledSettingChanged: function(event)
+ {
+ var enabled = /** @type {boolean} */ (event.data);
+ WebInspector.targetManager.targets().forEach(function(target) {target.consoleAgent().setMonitoringXHREnabled(enabled);});
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _messagesClicked: function(event)
+ {
+ if (!this._prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
+ this._prompt.moveCaretToEndOfPrompt();
+ var groupMessage = event.target.enclosingNodeOrSelfWithClass("console-group-title");
+ if (!groupMessage)
+ return;
+ var consoleGroupViewMessage = groupMessage.parentElement.message;
+ consoleGroupViewMessage.setCollapsed(!consoleGroupViewMessage.collapsed());
+ this._updateMessageList();
+ },
+
+ _registerShortcuts: function()
+ {
+ this._shortcuts = {};
+
+ var shortcut = WebInspector.KeyboardShortcut;
+ var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
+
+ var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
+ this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);
+ var keys = [shortcutL];
+ if (WebInspector.isMac()) {
+ var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
+ this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
+ keys.unshift(shortcutK);
+ }
+ section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
+
+ section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tab), WebInspector.UIString("Autocomplete common prefix"));
+ section.addKey(shortcut.makeDescriptor(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
+
+ var shortcutU = shortcut.makeDescriptor("u", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
+ this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
+ section.addAlternateKeys([shortcutU], WebInspector.UIString("Clear console prompt"));
+
+ keys = [
+ shortcut.makeDescriptor(shortcut.Keys.Down),
+ shortcut.makeDescriptor(shortcut.Keys.Up)
+ ];
+ section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
+
+ if (WebInspector.isMac()) {
+ keys = [
+ shortcut.makeDescriptor("N", shortcut.Modifiers.Alt),
+ shortcut.makeDescriptor("P", shortcut.Modifiers.Alt)
+ ];
+ section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
+ }
+
+ section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
+ },
+
+ _clearPromptBackwards: function()
+ {
+ this._prompt.text = "";
+ },
+
+ _requestClearMessages: function()
+ {
+ WebInspector.console.requestClearMessages();
+ },
+
+ _promptKeyDown: function(event)
+ {
+ if (isEnterKey(event)) {
+ this._enterKeyPressed(event);
+ return;
+ }
+
+ var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var handler = this._shortcuts[shortcut];
+ if (handler) {
+ handler();
+ event.preventDefault();
+ }
+ },
+
+ _enterKeyPressed: function(event)
+ {
+ if (event.altKey || event.ctrlKey || event.shiftKey)
+ return;
+
+ event.consume(true);
+
+ this._prompt.clearAutoComplete(true);
+
+ var str = this._prompt.text;
+ if (!str.length)
+ return;
+ this._appendCommand(str, true);
+ },
+
+ /**
+ * @param {?WebInspector.RemoteObject} result
+ * @param {boolean} wasThrown
+ * @param {!WebInspector.ConsoleMessage} originatingConsoleMessage
+ */
+ _printResult: function(result, wasThrown, originatingConsoleMessage)
+ {
+ if (!result)
+ return;
+
+ var target = result.target();
+ /**
+ * @param {string=} url
+ * @param {number=} lineNumber
+ * @param {number=} columnNumber
+ */
+ function addMessage(url, lineNumber, columnNumber)
+ {
+ var level = wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
+ var message = new WebInspector.ConsoleMessage(target, WebInspector.ConsoleMessage.MessageSource.JS, level, "", WebInspector.ConsoleMessage.MessageType.Result, url, lineNumber, columnNumber, undefined, [result]);
+ message.setOriginatingMessage(originatingConsoleMessage);
+ target.consoleModel.addMessage(message);
+ }
+
+ if (result.type !== "function") {
+ addMessage();
+ return;
+ }
+
+ result.functionDetails(didGetDetails);
+
+ /**
+ * @param {?DebuggerAgent.FunctionDetails} response
+ */
+ function didGetDetails(response)
+ {
+ if (!response) {
+ addMessage();
+ return;
+ }
+
+ var url;
+ var lineNumber;
+ var columnNumber;
+ var script = target.debuggerModel.scriptForId(response.location.scriptId);
+ if (script && script.sourceURL) {
+ url = script.sourceURL;
+ lineNumber = response.location.lineNumber + 1;
+ columnNumber = response.location.columnNumber + 1;
+ }
+ // FIXME: this should be using live location.
+ addMessage(url, lineNumber, columnNumber);
+ }
+ },
+
+ /**
+ * @param {string} text
+ * @param {boolean} useCommandLineAPI
+ */
+ _appendCommand: function(text, useCommandLineAPI)
+ {
+
+ this._prompt.text = "";
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (currentExecutionContext)
+ WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, text, useCommandLineAPI);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _commandEvaluated: function(event)
+ {
+ var data = /**{{result: ?WebInspector.RemoteObject, wasThrown: boolean, text: string, commandMessage: !WebInspector.ConsoleMessage}} */ (event.data);
+ this._prompt.pushHistoryItem(data.text);
+ WebInspector.settings.consoleHistory.set(this._prompt.historyData.slice(-30));
+ this._printResult(data.result, data.wasThrown, data.commandMessage);
+ },
+
+ /**
+ * @return {!Array.<!Element>}
+ */
+ elementsToRestoreScrollPositionsFor: function()
+ {
+ return [this._messagesElement];
+ },
+
+ searchCanceled: function()
+ {
+ this._clearCurrentSearchResultHighlight();
+ delete this._searchResults;
+ delete this._searchRegex;
+ this._viewport.refresh();
+ },
+
+ /**
+ * @param {string} query
+ * @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
+ */
+ performSearch: function(query, shouldJump, jumpBackwards)
+ {
+ this.searchCanceled();
+ this._searchableView.updateSearchMatchesCount(0);
+ this._searchRegex = createPlainTextSearchRegex(query, "gi");
+
+ /** @type {!Array.<number>} */
+ this._searchResults = [];
+ for (var i = 0; i < this._visibleViewMessages.length; i++) {
+ if (this._visibleViewMessages[i].matchesRegex(this._searchRegex))
+ this._searchResults.push(i);
+ }
+ this._searchableView.updateSearchMatchesCount(this._searchResults.length);
+ this._currentSearchResultIndex = -1;
+ if (shouldJump && this._searchResults.length)
+ this._jumpToSearchResult(jumpBackwards ? -1 : 0);
+ this._viewport.refresh();
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ this._jumpToSearchResult(this._currentSearchResultIndex + 1);
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ this._jumpToSearchResult(this._currentSearchResultIndex - 1);
+ },
+
+ _clearCurrentSearchResultHighlight: function()
+ {
+ if (!this._searchResults)
+ return;
+
+ var highlightedViewMessage = this._visibleViewMessages[this._searchResults[this._currentSearchResultIndex]];
+ if (highlightedViewMessage)
+ highlightedViewMessage.clearHighlight();
+ this._currentSearchResultIndex = -1;
+ },
+
+ _jumpToSearchResult: function(index)
+ {
+ index = mod(index, this._searchResults.length);
+ this._clearCurrentSearchResultHighlight();
+ this._currentSearchResultIndex = index;
+ this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
+ var currentViewMessageIndex = this._searchResults[index];
+ this._viewport.scrollItemIntoView(currentViewMessageIndex);
+ this._visibleViewMessages[currentViewMessageIndex].highlightSearchResults(this._searchRegex);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.ConsoleView} view
+ */
+WebInspector.ConsoleViewFilter = function(view)
+{
+ this._view = view;
+ this._messageURLFilters = WebInspector.settings.messageURLFilters.get();
+ this._filterChanged = this.dispatchEventToListeners.bind(this, WebInspector.ConsoleViewFilter.Events.FilterChanged);
+};
+
+WebInspector.ConsoleViewFilter.Events = {
+ FilterChanged: "FilterChanged"
+};
+
+WebInspector.ConsoleViewFilter.prototype = {
+ addFilters: function(filterBar)
+ {
+ this._textFilterUI = new WebInspector.TextFilterUI(true);
+ this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._textFilterChanged, this);
+ filterBar.addFilter(this._textFilterUI);
+
+ var levels = [
+ {name: "error", label: WebInspector.UIString("Errors")},
+ {name: "warning", label: WebInspector.UIString("Warnings")},
+ {name: "info", label: WebInspector.UIString("Info")},
+ {name: "log", label: WebInspector.UIString("Logs")},
+ {name: "debug", label: WebInspector.UIString("Debug")}
+ ];
+ this._levelFilterUI = new WebInspector.NamedBitSetFilterUI(levels, WebInspector.settings.messageLevelFilters);
+ this._levelFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
+ filterBar.addFilter(this._levelFilterUI);
+ },
+
+ _textFilterChanged: function(event)
+ {
+ this._filterRegex = this._textFilterUI.regex();
+
+ this._filterChanged();
+ },
+
+ /**
+ * @param {string} url
+ */
+ addMessageURLFilter: function(url)
+ {
+ this._messageURLFilters[url] = true;
+ WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
+ this._filterChanged();
+ },
+
+ /**
+ * @param {string} url
+ */
+ removeMessageURLFilter: function(url)
+ {
+ if (!url)
+ this._messageURLFilters = {};
+ else
+ delete this._messageURLFilters[url];
+
+ WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
+ this._filterChanged();
+ },
+
+ /**
+ * @returns {!Object}
+ */
+ get messageURLFilters()
+ {
+ return this._messageURLFilters;
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleViewMessage} viewMessage
+ * @return {boolean}
+ */
+ shouldBeVisible: function(viewMessage)
+ {
+ var message = viewMessage.consoleMessage();
+ var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (!message.target())
+ return true;
+
+ if (!this._view._showAllMessagesCheckbox.checked() && executionContext && (message.target() !== executionContext.target() || message.executionContextId !== executionContext.id))
+ return false;
+
+ if (viewMessage.consoleMessage().isGroupMessage())
+ return true;
+
+ if (message.type === WebInspector.ConsoleMessage.MessageType.Result || message.type === WebInspector.ConsoleMessage.MessageType.Command)
+ return true;
+
+ if (message.url && this._messageURLFilters[message.url])
+ return false;
+
+ if (message.level && !this._levelFilterUI.accept(message.level))
+ return false;
+
+ if (this._filterRegex) {
+ this._filterRegex.lastIndex = 0;
+ if (!viewMessage.matchesRegex(this._filterRegex))
+ return false;
+ }
+
+ return true;
+ },
+
+ reset: function()
+ {
+ this._messageURLFilters = {};
+ WebInspector.settings.messageURLFilters.set(this._messageURLFilters);
+ WebInspector.settings.messageLevelFilters.set({});
+ this._view._showAllMessagesCheckbox.inputElement.checked = true;
+ this._textFilterUI.setValue("");
+ this._filterChanged();
+ },
+
+ __proto__: WebInspector.Object.prototype
+};
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ConsoleViewMessage}
+ * @param {!WebInspector.ConsoleMessage} message
+ * @param {number} nestingLevel
+ */
+WebInspector.ConsoleCommand = function(message, nestingLevel)
+{
+ WebInspector.ConsoleViewMessage.call(this, message, null, nestingLevel);
+}
+
+WebInspector.ConsoleCommand.prototype = {
+ clearHighlight: function()
+ {
+ var highlightedMessage = this._formattedCommand;
+ delete this._formattedCommand;
+ this._formatCommand();
+ this._element.replaceChild(this._formattedCommand, highlightedMessage);
+ },
+
+ /**
+ * @param {!RegExp} regexObject
+ */
+ highlightSearchResults: function(regexObject)
+ {
+ regexObject.lastIndex = 0;
+ var match = regexObject.exec(this.text);
+ var matchRanges = [];
+ while (match) {
+ matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
+ match = regexObject.exec(this.text);
+ }
+ WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
+ this._element.scrollIntoViewIfNeeded();
+ },
+
+ /**
+ * @param {!RegExp} regexObject
+ * @return {boolean}
+ */
+ matchesRegex: function(regexObject)
+ {
+ regexObject.lastIndex = 0;
+ return regexObject.test(this.text);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ contentElement: function()
+ {
+ if (!this._element) {
+ this._element = document.createElement("div");
+ this._element.message = this;
+ this._element.className = "console-user-command";
+
+ this._formatCommand();
+ this._element.appendChild(this._formattedCommand);
+ }
+ return this._element;
+ },
+
+ _formatCommand: function()
+ {
+ this._formattedCommand = document.createElement("span");
+ this._formattedCommand.className = "console-message-text source-code";
+ this._formattedCommand.textContent = this.text;
+ },
+
+ __proto__: WebInspector.ConsoleViewMessage.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.ConsoleViewMessage}
+ * @param {!WebInspector.ConsoleMessage} message
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {number} nestingLevel
+ */
+WebInspector.ConsoleCommandResult = function(message, linkifier, nestingLevel)
+{
+ WebInspector.ConsoleViewMessage.call(this, message, linkifier, nestingLevel);
+}
+
+WebInspector.ConsoleCommandResult.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.RemoteObject} array
+ * @return {boolean}
+ */
+ useArrayPreviewInFormatter: function(array)
+ {
+ return false;
+ },
+
+ /**
+ * @return {!Element}
+ */
+ contentElement: function()
+ {
+ var element = WebInspector.ConsoleViewMessage.prototype.contentElement.call(this);
+ element.classList.add("console-user-command-result");
+ return element;
+ },
+
+ __proto__: WebInspector.ConsoleViewMessage.prototype
+}
+
+/**
+ * @constructor
+ * @param {?WebInspector.ConsoleGroup} parentGroup
+ * @param {?WebInspector.ConsoleViewMessage} groupMessage
+ */
+WebInspector.ConsoleGroup = function(parentGroup, groupMessage)
+{
+ this._parentGroup = parentGroup;
+ this._nestingLevel = parentGroup ? parentGroup.nestingLevel() + 1 : 0;
+ this._messagesHidden = groupMessage && groupMessage.collapsed() || this._parentGroup && this._parentGroup.messagesHidden();
+}
+
+/**
+ * @return {!WebInspector.ConsoleGroup}
+ */
+WebInspector.ConsoleGroup.createTopGroup = function()
+{
+ return new WebInspector.ConsoleGroup(null, null);
+}
+
+WebInspector.ConsoleGroup.prototype = {
+ /**
+ * @return {boolean}
+ */
+ messagesHidden: function()
+ {
+ return this._messagesHidden;
+ },
+
+ /**
+ * @return {number}
+ */
+ nestingLevel: function()
+ {
+ return this._nestingLevel;
+ },
+
+ /**
+ * @return {?WebInspector.ConsoleGroup}
+ */
+ parentGroup: function()
+ {
+ return this._parentGroup || this;
+ },
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.ConsoleView.ShowConsoleActionDelegate = function()
+{
+}
+
+WebInspector.ConsoleView.ShowConsoleActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ WebInspector.console.show();
+ return true;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleMessage.js b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
index 755c2e5d34b..80697a56e57 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ConsoleMessage.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -30,38 +30,25 @@
/**
* @constructor
- * @extends {WebInspector.ConsoleMessage}
- *
- * @param {string} source
- * @param {string} level
- * @param {string} message
- * @param {!WebInspector.Linkifier} linkifier
- * @param {string=} type
- * @param {string=} url
- * @param {number=} line
- * @param {number=} column
- * @param {number=} repeatCount
- * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
- * @param {!ConsoleAgent.StackTrace=} stackTrace
- * @param {!NetworkAgent.RequestId=} requestId
- * @param {boolean=} isOutdated
+ * @implements {WebInspector.ViewportElement}
+ * @param {!WebInspector.ConsoleMessage} consoleMessage
+ * @param {?WebInspector.Linkifier} linkifier
+ * @param {number} nestingLevel
*/
-WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, column, repeatCount, parameters, stackTrace, requestId, isOutdated)
+WebInspector.ConsoleViewMessage = function(consoleMessage, linkifier, nestingLevel)
{
- WebInspector.ConsoleMessage.call(this, source, level, url, line, column, repeatCount);
-
+ this._message = consoleMessage;
this._linkifier = linkifier;
- this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
- this._messageText = message;
- this._parameters = parameters;
- this._stackTrace = stackTrace;
- this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
- this._isOutdated = isOutdated;
+ this._repeatCount = 1;
+ this._closeGroupDecorationCount = 0;
+ this._nestingLevel = nestingLevel;
+
/** @type {!Array.<!WebInspector.DataGrid>} */
this._dataGrids = [];
/** @type {!Map.<!WebInspector.DataGrid, ?Element>} */
this._dataGridParents = new Map();
+ /** @type {!Object.<string, function(!WebInspector.RemoteObject, !Element, boolean=)>} */
this._customFormatters = {
"object": this._formatParameterAsObject,
"array": this._formatParameterAsArray,
@@ -70,7 +57,23 @@ WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, ty
};
}
-WebInspector.ConsoleMessageImpl.prototype = {
+WebInspector.ConsoleViewMessage.prototype = {
+ /**
+ * @return {?WebInspector.Target}
+ */
+ _target: function()
+ {
+ return this.consoleMessage().target();
+ },
+
+ /**
+ * @return {!Element}
+ */
+ element: function()
+ {
+ return this.toMessageElement();
+ },
+
wasShown: function()
{
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
@@ -81,6 +84,11 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
},
+ cacheFastHeight: function()
+ {
+ this._cachedHeight = this.contentElement().offsetHeight;
+ },
+
willHide: function()
{
for (var i = 0; this._dataGrids && i < this._dataGrids.length; ++i) {
@@ -90,84 +98,109 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
},
+ /**
+ * @return {number}
+ */
+ fastHeight: function()
+ {
+ if (this._cachedHeight)
+ return this._cachedHeight;
+ const defaultConsoleRowHeight = 16;
+ if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
+ var table = this._message.parameters[0];
+ if (table && table.preview)
+ return defaultConsoleRowHeight * table.preview.properties.length;
+ }
+ return defaultConsoleRowHeight;
+ },
+
+ /**
+ * @return {!WebInspector.ConsoleMessage}
+ */
+ consoleMessage: function()
+ {
+ return this._message;
+ },
+
_formatMessage: function()
{
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";
- if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
- switch (this.type) {
- case WebInspector.ConsoleMessage.MessageType.Trace:
- this._messageElement = this._format(this._parameters || ["console.trace()"]);
- break;
- case WebInspector.ConsoleMessage.MessageType.Clear:
- this._messageElement = document.createTextNode(WebInspector.UIString("Console was cleared"));
- this._formattedMessage.classList.add("console-info");
- break;
- case WebInspector.ConsoleMessage.MessageType.Assert:
- var args = [WebInspector.UIString("Assertion failed:")];
- if (this._parameters)
- args = args.concat(this._parameters);
- this._messageElement = this._format(args);
- break;
- case WebInspector.ConsoleMessage.MessageType.Dir:
- var obj = this._parameters ? this._parameters[0] : undefined;
- var args = ["%O", obj];
- this._messageElement = this._format(args);
- break;
- case WebInspector.ConsoleMessage.MessageType.Profile:
- this._messageElement = document.createTextNode(WebInspector.UIString("Profile '%s' started.", this._messageText));
- break;
- case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
- var hashIndex = this._messageText.lastIndexOf("#");
- var title = this._messageText.substring(0, hashIndex);
- var uid = this._messageText.substring(hashIndex + 1);
- var format = WebInspector.UIString("Profile '%s' finished.", "%_");
- var link = WebInspector.linkifyURLAsNode("webkit-profile://CPU/" + uid, title);
- this._messageElement = document.createElement("span");
- this._formatWithSubstitutionString(format, [link], this._messageElement);
- break;
- default:
- var args = this._parameters || [this._messageText];
- this._messageElement = this._format(args);
- }
- } else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) {
- if (this._request) {
- this._stackTrace = this._request.initiator.stackTrace;
- if (this._request.initiator && this._request.initiator.url) {
- this.url = this._request.initiator.url;
- this.line = this._request.initiator.lineNumber;
+ /**
+ * @param {string} title
+ * @return {!Element}
+ * @this {WebInspector.ConsoleMessage}
+ */
+ function linkifyRequest(title)
+ {
+ return WebInspector.Linkifier.linkifyUsingRevealer(/** @type {!WebInspector.NetworkRequest} */ (this.request), title, this.url);
+ }
+
+ var consoleMessage = this._message;
+ if (!this._messageElement) {
+ if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
+ switch (consoleMessage.type) {
+ case WebInspector.ConsoleMessage.MessageType.Trace:
+ this._messageElement = this._format(consoleMessage.parameters || ["console.trace()"]);
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Clear:
+ this._messageElement = document.createTextNode(WebInspector.UIString("Console was cleared"));
+ this._formattedMessage.classList.add("console-info");
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Assert:
+ var args = [WebInspector.UIString("Assertion failed:")];
+ if (consoleMessage.parameters)
+ args = args.concat(consoleMessage.parameters);
+ this._messageElement = this._format(args);
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Dir:
+ var obj = consoleMessage.parameters ? consoleMessage.parameters[0] : undefined;
+ var args = ["%O", obj];
+ this._messageElement = this._format(args);
+ break;
+ case WebInspector.ConsoleMessage.MessageType.Profile:
+ case WebInspector.ConsoleMessage.MessageType.ProfileEnd:
+ this._messageElement = this._format([consoleMessage.messageText]);
+ break;
+ default:
+ var args = consoleMessage.parameters || [consoleMessage.messageText];
+ this._messageElement = this._format(args);
}
- this._messageElement = document.createElement("span");
- if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
- this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " "));
- this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request));
- if (this._request.failed)
- this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription));
- else
- this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")"));
+ } else if (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network) {
+ if (consoleMessage.request) {
+ this._messageElement = document.createElement("span");
+ if (consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
+ this._messageElement.appendChild(document.createTextNode(consoleMessage.request.requestMethod + " "));
+ this._messageElement.appendChild(WebInspector.Linkifier.linkifyUsingRevealer(consoleMessage.request, consoleMessage.request.url, consoleMessage.request.url));
+ if (consoleMessage.request.failed)
+ this._messageElement.appendChild(document.createTextNode(" " + consoleMessage.request.localizedFailDescription));
+ else
+ this._messageElement.appendChild(document.createTextNode(" " + consoleMessage.request.statusCode + " (" + consoleMessage.request.statusText + ")"));
+ } else {
+ var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(consoleMessage.messageText, linkifyRequest.bind(consoleMessage));
+ this._messageElement.appendChild(fragment);
+ }
} else {
- var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request));
- this._messageElement.appendChild(fragment);
+ var url = consoleMessage.url;
+ if (url) {
+ var isExternal = !WebInspector.resourceForURL(url) && !WebInspector.workspace.uiSourceCodeForURL(url);
+ this._anchorElement = WebInspector.linkifyURLAsNode(url, url, "console-message-url", isExternal);
+ }
+ this._messageElement = this._format([consoleMessage.messageText]);
}
} else {
- if (this.url) {
- var isExternal = !WebInspector.resourceForURL(this.url) && !WebInspector.workspace.uiSourceCodeForURL(this.url);
- this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal);
- }
- this._messageElement = this._format([this._messageText]);
+ var args = consoleMessage.parameters || [consoleMessage.messageText];
+ this._messageElement = this._format(args);
}
- } else {
- var args = this._parameters || [this._messageText];
- this._messageElement = this._format(args);
}
- if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
- if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].scriptId) {
- this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]);
- } else if (this.url && this.url !== "undefined") {
- this._anchorElement = this._linkifyLocation(this.url, this.line, this.column);
- }
+ if (consoleMessage.source !== WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.request) {
+ var callFrame = this._callFrameAnchorFromStackTrace(consoleMessage.stackTrace);
+ if (callFrame)
+ this._anchorElement = this._linkifyCallFrame(callFrame);
+ else if (consoleMessage.url && consoleMessage.url !== "undefined")
+ this._anchorElement = this._linkifyLocation(consoleMessage.url, consoleMessage.line, consoleMessage.column);
}
this._formattedMessage.appendChild(this._messageElement);
@@ -175,8 +208,8 @@ WebInspector.ConsoleMessageImpl.prototype = {
this._formattedMessage.appendChild(document.createTextNode(" "));
this._formattedMessage.appendChild(this._anchorElement);
}
-
- var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
+
+ var dumpStackTrace = !!consoleMessage.stackTrace && consoleMessage.stackTrace.length && (consoleMessage.source === WebInspector.ConsoleMessage.MessageSource.Network || consoleMessage.level === WebInspector.ConsoleMessage.MessageLevel.Error || consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace);
if (dumpStackTrace) {
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
@@ -186,31 +219,24 @@ WebInspector.ConsoleMessageImpl.prototype = {
var root = new TreeElement(content, null, true);
content.treeElementForTest = root;
treeOutline.appendChild(root);
- if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
+ if (consoleMessage.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();
this._populateStackTraceTreeElement(root);
this._formattedMessage = ol;
}
-
- // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
- this._message = this._messageElement.textContent;
},
- /**
- * @return {string}
- */
- get message()
+ _formattedMessageText: function()
{
- // force message formatting
- var formattedMessage = this.formattedMessage;
- return this._message;
+ this.formattedMessage();
+ return this._messageElement.textContent;
},
/**
* @return {!Element}
*/
- get formattedMessage()
+ formattedMessage: function()
{
if (!this._formattedMessage)
this._formatMessage();
@@ -218,14 +244,6 @@ WebInspector.ConsoleMessageImpl.prototype = {
},
/**
- * @return {?WebInspector.NetworkRequest}
- */
- request: function()
- {
- return this._request;
- },
-
- /**
* @param {string} url
* @param {number} lineNumber
* @param {number} columnNumber
@@ -233,16 +251,20 @@ WebInspector.ConsoleMessageImpl.prototype = {
*/
_linkifyLocation: function(url, lineNumber, columnNumber)
{
+ console.assert(this._linkifier);
+ var target = this._target();
+ if (!this._linkifier || !target)
+ return null;
// FIXME(62725): stack trace line/column numbers are one-based.
lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
- if (this.source === WebInspector.ConsoleMessage.MessageSource.CSS) {
- var headerIds = WebInspector.cssModel.styleSheetIdsForURL(url);
- var cssLocation = new WebInspector.CSSLocation(url, lineNumber, columnNumber);
+ if (this._message.source === WebInspector.ConsoleMessage.MessageSource.CSS) {
+ var headerIds = target.cssModel.styleSheetIdsForURL(url);
+ var cssLocation = new WebInspector.CSSLocation(target, url, lineNumber, columnNumber);
return this._linkifier.linkifyCSSLocation(headerIds[0] || null, cssLocation, "console-message-url");
}
- return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
+ return this._linkifier.linkifyLocation(target, url, lineNumber, columnNumber, "console-message-url");
},
/**
@@ -251,19 +273,47 @@ WebInspector.ConsoleMessageImpl.prototype = {
*/
_linkifyCallFrame: function(callFrame)
{
+ console.assert(this._linkifier);
+ var target = this._target();
+ if (!this._linkifier || !target)
+ return null;
// FIXME(62725): stack trace line/column numbers are one-based.
var lineNumber = callFrame.lineNumber ? callFrame.lineNumber - 1 : 0;
var columnNumber = callFrame.columnNumber ? callFrame.columnNumber - 1 : 0;
- var rawLocation = new WebInspector.DebuggerModel.Location(callFrame.scriptId, lineNumber, columnNumber);
+ var rawLocation = new WebInspector.DebuggerModel.Location(target, callFrame.scriptId, lineNumber, columnNumber);
return this._linkifier.linkifyRawLocation(rawLocation, "console-message-url");
},
/**
+ * @param {?Array.<!ConsoleAgent.CallFrame>} stackTrace
+ * @return {?ConsoleAgent.CallFrame}
+ */
+ _callFrameAnchorFromStackTrace: function(stackTrace)
+ {
+ if (!stackTrace || !stackTrace.length)
+ return null;
+ var callFrame = stackTrace[0].scriptId ? stackTrace[0] : null;
+ if (!WebInspector.experimentsSettings.frameworksDebuggingSupport.isEnabled())
+ return callFrame;
+ if (!WebInspector.settings.skipStackFramesSwitch.get())
+ return callFrame;
+ var regex = WebInspector.settings.skipStackFramesPattern.asRegExp();
+ if (!regex)
+ return callFrame;
+ for (var i = 0; i < stackTrace.length; ++i) {
+ var script = this._target().debuggerModel.scriptForId(stackTrace[i].scriptId);
+ if (!script || !regex.test(script.sourceURL))
+ return stackTrace[i].scriptId ? stackTrace[i] : null;
+ }
+ return callFrame;
+ },
+
+ /**
* @return {boolean}
*/
isErrorOrWarning: function()
{
- return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
+ return (this._message.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this._message.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},
_format: function(parameters)
@@ -273,6 +323,8 @@ WebInspector.ConsoleMessageImpl.prototype = {
if (!parameters.length)
return formattedResult;
+ var target = this._target();
+
// Formatting code below assumes that parameters are all wrappers whereas frontend console
// API allows passing arbitrary values as messages (strings, numbers, etc.). Wrap them here.
for (var i = 0; i < parameters.length; ++i) {
@@ -280,14 +332,19 @@ WebInspector.ConsoleMessageImpl.prototype = {
if (parameters[i] instanceof WebInspector.RemoteObject)
continue;
+ if (!target) {
+ parameters[i] = WebInspector.RemoteObject.fromLocalObject(parameters[i]);
+ continue;
+ }
+
if (typeof parameters[i] === "object")
- parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
+ parameters[i] = target.runtimeModel.createRemoteObject(parameters[i]);
else
- parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
+ parameters[i] = target.runtimeModel.createRemoteObjectFromPrimitiveValue(parameters[i]);
}
// There can be string log and string eval result. We distinguish between them based on message type.
- var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;
+ var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this._message.type !== WebInspector.ConsoleMessage.MessageType.Result;
// Multiple parameters with the first being a format string. Save unused substitutions.
if (shouldFormatMessage) {
@@ -298,7 +355,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
formattedResult.appendChild(document.createTextNode(" "));
}
- if (this.type === WebInspector.ConsoleMessage.MessageType.Table) {
+ if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
formattedResult.appendChild(this._formatParameterAsTable(parameters));
return formattedResult;
}
@@ -317,42 +374,36 @@ WebInspector.ConsoleMessageImpl.prototype = {
},
/**
- * @param {?Object} output
+ * @param {!WebInspector.RemoteObject} output
* @param {boolean=} forceObjectFormat
* @param {boolean=} includePreview
* @return {!Element}
*/
_formatParameter: function(output, forceObjectFormat, includePreview)
{
- var type;
- if (forceObjectFormat)
- type = "object";
- else if (output instanceof WebInspector.RemoteObject)
- type = output.subtype || output.type;
- else
- type = typeof output;
-
- var formatter = this._customFormatters[type];
- if (!formatter) {
- formatter = this._formatParameterAsValue;
- output = output.description;
- }
-
+ var type = forceObjectFormat ? "object" : (output.subtype || output.type);
+ var formatter = this._customFormatters[type] || this._formatParameterAsValue;
var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span, includePreview);
return span;
},
- _formatParameterAsValue: function(val, elem)
+ /**
+ * @param {!WebInspector.RemoteObject} obj
+ * @param {!Element} elem
+ */
+ _formatParameterAsValue: function(obj, elem)
{
- elem.appendChild(document.createTextNode(val));
+ elem.appendChild(document.createTextNode(obj.description || ""));
+ if (obj.objectId)
+ elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
},
/**
* @param {!WebInspector.RemoteObject} obj
* @param {!Element} elem
- * @param {boolean} includePreview
+ * @param {boolean=} includePreview
*/
_formatParameterAsObject: function(obj, elem, includePreview)
{
@@ -363,7 +414,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
* @param {!WebInspector.RemoteObject} obj
* @param {string} description
* @param {!Element} elem
- * @param {boolean} includePreview
+ * @param {boolean=} includePreview
*/
_formatParameterAsArrayOrObject: function(obj, description, elem, includePreview)
{
@@ -375,6 +426,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
var lossless = this._appendObjectPreview(obj, description, titleElement);
if (lossless) {
elem.appendChild(titleElement);
+ titleElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, obj), false);
return;
}
}
@@ -388,6 +440,17 @@ WebInspector.ConsoleMessageImpl.prototype = {
/**
* @param {!WebInspector.RemoteObject} obj
+ * @param {?Event} event
+ */
+ _contextMenuEventFired: function(obj, event)
+ {
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendApplicableItems(obj);
+ contextMenu.show();
+ },
+
+ /**
+ * @param {!WebInspector.RemoteObject} obj
* @param {string} description
* @param {!Element} titleElement
* @return {boolean} true iff preview captured all information.
@@ -471,28 +534,29 @@ WebInspector.ConsoleMessageImpl.prototype = {
return span;
},
+ /**
+ * @param {!WebInspector.RemoteObject} object
+ * @param {!Element} elem
+ */
_formatParameterAsNode: function(object, elem)
{
/**
- * @param {!DOMAgent.NodeId} nodeId
- * @this {WebInspector.ConsoleMessageImpl}
+ * @param {!WebInspector.DOMNode} node
+ * @this {WebInspector.ConsoleViewMessage}
*/
- function printNode(nodeId)
+ function printNode(node)
{
- if (!nodeId) {
+ if (!node) {
// Sometimes DOM is loaded after the sync message is being formatted, so we get no
// nodeId here. So we fall back to object formatting here.
this._formatParameterAsObject(object, elem, false);
return;
}
- var treeOutline = new WebInspector.ElementsTreeOutline(false, false);
- treeOutline.setVisible(true);
- treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
- treeOutline.element.classList.add("outline-disclosure");
- if (!treeOutline.children[0].hasChildren)
- treeOutline.element.classList.add("single-node");
- elem.appendChild(treeOutline.element);
- treeOutline.element.treeElementForTest = treeOutline.children[0];
+ var renderer = WebInspector.moduleManager.instance(WebInspector.Renderer, node);
+ if (renderer)
+ elem.appendChild(renderer.render(node));
+ else
+ console.error("No renderer for node found");
}
object.pushNodeToFrontend(printNode.bind(this));
},
@@ -503,7 +567,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
*/
useArrayPreviewInFormatter: function(array)
{
- return this.type !== WebInspector.ConsoleMessage.MessageType.DirXML && !!array.preview;
+ return this._message.type !== WebInspector.ConsoleMessage.MessageType.DirXML && !!array.preview;
},
/**
@@ -518,7 +582,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
const maxFlatArrayLength = 100;
- if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
+ if (this._message.isOutdated || array.arrayLength() > maxFlatArrayLength)
this._formatParameterAsObject(array, elem, false);
else
array.getOwnProperties(this._printArray.bind(this, array, elem));
@@ -574,21 +638,30 @@ WebInspector.ConsoleMessageImpl.prototype = {
flatValues.push(rowValue[columnNames[j]]);
}
- if (!flatValues.length)
- return element;
+ var dataGridContainer = element.createChild("span");
+ if (!preview.lossless || !flatValues.length) {
+ element.appendChild(this._formatParameter(table, true, false));
+ if (!flatValues.length)
+ return element;
+ }
+
columnNames.unshift(WebInspector.UIString("(index)"));
var dataGrid = WebInspector.DataGrid.createSortableDataGrid(columnNames, flatValues);
dataGrid.renderInline();
this._dataGrids.push(dataGrid);
- this._dataGridParents.put(dataGrid, element);
+ this._dataGridParents.put(dataGrid, dataGridContainer);
return element;
},
+ /**
+ * @param {!WebInspector.RemoteObject} output
+ * @param {!Element} elem
+ */
_formatParameterAsString: function(output, elem)
{
var span = document.createElement("span");
span.className = "console-formatted-string source-code";
- span.appendChild(WebInspector.linkifyStringAsFragment(output.description));
+ span.appendChild(WebInspector.linkifyStringAsFragment(output.description || ""));
// Make black quotes.
elem.classList.remove("console-formatted-string");
@@ -649,6 +722,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
appendUndefined(elem, length);
elem.appendChild(document.createTextNode("]"));
+ elem.addEventListener("contextmenu", this._contextMenuEventFired.bind(this, array), false);
},
/**
@@ -674,7 +748,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
/**
* @param {?WebInspector.RemoteObject} result
* @param {boolean=} wasThrown
- * @this {WebInspector.ConsoleMessageImpl}
+ * @this {WebInspector.ConsoleViewMessage}
*/
function onInvokeGetterClick(result, wasThrown)
{
@@ -684,7 +758,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
if (wasThrown) {
var element = rootElement.createChild("span", "error-message");
element.textContent = WebInspector.UIString("<exception>");
- element.title = result.description;
+ element.title = /** @type {string} */ (result.description);
} else if (isArrayEntry) {
rootElement.appendChild(this._formatAsArrayEntry(result));
} else {
@@ -710,7 +784,6 @@ WebInspector.ConsoleMessageImpl.prototype = {
* @param {string} format
* @param {!Array.<string>} parameters
* @param {!Element} formattedResult
- * @this {WebInspector.ConsoleMessageImpl}
*/
_formatWithSubstitutionString: function(format, parameters, formattedResult)
{
@@ -718,9 +791,9 @@ WebInspector.ConsoleMessageImpl.prototype = {
/**
* @param {boolean} force
- * @param {!Object} obj
+ * @param {!WebInspector.RemoteObject} obj
* @return {!Element}
- * @this {WebInspector.ConsoleMessageImpl}
+ * @this {WebInspector.ConsoleViewMessage}
*/
function parameterFormatter(force, obj)
{
@@ -833,8 +906,6 @@ WebInspector.ConsoleMessageImpl.prototype = {
this._highlightSearchResultsInElement(regexObject, this._messageElement);
if (this._anchorElement)
this._highlightSearchResultsInElement(regexObject, this._anchorElement);
-
- this._element.scrollIntoViewIfNeeded();
},
_highlightSearchResultsInElement: function(regexObject, element)
@@ -850,24 +921,79 @@ WebInspector.ConsoleMessageImpl.prototype = {
WebInspector.highlightSearchResults(element, matchRanges);
},
+ /**
+ * @return {boolean}
+ */
matchesRegex: function(regexObject)
{
regexObject.lastIndex = 0;
- return regexObject.test(this.message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent));
+ return regexObject.test(this._formattedMessageText()) || (!!this._anchorElement && regexObject.test(this._anchorElement.textContent));
},
- toMessageElement: function()
+ /**
+ * @param {boolean} show
+ */
+ updateTimestamp: function(show)
+ {
+ if (!this._element)
+ return;
+
+ if (show && !this.timestampElement) {
+ this.timestampElement = this._element.createChild("span", "console-timestamp");
+ this.timestampElement.textContent = (new Date(this._message.timestamp)).toConsoleTime();
+ var afterRepeatCountChild = this._repeatCountElement && this._repeatCountElement.nextSibling;
+ this._element.insertBefore(this.timestampElement, afterRepeatCountChild || this._element.firstChild);
+ return;
+ }
+
+ if (!show && this.timestampElement) {
+ this.timestampElement.remove();
+ delete this.timestampElement;
+ }
+ },
+
+ /**
+ * @return {number}
+ */
+ nestingLevel: function()
+ {
+ return this._nestingLevel;
+ },
+
+ resetCloseGroupDecorationCount: function()
+ {
+ this._closeGroupDecorationCount = 0;
+ this._updateCloseGroupDecorations();
+ },
+
+ incrementCloseGroupDecorationCount: function()
+ {
+ ++this._closeGroupDecorationCount;
+ this._updateCloseGroupDecorations();
+ },
+
+ _updateCloseGroupDecorations: function()
+ {
+ if (!this._nestingLevelMarkers)
+ return;
+ for (var i = 0, n = this._nestingLevelMarkers.length; i < n; ++i) {
+ var marker = this._nestingLevelMarkers[i];
+ marker.classList.toggle("group-closed", n - i <= this._closeGroupDecorationCount);
+ }
+ },
+
+ /**
+ * @return {!Element}
+ */
+ contentElement: function()
{
if (this._element)
return this._element;
- var element = document.createElement("div");
- element.message = this;
- element.className = "console-message";
-
+ var element = document.createElementWithClass("div", "console-message");
this._element = element;
- switch (this.level) {
+ switch (this._message.level) {
case WebInspector.ConsoleMessage.MessageLevel.Log:
element.classList.add("console-log-level");
break;
@@ -885,21 +1011,42 @@ WebInspector.ConsoleMessageImpl.prototype = {
break;
}
- if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
+ if (this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this._message.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.classList.add("console-group-title");
- element.appendChild(this.formattedMessage);
+ element.appendChild(this.formattedMessage());
- if (this.repeatCount > 1)
- this.updateRepeatCount();
+ if (this._repeatCount > 1)
+ this._showRepeatCountElement();
- return element;
+ this.updateTimestamp(WebInspector.settings.consoleTimestampsEnabled.get());
+
+ return this._element;
+ },
+
+ /**
+ * @return {!Element}
+ */
+ toMessageElement: function()
+ {
+ if (this._wrapperElement)
+ return this._wrapperElement;
+
+ this._wrapperElement = document.createElementWithClass("div", "console-message-wrapper");
+ this._nestingLevelMarkers = [];
+ for (var i = 0; i < this._nestingLevel; ++i)
+ this._nestingLevelMarkers.push(this._wrapperElement.createChild("div", "nesting-level-marker"));
+ this._updateCloseGroupDecorations();
+ this._wrapperElement.message = this;
+
+ this._wrapperElement.appendChild(this.contentElement());
+ return this._wrapperElement;
},
_populateStackTraceTreeElement: function(parentTreeElement)
{
- for (var i = 0; i < this._stackTrace.length; i++) {
- var frame = this._stackTrace[i];
+ for (var i = 0; i < this._message.stackTrace.length; i++) {
+ var frame = this._message.stackTrace[i];
var content = document.createElementWithClass("div", "stacktrace-entry");
var messageTextElement = document.createElement("span");
@@ -921,29 +1068,49 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
},
- updateRepeatCount: function() {
+ resetIncrementRepeatCount: function()
+ {
+ this._repeatCount = 1;
+ if (!this._repeatCountElement)
+ return;
+
+ this._repeatCountElement.remove();
+ delete this._repeatCountElement;
+ },
+
+ incrementRepeatCount: function()
+ {
+ this._repeatCount++;
+ this._showRepeatCountElement();
+ },
+
+ _showRepeatCountElement: function()
+ {
if (!this._element)
return;
- if (!this.repeatCountElement) {
- this.repeatCountElement = document.createElement("span");
- this.repeatCountElement.className = "bubble";
+ if (!this._repeatCountElement) {
+ this._repeatCountElement = document.createElement("span");
+ this._repeatCountElement.className = "bubble";
- this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
+ this._element.insertBefore(this._repeatCountElement, this._element.firstChild);
this._element.classList.add("repeated-message");
}
- this.repeatCountElement.textContent = this.repeatCount;
+ this._repeatCountElement.textContent = this._repeatCount;
},
+ /**
+ * @return {string}
+ */
toString: function()
{
var sourceString;
- switch (this.source) {
+ switch (this._message.source) {
case WebInspector.ConsoleMessage.MessageSource.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
- sourceString = "JS";
+ sourceString = "JavaScript";
break;
case WebInspector.ConsoleMessage.MessageSource.Network:
sourceString = "Network";
@@ -972,7 +1139,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
var typeString;
- switch (this.type) {
+ switch (this._message.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
typeString = "Log";
break;
@@ -1005,7 +1172,7 @@ WebInspector.ConsoleMessageImpl.prototype = {
}
var levelString;
- switch (this.level) {
+ switch (this._message.level) {
case WebInspector.ConsoleMessage.MessageLevel.Log:
levelString = "Log";
break;
@@ -1023,67 +1190,59 @@ WebInspector.ConsoleMessageImpl.prototype = {
break;
}
- return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
+ return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage().textContent + "\n" + this._message.url + " line " + this._message.line;
},
get text()
{
- return this._messageText;
+ return this._message.messageText;
},
+}
+/**
+ * @constructor
+ * @extends {WebInspector.ConsoleViewMessage}
+ * @param {!WebInspector.ConsoleMessage} consoleMessage
+ * @param {?WebInspector.Linkifier} linkifier
+ * @param {number} nestingLevel
+ */
+WebInspector.ConsoleGroupViewMessage = function(consoleMessage, linkifier, nestingLevel)
+{
+ console.assert(consoleMessage.isGroupStartMessage());
+ WebInspector.ConsoleViewMessage.call(this, consoleMessage, linkifier, nestingLevel);
+ this.setCollapsed(consoleMessage.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed);
+}
+
+WebInspector.ConsoleGroupViewMessage.prototype = {
/**
- * @return {?WebInspector.DebuggerModel.Location}
+ * @param {boolean} collapsed
*/
- location: function()
+ setCollapsed: function(collapsed)
{
- // FIXME(62725): stack trace line/column numbers are one-based.
- var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1;
- var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0;
- return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber);
+ this._collapsed = collapsed;
+ if (this._wrapperElement)
+ this._wrapperElement.classList.toggle("collapsed", this._collapsed);
},
- isEqual: function(msg)
- {
- if (!msg)
- return false;
-
- if (this._stackTrace) {
- if (!msg._stackTrace)
- return false;
- var l = this._stackTrace;
- var r = msg._stackTrace;
- if (l.length !== r.length)
- return false;
- for (var i = 0; i < l.length; i++) {
- if (l[i].url !== r[i].url ||
- l[i].functionName !== r[i].functionName ||
- l[i].lineNumber !== r[i].lineNumber ||
- l[i].columnNumber !== r[i].columnNumber)
- return false;
- }
- }
-
- return (this.source === msg.source)
- && (this.type === msg.type)
- && (this.level === msg.level)
- && (this.line === msg.line)
- && (this.url === msg.url)
- && (this.message === msg.message)
- && (this._request === msg._request);
- },
-
- get stackTrace()
+ /**
+ * @return {boolean}
+ */
+ collapsed: function()
{
- return this._stackTrace;
+ return this._collapsed;
},
/**
- * @return {!WebInspector.ConsoleMessage}
+ * @return {!Element}
*/
- clone: function()
+ toMessageElement: function()
{
- return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.column, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated);
+ if (!this._wrapperElement) {
+ WebInspector.ConsoleViewMessage.prototype.toMessageElement.call(this);
+ this._wrapperElement.classList.toggle("collapsed", this._collapsed);
+ }
+ return this._wrapperElement;
},
- __proto__: WebInspector.ConsoleMessage.prototype
+ __proto__: WebInspector.ConsoleViewMessage.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/console/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/console/module.json
new file mode 100644
index 00000000000..576ab686d5b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/console/module.json
@@ -0,0 +1,55 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "console",
+ "title": "Console",
+ "order": 20,
+ "className": "WebInspector.ConsolePanel"
+ },
+ {
+ "type": "drawer-view",
+ "name": "console",
+ "title": "Console",
+ "order": "0",
+ "className": "WebInspector.ConsolePanel.WrapperView"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.ConsoleModel"],
+ "className": "WebInspector.ConsolePanel.ConsoleRevealer"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "console.show",
+ "className": "WebInspector.ConsoleView.ShowConsoleActionDelegate",
+ "bindings": [
+ {
+ "shortcut": "Ctrl+`"
+ }
+ ]
+ },
+ {
+ "type": "ui-setting",
+ "section": "Console",
+ "title": "Log XMLHttpRequests",
+ "settingName": "monitoringXHREnabled",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Console",
+ "title": "Preserve log upon navigation",
+ "settingName": "preserveConsoleLog",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Console",
+ "title": "Show timestamps",
+ "settingName": "consoleTimestampsEnabled",
+ "settingType": "checkbox"
+ }
+ ],
+ "scripts": [ "ConsolePanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/cssNamedFlows.css b/chromium/third_party/WebKit/Source/devtools/front_end/cssNamedFlows.css
deleted file mode 100644
index 62b530f36fb..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/cssNamedFlows.css
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.css-named-flow-collections-view .split-view-sidebar {
- overflow-x: hidden;
-}
-
-.css-named-flow-collections-view .tabbed-pane-header {
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(236, 236, 236)), to(rgb(217, 217, 217)));
-}
-
-.css-named-flow-collections-view .info {
- font-style: italic;
- font-size: 10px;
- margin-top: -5px;
- position: absolute;
- top: 50%;
- text-align: center;
- width: 100%;
-}
-
-.css-named-flow-collections-view .split-view-sidebar .sidebar-content {
- bottom: 0;
- left: 0;
- padding: 0;
- position: absolute;
- right: 0;
- top: 23px;
-}
-
-.css-named-flow-collections-view .split-view-sidebar .selection {
- margin-left: -12px;
- z-index: 0;
-}
-
-.css-named-flow-collections-view .split-view-contents .title {
- position: relative;
-}
-
-.css-named-flow-collections-view .split-view-sidebar .named-flow-overflow::before,
-.css-named-flow-collections-view .region-empty:before,
-.css-named-flow-collections-view .region-fit::before,
-.css-named-flow-collections-view .region-overset::before {
- cursor: default;
- float: left;
- height: 10px;
- margin-top: 1px;
- opacity: 0.75;
- position: relative;
- vertical-align: middle;
- z-index: 1;
-}
-
-.css-named-flow-collections-view .split-view-sidebar .named-flow-overflow::before {
- content: url(Images/namedFlowOverflow.png);
- margin: 2px 3px 0 -13px;
-}
-
-.css-named-flow-collections-view .region-empty::before {
- content: url(Images/regionEmpty.png);
-}
-
-.css-named-flow-collections-view .region-fit::before {
- content: url(Images/regionFit.png);
-}
-
-.css-named-flow-collections-view .region-overset::before {
- content: url(Images/regionOverset.png);
-}
-
-.css-named-flow-collections-view .split-view-contents .named-flow-element {
- margin: 0 0 0 -24px;
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/dataGrid.css b/chromium/third_party/WebKit/Source/devtools/front_end/dataGrid.css
index 78fbb21fd70..c403a3fd495 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/dataGrid.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/dataGrid.css
@@ -22,12 +22,13 @@
.data-grid .data-container {
position: absolute;
- top: 16px;
+ top: 17px;
bottom: 0;
left: 0;
right: 0;
overflow-x: hidden;
overflow-y: overlay;
+ -webkit-transform: translateZ(0);
}
.data-grid.inline {
@@ -38,24 +39,12 @@
position: static;
}
+.data-grid.inline col.corner,
.data-grid.inline th.corner,
.data-grid.inline td.corner {
display: none;
}
-.data-grid th {
- text-align: left;
- background-image: url(Images/glossyHeader.png);
- background-repeat: repeat-x;
- border-left: 1px solid rgb(179, 179, 179);
- border-bottom: 1px solid rgb(179, 179, 179);
- height: 15px;
- font-weight: normal;
- vertical-align: middle;
- padding: 0 4px;
- white-space: nowrap;
-}
-
.data-grid th.corner,
.data-grid td.corner,
.data-grid col.corner {
@@ -83,8 +72,8 @@
bottom: 0;
height: 100%;
border-top: 0 none transparent;
- background-image: -webkit-gradient(linear, left top, left bottom, from(white), color-stop(0.5, white), color-stop(0.5, rgb(234, 243, 255)), to(rgb(234, 243, 255)));
- background-size: 1px 32px;
+ background-image: linear-gradient(to bottom, white, white 50%, rgb(234, 243, 255) 50%, rgb(234, 243, 255));
+ background-size: 128px 32px;
table-layout: fixed;
}
@@ -100,22 +89,36 @@
display: table-row;
}
-.data-grid td {
- vertical-align: top;
- height: 16px; /* Keep in sync with .data-grid table.data @ background-size */
- line-height: 13px;
- padding: 1px 4px;
+.data-grid td,
+.data-grid th {
white-space: nowrap;
+ text-overflow: ellipsis;
overflow: hidden;
+ height: 16px; /* Keep in sync with .data-grid table.data @ background-size */
+ line-height: 14px;
border-left: 1px solid #aaa;
- -webkit-user-select: text;
}
-.data-grid th:first-child,
-.data-grid td:first-child {
+.data-grid:not(.inline) th:first-child,
+.data-grid:not(.inline) td:first-child {
border-left: none !important;
}
+.data-grid td {
+ vertical-align: top;
+ padding: 1px 4px;
+ -webkit-user-select: text;
+}
+
+.data-grid th {
+ text-align: left;
+ background-color: rgb(236, 236, 236);
+ border-bottom: 1px solid #aaa;
+ font-weight: normal;
+ vertical-align: middle;
+ padding: 0 4px;
+}
+
.data-grid td > div,
.data-grid th > div {
white-space: nowrap;
@@ -123,15 +126,19 @@
overflow: hidden;
}
+.data-grid th > div {
+ overflow: hidden;
+}
+
.data-grid td.editing > div {
text-overflow: clip;
}
-.data-grid .center div {
+.data-grid .center {
text-align: center;
}
-.data-grid .right div {
+.data-grid .right {
text-align: right;
}
@@ -140,18 +147,7 @@
}
.data-grid th.sortable:active {
- background-image: url(Images/glossyHeaderPressed.png);
-}
-.data-grid th.sort-ascending,
-.data-grid th.sort-descending {
- border-left: 1px solid rgb(107, 140, 196);
- border-bottom: 1px solid rgb(107, 140, 196);
- background-image: url(Images/glossyHeaderSelected.png);
- background-repeat: repeat-x;
-}
-
-.data-grid th.sortable.sort-ascending:active, .data-grid th.sortable.sort-descending:active {
- background-image: url(Images/glossyHeaderSelectedPressed.png);
+ background-color: rgba(0, 0, 0, 0.15);
}
.data-grid th.sort-ascending > div::after,
@@ -160,7 +156,7 @@
top: 1px;
right: 0;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
width: 8px;
height: 10px;
@@ -171,7 +167,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.data-grid th.sort-ascending > div::after,
.data-grid th.sort-descending > div::after {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -183,22 +179,19 @@
background-position: -20px -96px;
}
+.data-grid th:hover {
+ background-color: rgba(0, 0, 0, 0.1);
+}
+
.data-grid button {
line-height: 18px;
color: inherit;
}
-body.inactive .data-grid th.sort-ascending,
-body.inactive .data-grid th.sort-descending {
- background-image: url(Images/glossyHeader.png);
- border-left: 1px solid rgb(179, 179, 179);
- border-bottom: 1px solid rgb(179, 179, 179);
-}
-
.data-grid tr.parent td.disclosure::before {
-webkit-user-select: none;
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
float: left;
width: 8px;
margin-right: 2px;
@@ -215,7 +208,7 @@ body.inactive .data-grid th.sort-descending {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.data-grid tr.parent td.disclosure::before {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js b/chromium/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js
new file mode 100644
index 00000000000..95248d0cd9f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/devices/DevicesView.js
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.DevicesView = function()
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("devicesView.css");
+ this.element.classList.add("devices");
+ this._devicesHelp = this.element.createChild("div");
+ this._devicesHelp.innerHTML = WebInspector.UIString("No devices detected. \
+ Please read the <a href=\"https://developers.google.com/chrome-developer\
+ -tools/docs/remote-debugging\"> remote debugging documentation</a> to \
+ verify your device is enabled for USB debugging.");
+ this.element.createChild("div", "devices-info").innerHTML = WebInspector.UIString("Click \"Try here\" button, to open the current page in the selected remote browser.");
+ this._devicesList = this.element.createChild("div");
+ this._devicesList.cellSpacing = 0;
+};
+
+WebInspector.DevicesView.MinVersionNewTab = 29;
+
+
+var Adb = {};
+
+/**
+ * @typedef {{id: string, adbBrowserChromeVersion: string, compatibleVersion: boolean, adbBrowserName: string, source: string, adbBrowserVersion: string}}
+ */
+Adb.Browser;
+
+/**
+ * @typedef {{id: string, adbModel: string, adbSerial: string, browsers: !Array.<!Adb.Browser>, adbPortStatus: !Array.<number>, adbConnected: boolean}}
+ */
+Adb.Device;
+
+WebInspector.DevicesView.Events = {
+ DevicesChanged: "DevicesChanged"
+};
+
+WebInspector.DevicesView.prototype = {
+ _onDevicesChanged: function(event)
+ {
+ this._updateDeviceList(/** @type {!Array.<!Adb.Device>} */(event.data));
+ },
+
+ /**
+ * @param {!Array.<!Adb.Device>} devices
+ */
+ _updateDeviceList: function(devices)
+ {
+ /**
+ * @param {string} id
+ * @return {string}
+ */
+ function sanitizeForId(id)
+ {
+ return id.replace(/[.:/\/ ]/g, "-");
+ }
+
+ /**
+ * @param {!Element} element
+ * @param {!Object} data
+ * @return {boolean}
+ */
+ function alreadyDisplayed(element, data)
+ {
+ var json = JSON.stringify(data);
+ if (element.__cachedJSON === json)
+ return true;
+ element.__cachedJSON = json;
+ return false;
+ }
+
+ /**
+ * @param {!Element} parent
+ * @param {!Element} child
+ */
+ function insertChildSortedById(parent, child)
+ {
+ for (var sibling = parent.firstElementChild; sibling; sibling = sibling.nextElementSibling) {
+ if (sibling.id && sibling.id > child.id) {
+ parent.insertBefore(child, sibling);
+ return;
+ }
+ }
+ parent.appendChild(child);
+ }
+
+ /**
+ *
+ * @param {!Array.<string>} validIds
+ * @param {!Element} section
+ */
+ function removeObsolete(validIds, section)
+ {
+ if (validIds.indexOf(section.id) < 0)
+ section.remove();
+ }
+
+ if (alreadyDisplayed(this._devicesList, devices))
+ return;
+
+ var newDeviceIds = devices.map(function(device) { return device.id; });
+
+ Array.prototype.forEach.call(
+ this._devicesList.querySelectorAll(".device"),
+ removeObsolete.bind(null, newDeviceIds));
+
+ this._devicesHelp.hidden = !!devices.length;
+
+ for (var d = 0; d < devices.length; d++) {
+ // FIXME: Try to use shadow DOM.
+ var device = devices[d];
+
+ var deviceSection = this._devicesList.querySelector("#" + sanitizeForId(device.id));
+ if (!deviceSection) {
+ deviceSection = this._devicesList.createChild("div", "device");
+ deviceSection.id = sanitizeForId(device.id);
+ var deviceHeader = deviceSection.createChild("div", "device-header");
+ deviceHeader.createChild("div", "device-name");
+ var deviceSerial = deviceHeader.createChild("div", "device-serial");
+ deviceSerial.textContent = "#" + device.adbSerial.toUpperCase();
+ deviceSection.createChild("div", "device-auth");
+ }
+
+ if (alreadyDisplayed(deviceSection, device))
+ continue;
+
+ deviceSection.querySelector(".device-name").textContent = device.adbModel;
+ deviceSection.querySelector(".device-auth").textContent =
+ device.adbConnected ? ""
+ : WebInspector.UIString("Pending authentication: please accept debugging session on the device.");
+
+ var browsers = device.browsers.filter(function(browser) { return browser.adbBrowserChromeVersion; });
+
+ var newBrowserIds = browsers.map(function(browser) { return browser.id });
+ Array.prototype.forEach.call(deviceSection.querySelectorAll(".browser"), removeObsolete.bind(null, newBrowserIds));
+
+ for (var b = 0; b < browsers.length; b++) {
+ var browser = browsers[b];
+ var incompatibleVersion = browser.hasOwnProperty("compatibleVersion") && !browser.compatibleVersion;
+ var browserSection = deviceSection.querySelector("#" + sanitizeForId(browser.id));
+ if (!browserSection) {
+ browserSection = document.createElementWithClass("div", "browser");
+ browserSection.id = sanitizeForId(browser.id);
+ insertChildSortedById(deviceSection, browserSection);
+
+ var browserName = browserSection.createChild("div", "browser-name");
+ browserName.textContent = browser.adbBrowserName;
+ if (browser.adbBrowserVersion)
+ browserName.textContent += " (" + browser.adbBrowserVersion + ")";
+
+ if (incompatibleVersion || browser.adbBrowserChromeVersion < WebInspector.DevicesView.MinVersionNewTab) {
+ var warningSection = browserSection.createChild("div", "warning");
+ warningSection.textContent = incompatibleVersion
+ ? WebInspector.UIString("You may need a newer version of desktop Chrome. Please try Chrome %s or later.", browser.adbBrowserVersion)
+ : WebInspector.UIString("You may need a newer version of Chrome on your device. Please try Chrome %s or later.", WebInspector.DevicesView.MinVersionNewTab);
+ } else {
+ var newPageButton = browserSection.createChild("button", "settings-tab-text-button");
+ newPageButton.textContent = WebInspector.UIString("Try here");
+ newPageButton.title = WebInspector.UIString("Inspect current page in this browser.");
+ newPageButton.addEventListener("click", InspectorFrontendHost.openUrlOnRemoteDeviceAndInspect.bind(null, browser.id, WebInspector.resourceTreeModel.inspectedPageURL()), true);
+ }
+ }
+
+ }
+ }
+ },
+
+ willHide: function()
+ {
+ WebInspector.inspectorFrontendEventSink.removeEventListener(WebInspector.DevicesView.Events.DevicesChanged, this._onDevicesChanged, this);
+ },
+
+ wasShown: function()
+ {
+ WebInspector.inspectorFrontendEventSink.addEventListener(WebInspector.DevicesView.Events.DevicesChanged, this._onDevicesChanged, this);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/devices/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/devices/module.json
new file mode 100644
index 00000000000..8542c6954a5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/devices/module.json
@@ -0,0 +1,13 @@
+{
+ "extensions": [
+ {
+ "type": "drawer-view",
+ "name": "devices",
+ "title": "Devices",
+ "order": "12",
+ "experiment": "devicesPanel",
+ "className": "WebInspector.DevicesView"
+ }
+ ],
+ "scripts": [ "DevicesView.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/devicesView.css b/chromium/third_party/WebKit/Source/devtools/front_end/devicesView.css
new file mode 100644
index 00000000000..9815e8973f3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/devicesView.css
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+.devices {
+ padding: 10px;
+}
+
+.devices-info {
+ flex: none;
+ padding-bottom: 10px;
+}
+
+.browser {
+ align-items: baseline;
+ display: flex;
+ padding: 1px;
+}
+
+.browser button {
+ white-space: nowrap;
+ flex: none;
+}
+
+.device-header {
+ align-items: baseline;
+ display: flex;
+ flex-flow: row wrap;
+ padding: 2px 0;
+}
+
+.device-name {
+ color: #222;
+ font-size: 120%;
+ font-weight: normal;
+}
+
+.device-serial {
+ color: #888;
+ font-size: 80%;
+ margin-left: 6px;
+ font-weight: normal;
+}
+
+.browser-name {
+ overflow: hidden;
+ padding-left: 20px;
+ padding-right: 10px;
+ flex: 0 1 250px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/dialog.css b/chromium/third_party/WebKit/Source/devtools/front_end/dialog.css
index a82792c82a8..ff93919a461 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/dialog.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/dialog.css
@@ -10,7 +10,7 @@
display: -webkit-flex;
-webkit-flex-direction: column;
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#E9E9E9), to(#CFCFCF));
+ background-image: linear-gradient(to bottom, #E9E9E9, #CFCFCF);
}
.dialog-contents {
@@ -31,7 +31,7 @@
color: rgb(6, 6, 6);
border: 1px solid rgb(165, 165, 165);
background-color: rgb(237, 237, 237);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
border-radius: 12px;
-webkit-appearance: none;
@@ -41,6 +41,6 @@
.go-to-line-dialog button:active {
background-color: rgb(215, 215, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMSyntaxHighlighter.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/DOMSyntaxHighlighter.js
index 1fec5e8f732..8441dbd5210 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMSyntaxHighlighter.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/DOMSyntaxHighlighter.js
@@ -33,12 +33,16 @@
*/
WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
{
- loadScript("CodeMirrorTextEditor.js");
this._mimeType = mimeType;
this._stripExtraWhitespace = stripExtraWhitespace;
}
WebInspector.DOMSyntaxHighlighter.prototype = {
+ /**
+ * @param {string} content
+ * @param {string} className
+ * @return {!Element}
+ */
createSpan: function(content, className)
{
var span = document.createElement("span");
@@ -56,7 +60,7 @@ WebInspector.DOMSyntaxHighlighter.prototype = {
/**
* @param {string} token
- * @param {string} tokenType
+ * @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
* @this {WebInspector.DOMSyntaxHighlighter}
@@ -74,7 +78,7 @@ WebInspector.DOMSyntaxHighlighter.prototype = {
plainTextStart = newColumn;
}
- var tokenize = WebInspector.CodeMirrorUtils.createTokenizer(this._mimeType);
+ var tokenize = WebInspector.moduleManager.instance(WebInspector.TokenizerFactory).createTokenizer(this._mimeType);
for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
var line = lines[i];
var plainTextStart = 0;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
index 25508587457..35e65ad1e57 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsPanel.js
@@ -28,8 +28,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-importScript("CSSNamedFlowCollectionsView.js");
-importScript("CSSNamedFlowView.js");
+importScript("Spectrum.js");
+importScript("DOMSyntaxHighlighter.js");
+importScript("ElementsTreeOutline.js");
importScript("EventListenersSidebarPane.js");
importScript("MetricsSidebarPane.js");
importScript("OverridesView.js");
@@ -40,8 +41,8 @@ importScript("StylesSidebarPane.js");
/**
* @constructor
- * @implements {WebInspector.ViewFactory}
* @implements {WebInspector.Searchable}
+ * @implements {WebInspector.TargetManager.Observer}
* @extends {WebInspector.Panel}
*/
WebInspector.ElementsPanel = function()
@@ -49,22 +50,16 @@ WebInspector.ElementsPanel = function()
WebInspector.Panel.call(this, "elements");
this.registerRequiredCSS("breadcrumbList.css");
this.registerRequiredCSS("elementsPanel.css");
- this.registerRequiredCSS("textPrompt.css");
+ this.registerRequiredCSS("suggestBox.css");
this.setHideOnDetach();
- const initialSidebarWidth = 325;
- const minimumContentWidthPercent = 0.34;
- const initialSidebarHeight = 325;
- const minimumContentHeightPercent = 0.34;
- this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.End, initialSidebarWidth, initialSidebarHeight);
- this.splitView.sidebarElement.classList.add("vbox");
- this.splitView.setSidebarElementConstraints(Preferences.minElementsSidebarWidth, Preferences.minElementsSidebarHeight);
- this.splitView.setMainElementConstraints(minimumContentWidthPercent, minimumContentHeightPercent);
- this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._updateTreeOutlineVisibleWidth.bind(this));
+ this._splitView = new WebInspector.SplitView(true, true, "elementsPanelSplitViewState", 325, 325);
+ this._splitView.addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._updateTreeOutlineVisibleWidth.bind(this));
+ this._splitView.show(this.element);
this._searchableView = new WebInspector.SearchableView(this);
- this.splitView.mainElement.classList.add("vbox");
- this._searchableView.show(this.splitView.mainElement);
+ this._searchableView.setMinimumSize(25, 19);
+ this._searchableView.show(this._splitView.mainElement());
var stackElement = this._searchableView.element;
this.contentElement = stackElement.createChild("div");
@@ -76,13 +71,7 @@ WebInspector.ElementsPanel = function()
WebInspector.settings.domWordWrap.addChangeListener(this._domWordWrapSettingChanged.bind(this));
this.contentElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
- this.splitView.sidebarElement.addEventListener("contextmenu", this._sidebarContextMenuEventFired.bind(this), false);
-
- this.treeOutline = new WebInspector.ElementsTreeOutline(true, true, this._populateContextMenu.bind(this), this._setPseudoClassForNodeId.bind(this));
- this.treeOutline.wireToDomAgent();
-
- this.treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
- this.treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.ElementsTreeUpdated, this._updateBreadcrumbIfNeeded, this);
+ this._splitView.sidebarElement().addEventListener("contextmenu", this._sidebarContextMenuEventFired.bind(this), false);
var crumbsContainer = stackElement.createChild("div");
crumbsContainer.id = "elements-crumbs";
@@ -93,7 +82,14 @@ WebInspector.ElementsPanel = function()
this.sidebarPanes = {};
this.sidebarPanes.platformFonts = new WebInspector.PlatformFontsSidebarPane();
this.sidebarPanes.computedStyle = new WebInspector.ComputedStyleSidebarPane();
- this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle, this._setPseudoClassForNodeId.bind(this));
+ this.sidebarPanes.styles = new WebInspector.StylesSidebarPane(this.sidebarPanes.computedStyle, this._setPseudoClassForNode.bind(this));
+
+ this._matchedStylesFilterBoxContainer = document.createElement("div");
+ this._matchedStylesFilterBoxContainer.className = "sidebar-pane-filter-box";
+ this._computedStylesFilterBoxContainer = document.createElement("div");
+ this._computedStylesFilterBoxContainer.className = "sidebar-pane-filter-box";
+ this.sidebarPanes.styles.setFilterBoxContainers(this._matchedStylesFilterBoxContainer, this._computedStylesFilterBoxContainer);
+
this.sidebarPanes.metrics = new WebInspector.MetricsSidebarPane();
this.sidebarPanes.properties = new WebInspector.PropertiesSidebarPane();
this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
@@ -117,31 +113,78 @@ WebInspector.ElementsPanel = function()
this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
this._popoverHelper.setTimeout(0);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdatedEvent, this);
- WebInspector.settings.showShadowDOM.addChangeListener(this._showShadowDOMChanged.bind(this));
-
- if (WebInspector.domAgent.existingDocument())
- this._documentUpdated(WebInspector.domAgent.existingDocument());
-
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.ModelWasEnabled, this._updateSidebars, this);
+ /** @type {!Array.<!WebInspector.ElementsTreeOutline>} */
+ this._treeOutlines = [];
+ /** @type {!Map.<!WebInspector.Target, !WebInspector.ElementsTreeOutline>} */
+ this._targetToTreeOutline = new Map();
+ WebInspector.targetManager.observeTargets(this);
+ WebInspector.settings.showUAShadowDOM.addChangeListener(this._showUAShadowDOMChanged.bind(this));
}
WebInspector.ElementsPanel.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ var treeOutline = new WebInspector.ElementsTreeOutline(target, true, true, this._populateContextMenu.bind(this), this._setPseudoClassForNode.bind(this));
+ treeOutline.wireToDOMModel();
+ treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
+ treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.ElementsTreeUpdated, this._updateBreadcrumbIfNeeded, this);
+ this._treeOutlines.push(treeOutline);
+ this._targetToTreeOutline.put(target, treeOutline);
+
+ target.domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this);
+ target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.ModelWasEnabled, this._updateSidebars, this);
+
+ // Perform attach if necessary.
+ if (this.isShowing())
+ this.wasShown();
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ var treeOutline = this._targetToTreeOutline.get(target);
+ treeOutline.unwireFromDOMModel();
+ this._treeOutlines.remove(treeOutline);
+ treeOutline.element.remove();
+
+ target.domModel.removeEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdatedEvent, this);
+ target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.ModelWasEnabled, this._updateSidebars, this);
+ },
+
+ /**
+ * @return {?WebInspector.ElementsTreeOutline}
+ */
+ _firstTreeOutlineDeprecated: function()
+ {
+ return this._treeOutlines[0] || null;
+ },
+
_updateTreeOutlineVisibleWidth: function()
{
- if (!this.treeOutline)
+ if (!this._treeOutlines.length)
return;
- var width = this.splitView.element.offsetWidth;
- if (this.splitView.isVertical())
- width -= this.splitView.sidebarWidth();
- this.treeOutline.setVisibleWidth(width);
+ var width = this._splitView.element.offsetWidth;
+ if (this._splitView.isVertical())
+ width -= this._splitView.sidebarSize();
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ this._treeOutlines[i].setVisibleWidth(width);
+ this._treeOutlines[i].updateSelection();
+ }
this.updateBreadcrumbSizes();
},
+ /**
+ * @return {!Element}
+ */
defaultFocusedElement: function()
{
- return this.treeOutline.element;
+ return this._treeOutlines.length ? this._treeOutlines[0].element : this.element;
},
/**
@@ -152,106 +195,92 @@ WebInspector.ElementsPanel.prototype = {
return this._searchableView;
},
- statusBarResized: function()
- {
- this.updateBreadcrumbSizes();
- },
-
wasShown: function()
{
- // Attach heavy component lazily
- if (this.treeOutline.element.parentElement !== this.contentElement)
- this.contentElement.appendChild(this.treeOutline.element);
-
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ var treeOutline = this._treeOutlines[i];
+ // Attach heavy component lazily
+ if (treeOutline.element.parentElement !== this.contentElement)
+ this.contentElement.appendChild(treeOutline.element);
+ }
WebInspector.Panel.prototype.wasShown.call(this);
-
this.updateBreadcrumb();
- this.treeOutline.updateSelection();
- this.treeOutline.setVisible(true);
- if (!this.treeOutline.rootDOMNode)
- WebInspector.domAgent.requestDocument();
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ var treeOutline = this._treeOutlines[i];
+ treeOutline.updateSelection();
+ treeOutline.setVisible(true);
+
+ if (!treeOutline.rootDOMNode)
+ if (treeOutline.domModel().existingDocument())
+ this._documentUpdated(treeOutline.domModel(), treeOutline.domModel().existingDocument());
+ else
+ treeOutline.domModel().requestDocument();
+ }
+
},
willHide: function()
{
- WebInspector.domAgent.hideDOMNodeHighlight();
- this.treeOutline.setVisible(false);
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ var treeOutline = this._treeOutlines[i];
+ treeOutline.domModel().hideDOMNodeHighlight();
+ treeOutline.setVisible(false);
+ // Detach heavy component on hide
+ this.contentElement.removeChild(treeOutline.element);
+ }
this._popoverHelper.hidePopover();
-
- // Detach heavy component on hide
- this.contentElement.removeChild(this.treeOutline.element);
-
WebInspector.Panel.prototype.willHide.call(this);
},
onResize: function()
{
- this.treeOutline.updateSelection();
- this.updateBreadcrumbSizes();
+ this._updateTreeOutlineVisibleWidth();
},
- /**
- * @param {string=} id
- * @return {?WebInspector.View}
- */
- createView: function(id)
+ omitDefaultSelection: function()
{
- if (id === "emulation") {
- if (!this._overridesView)
- this._overridesView = new WebInspector.OverridesView();
- return this._overridesView;
- }
- if (id === "rendering") {
- if (!this._renderingView)
- this._renderingView = new WebInspector.RenderingOptionsView();
- return this._renderingView;
- }
- return null;
+ this._omitDefaultSelection = true;
+ },
+
+ stopOmittingDefaultSelection: function()
+ {
+ delete this._omitDefaultSelection;
},
/**
- * @param {!DOMAgent.NodeId} nodeId
+ * @param {!WebInspector.DOMNode} node
* @param {string} pseudoClass
* @param {boolean} enable
*/
- _setPseudoClassForNodeId: function(nodeId, pseudoClass, enable)
+ _setPseudoClassForNode: function(node, pseudoClass, enable)
{
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
+ if (!node || !node.target().cssModel.forcePseudoState(node, pseudoClass, enable))
return;
- var pseudoClasses = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
- if (enable) {
- pseudoClasses = pseudoClasses || [];
- if (pseudoClasses.indexOf(pseudoClass) >= 0)
- return;
- pseudoClasses.push(pseudoClass);
- node.setUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName, pseudoClasses);
- } else {
- if (!pseudoClasses || pseudoClasses.indexOf(pseudoClass) < 0)
- return;
- pseudoClasses.remove(pseudoClass);
- if (!pseudoClasses.length)
- node.removeUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
- }
-
- this.treeOutline.updateOpenCloseTags(node);
- WebInspector.cssModel.forcePseudoState(node.id, node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName));
+ this._targetToTreeOutline.get(node.target()).updateOpenCloseTags(node);
this._metricsPaneEdited();
this._stylesPaneEdited();
WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.ForcedElementState,
- selector: WebInspector.DOMPresentationUtils.appropriateSelectorFor(node, false),
+ selector: WebInspector.DOMPresentationUtils.fullQualifiedSelector(node, false),
enabled: enable,
state: pseudoClass
});
},
- _selectedNodeChanged: function()
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _selectedNodeChanged: function(event)
{
- var selectedNode = this.selectedDOMNode();
+ var selectedNode = /** @type {?WebInspector.DOMNode} */ (event.data);
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ if (!selectedNode || selectedNode.domModel() !== this._treeOutlines[i].domModel())
+ this._treeOutlines[i].selectDOMNode(null);
+ }
+
if (!selectedNode && this._lastValidSelectedNode)
this._selectedPathOnReset = this._lastValidSelectedNode.path();
@@ -263,7 +292,7 @@ WebInspector.ElementsPanel.prototype = {
ConsoleAgent.addInspectedNode(selectedNode.id);
this._lastValidSelectedNode = selectedNode;
}
- WebInspector.notifications.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged);
+ WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.SelectedNodeChanged);
},
_updateSidebars: function()
@@ -283,25 +312,33 @@ WebInspector.ElementsPanel.prototype = {
delete this.currentQuery;
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
_documentUpdatedEvent: function(event)
{
- this._documentUpdated(event.data);
+ this._documentUpdated(/** @type {!WebInspector.DOMModel} */ (event.target), /** @type {?WebInspector.DOMDocument} */ (event.data));
},
- _documentUpdated: function(inspectedRootDocument)
+ /**
+ * @param {!WebInspector.DOMModel} domModel
+ * @param {?WebInspector.DOMDocument} inspectedRootDocument
+ */
+ _documentUpdated: function(domModel, inspectedRootDocument)
{
this._reset();
this.searchCanceled();
- this.treeOutline.rootDOMNode = inspectedRootDocument;
+ var treeOutline = this._targetToTreeOutline.get(domModel.target());
+ treeOutline.rootDOMNode = inspectedRootDocument;
if (!inspectedRootDocument) {
if (this.isShowing())
- WebInspector.domAgent.requestDocument();
+ domModel.requestDocument();
return;
}
- WebInspector.domBreakpointsSidebarPane.restoreBreakpoints();
+ WebInspector.domBreakpointsSidebarPane.restoreBreakpoints(domModel.target());
/**
* @this {WebInspector.ElementsPanel}
@@ -316,8 +353,8 @@ WebInspector.ElementsPanel.prototype = {
return;
this.selectDOMNode(candidateFocusNode);
- if (this.treeOutline.selectedTreeElement)
- this.treeOutline.selectedTreeElement.expand();
+ if (treeOutline.selectedTreeElement)
+ treeOutline.selectedTreeElement.expand();
}
/**
@@ -330,12 +367,15 @@ WebInspector.ElementsPanel.prototype = {
// Focused node has been explicitly set while reaching out for the last selected node.
return;
}
- var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null;
+ var node = nodeId ? domModel.nodeForId(nodeId) : null;
selectNode.call(this, node);
}
+ if (this._omitDefaultSelection)
+ return;
+
if (this._selectedPathOnReset)
- WebInspector.domAgent.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
+ domModel.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
else
selectNode.call(this, null);
delete this._selectedPathOnReset;
@@ -350,14 +390,15 @@ WebInspector.ElementsPanel.prototype = {
delete this._currentSearchResultIndex;
delete this._searchResults;
- WebInspector.domAgent.cancelSearch();
+ WebInspector.domModel.cancelSearch();
},
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump)
+ performSearch: function(query, shouldJump, jumpBackwards)
{
// Call searchCanceled since it will reset everything we need before doing a new search.
this.searchCanceled();
@@ -378,42 +419,22 @@ WebInspector.ElementsPanel.prototype = {
if (!resultCount)
return;
- this._searchResults = new Array(resultCount);
this._currentSearchResultIndex = -1;
+ this._searchResults = new Array(resultCount);
if (shouldJump)
- this.jumpToNextSearchResult();
+ this._jumpToSearchResult(jumpBackwards ? -1 : 0);
}
- WebInspector.domAgent.performSearch(whitespaceTrimmedQuery, resultCountCallback.bind(this));
+ WebInspector.domModel.performSearch(whitespaceTrimmedQuery, resultCountCallback.bind(this));
},
_contextMenuEventFired: function(event)
{
- function toggleWordWrap()
- {
- WebInspector.settings.domWordWrap.set(!WebInspector.settings.domWordWrap.get());
- }
-
var contextMenu = new WebInspector.ContextMenu(event);
- this.treeOutline.populateContextMenu(contextMenu, event);
-
- if (WebInspector.experimentsSettings.cssRegions.isEnabled()) {
- contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "CSS named flows\u2026" : "CSS Named Flows\u2026"), this._showNamedFlowCollections.bind(this));
- }
-
- contextMenu.appendSeparator();
- contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Word wrap" : "Word Wrap"), toggleWordWrap.bind(this), WebInspector.settings.domWordWrap.get());
-
+ for (var i = 0; i < this._treeOutlines.length; ++i)
+ this._treeOutlines[i].populateContextMenu(contextMenu, event);
contextMenu.show();
},
- _showNamedFlowCollections: function()
- {
- if (!WebInspector.cssNamedFlowCollectionsView)
- WebInspector.cssNamedFlowCollectionsView = new WebInspector.CSSNamedFlowCollectionsView();
- WebInspector.cssNamedFlowCollectionsView.showInDrawer();
- },
-
_domWordWrapSettingChanged: function(event)
{
if (event.data)
@@ -425,7 +446,8 @@ WebInspector.ElementsPanel.prototype = {
if (!selectedNode)
return;
- var treeElement = this.treeOutline.findTreeElement(selectedNode);
+ var treeOutline = this._targetToTreeOutline.get(selectedNode.target());
+ var treeElement = treeOutline.findTreeElement(selectedNode);
if (treeElement)
treeElement.updateSelection(); // Recalculate selection highlight dimensions.
},
@@ -449,35 +471,38 @@ WebInspector.ElementsPanel.prototype = {
_getPopoverAnchor: function(element)
{
var anchor = element.enclosingNodeOrSelfWithClass("webkit-html-resource-link");
- if (anchor) {
- if (!anchor.href)
- return null;
+ if (!anchor || !anchor.href)
+ return null;
- var resource = WebInspector.resourceTreeModel.resourceForURL(anchor.href);
+ var treeOutlineElement = anchor.enclosingNodeOrSelfWithClass("elements-tree-outline");
+ if (!treeOutlineElement)
+ return null;
+
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ if (this._treeOutlines[i].element !== treeOutlineElement)
+ continue;
+
+ var resource = this._treeOutlines[i].target().resourceTreeModel.resourceForURL(anchor.href);
if (!resource || resource.type !== WebInspector.resourceTypes.Image)
return null;
-
anchor.removeAttribute("title");
+ return anchor;
}
- return anchor;
+ return null;
},
-
- _loadDimensionsForNode: function(treeElement, callback)
- {
- // We get here for CSS properties, too, so bail out early for non-DOM treeElements.
- if (treeElement.treeOutline !== this.treeOutline) {
- callback();
- return;
- }
-
- var node = /** @type {!WebInspector.DOMNode} */ (treeElement.representedObject);
+ /**
+ * @param {!WebInspector.DOMNode} node
+ * @param {function()} callback
+ */
+ _loadDimensionsForNode: function(node, callback)
+ {
if (!node.nodeName() || node.nodeName().toLowerCase() !== "img") {
callback();
return;
}
- WebInspector.RemoteObject.resolveNode(node, "", resolvedNode);
+ node.resolveToObject("", resolvedNode);
function resolvedNode(object)
{
@@ -490,7 +515,8 @@ WebInspector.ElementsPanel.prototype = {
object.release();
/**
- * @return {{ offsetWidth: number, offsetHeight: number, naturalWidth: number, naturalHeight: number }}
+ * @return {!{offsetWidth: number, offsetHeight: number, naturalWidth: number, naturalHeight: number}}
+ * @suppressReceiverCheck
* @this {!Element}
*/
function dimensions()
@@ -507,10 +533,15 @@ WebInspector.ElementsPanel.prototype = {
_showPopover: function(anchor, popover)
{
var listItem = anchor.enclosingNodeOrSelfWithNodeName("li");
- if (listItem && listItem.treeElement)
- this._loadDimensionsForNode(listItem.treeElement, WebInspector.DOMPresentationUtils.buildImagePreviewContents.bind(WebInspector.DOMPresentationUtils, anchor.href, true, showPopover));
- else
- WebInspector.DOMPresentationUtils.buildImagePreviewContents(anchor.href, true, showPopover);
+ // We get here for CSS properties, too.
+ if (listItem && listItem.treeElement && listItem.treeElement.treeOutline instanceof WebInspector.ElementsTreeOutline) {
+ var node = /** @type {!WebInspector.DOMNode} */ (listItem.treeElement.representedObject);
+ this._loadDimensionsForNode(node, WebInspector.DOMPresentationUtils.buildImagePreviewContents.bind(WebInspector.DOMPresentationUtils, node.target(), anchor.href, true, showPopover));
+ } else {
+ var node = this.selectedDOMNode();
+ if (node)
+ WebInspector.DOMPresentationUtils.buildImagePreviewContents(node.target(), anchor.href, true, showPopover);
+ }
/**
* @param {!Element=} contents
@@ -524,32 +555,33 @@ WebInspector.ElementsPanel.prototype = {
}
},
+ _jumpToSearchResult: function(index)
+ {
+ this._hideSearchHighlights();
+ this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
+ this._highlightCurrentSearchResult();
+ },
+
jumpToNextSearchResult: function()
{
if (!this._searchResults)
return;
-
- this._hideSearchHighlights();
- if (++this._currentSearchResultIndex >= this._searchResults.length)
- this._currentSearchResultIndex = 0;
-
- this._highlightCurrentSearchResult();
+ this._jumpToSearchResult(this._currentSearchResultIndex + 1);
},
jumpToPreviousSearchResult: function()
{
if (!this._searchResults)
return;
-
- this._hideSearchHighlights();
- if (--this._currentSearchResultIndex < 0)
- this._currentSearchResultIndex = (this._searchResults.length - 1);
-
- this._highlightCurrentSearchResult();
+ this._jumpToSearchResult(this._currentSearchResultIndex - 1);
},
_highlightCurrentSearchResult: function()
{
+ var treeOutline = this._firstTreeOutlineDeprecated();
+ if (!treeOutline)
+ return;
+
var index = this._currentSearchResultIndex;
var searchResults = this._searchResults;
var searchResult = searchResults[index];
@@ -571,13 +603,13 @@ WebInspector.ElementsPanel.prototype = {
if (typeof searchResult === "undefined") {
// No data for slot, request it.
- WebInspector.domAgent.searchResult(index, searchCallback.bind(this));
+ WebInspector.domModel.searchResult(index, searchCallback.bind(this));
return;
}
this._searchableView.updateCurrentMatchIndex(index);
- var treeElement = this.treeOutline.findTreeElement(searchResult);
+ var treeElement = treeOutline.findTreeElement(searchResult);
if (treeElement) {
treeElement.highlightSearchResults(this._searchQuery);
treeElement.reveal();
@@ -594,7 +626,8 @@ WebInspector.ElementsPanel.prototype = {
var searchResult = this._searchResults[this._currentSearchResultIndex];
if (!searchResult)
return;
- var treeElement = this.treeOutline.findTreeElement(searchResult);
+ var treeOutline = this._targetToTreeOutline.get(searchResult.target());
+ var treeElement = treeOutline.findTreeElement(searchResult);
if (treeElement)
treeElement.hideSearchHighlights();
},
@@ -604,15 +637,27 @@ WebInspector.ElementsPanel.prototype = {
*/
selectedDOMNode: function()
{
- return this.treeOutline.selectedDOMNode();
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ var treeOutline = this._treeOutlines[i];
+ if (treeOutline.selectedDOMNode())
+ return treeOutline.selectedDOMNode();
+ }
+ return null;
},
/**
+ * @param {!WebInspector.DOMNode} node
* @param {boolean=} focus
*/
selectDOMNode: function(node, focus)
{
- this.treeOutline.selectDOMNode(node, focus);
+ for (var i = 0; i < this._treeOutlines.length; ++i) {
+ var treeOutline = this._treeOutlines[i];
+ if (treeOutline.target() === node.target())
+ treeOutline.selectDOMNode(node, focus);
+ else
+ treeOutline.selectDOMNode(null);
+ }
},
/**
@@ -653,13 +698,9 @@ WebInspector.ElementsPanel.prototype = {
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb");
-
- WebInspector.domAgent.highlightDOMNode(crumbElement ? crumbElement.representedObject.id : 0);
-
- if ("_mouseOutOfCrumbsTimeout" in this) {
- clearTimeout(this._mouseOutOfCrumbsTimeout);
- delete this._mouseOutOfCrumbsTimeout;
- }
+ var node = /** @type {?WebInspector.DOMNode} */ (crumbElement ? crumbElement.representedObject : null);
+ if (node)
+ node.highlight();
},
_mouseMovedOutOfCrumbs: function(event)
@@ -668,9 +709,8 @@ WebInspector.ElementsPanel.prototype = {
if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.crumbsElement))
return;
- WebInspector.domAgent.hideDOMNodeHighlight();
-
- this._mouseOutOfCrumbsTimeout = setTimeout(this.updateBreadcrumbSizes.bind(this), 1000);
+ for (var i = 0; i < this._treeOutlines.length; ++i)
+ this._treeOutlines[i].domModel().hideDOMNodeHighlight();
},
/**
@@ -780,15 +820,9 @@ WebInspector.ElementsPanel.prototype = {
if (current === this.selectedDOMNode())
crumb.classList.add("selected");
- if (!crumbs.childNodes.length)
- crumb.classList.add("end");
-
crumbs.insertBefore(crumb, crumbs.firstChild);
}
- if (crumbs.hasChildNodes())
- crumbs.lastChild.classList.add("start");
-
this.updateBreadcrumbSizes();
},
@@ -800,24 +834,17 @@ WebInspector.ElementsPanel.prototype = {
if (!this.isShowing())
return;
- if (document.body.offsetWidth <= 0) {
- // The stylesheet hasn't loaded yet or the window is closed,
- // so we can't calculate what is need. Return early.
- return;
- }
-
var crumbs = this.crumbsElement;
- if (!crumbs.childNodes.length || crumbs.offsetWidth <= 0)
- return; // No crumbs, do nothing.
+ if (!crumbs.firstChild)
+ return;
- // A Zero index is the right most child crumb in the breadcrumb.
var selectedIndex = 0;
var focusedIndex = 0;
var selectedCrumb;
- var i = 0;
- var crumb = crumbs.firstChild;
- while (crumb) {
+ // Reset crumb styles.
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
// Find the selected crumb and index.
if (!selectedCrumb && crumb.classList.contains("selected")) {
selectedCrumb = crumb;
@@ -828,31 +855,53 @@ WebInspector.ElementsPanel.prototype = {
if (crumb === focusedCrumb)
focusedIndex = i;
- // Remove any styles that affect size before
- // deciding to shorten any crumbs.
- if (crumb !== crumbs.lastChild)
- crumb.classList.remove("start");
- if (crumb !== crumbs.firstChild)
- crumb.classList.remove("end");
+ crumb.classList.remove("compact", "collapsed", "hidden");
+ }
- crumb.classList.remove("compact");
- crumb.classList.remove("collapsed");
- crumb.classList.remove("hidden");
+ // Layout 1: Measure total and normal crumb sizes
+ var contentElementWidth = this.contentElement.offsetWidth;
+ var normalSizes = [];
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
+ normalSizes[i] = crumb.offsetWidth;
+ }
- crumb = crumb.nextSibling;
- ++i;
+ // Layout 2: Measure collapsed crumb sizes
+ var compactSizes = [];
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
+ crumb.classList.add("compact");
+ }
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
+ compactSizes[i] = crumb.offsetWidth;
}
- // Restore the start and end crumb classes in case they got removed in coalesceCollapsedCrumbs().
- // The order of the crumbs in the document is opposite of the visual order.
- crumbs.firstChild.classList.add("end");
- crumbs.lastChild.classList.add("start");
+ // Layout 3: Measure collapsed crumb size
+ crumbs.firstChild.classList.add("collapsed");
+ var collapsedSize = crumbs.firstChild.offsetWidth;
+
+ // Clean up.
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
+ crumb.classList.remove("compact", "collapsed");
+ }
- var contentElement = this.contentElement;
function crumbsAreSmallerThanContainer()
{
+ var totalSize = 0;
+ for (var i = 0; i < crumbs.childNodes.length; ++i) {
+ var crumb = crumbs.childNodes[i];
+ if (crumb.classList.contains("hidden"))
+ continue;
+ if (crumb.classList.contains("collapsed")) {
+ totalSize += collapsedSize;
+ continue;
+ }
+ totalSize += crumb.classList.contains("compact") ? compactSizes[i] : normalSizes[i];
+ }
const rightPadding = 10;
- return crumbs.offsetWidth + rightPadding < contentElement.offsetWidth;
+ return totalSize + rightPadding < contentElementWidth;
}
if (crumbsAreSmallerThanContainer())
@@ -863,26 +912,13 @@ WebInspector.ElementsPanel.prototype = {
var ChildSide = 1;
/**
- * @param {boolean=} significantCrumb
+ * @param {function(!Element)} shrinkingFunction
+ * @param {number} direction
*/
- function makeCrumbsSmaller(shrinkingFunction, direction, significantCrumb)
+ function makeCrumbsSmaller(shrinkingFunction, direction)
{
- if (!significantCrumb)
- significantCrumb = (focusedCrumb || selectedCrumb);
-
- if (significantCrumb === selectedCrumb)
- var significantIndex = selectedIndex;
- else if (significantCrumb === focusedCrumb)
- var significantIndex = focusedIndex;
- else {
- var significantIndex = 0;
- for (var i = 0; i < crumbs.childNodes.length; ++i) {
- if (crumbs.childNodes[i] === significantCrumb) {
- significantIndex = i;
- break;
- }
- }
- }
+ var significantCrumb = focusedCrumb || selectedCrumb;
+ var significantIndex = significantCrumb === selectedCrumb ? selectedIndex : focusedIndex;
function shrinkCrumbAtIndex(index)
{
@@ -976,6 +1012,9 @@ WebInspector.ElementsPanel.prototype = {
}
}
+ /**
+ * @param {!Element} crumb
+ */
function compact(crumb)
{
if (crumb.classList.contains("hidden"))
@@ -983,6 +1022,10 @@ WebInspector.ElementsPanel.prototype = {
crumb.classList.add("compact");
}
+ /**
+ * @param {!Element} crumb
+ * @param {boolean=} dontCoalesce
+ */
function collapse(crumb, dontCoalesce)
{
if (crumb.classList.contains("hidden"))
@@ -1007,11 +1050,11 @@ WebInspector.ElementsPanel.prototype = {
}
// Compact ancestor crumbs, or from both sides if focused.
- if (makeCrumbsSmaller(compact, (focusedCrumb ? BothSides : AncestorSide)))
+ if (makeCrumbsSmaller(compact, focusedCrumb ? BothSides : AncestorSide))
return;
// Collapse ancestor crumbs, or from both sides if focused.
- if (makeCrumbsSmaller(collapse, (focusedCrumb ? BothSides : AncestorSide)))
+ if (makeCrumbsSmaller(collapse, focusedCrumb ? BothSides : AncestorSide))
return;
if (!selectedCrumb)
@@ -1027,11 +1070,21 @@ WebInspector.ElementsPanel.prototype = {
},
/**
+ * @return {boolean}
+ */
+ _cssModelEnabledForSelectedNode: function()
+ {
+ if (!this.selectedDOMNode())
+ return true;
+ return this.selectedDOMNode().target().cssModel.isEnabled();
+ },
+
+ /**
* @param {boolean=} forceUpdate
*/
updateStyles: function(forceUpdate)
{
- if (!WebInspector.cssModel.isEnabled())
+ if (!this._cssModelEnabledForSelectedNode())
return;
var stylesSidebarPane = this.sidebarPanes.styles;
var computedStylePane = this.sidebarPanes.computedStyle;
@@ -1044,7 +1097,7 @@ WebInspector.ElementsPanel.prototype = {
updateMetrics: function()
{
- if (!WebInspector.cssModel.isEnabled())
+ if (!this._cssModelEnabledForSelectedNode())
return;
var metricsSidebarPane = this.sidebarPanes.metrics;
if (!metricsSidebarPane.isShowing() || !metricsSidebarPane.needsUpdate)
@@ -1056,7 +1109,7 @@ WebInspector.ElementsPanel.prototype = {
updatePlatformFonts: function()
{
- if (!WebInspector.cssModel.isEnabled())
+ if (!this._cssModelEnabledForSelectedNode())
return;
var platformFontsSidebar = this.sidebarPanes.platformFonts;
if (!platformFontsSidebar.isShowing() || !platformFontsSidebar.needsUpdate)
@@ -1097,7 +1150,7 @@ WebInspector.ElementsPanel.prototype = {
function handleUndoRedo()
{
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && event.keyIdentifier === "U+005A") { // Z key
- WebInspector.domAgent.undo(this._updateSidebars.bind(this));
+ WebInspector.domModel.undo(this._updateSidebars.bind(this));
event.handled = true;
return;
}
@@ -1105,18 +1158,22 @@ WebInspector.ElementsPanel.prototype = {
var isRedoKey = WebInspector.isMac() ? event.metaKey && event.shiftKey && event.keyIdentifier === "U+005A" : // Z key
event.ctrlKey && event.keyIdentifier === "U+0059"; // Y key
if (isRedoKey) {
- DOMAgent.redo(this._updateSidebars.bind(this));
+ WebInspector.domModel.redo(this._updateSidebars.bind(this));
event.handled = true;
}
}
- if (!this.treeOutline.editing()) {
+ var treeOutline = this._firstTreeOutlineDeprecated();
+ if (!treeOutline)
+ return;
+
+ if (!treeOutline.editing()) {
handleUndoRedo.call(this);
if (event.handled)
return;
}
- this.treeOutline.handleShortcut(event);
+ treeOutline.handleShortcut(event);
},
handleCopyEvent: function(event)
@@ -1133,63 +1190,47 @@ WebInspector.ElementsPanel.prototype = {
this.selectedDOMNode().copyNode();
},
- sidebarResized: function(event)
+ /**
+ * @param {!WebInspector.DOMNode} node
+ * @return {!WebInspector.DOMNode}
+ */
+ _leaveUserAgentShadowDOM: function(node)
{
- this.treeOutline.updateSelection();
+ var userAgentShadowRoot = node.ancestorUserAgentShadowRoot();
+ return userAgentShadowRoot ? /** @type {!WebInspector.DOMNode} */ (userAgentShadowRoot.parentNode) : node;
},
- revealAndSelectNode: function(nodeId)
+ /**
+ * @param {!WebInspector.DOMNode} node
+ */
+ revealAndSelectNode: function(node)
{
WebInspector.inspectorView.setCurrentPanel(this);
-
- var node = WebInspector.domAgent.nodeForId(nodeId);
- if (!node)
- return;
-
- while (!WebInspector.ElementsTreeOutline.showShadowDOM() && node && node.isInShadowTree())
- node = node.parentNode;
-
- WebInspector.domAgent.highlightDOMNodeForTwoSeconds(nodeId);
+ node = WebInspector.settings.showUAShadowDOM.get() ? node : this._leaveUserAgentShadowDOM(node);
+ node.highlightForTwoSeconds();
this.selectDOMNode(node, true);
},
- /**
+ /**
+ * @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
+ * @param {!Object} object
*/
- appendApplicableItems: function(event, contextMenu, target)
+ appendApplicableItems: function(event, contextMenu, object)
{
- /**
- * @param {?DOMAgent.NodeId} nodeId
- */
- function selectNode(nodeId)
- {
- if (nodeId)
- WebInspector.domAgent.inspectElement(nodeId);
- }
-
- /**
- * @param {!WebInspector.RemoteObject} remoteObject
- */
- function revealElement(remoteObject)
- {
- remoteObject.pushNodeToFrontend(selectNode);
- }
-
var commandCallback;
- if (target instanceof WebInspector.RemoteObject) {
- var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
- if (remoteObject.subtype === "node")
- commandCallback = revealElement.bind(this, remoteObject);
- } else if (target instanceof WebInspector.DOMNode) {
- var domNode = /** @type {!WebInspector.DOMNode} */ (target);
- if (domNode.id)
- commandCallback = WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, domNode.id);
+ if (object instanceof WebInspector.RemoteObject) {
+ var remoteObject = /** @type {!WebInspector.RemoteObject} */ (object);
+ if (remoteObject.isNode())
+ commandCallback = remoteObject.reveal.bind(remoteObject);
+ } else if (object instanceof WebInspector.DOMNode) {
+ var domNode = /** @type {!WebInspector.DOMNode} */ (object);
+ commandCallback = domNode.reveal.bind(domNode);
}
if (!commandCallback)
return;
// Skip adding "Reveal..." menu item for our own tree outline.
- if (this.treeOutline.element.isAncestor(event.target))
+ if (this.element.isAncestor(/** @type {!Node} */ (event.target)))
return;
contextMenu.appendItem(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Elements panel" : "Reveal in Elements Panel", commandCallback);
},
@@ -1202,14 +1243,14 @@ WebInspector.ElementsPanel.prototype = {
_dockSideChanged: function()
{
- var dockSide = WebInspector.dockController.dockSide();
- var vertically = dockSide === WebInspector.DockController.State.DockedToRight && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
+ var vertically = WebInspector.dockController.isVertical() && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
this._splitVertically(vertically);
},
- _showShadowDOMChanged: function()
+ _showUAShadowDOMChanged: function()
{
- this.treeOutline.update();
+ for (var i = 0; i < this._treeOutlines.length; ++i)
+ this._treeOutlines[i].update();
},
/**
@@ -1217,34 +1258,39 @@ WebInspector.ElementsPanel.prototype = {
*/
_splitVertically: function(vertically)
{
- if (this.sidebarPaneView && vertically === !this.splitView.isVertical())
+ if (this.sidebarPaneView && vertically === !this._splitView.isVertical())
return;
- if (this.sidebarPaneView)
+ if (this.sidebarPaneView) {
this.sidebarPaneView.detach();
+ this._splitView.uninstallResizer(this.sidebarPaneView.headerElement());
+ }
- this.splitView.setVertical(!vertically);
+ this._splitView.setVertical(!vertically);
var computedPane = new WebInspector.SidebarPane(WebInspector.UIString("Computed"));
computedPane.element.classList.add("composite");
computedPane.element.classList.add("fill");
var expandComputed = computedPane.expand.bind(computedPane);
- computedPane.bodyElement.appendChild(this.sidebarPanes.computedStyle.titleElement);
computedPane.bodyElement.classList.add("metrics-and-computed");
- this.sidebarPanes.computedStyle.show(computedPane.bodyElement);
this.sidebarPanes.computedStyle.setExpandCallback(expandComputed);
- this.sidebarPanes.platformFonts.show(computedPane.bodyElement);
+ var matchedStylePanesWrapper = document.createElement("div");
+ matchedStylePanesWrapper.className = "style-panes-wrapper";
+ var computedStylePanesWrapper = document.createElement("div");
+ computedStylePanesWrapper.className = "style-panes-wrapper";
/**
- * @param {!WebInspector.SidebarPane} pane
- * @param {!Element=} beforeElement
+ * @param {boolean} inComputedStyle
* @this {WebInspector.ElementsPanel}
*/
- function showMetrics(pane, beforeElement)
+ function showMetrics(inComputedStyle)
{
- this.sidebarPanes.metrics.show(pane.bodyElement, beforeElement);
+ if (inComputedStyle)
+ this.sidebarPanes.metrics.show(computedStylePanesWrapper, this.sidebarPanes.computedStyle.element);
+ else
+ this.sidebarPanes.metrics.show(matchedStylePanesWrapper);
}
/**
@@ -1255,15 +1301,15 @@ WebInspector.ElementsPanel.prototype = {
{
var tabId = /** @type {string} */ (event.data.tabId);
if (tabId === computedPane.title())
- showMetrics.call(this, computedPane, this.sidebarPanes.computedStyle.element);
- if (tabId === stylesPane.title())
- showMetrics.call(this, stylesPane);
+ showMetrics.call(this, true);
+ else if (tabId === stylesPane.title())
+ showMetrics.call(this, false);
}
this.sidebarPaneView = new WebInspector.SidebarTabbedPane();
if (vertically) {
- this.sidebarPanes.metrics.show(computedPane.bodyElement, this.sidebarPanes.computedStyle.element);
+ this._splitView.installResizer(this.sidebarPaneView.headerElement());
this.sidebarPanes.metrics.setExpandCallback(expandComputed);
var compositePane = new WebInspector.SidebarPane(this.sidebarPanes.styles.title());
@@ -1271,16 +1317,20 @@ WebInspector.ElementsPanel.prototype = {
compositePane.element.classList.add("fill");
var expandComposite = compositePane.expand.bind(compositePane);
- var splitView = new WebInspector.SplitView(true, "StylesPaneSplitRatio", 0.5);
+ var splitView = new WebInspector.SplitView(true, true, "stylesPaneSplitViewState", 0.5);
splitView.show(compositePane.bodyElement);
- this.sidebarPanes.styles.show(splitView.firstElement());
- splitView.firstElement().appendChild(this.sidebarPanes.styles.titleElement);
+ splitView.mainElement().appendChild(matchedStylePanesWrapper);
+ splitView.sidebarElement().appendChild(computedStylePanesWrapper);
+
this.sidebarPanes.styles.setExpandCallback(expandComposite);
- computedPane.show(splitView.secondElement());
+ computedPane.show(computedStylePanesWrapper);
computedPane.setExpandCallback(expandComposite);
+ splitView.mainElement().appendChild(this._matchedStylesFilterBoxContainer);
+ splitView.sidebarElement().appendChild(this._computedStylesFilterBoxContainer);
+
this.sidebarPaneView.addPane(compositePane);
} else {
var stylesPane = new WebInspector.SidebarPane(this.sidebarPanes.styles.title());
@@ -1288,18 +1338,28 @@ WebInspector.ElementsPanel.prototype = {
stylesPane.element.classList.add("fill");
var expandStyles = stylesPane.expand.bind(stylesPane);
stylesPane.bodyElement.classList.add("metrics-and-styles");
- this.sidebarPanes.styles.show(stylesPane.bodyElement);
+
+ stylesPane.bodyElement.appendChild(matchedStylePanesWrapper);
+ computedPane.bodyElement.appendChild(computedStylePanesWrapper);
+
this.sidebarPanes.styles.setExpandCallback(expandStyles);
this.sidebarPanes.metrics.setExpandCallback(expandStyles);
- stylesPane.bodyElement.appendChild(this.sidebarPanes.styles.titleElement);
this.sidebarPaneView.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, tabSelected, this);
- showMetrics.call(this, stylesPane);
+ stylesPane.bodyElement.appendChild(this._matchedStylesFilterBoxContainer);
+ computedPane.bodyElement.appendChild(this._computedStylesFilterBoxContainer);
+
this.sidebarPaneView.addPane(stylesPane);
this.sidebarPaneView.addPane(computedPane);
}
+ this.sidebarPanes.styles.show(matchedStylePanesWrapper);
+ this.sidebarPanes.computedStyle.show(computedStylePanesWrapper);
+ matchedStylePanesWrapper.appendChild(this.sidebarPanes.styles.titleElement);
+ showMetrics.call(this, vertically);
+ this.sidebarPanes.platformFonts.show(computedStylePanesWrapper);
+
this.sidebarPaneView.addPane(this.sidebarPanes.eventListeners);
this.sidebarPaneView.addPane(this.sidebarPanes.domBreakpoints);
this.sidebarPaneView.addPane(this.sidebarPanes.properties);
@@ -1308,7 +1368,7 @@ WebInspector.ElementsPanel.prototype = {
for (var i = 0; i < this._extensionSidebarPanes.length; ++i)
this._extensionSidebarPanesContainer.addPane(this._extensionSidebarPanes[i]);
- this.sidebarPaneView.show(this.splitView.sidebarElement);
+ this.sidebarPaneView.show(this._splitView.sidebarElement());
this.sidebarPanes.styles.expand();
},
@@ -1324,3 +1384,97 @@ WebInspector.ElementsPanel.prototype = {
__proto__: WebInspector.Panel.prototype
}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ */
+WebInspector.ElementsPanel.ContextMenuProvider = function()
+{
+}
+
+WebInspector.ElementsPanel.ContextMenuProvider.prototype = {
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ /** @type {!WebInspector.ElementsPanel} */ (WebInspector.inspectorView.panel("elements")).appendApplicableItems(event, contextMenu, target);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.ElementsPanel.DOMNodeRevealer = function()
+{
+}
+
+WebInspector.ElementsPanel.DOMNodeRevealer.prototype = {
+ /**
+ * @param {!Object} node
+ */
+ reveal: function(node)
+ {
+ if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.enabled()) {
+ InspectorFrontendHost.bringToFront();
+ WebInspector.inspectElementModeController.disable();
+ }
+
+ /** @type {!WebInspector.ElementsPanel} */ (WebInspector.inspectorView.panel("elements")).revealAndSelectNode(/** @type {!WebInspector.DOMNode} */ (node));
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.ElementsPanel.NodeRemoteObjectRevealer = function()
+{
+}
+
+WebInspector.ElementsPanel.NodeRemoteObjectRevealer.prototype = {
+ /**
+ * @param {!Object} remoteObject
+ */
+ reveal: function(remoteObject)
+ {
+ revealElement(/** @type {!WebInspector.RemoteObject} */ (remoteObject));
+
+ /**
+ * @param {?WebInspector.RemoteObject} remoteObject
+ */
+ function revealElement(remoteObject)
+ {
+ if (remoteObject)
+ remoteObject.pushNodeToFrontend(selectNode.bind(null, remoteObject));
+ }
+
+ /**
+ * @param {?WebInspector.RemoteObject} remoteObject
+ * @param {?WebInspector.DOMNode} node
+ */
+ function selectNode(remoteObject, node)
+ {
+ if (node) {
+ node.reveal();
+ return;
+ }
+ if (!remoteObject || remoteObject.description !== "#text" || !remoteObject.isNode())
+ return;
+ remoteObject.callFunction(parentElement, undefined, revealElement);
+ }
+
+ /**
+ * @suppressReceiverCheck
+ * @this {Element}
+ */
+ function parentElement()
+ {
+ return this.parentElement;
+ }
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsTreeOutline.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
index aab8d633c17..38e66d51700 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ElementsTreeOutline.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeOutline.js
@@ -31,13 +31,16 @@
/**
* @constructor
* @extends {TreeOutline}
+ * @param {!WebInspector.Target} target
* @param {boolean=} omitRootDOMNode
* @param {boolean=} selectEnabled
* @param {function(!WebInspector.ContextMenu, !WebInspector.DOMNode)=} contextMenuCallback
- * @param {function(!DOMAgent.NodeId, string, boolean)=} setPseudoClassCallback
+ * @param {function(!WebInspector.DOMNode, string, boolean)=} setPseudoClassCallback
*/
-WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, contextMenuCallback, setPseudoClassCallback)
+WebInspector.ElementsTreeOutline = function(target, omitRootDOMNode, selectEnabled, contextMenuCallback, setPseudoClassCallback)
{
+ this._target = target;
+ this._domModel = target.domModel;
this.element = document.createElement("ol");
this.element.className = "elements-tree-outline";
this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
@@ -100,6 +103,22 @@ WebInspector.ElementsTreeOutline.MappedCharToEntity = {
WebInspector.ElementsTreeOutline.prototype = {
/**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ },
+
+ /**
+ * @return {!WebInspector.DOMModel}
+ */
+ domModel: function()
+ {
+ return this._domModel;
+ },
+
+ /**
* @param {number} width
*/
setVisibleWidth: function(width)
@@ -115,11 +134,16 @@ WebInspector.ElementsTreeOutline.prototype = {
this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator());
},
- wireToDomAgent: function()
+ wireToDOMModel: function()
{
- this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this);
+ this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this._target.domModel, this);
},
+ unwireFromDOMModel: function()
+ {
+ if (this._elementsTreeUpdater)
+ this._elementsTreeUpdater.dispose();
+ },
/**
* @param {boolean} visible
*/
@@ -280,20 +304,15 @@ WebInspector.ElementsTreeOutline.prototype = {
*/
findTreeElement: function(node)
{
- function isAncestorNode(ancestor, node)
- {
- return ancestor.isAncestor(node);
- }
-
function parentNode(node)
{
return node.parentNode;
}
- var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
+ var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, parentNode);
if (!treeElement && node.nodeType() === Node.TEXT_NODE) {
// The text node might have been inlined if it was short, so try to find the parent element.
- treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
+ treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, parentNode);
}
return treeElement;
@@ -397,7 +416,10 @@ WebInspector.ElementsTreeOutline.prototype = {
this._previousHoveredElement = element;
}
- WebInspector.domAgent.highlightDOMNode(element && element._node ? element._node.id : 0);
+ if (element && element._node)
+ this._domModel.highlightDOMNodeWithConfig(element._node.id, { mode: "all", showInfo: !WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) });
+ else
+ this._domModel.hideDOMNodeHighlight();
},
_onmouseout: function(event)
@@ -411,7 +433,7 @@ WebInspector.ElementsTreeOutline.prototype = {
delete this._previousHoveredElement;
}
- WebInspector.domAgent.hideDOMNodeHighlight();
+ this._domModel.hideDOMNodeHighlight();
},
_ondragstart: function(event)
@@ -435,7 +457,7 @@ WebInspector.ElementsTreeOutline.prototype = {
event.dataTransfer.effectAllowed = "copyMove";
this._treeElementBeingDragged = treeElement;
- WebInspector.domAgent.hideDOMNodeHighlight();
+ this._domModel.hideDOMNodeHighlight();
return true;
},
@@ -594,6 +616,8 @@ WebInspector.ElementsTreeOutline.prototype = {
treeElement._populateNodeContextMenu(contextMenu, textNode);
} else if (isPseudoElement) {
treeElement._populateScrollIntoView(contextMenu);
+ } else if (treeElement._node.isShadowRoot()) {
+ this.treeOutline._populateContextMenu(contextMenu, treeElement._node);
}
},
@@ -616,7 +640,7 @@ WebInspector.ElementsTreeOutline.prototype = {
if (!node || !treeElement)
return;
- if (event.keyIdentifier === "F2") {
+ if (event.keyIdentifier === "F2" && treeElement.hasEditableNode()) {
this._toggleEditAsHTML(node);
event.handled = true;
return;
@@ -664,7 +688,7 @@ WebInspector.ElementsTreeOutline.prototype = {
// Select it and expand if necessary. We force tree update so that it processes dom events and is up to date.
this._updateModifiedNodes();
- var newNode = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null;
+ var newNode = nodeId ? this._domModel.nodeForId(nodeId) : null;
if (!newNode)
return;
@@ -701,6 +725,7 @@ WebInspector.ElementsTreeOutline.prototype = {
/**
* @param {?string} pseudoType
+ * @suppressReceiverCheck
* @this {!Element}
*/
function toggleClassAndInjectStyleRule(pseudoType)
@@ -728,18 +753,12 @@ WebInspector.ElementsTreeOutline.prototype = {
object.release();
}
- WebInspector.RemoteObject.resolveNode(effectiveNode, "", resolvedNode);
+ effectiveNode.resolveToObject("", resolvedNode);
},
__proto__: TreeOutline.prototype
}
-WebInspector.ElementsTreeOutline.showShadowDOM = function()
-{
- return WebInspector.settings.showShadowDOM.get() || WebInspector.ElementsTreeOutline["showShadowDOMForTest"];
-}
-
-
/**
* @interface
*/
@@ -774,38 +793,43 @@ WebInspector.ElementsTreeOutline.PseudoStateDecorator = function()
WebInspector.ElementsTreeOutline.ElementDecorator.call(this);
}
-WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState";
-
WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = {
+ /**
+ * @param {!WebInspector.DOMNode} node
+ * @return {?string}
+ */
decorate: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
- var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
+ var propertyValue = node.getUserProperty(WebInspector.CSSStyleModel.PseudoStatePropertyName);
if (!propertyValue)
return null;
return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :"));
},
+ /**
+ * @param {!WebInspector.DOMNode} node
+ * @return {?string}
+ */
decorateAncestor: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
- var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
+ var descendantCount = node.descendantUserPropertyCount(WebInspector.CSSStyleModel.PseudoStatePropertyName);
if (!descendantCount)
return null;
if (descendantCount === 1)
return WebInspector.UIString("%d descendant with forced state", descendantCount);
return WebInspector.UIString("%d descendants with forced state", descendantCount);
- },
-
- __proto__: WebInspector.ElementsTreeOutline.ElementDecorator.prototype
+ }
}
/**
* @constructor
* @extends {TreeElement}
+ * @param {!WebInspector.DOMNode} node
* @param {boolean=} elementCloseTag
*/
WebInspector.ElementsTreeElement = function(node, elementCloseTag)
@@ -830,7 +854,7 @@ WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
// FIXME: Revise once HTML5 Final is published.
WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
"area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
- "hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
+ "hr", "img", "input", "keygen", "link", "meta", "param", "source"
].keySet();
// These tags we do not allow editing their tag name.
@@ -1004,7 +1028,7 @@ WebInspector.ElementsTreeElement.prototype = {
_preventFollowingLinksOnDoubleClick: function()
{
- var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
+ var links = this.listItemElement.querySelectorAll("li .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
if (!links)
return;
@@ -1031,7 +1055,10 @@ WebInspector.ElementsTreeElement.prototype = {
},
/**
+ * @param {!WebInspector.DOMNode} child
+ * @param {number} index
* @param {boolean=} closingTag
+ * @return {!WebInspector.ElementsTreeElement}
*/
insertChildElement: function(child, index, closingTag)
{
@@ -1070,48 +1097,48 @@ WebInspector.ElementsTreeElement.prototype = {
this.removeChildren();
}
- var treeElement = this;
- var treeChildIndex = 0;
- var elementToSelect;
-
/**
* @this {WebInspector.ElementsTreeElement}
+ * @return {?WebInspector.ElementsTreeElement}
*/
function updateChildrenOfNode()
{
- var treeOutline = treeElement.treeOutline;
+ var treeOutline = this.treeOutline;
var visibleChildren = this._visibleChildren();
+ var treeChildIndex = 0;
+ var elementToSelect = null;
for (var i = 0; i < visibleChildren.length; ++i) {
var child = visibleChildren[i];
- var currentTreeElement = treeElement.children[treeChildIndex];
+ var currentTreeElement = this.children[treeChildIndex];
if (!currentTreeElement || currentTreeElement._node !== child) {
// Find any existing element that is later in the children list.
var existingTreeElement = null;
- for (var j = (treeChildIndex + 1), size = treeElement.expandedChildCount; j < size; ++j) {
- if (treeElement.children[j]._node === child) {
- existingTreeElement = treeElement.children[j];
+ for (var j = (treeChildIndex + 1), size = this.expandedChildCount; j < size; ++j) {
+ if (this.children[j]._node === child) {
+ existingTreeElement = this.children[j];
break;
}
}
- if (existingTreeElement && existingTreeElement.parent === treeElement) {
+ if (existingTreeElement && existingTreeElement.parent === this) {
// If an existing element was found and it has the same parent, just move it.
- treeElement.moveChild(existingTreeElement, treeChildIndex);
+ this.moveChild(existingTreeElement, treeChildIndex);
} else {
// No existing element found, insert a new element.
- if (treeChildIndex < treeElement.expandedChildrenLimit) {
- var newElement = treeElement.insertChildElement(child, treeChildIndex);
+ if (treeChildIndex < this.expandedChildrenLimit) {
+ var newElement = this.insertChildElement(child, treeChildIndex);
if (child === selectedNode)
elementToSelect = newElement;
- if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
- treeElement.expandedChildrenLimit++;
+ if (this.expandedChildCount > this.expandedChildrenLimit)
+ this.expandedChildrenLimit++;
}
}
}
++treeChildIndex;
}
+ return elementToSelect;
}
// Remove any tree elements that no longer have this node (or this node's contentDocument) as their parent.
@@ -1132,7 +1159,8 @@ WebInspector.ElementsTreeElement.prototype = {
this.removeChildAtIndex(i);
}
- updateChildrenOfNode.call(this);
+ var elementToSelect = updateChildrenOfNode.call(this);
+ this.updateTitle();
this._adjustCollapsedRange();
var lastChild = this.children[this.children.length - 1];
@@ -1198,7 +1226,7 @@ WebInspector.ElementsTreeElement.prototype = {
{
TreeElement.prototype.expandRecursively.call(this, Number.MAX_VALUE);
}
-
+
this._node.getSubtree(-1, callback.bind(this));
},
@@ -1239,13 +1267,15 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @override
+ * @param {boolean=} selectedByUser
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.selectDOMNode(this._node, selectedByUser);
if (selectedByUser)
- WebInspector.domAgent.highlightDOMNode(this._node.id);
+ this._node.highlight();
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
return true;
@@ -1253,6 +1283,7 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
ondelete: function()
{
@@ -1263,6 +1294,7 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onenter: function()
{
@@ -1285,7 +1317,7 @@ WebInspector.ElementsTreeElement.prototype = {
return;
if (this.treeOutline._showInElementsPanelEnabled) {
- WebInspector.showPanel("elements");
+ WebInspector.inspectorView.showPanel("elements");
this.treeOutline.selectDOMNode(this._node, true);
}
@@ -1296,6 +1328,7 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
ondblclick: function(event)
{
@@ -1310,6 +1343,14 @@ WebInspector.ElementsTreeElement.prototype = {
return false;
},
+ /**
+ * @return {boolean}
+ */
+ hasEditableNode: function()
+ {
+ return !this.representedObject.isShadowRoot() && !this.representedObject.ancestorUserAgentShadowRoot();
+ },
+
_insertInLastAttributePosition: function(tag, node)
{
if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
@@ -1360,7 +1401,7 @@ WebInspector.ElementsTreeElement.prototype = {
{
// Add attribute-related actions.
var treeElement = this._elementCloseTag ? this.treeOutline.findTreeElement(this._node) : this;
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(treeElement));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), treeElement._addNewAttribute.bind(treeElement));
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
@@ -1383,7 +1424,7 @@ WebInspector.ElementsTreeElement.prototype = {
_populateScrollIntoView: function(contextMenu)
{
contextMenu.appendSeparator();
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll into View"), this._scrollIntoView.bind(this));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll into View"), this._scrollIntoView.bind(this));
},
_populateForcedPseudoStateItems: function(subMenu)
@@ -1393,13 +1434,14 @@ WebInspector.ElementsTreeElement.prototype = {
var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || [];
for (var i = 0; i < pseudoClasses.length; ++i) {
var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
- subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
+ subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
}
},
_populateTextContextMenu: function(contextMenu, textNode)
{
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
+ if (!this._editing)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
this._populateNodeContextMenu(contextMenu);
},
@@ -1407,15 +1449,20 @@ WebInspector.ElementsTreeElement.prototype = {
{
// Add free-form node-related actions.
var openTagElement = this.treeOutline.getCachedTreeElement(this.representedObject) || this;
- contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTagElement._editAsHTML.bind(openTagElement));
- contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
+ var isEditable = this.hasEditableNode();
+ if (isEditable && !this._editing)
+ contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), openTagElement._editAsHTML.bind(openTagElement));
+ var isShadowRoot = this.representedObject.isShadowRoot();
+ if (!isShadowRoot)
+ contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
// Place it here so that all "Copy"-ing items stick together.
if (this.representedObject.nodeType() === Node.ELEMENT_NODE)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy CSS path" : "Copy CSS Path"), this._copyCSSPath.bind(this));
- contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Inspect DOM properties" : "Inspect DOM Properties"), this._inspectDOMProperties.bind(this));
+ if (!isShadowRoot)
+ contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
+ if (isEditable)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
},
_startEditing: function()
@@ -1447,7 +1494,7 @@ WebInspector.ElementsTreeElement.prototype = {
// a parent node. Use a temporary span container for the HTML.
var container = document.createElement("span");
this._buildAttributeDOM(container, " ", "");
- var attr = container.firstChild;
+ var attr = container.firstElementChild;
attr.style.marginLeft = "2px"; // overrides the .editing margin rule
attr.style.marginRight = "2px"; // overrides the .editing margin rule
@@ -1510,8 +1557,8 @@ WebInspector.ElementsTreeElement.prototype = {
// Remove zero-width spaces that were added by nodeTitleInfo.
removeZeroWidthSpaceRecursive(attribute);
- var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
-
+ var config = new WebInspector.InplaceEditor.Config(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
+
function handleKeyDownEvents(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
@@ -1529,9 +1576,9 @@ WebInspector.ElementsTreeElement.prototype = {
}
}
- config.customFinishHandler = handleKeyDownEvents.bind(this);
+ config.customFinishHandler = handleKeyDownEvents;
- this._editing = WebInspector.startEditing(attribute, config);
+ this._editing = WebInspector.InplaceEditor.startEditing(attribute, config);
window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
@@ -1555,8 +1602,8 @@ WebInspector.ElementsTreeElement.prototype = {
var container = textNodeElement.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (container)
container.textContent = textNode.nodeValue(); // Strip the CSS or JS highlighting if present.
- var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
- this._editing = WebInspector.startEditing(textNodeElement, config);
+ var config = new WebInspector.InplaceEditor.Config(this._textNodeEditingCommitted.bind(this, textNode), this._editingCancelled.bind(this));
+ this._editing = WebInspector.InplaceEditor.startEditing(textNodeElement, config);
window.getSelection().setBaseAndExtent(textNodeElement, 0, textNodeElement, 1);
return true;
@@ -1584,7 +1631,6 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @param {?Event} event
- * @this {WebInspector.ElementsTreeElement}
*/
function keyupListener(event)
{
@@ -1614,12 +1660,17 @@ WebInspector.ElementsTreeElement.prototype = {
tagNameElement.addEventListener('keyup', keyupListener, false);
- var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName);
- this._editing = WebInspector.startEditing(tagNameElement, config);
+ var config = new WebInspector.InplaceEditor.Config(editingComitted.bind(this), editingCancelled.bind(this), tagName);
+ this._editing = WebInspector.InplaceEditor.startEditing(tagNameElement, config);
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},
+ /**
+ * @param {function(string, string)} commitCallback
+ * @param {?Protocol.Error} error
+ * @param {string} initialValue
+ */
_startEditingAsHTML: function(commitCallback, error, initialValue)
{
if (error)
@@ -1690,9 +1741,9 @@ WebInspector.ElementsTreeElement.prototype = {
this.treeOutline.element.focus();
}
- var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
+ var config = new WebInspector.InplaceEditor.Config(commit.bind(this), dispose.bind(this));
config.setMultilineOptions(initialValue, { name: "xml", htmlMode: true }, "web-inspector-html", WebInspector.settings.domWordWrap.get(), true);
- this._editing = WebInspector.startEditing(this._htmlEditElement, config);
+ this._editing = WebInspector.InplaceEditor.startEditing(this._htmlEditElement, config);
this._editing.setWidth(this.treeOutline._visibleWidth);
this.treeOutline._multilineEditing = this._editing;
},
@@ -1956,12 +2007,52 @@ WebInspector.ElementsTreeElement.prototype = {
* @param {!Node} parentElement
* @param {string} name
* @param {string} value
+ * @param {boolean=} forceValue
* @param {!WebInspector.DOMNode=} node
* @param {function(string, string, string, boolean=, string=)=} linkify
*/
- _buildAttributeDOM: function(parentElement, name, value, node, linkify)
+ _buildAttributeDOM: function(parentElement, name, value, forceValue, node, linkify)
{
- var hasText = (value.length > 0);
+ var closingPunctuationRegex = /[\/;:\)\]\}]/g;
+ var highlightIndex = 0;
+ var highlightCount;
+ var additionalHighlightOffset = 0;
+ var result;
+
+ /**
+ * @param {string} match
+ * @param {number} replaceOffset
+ * @return {string}
+ */
+ function replacer(match, replaceOffset) {
+ while (highlightIndex < highlightCount && result.entityRanges[highlightIndex].offset < replaceOffset) {
+ result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
+ ++highlightIndex;
+ }
+ additionalHighlightOffset += 1;
+ return match + "\u200B";
+ }
+
+ /**
+ * @param {!Element} element
+ * @param {string} value
+ * @this {WebInspector.ElementsTreeElement}
+ */
+ function setValueWithEntities(element, value)
+ {
+ var attrValueElement = element.createChild("span", "webkit-html-attribute-value");
+ result = this._convertWhitespaceToEntities(value);
+ highlightCount = result.entityRanges.length;
+ value = result.text.replace(closingPunctuationRegex, replacer);
+ while (highlightIndex < highlightCount) {
+ result.entityRanges[highlightIndex].offset += additionalHighlightOffset;
+ ++highlightIndex;
+ }
+ attrValueElement.textContent = value;
+ WebInspector.highlightRangesWithStyleClass(attrValueElement, result.entityRanges, "webkit-html-entity-value");
+ }
+
+ var hasText = (forceValue || value.length > 0);
var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
attrNameElement.textContent = name;
@@ -1971,19 +2062,16 @@ WebInspector.ElementsTreeElement.prototype = {
if (linkify && (name === "src" || name === "href")) {
var rewrittenHref = node.resolveURL(value);
- value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
if (rewrittenHref === null) {
- var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
- attrValueElement.textContent = value;
+ setValueWithEntities.call(this, attrSpanElement, value);
} else {
+ value = value.replace(closingPunctuationRegex, "$&\u200B");
if (value.startsWith("data:"))
value = value.trimMiddle(60);
attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
}
} else {
- value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
- var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
- attrValueElement.textContent = value;
+ setValueWithEntities.call(this, attrSpanElement, value);
}
if (hasText)
@@ -2023,7 +2111,7 @@ WebInspector.ElementsTreeElement.prototype = {
for (var i = 0; i < attributes.length; ++i) {
var attr = attributes[i];
tagElement.appendChild(document.createTextNode(" "));
- this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify);
+ this._buildAttributeDOM(tagElement, attr.name, attr.value, false, node, linkify);
}
}
tagElement.appendChild(document.createTextNode(">"));
@@ -2066,13 +2154,13 @@ WebInspector.ElementsTreeElement.prototype = {
switch (node.nodeType()) {
case Node.ATTRIBUTE_NODE:
- var value = node.value || "\u200B"; // Zero width space to force showing an empty value.
- this._buildAttributeDOM(info.titleDOM, node.name, value);
+ this._buildAttributeDOM(info.titleDOM, /** @type {string} */ (node.name), /** @type {string} */ (node.value), true);
break;
case Node.ELEMENT_NODE:
- if (node.pseudoType()) {
- this._buildPseudoElementDOM(info.titleDOM, node.pseudoType());
+ var pseudoType = node.pseudoType();
+ if (pseudoType) {
+ this._buildPseudoElementDOM(info.titleDOM, pseudoType);
info.hasChildren = false;
break;
}
@@ -2087,7 +2175,7 @@ WebInspector.ElementsTreeElement.prototype = {
this._buildTagDOM(info.titleDOM, tagName, false, false, linkify);
var showInlineText = this._showInlineText() && !this.hasChildren;
- if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
+ if (!this.expanded && !showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName])) {
if (this.hasChildren) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus");
textNodeElement.textContent = "\u2026";
@@ -2160,20 +2248,14 @@ WebInspector.ElementsTreeElement.prototype = {
break;
case Node.DOCUMENT_FRAGMENT_NODE:
var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment");
- var nodeTitle;
if (node.isInShadowTree()) {
var shadowRootType = node.shadowRootType();
if (shadowRootType) {
info.shadowRoot = true;
fragmentElement.classList.add("shadow-root");
- nodeTitle = "#shadow-root";
- if (shadowRootType === WebInspector.DOMNode.ShadowRootTypes.UserAgent)
- nodeTitle += " (" + shadowRootType + ")";
}
}
- if (!nodeTitle)
- nodeTitle = node.nodeNameInCorrectCase().collapseWhitespace();
- fragmentElement.textContent = nodeTitle;
+ fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
break;
default:
info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace()));
@@ -2186,14 +2268,15 @@ WebInspector.ElementsTreeElement.prototype = {
*/
_showInlineText: function()
{
- if (this._node.templateContent() || (WebInspector.ElementsTreeOutline.showShadowDOM() && this._node.hasShadowRoots()) || this._node.hasPseudoElements())
+ if (this._node.importedDocument() || this._node.templateContent() || this._visibleShadowRoots().length > 0 || this._node.hasPseudoElements())
return false;
if (this._node.nodeType() !== Node.ELEMENT_NODE)
return false;
if (!this._node.firstChild || this._node.firstChild !== this._node.lastChild || this._node.firstChild.nodeType() !== Node.TEXT_NODE)
return false;
var textChild = this._node.firstChild;
- if (textChild.nodeValue().length < Preferences.maxInlineTextChildLength)
+ var maxInlineTextChildLength = 80;
+ if (textChild.nodeValue().length < maxInlineTextChildLength)
return true;
return false;
},
@@ -2207,7 +2290,7 @@ WebInspector.ElementsTreeElement.prototype = {
return;
var self = this;
- function removeNodeCallback(error, removedNodeId)
+ function removeNodeCallback(error)
{
if (error)
return;
@@ -2232,7 +2315,10 @@ WebInspector.ElementsTreeElement.prototype = {
var index = node.index;
var wasExpanded = this.expanded;
- function selectNode(error, nodeId)
+ /**
+ * @param {?Protocol.Error} error
+ */
+ function selectNode(error)
{
if (error)
return;
@@ -2253,12 +2339,14 @@ WebInspector.ElementsTreeElement.prototype = {
}
}
+ /**
+ * @param {string} initialValue
+ * @param {string} value
+ */
function commitChange(initialValue, value)
{
if (initialValue !== value)
node.setOuterHTML(value, selectNode);
- else
- return;
}
node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange));
@@ -2279,24 +2367,6 @@ WebInspector.ElementsTreeElement.prototype = {
InspectorFrontendHost.copyText(WebInspector.DOMPresentationUtils.xPath(this._node, true));
},
- _inspectDOMProperties: function()
- {
- WebInspector.RemoteObject.resolveNode(this._node, "console", callback);
-
- /**
- * @param {?WebInspector.RemoteObject} nodeObject
- */
- function callback(nodeObject)
- {
- if (!nodeObject)
- return;
-
- var message = WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.ConsoleAPI, WebInspector.ConsoleMessage.MessageLevel.Log, "", WebInspector.ConsoleMessage.MessageType.Dir, undefined, undefined, undefined, undefined, [nodeObject]);
- WebInspector.console.addMessage(message);
- WebInspector.showConsole();
- }
- },
-
_highlightSearchResults: function()
{
if (!this._searchQuery || !this._searchHighlightsVisible)
@@ -2330,6 +2400,7 @@ WebInspector.ElementsTreeElement.prototype = {
function scrollIntoViewCallback(object)
{
/**
+ * @suppressReceiverCheck
* @this {!Element}
*/
function scrollIntoView()
@@ -2340,8 +2411,22 @@ WebInspector.ElementsTreeElement.prototype = {
if (object)
object.callFunction(scrollIntoView);
}
-
- WebInspector.RemoteObject.resolveNode(this._node, "", scrollIntoViewCallback);
+
+ this._node.resolveToObject("", scrollIntoViewCallback);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.DOMNode>}
+ */
+ _visibleShadowRoots: function()
+ {
+ var roots = this._node.shadowRoots();
+ if (roots.length && !WebInspector.settings.showUAShadowDOM.get()) {
+ roots = roots.filter(function(root) {
+ return root.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes.Author;
+ });
+ }
+ return roots;
},
/**
@@ -2349,7 +2434,9 @@ WebInspector.ElementsTreeElement.prototype = {
*/
_visibleChildren: function()
{
- var visibleChildren = WebInspector.ElementsTreeOutline.showShadowDOM() ? this._node.shadowRoots() : [];
+ var visibleChildren = this._visibleShadowRoots();
+ if (this._node.importedDocument())
+ visibleChildren.push(this._node.importedDocument());
if (this._node.templateContent())
visibleChildren.push(this._node.templateContent());
var pseudoElements = this._node.pseudoElements();
@@ -2367,11 +2454,11 @@ WebInspector.ElementsTreeElement.prototype = {
*/
_visibleChildCount: function()
{
- var childCount = this._node.childNodeCount();
+ var childCount = this._node.childNodeCount() + this._visibleShadowRoots().length;
+ if (this._node.importedDocument())
+ ++childCount;
if (this._node.templateContent())
++childCount;
- if (WebInspector.ElementsTreeOutline.showShadowDOM())
- childCount += this._node.shadowRoots().length;
for (var pseudoType in this._node.pseudoElements())
++childCount;
return childCount;
@@ -2387,24 +2474,37 @@ WebInspector.ElementsTreeElement.prototype = {
/**
* @constructor
+ * @param {!WebInspector.DOMModel} domModel
* @param {!WebInspector.ElementsTreeOutline} treeOutline
*/
-WebInspector.ElementsTreeUpdater = function(treeOutline)
+WebInspector.ElementsTreeUpdater = function(domModel, treeOutline)
{
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
-
+ domModel.addEventListener(WebInspector.DOMModel.Events.NodeInserted, this._nodeInserted, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributesUpdated, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributesUpdated, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
+ domModel.addEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
+
+ this._domModel = domModel;
this._treeOutline = treeOutline;
/** @type {!Map.<!WebInspector.DOMNode, !WebInspector.ElementsTreeUpdater.UpdateEntry>} */
this._recentlyModifiedNodes = new Map();
}
WebInspector.ElementsTreeUpdater.prototype = {
+ dispose: function()
+ {
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeInserted, this._nodeInserted, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributesUpdated, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributesUpdated, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._characterDataModified, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._documentUpdated, this);
+ this._domModel.removeEventListener(WebInspector.DOMModel.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
+ },
+
/**
* @param {!WebInspector.DOMNode} node
* @param {boolean} isUpdated
@@ -2462,8 +2562,12 @@ WebInspector.ElementsTreeUpdater.prototype = {
_childNodeCountUpdated: function(event)
{
var treeElement = this._treeOutline.findTreeElement(event.data);
- if (treeElement)
+ if (treeElement) {
+ var oldHasChildren = treeElement.hasChildren;
treeElement._updateHasChildren();
+ if (treeElement.hasChildren !== oldHasChildren)
+ treeElement.updateTitle();
+ }
},
_updateModifiedNodesSoon: function()
@@ -2534,7 +2638,7 @@ WebInspector.ElementsTreeUpdater.prototype = {
{
this._treeOutline.rootDOMNode = null;
this._treeOutline.selectDOMNode(null, false);
- WebInspector.domAgent.hideDOMNodeHighlight();
+ this._domModel.hideDOMNodeHighlight();
this._recentlyModifiedNodes.clear();
}
}
@@ -2550,3 +2654,32 @@ WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
if (parent)
this.parent = parent;
}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Renderer}
+ */
+WebInspector.ElementsTreeOutline.Renderer = function()
+{
+}
+
+WebInspector.ElementsTreeOutline.Renderer.prototype = {
+ /**
+ * @param {!Object} object
+ * @return {?Element}
+ */
+ render: function(object)
+ {
+ if (!(object instanceof WebInspector.DOMNode))
+ return null;
+ var node = /** @type {!WebInspector.DOMNode} */ (object);
+ var treeOutline = new WebInspector.ElementsTreeOutline(node.target(), false, false);
+ treeOutline.rootDOMNode = node;
+ treeOutline.element.classList.add("outline-disclosure");
+ if (!treeOutline.children[0].hasChildren)
+ treeOutline.element.classList.add("single-node");
+ treeOutline.setVisible(true);
+ treeOutline.element.treeElementForTest = treeOutline.children[0];
+ return treeOutline.element;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/EventListenersSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/EventListenersSidebarPane.js
index 2021da7b058..a639a53f2ff 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/EventListenersSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/EventListenersSidebarPane.js
@@ -38,6 +38,12 @@ WebInspector.EventListenersSidebarPane = function()
this.sections = [];
+ var refreshButton = document.createElement("button");
+ refreshButton.className = "pane-title-button refresh";
+ refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
+ refreshButton.title = WebInspector.UIString("Refresh");
+ this.titleElement.appendChild(refreshButton);
+
this.settingsSelectElement = document.createElement("select");
this.settingsSelectElement.className = "select-filter";
@@ -67,6 +73,9 @@ WebInspector.EventListenersSidebarPane = function()
WebInspector.EventListenersSidebarPane._objectGroupName = "event-listeners-sidebar-pane";
WebInspector.EventListenersSidebarPane.prototype = {
+ /**
+ * @param {?WebInspector.DOMNode} node
+ */
update: function(node)
{
RuntimeAgent.releaseObjectGroup(WebInspector.EventListenersSidebarPane._objectGroupName);
@@ -77,8 +86,12 @@ WebInspector.EventListenersSidebarPane.prototype = {
this.sections = [];
var self = this;
- function callback(error, eventListeners) {
- if (error)
+ /**
+ * @param {?Array.<!WebInspector.DOMModel.EventListener>} eventListeners
+ */
+ function callback(eventListeners)
+ {
+ if (!eventListeners)
return;
var selectedNodeOnly = "selected" === WebInspector.settings.eventListenersFilter.get();
@@ -86,13 +99,11 @@ WebInspector.EventListenersSidebarPane.prototype = {
var sectionMap = {};
for (var i = 0; i < eventListeners.length; ++i) {
var eventListener = eventListeners[i];
- if (selectedNodeOnly && (node.id !== eventListener.nodeId))
+ if (selectedNodeOnly && (node.id !== eventListener.payload().nodeId))
continue;
- eventListener.node = WebInspector.domAgent.nodeForId(eventListener.nodeId);
- delete eventListener.nodeId; // no longer needed
- if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.handlerBody.toString()))
+ if (/^function _inspectorCommandLineAPI_logEvent\(/.test(eventListener.payload().handlerBody.toString()))
continue; // ignore event listeners generated by monitorEvent
- var type = eventListener.type;
+ var type = eventListener.payload().type;
var section = sectionMap[type];
if (!section) {
section = new WebInspector.EventListenersSection(type, node.id, self._linkifier);
@@ -128,6 +139,13 @@ WebInspector.EventListenersSidebarPane.prototype = {
delete this._selectedNode;
},
+ _refreshButtonClicked: function()
+ {
+ if (!this._selectedNode)
+ return;
+ this.update(this._selectedNode);
+ },
+
_changeSetting: function()
{
var selectedOption = this.settingsSelectElement[this.settingsSelectElement.selectedIndex];
@@ -160,6 +178,9 @@ WebInspector.EventListenersSection = function(title, nodeId, linkifier)
}
WebInspector.EventListenersSection.prototype = {
+ /**
+ * @param {!WebInspector.DOMModel.EventListener} eventListener
+ */
addListener: function(eventListener)
{
var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId, this._linkifier);
@@ -172,12 +193,17 @@ WebInspector.EventListenersSection.prototype = {
/**
* @constructor
* @extends {WebInspector.ObjectPropertiesSection}
+ * @param {!WebInspector.DOMModel.EventListener} eventListener
+ * @param {!DOMAgent.NodeId} nodeId
+ * @param {!WebInspector.Linkifier} linkifier
*/
WebInspector.EventListenerBar = function(eventListener, nodeId, linkifier)
{
- WebInspector.ObjectPropertiesSection.call(this, WebInspector.RemoteObject.fromPrimitiveValue(""));
+ var target = eventListener.target();
+ WebInspector.ObjectPropertiesSection.call(this, target.runtimeModel.createRemoteObjectFromPrimitiveValue(""));
- this.eventListener = eventListener;
+ this._runtimeModel = target.runtimeModel;
+ this._eventListener = eventListener;
this._nodeId = nodeId;
this._setNodeTitle();
this._setFunctionSubtitle(linkifier);
@@ -197,34 +223,30 @@ WebInspector.EventListenerBar.prototype = {
function updateWithNodeObject(nodeObject)
{
var properties = [];
+ var payload = this._eventListener.payload();
- if (this.eventListener.type)
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("type", this.eventListener.type));
- if (typeof this.eventListener.useCapture !== "undefined")
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("useCapture", this.eventListener.useCapture));
- if (typeof this.eventListener.isAttribute !== "undefined")
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("isAttribute", this.eventListener.isAttribute));
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("type", payload.type));
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("useCapture", payload.useCapture));
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("isAttribute", payload.isAttribute));
if (nodeObject)
properties.push(new WebInspector.RemoteObjectProperty("node", nodeObject));
- if (typeof this.eventListener.handler !== "undefined") {
- var remoteObject = WebInspector.RemoteObject.fromPayload(this.eventListener.handler);
+ if (typeof payload.handler !== "undefined") {
+ var remoteObject = this._runtimeModel.createRemoteObject(payload.handler);
properties.push(new WebInspector.RemoteObjectProperty("handler", remoteObject));
}
- if (typeof this.eventListener.handlerBody !== "undefined")
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("listenerBody", this.eventListener.handlerBody));
- if (this.eventListener.sourceName)
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("sourceName", this.eventListener.sourceName));
- if (this.eventListener.location)
- properties.push(WebInspector.RemoteObjectProperty.fromPrimitiveValue("lineNumber", this.eventListener.location.lineNumber + 1));
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("listenerBody", payload.handlerBody));
+ if (payload.sourceName)
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("sourceName", payload.sourceName));
+ properties.push(this._runtimeModel.createRemotePropertyFromPrimitiveValue("lineNumber", payload.location.lineNumber + 1));
this.updateProperties(properties);
}
- WebInspector.RemoteObject.resolveNode(this.eventListener.node, WebInspector.EventListenersSidebarPane._objectGroupName, updateWithNodeObject.bind(this));
+ this._eventListener.node().resolveToObject(WebInspector.EventListenersSidebarPane._objectGroupName, updateWithNodeObject.bind(this));
},
_setNodeTitle: function()
{
- var node = this.eventListener.node;
+ var node = this._eventListener.node();
if (!node)
return;
@@ -234,36 +256,18 @@ WebInspector.EventListenerBar.prototype = {
}
if (node.id === this._nodeId) {
- this.titleElement.textContent = WebInspector.DOMPresentationUtils.appropriateSelectorFor(node);
+ this.titleElement.textContent = WebInspector.DOMPresentationUtils.simpleSelector(node);
return;
}
this.titleElement.removeChildren();
- this.titleElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(this.eventListener.node));
+ this.titleElement.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
},
_setFunctionSubtitle: function(linkifier)
{
- // Requires that Function.toString() return at least the function's signature.
- if (this.eventListener.location) {
- this.subtitleElement.removeChildren();
- var urlElement;
- if (this.eventListener.location.scriptId)
- urlElement = linkifier.linkifyRawLocation(this.eventListener.location);
- if (!urlElement) {
- var url = this.eventListener.sourceName;
- var lineNumber = this.eventListener.location.lineNumber;
- var columnNumber = 0;
- urlElement = linkifier.linkifyLocation(url, lineNumber, columnNumber);
- }
- this.subtitleElement.appendChild(urlElement);
- } else {
- var match = this.eventListener.handlerBody.match(/function ([^\(]+?)\(/);
- if (match)
- this.subtitleElement.textContent = match[1];
- else
- this.subtitleElement.textContent = WebInspector.UIString("(anonymous function)");
- }
+ this.subtitleElement.removeChildren();
+ this.subtitleElement.appendChild(linkifier.linkifyRawLocation(this._eventListener.location()));
},
__proto__: WebInspector.ObjectPropertiesSection.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/MetricsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js
index 409c59fc5b0..2bbdddbd74d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/MetricsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/MetricsSidebarPane.js
@@ -33,12 +33,6 @@
WebInspector.MetricsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Metrics"));
-
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
}
WebInspector.MetricsSidebarPane.prototype = {
@@ -47,11 +41,39 @@ WebInspector.MetricsSidebarPane.prototype = {
*/
update: function(node)
{
- if (node)
- this.node = node;
+ if (!node || this._node === node) {
+ this._innerUpdate();
+ return;
+ }
+
+ this._node = node;
+ this._updateTarget(node.target());
this._innerUpdate();
},
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ _updateTarget: function(target)
+ {
+ if (this._target === target)
+ return;
+
+ if (this._target) {
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributesUpdated, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributesUpdated, this);
+ this._target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
+ }
+ this._target = target;
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributesUpdated, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributesUpdated, this);
+ this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
+ },
+
_innerUpdate: function()
{
// "style" attribute might have changed. Update metrics unless they are being edited
@@ -60,7 +82,7 @@ WebInspector.MetricsSidebarPane.prototype = {
return;
// FIXME: avoid updates of a collapsed pane.
- var node = this.node;
+ var node = this._node;
if (!node || node.nodeType() !== Node.ELEMENT_NODE) {
this.bodyElement.removeChildren();
@@ -73,11 +95,11 @@ WebInspector.MetricsSidebarPane.prototype = {
*/
function callback(style)
{
- if (!style || this.node !== node)
+ if (!style || this._node !== node)
return;
this._updateMetrics(style);
}
- WebInspector.cssModel.getComputedStyleAsync(node.id, callback.bind(this));
+ this._target.cssModel.getComputedStyleAsync(node.id, callback.bind(this));
/**
* @param {?WebInspector.CSSStyleDeclaration} style
@@ -85,11 +107,11 @@ WebInspector.MetricsSidebarPane.prototype = {
*/
function inlineStyleCallback(style)
{
- if (!style || this.node !== node)
+ if (!style || this._node !== node)
return;
this.inlineStyle = style;
}
- WebInspector.cssModel.getInlineStylesAsync(node.id, inlineStyleCallback.bind(this));
+ this._target.cssModel.getInlineStylesAsync(node.id, inlineStyleCallback.bind(this));
},
_styleSheetOrMediaQueryResultChanged: function()
@@ -116,7 +138,7 @@ WebInspector.MetricsSidebarPane.prototype = {
_attributesUpdated: function(event)
{
- if (this.node !== event.data.node)
+ if (this._node !== event.data.node)
return;
this._innerUpdate();
@@ -137,23 +159,27 @@ WebInspector.MetricsSidebarPane.prototype = {
return { left: left, top: top, right: right, bottom: bottom };
},
+ /**
+ * @param {boolean} showHighlight
+ * @param {string} mode
+ * @param {?Event} event
+ */
_highlightDOMNode: function(showHighlight, mode, event)
{
event.consume();
- var nodeId = showHighlight && this.node ? this.node.id : 0;
- if (nodeId) {
+ if (showHighlight && this._node) {
if (this._highlightMode === mode)
return;
this._highlightMode = mode;
- WebInspector.domAgent.highlightDOMNode(nodeId, mode);
+ this._node.highlight(mode);
} else {
delete this._highlightMode;
- WebInspector.domAgent.hideDOMNodeHighlight();
+ this._target.domModel.hideDOMNodeHighlight();
}
for (var i = 0; this._boxElements && i < this._boxElements.length; ++i) {
var element = this._boxElements[i];
- if (!nodeId || mode === "all" || element._name === mode)
+ if (!this._node || mode === "all" || element._name === mode)
element.style.backgroundColor = element._backgroundColor;
else
element.style.backgroundColor = "";
@@ -312,7 +338,7 @@ WebInspector.MetricsSidebarPane.prototype = {
}
metricsElement.appendChild(previousBox);
- metricsElement.addEventListener("mouseover", this._highlightDOMNode.bind(this, false, ""), false);
+ metricsElement.addEventListener("mouseover", this._highlightDOMNode.bind(this, false, "all"), false);
this.bodyElement.removeChildren();
this.bodyElement.appendChild(metricsElement);
},
@@ -329,8 +355,8 @@ WebInspector.MetricsSidebarPane.prototype = {
this._isEditingMetrics = true;
- var config = new WebInspector.EditingConfig(this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
- WebInspector.startEditing(targetElement, config);
+ var config = new WebInspector.InplaceEditor.Config(this.editingCommitted.bind(this), this.editingCancelled.bind(this), context);
+ WebInspector.InplaceEditor.startEditing(targetElement, config);
window.getSelection().setBaseAndExtent(targetElement, 0, targetElement, 1);
},
@@ -407,7 +433,7 @@ WebInspector.MetricsSidebarPane.prototype = {
if (computedStyle.getPropertyValue("box-sizing") === "border-box" && (styleProperty === "width" || styleProperty === "height")) {
if (!userInput.match(/px$/)) {
- WebInspector.log("For elements with box-sizing: border-box, only absolute content area dimensions can be applied", WebInspector.ConsoleMessage.MessageLevel.Error, true);
+ WebInspector.messageSink.addErrorMessage("For elements with box-sizing: border-box, only absolute content area dimensions can be applied", true);
return;
}
@@ -433,9 +459,8 @@ WebInspector.MetricsSidebarPane.prototype = {
if (!("originalPropertyData" in self))
self.originalPropertyData = self.previousPropertyDataCandidate;
- if (typeof self._highlightMode !== "undefined") {
- WebInspector.domAgent.highlightDOMNode(self.node.id, self._highlightMode);
- }
+ if (typeof self._highlightMode !== "undefined")
+ self._node.highlight(self._highlightMode);
if (commitEditor) {
self.dispatchEventToListeners("metrics edited");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/elements/OverridesView.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/OverridesView.js
new file mode 100644
index 00000000000..11cc1538996
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/OverridesView.js
@@ -0,0 +1,653 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.OverridesView = function()
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("overrides.css");
+ this.registerRequiredCSS("helpScreen.css");
+ this.element.classList.add("overrides-view");
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.shrinkableTabs = false;
+ this._tabbedPane.verticalTabLayout = true;
+
+
+ new WebInspector.OverridesView.DeviceTab().appendAsTab(this._tabbedPane);
+ new WebInspector.OverridesView.MediaTab().appendAsTab(this._tabbedPane);
+ new WebInspector.OverridesView.NetworkTab().appendAsTab(this._tabbedPane);
+ new WebInspector.OverridesView.SensorsTab().appendAsTab(this._tabbedPane);
+
+ this._lastSelectedTabSetting = WebInspector.settings.createSetting("lastSelectedEmulateTab", "device");
+ this._tabbedPane.selectTab(this._lastSelectedTabSetting.get());
+ this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+ this._tabbedPane.show(this.element);
+
+ var resetButtonElement = this._tabbedPane.headerElement().createChild("button", "settings-tab-text-button overrides-reset-button");
+ resetButtonElement.textContent = WebInspector.UIString("Reset");
+ resetButtonElement.addEventListener("click", WebInspector.overridesSupport.reset.bind(WebInspector.overridesSupport), false);
+
+ this._warningFooter = this.element.createChild("div", "overrides-footer");
+ this._overridesWarningUpdated();
+
+ this._splashScreenElement = this.element.createChild("div", "overrides-splash-screen");
+ this._splashScreenElement.createTextChild(WebInspector.UIString("Emulation is currently disabled. Toggle "));
+ var toggleEmulationButton = new WebInspector.StatusBarButton("", "emulation-status-bar-item");
+ toggleEmulationButton.addEventListener("click", this._toggleEmulationEnabled, this);
+ this._splashScreenElement.appendChild(toggleEmulationButton.element);
+ this._splashScreenElement.createTextChild(WebInspector.UIString("in the main toolbar to enable it."));
+
+ WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.OverridesWarningUpdated, this._overridesWarningUpdated, this);
+ WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.EmulationStateChanged, this._emulationEnabledChanged, this);
+ this._emulationEnabledChanged();
+}
+
+WebInspector.OverridesView.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _tabSelected: function(event)
+ {
+ this._lastSelectedTabSetting.set(this._tabbedPane.selectedTabId);
+ },
+
+ _overridesWarningUpdated: function()
+ {
+ var message = WebInspector.overridesSupport.warningMessage();
+ this._warningFooter.classList.toggle("hidden", !WebInspector.overridesSupport.emulationEnabled() || !message);
+ this._warningFooter.textContent = message;
+ },
+
+ _toggleEmulationEnabled: function()
+ {
+ WebInspector.overridesSupport.setEmulationEnabled(true);
+ },
+
+ _emulationEnabledChanged: function()
+ {
+ this._tabbedPane.element.classList.toggle("hidden", !WebInspector.overridesSupport.emulationEnabled());
+ this._overridesWarningUpdated();
+ this._splashScreenElement.classList.toggle("hidden", WebInspector.overridesSupport.emulationEnabled());
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {string} id
+ * @param {string} name
+ * @param {!Array.<!WebInspector.Setting>} settings
+ * @param {!Array.<function():boolean>=} predicates
+ */
+WebInspector.OverridesView.Tab = function(id, name, settings, predicates)
+{
+ WebInspector.VBox.call(this);
+ this._id = id;
+ this._name = name;
+ this._settings = settings;
+ this._predicates = predicates || [];
+ for (var i = 0; i < settings.length; ++i)
+ settings[i].addChangeListener(this.updateActiveState, this);
+}
+
+WebInspector.OverridesView.Tab.prototype = {
+ /**
+ * @param {!WebInspector.TabbedPane} tabbedPane
+ */
+ appendAsTab: function(tabbedPane)
+ {
+ this._tabbedPane = tabbedPane;
+ tabbedPane.appendTab(this._id, this._name, this);
+ this.updateActiveState();
+ },
+
+ updateActiveState: function()
+ {
+ if (!this._tabbedPane)
+ return;
+ var active = false;
+ for (var i = 0; !active && i < this._settings.length; ++i)
+ active = this._settings[i].get();
+ for (var i = 0; !active && i < this._predicates.length; ++i)
+ active = this._predicates[i]();
+ this._tabbedPane.element.classList.toggle("overrides-activate-" + this._id, active);
+ },
+
+ /**
+ * @param {string} name
+ * @param {!WebInspector.Setting} setting
+ * @param {function(boolean)=} callback
+ */
+ _createSettingCheckbox: function(name, setting, callback)
+ {
+ var checkbox = WebInspector.SettingsUI.createSettingCheckbox(name, setting, true);
+
+ function changeListener(value)
+ {
+ callback(setting.get());
+ }
+
+ if (callback)
+ setting.addChangeListener(changeListener);
+
+ return checkbox;
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.OverridesView.Tab}
+ */
+WebInspector.OverridesView.DeviceTab = function()
+{
+ WebInspector.OverridesView.Tab.call(this, "device", WebInspector.UIString("Device"), [
+ WebInspector.overridesSupport.settings.deviceWidth,
+ WebInspector.overridesSupport.settings.deviceHeight,
+ WebInspector.overridesSupport.settings.deviceScaleFactor,
+ WebInspector.overridesSupport.settings.emulateViewport,
+ WebInspector.overridesSupport.settings.deviceTextAutosizing
+ ]);
+ this.element.classList.add("overrides-device");
+
+ this.element.appendChild(this._createDeviceElement());
+
+ var footnote = this.element.createChild("p", "help-footnote");
+ var footnoteLink = footnote.createChild("a");
+ footnoteLink.href = "https://developers.google.com/chrome-developer-tools/docs/mobile-emulation";
+ footnoteLink.target = "_blank";
+ footnoteLink.createTextChild(WebInspector.UIString("More information about screen emulation"));
+}
+
+WebInspector.OverridesView.DeviceTab.prototype = {
+ _createDeviceElement: function()
+ {
+ var fieldsetElement = document.createElement("fieldset");
+ fieldsetElement.id = "metrics-override-section";
+
+ fieldsetElement.createChild("span").textContent = WebInspector.UIString("Model:");
+ fieldsetElement.appendChild(WebInspector.overridesSupport.createDeviceSelect(document));
+
+ var tableElement = fieldsetElement.createChild("table", "nowrap");
+
+ var rowElement = tableElement.createChild("tr");
+ var cellElement = rowElement.createChild("td");
+ cellElement.appendChild(document.createTextNode(WebInspector.UIString("Resolution:")));
+ cellElement = rowElement.createChild("td");
+
+ var widthOverrideInput = WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceWidth, true, 4, "80px", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013"));
+ cellElement.appendChild(widthOverrideInput);
+ this._swapDimensionsElement = cellElement.createChild("button", "overrides-swap");
+ this._swapDimensionsElement.appendChild(document.createTextNode(" \u21C4 ")); // RIGHTWARDS ARROW OVER LEFTWARDS ARROW.
+ this._swapDimensionsElement.title = WebInspector.UIString("Swap dimensions");
+ this._swapDimensionsElement.addEventListener("click", WebInspector.overridesSupport.swapDimensions.bind(WebInspector.overridesSupport), false);
+ this._swapDimensionsElement.tabIndex = -1;
+ var heightOverrideInput = WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceHeight, true, 4, "80px", WebInspector.OverridesSupport.deviceSizeValidator, true, true, WebInspector.UIString("\u2013"));
+ cellElement.appendChild(heightOverrideInput);
+
+ rowElement = tableElement.createChild("tr");
+ cellElement = rowElement.createChild("td");
+ cellElement.colSpan = 4;
+
+ rowElement = tableElement.createChild("tr");
+ rowElement.title = WebInspector.UIString("Ratio between a device's physical pixels and device-independent pixels.");
+ rowElement.createChild("td").appendChild(document.createTextNode(WebInspector.UIString("Device pixel ratio:")));
+ rowElement.createChild("td").appendChild(WebInspector.SettingsUI.createSettingInputField("", WebInspector.overridesSupport.settings.deviceScaleFactor, true, 4, "80px", WebInspector.OverridesSupport.deviceScaleFactorValidator, true, true, WebInspector.UIString("\u2013")));
+
+ var viewportCheckbox = this._createSettingCheckbox(WebInspector.UIString("Emulate mobile"), WebInspector.overridesSupport.settings.emulateViewport);
+ viewportCheckbox.title = WebInspector.UIString("Enable meta viewport, overlay scrollbars and default 980px body width");
+ fieldsetElement.appendChild(viewportCheckbox);
+
+ // FIXME: move text autosizing to the "misc" tab together with css media, and separate it from device emulation.
+ var textAutosizingOverrideElement = this._createSettingCheckbox(WebInspector.UIString("Enable text autosizing "), WebInspector.overridesSupport.settings.deviceTextAutosizing);
+ textAutosizingOverrideElement.title = WebInspector.UIString("Text autosizing is the feature that boosts font sizes on mobile devices.");
+ fieldsetElement.appendChild(textAutosizingOverrideElement);
+
+ if (!WebInspector.overridesSupport.responsiveDesignAvailable())
+ fieldsetElement.appendChild(this._createSettingCheckbox(WebInspector.UIString("Shrink to fit"), WebInspector.overridesSupport.settings.deviceFitWindow));
+
+ return fieldsetElement;
+ },
+
+ __proto__: WebInspector.OverridesView.Tab.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.OverridesView.Tab}
+ */
+WebInspector.OverridesView.MediaTab = function()
+{
+ var settings = [WebInspector.overridesSupport.settings.overrideCSSMedia];
+ WebInspector.OverridesView.Tab.call(this, "media", WebInspector.UIString("Media"), settings);
+ this.element.classList.add("overrides-media");
+
+ this._createMediaEmulationFragment();
+}
+
+WebInspector.OverridesView.MediaTab.prototype = {
+ _createMediaEmulationFragment: function()
+ {
+ var checkbox = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("CSS media"), WebInspector.overridesSupport.settings.overrideCSSMedia, true);
+ var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.overridesSupport.settings.overrideCSSMedia);
+ var mediaSelectElement = fieldsetElement.createChild("select");
+ var mediaTypes = WebInspector.CSSStyleModel.MediaTypes;
+ var defaultMedia = WebInspector.overridesSupport.settings.emulatedCSSMedia.get();
+ for (var i = 0; i < mediaTypes.length; ++i) {
+ var mediaType = mediaTypes[i];
+ if (mediaType === "all") {
+ // "all" is not a device-specific media type.
+ continue;
+ }
+ var option = document.createElement("option");
+ option.text = mediaType;
+ option.value = mediaType;
+ mediaSelectElement.add(option);
+ if (mediaType === defaultMedia)
+ mediaSelectElement.selectedIndex = mediaSelectElement.options.length - 1;
+ }
+
+ mediaSelectElement.addEventListener("change", this._emulateMediaChanged.bind(this, mediaSelectElement), false);
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild(checkbox);
+ fragment.appendChild(fieldsetElement);
+ this.element.appendChild(fragment);
+ },
+
+ _emulateMediaChanged: function(select)
+ {
+ var media = select.options[select.selectedIndex].value;
+ WebInspector.overridesSupport.settings.emulatedCSSMedia.set(media);
+ },
+
+ __proto__: WebInspector.OverridesView.Tab.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.OverridesView.Tab}
+ */
+WebInspector.OverridesView.NetworkTab = function()
+{
+ var predicates = [this._userAgentOverrideEnabled.bind(this)];
+ if (WebInspector.experimentsSettings.networkConditions.isEnabled())
+ predicates.push(this._networkThroughputIsLimited.bind(this));
+ WebInspector.OverridesView.Tab.call(this, "network", WebInspector.UIString("Network"), [], predicates);
+ this.element.classList.add("overrides-network");
+ if (WebInspector.experimentsSettings.networkConditions.isEnabled())
+ this._createNetworkConditionsElement();
+ this._createUserAgentSection();
+}
+
+WebInspector.OverridesView.NetworkTab.prototype = {
+ /**
+ * @return {boolean}
+ */
+ _networkThroughputIsLimited: function()
+ {
+ return WebInspector.overridesSupport.networkThroughputIsLimited();
+ },
+
+ _createNetworkConditionsElement: function()
+ {
+ var fieldsetElement = this.element.createChild("fieldset");
+ fieldsetElement.createChild("span").textContent = WebInspector.UIString("Limit network throughput:");
+
+ var networkThroughput = WebInspector.overridesSupport.createNetworkThroughputSelect(document);
+ fieldsetElement.appendChild(networkThroughput);
+
+ WebInspector.overridesSupport.settings.networkConditionsThroughput.addChangeListener(this.updateActiveState, this);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _userAgentOverrideEnabled: function()
+ {
+ return !!WebInspector.overridesSupport.settings.userAgent.get();
+ },
+
+ _createUserAgentSection: function()
+ {
+ var fieldsetElement = this.element.createChild("fieldset");
+ var userAgentInput = WebInspector.SettingsUI.createSettingInputField("Spoof user agent:", WebInspector.overridesSupport.settings.userAgent, false, 0, "", undefined, false, false, WebInspector.UIString("no override"));
+ fieldsetElement.appendChild(userAgentInput);
+
+ WebInspector.overridesSupport.settings.userAgent.addChangeListener(this.updateActiveState, this);
+ },
+
+ __proto__: WebInspector.OverridesView.Tab.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.OverridesView.Tab}
+ */
+WebInspector.OverridesView.SensorsTab = function()
+{
+ var settings = [WebInspector.overridesSupport.settings.overrideGeolocation, WebInspector.overridesSupport.settings.overrideDeviceOrientation];
+ if (!WebInspector.overridesSupport.hasTouchInputs())
+ settings.push(WebInspector.overridesSupport.settings.emulateTouch);
+ WebInspector.OverridesView.Tab.call(this, "sensors", WebInspector.UIString("Sensors"), settings);
+
+ this.element.classList.add("overrides-sensors");
+ this.registerRequiredCSS("accelerometer.css");
+ if (!WebInspector.overridesSupport.hasTouchInputs())
+ this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate touch screen"), WebInspector.overridesSupport.settings.emulateTouch, undefined));
+ this._appendGeolocationOverrideControl();
+ this._apendDeviceOrientationOverrideControl();
+}
+
+WebInspector.OverridesView.SensorsTab.prototype = {
+ _appendGeolocationOverrideControl: function()
+ {
+ const geolocationSetting = WebInspector.overridesSupport.settings.geolocationOverride.get();
+ var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(geolocationSetting);
+ this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Emulate geolocation coordinates"), WebInspector.overridesSupport.settings.overrideGeolocation, this._geolocationOverrideCheckboxClicked.bind(this)));
+ this.element.appendChild(this._createGeolocationOverrideElement(geolocation));
+ this._geolocationOverrideCheckboxClicked(WebInspector.overridesSupport.settings.overrideGeolocation.get());
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ _geolocationOverrideCheckboxClicked: function(enabled)
+ {
+ if (enabled && !this._latitudeElement.value)
+ this._latitudeElement.focus();
+ },
+
+ _applyGeolocationUserInput: function()
+ {
+ this._setGeolocationPosition(WebInspector.OverridesSupport.GeolocationPosition.parseUserInput(this._latitudeElement.value.trim(), this._longitudeElement.value.trim(), this._geolocationErrorElement.checked), true);
+ },
+
+ /**
+ * @param {?WebInspector.OverridesSupport.GeolocationPosition} geolocation
+ * @param {boolean} userInputModified
+ */
+ _setGeolocationPosition: function(geolocation, userInputModified)
+ {
+ if (!geolocation)
+ return;
+
+ if (!userInputModified) {
+ this._latitudeElement.value = geolocation.latitude;
+ this._longitudeElement.value = geolocation.longitude;
+ }
+
+ var value = geolocation.toSetting();
+ WebInspector.overridesSupport.settings.geolocationOverride.set(value);
+ },
+
+ /**
+ * @param {!WebInspector.OverridesSupport.GeolocationPosition} geolocation
+ * @return {!Element}
+ */
+ _createGeolocationOverrideElement: function(geolocation)
+ {
+ var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.overridesSupport.settings.overrideGeolocation);
+ fieldsetElement.id = "geolocation-override-section";
+
+ var tableElement = fieldsetElement.createChild("table");
+ var rowElement = tableElement.createChild("tr");
+ var cellElement = rowElement.createChild("td");
+ cellElement = rowElement.createChild("td");
+ cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lat = ")));
+ this._latitudeElement = WebInspector.SettingsUI.createInput(cellElement, "geolocation-override-latitude", String(geolocation.latitude), this._applyGeolocationUserInput.bind(this), true);
+ cellElement.appendChild(document.createTextNode(" , "));
+ cellElement.appendChild(document.createTextNode(WebInspector.UIString("Lon = ")));
+ this._longitudeElement = WebInspector.SettingsUI.createInput(cellElement, "geolocation-override-longitude", String(geolocation.longitude), this._applyGeolocationUserInput.bind(this), true);
+ rowElement = tableElement.createChild("tr");
+ cellElement = rowElement.createChild("td");
+ cellElement.colSpan = 2;
+ var geolocationErrorLabelElement = document.createElement("label");
+ var geolocationErrorCheckboxElement = geolocationErrorLabelElement.createChild("input");
+ geolocationErrorCheckboxElement.id = "geolocation-error";
+ geolocationErrorCheckboxElement.type = "checkbox";
+ geolocationErrorCheckboxElement.checked = !geolocation || geolocation.error;
+ geolocationErrorCheckboxElement.addEventListener("click", this._applyGeolocationUserInput.bind(this), false);
+ geolocationErrorLabelElement.appendChild(document.createTextNode(WebInspector.UIString("Emulate position unavailable")));
+ this._geolocationErrorElement = geolocationErrorCheckboxElement;
+ cellElement.appendChild(geolocationErrorLabelElement);
+
+ return fieldsetElement;
+ },
+
+ _apendDeviceOrientationOverrideControl: function()
+ {
+ const deviceOrientationSetting = WebInspector.overridesSupport.settings.deviceOrientationOverride.get();
+ var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(deviceOrientationSetting);
+ this.element.appendChild(this._createSettingCheckbox(WebInspector.UIString("Accelerometer"), WebInspector.overridesSupport.settings.overrideDeviceOrientation, this._deviceOrientationOverrideCheckboxClicked.bind(this)));
+ this.element.appendChild(this._createDeviceOrientationOverrideElement(deviceOrientation));
+ this._deviceOrientationOverrideCheckboxClicked(WebInspector.overridesSupport.settings.overrideDeviceOrientation.get());
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ _deviceOrientationOverrideCheckboxClicked: function(enabled)
+ {
+ if (enabled && !this._alphaElement.value)
+ this._alphaElement.focus();
+ },
+
+ _applyDeviceOrientationUserInput: function()
+ {
+ this._setDeviceOrientation(WebInspector.OverridesSupport.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(), this._betaElement.value.trim(), this._gammaElement.value.trim()), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput);
+ },
+
+ _resetDeviceOrientation: function()
+ {
+ this._setDeviceOrientation(new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0), WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.ResetButton);
+ },
+
+ /**
+ * @param {?WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
+ * @param {!WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource} modificationSource
+ */
+ _setDeviceOrientation: function(deviceOrientation, modificationSource)
+ {
+ if (!deviceOrientation)
+ return;
+
+ if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserInput) {
+ this._alphaElement.value = deviceOrientation.alpha;
+ this._betaElement.value = deviceOrientation.beta;
+ this._gammaElement.value = deviceOrientation.gamma;
+ }
+
+ if (modificationSource != WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag)
+ this._setBoxOrientation(deviceOrientation);
+
+ var value = deviceOrientation.toSetting();
+ WebInspector.overridesSupport.settings.deviceOrientationOverride.set(value);
+ },
+
+ /**
+ * @param {!Element} parentElement
+ * @param {string} id
+ * @param {string} label
+ * @param {string} defaultText
+ * @return {!Element}
+ */
+ _createAxisInput: function(parentElement, id, label, defaultText)
+ {
+ var div = parentElement.createChild("div", "accelerometer-axis-input-container");
+ div.appendChild(document.createTextNode(label));
+ return WebInspector.SettingsUI.createInput(div, id, defaultText, this._applyDeviceOrientationUserInput.bind(this), true);
+ },
+
+ /**
+ * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
+ */
+ _createDeviceOrientationOverrideElement: function(deviceOrientation)
+ {
+ var fieldsetElement = WebInspector.SettingsUI.createSettingFieldset(WebInspector.overridesSupport.settings.overrideDeviceOrientation);
+ fieldsetElement.id = "device-orientation-override-section";
+ var tableElement = fieldsetElement.createChild("table");
+ var rowElement = tableElement.createChild("tr");
+ var cellElement = rowElement.createChild("td", "accelerometer-inputs-cell");
+
+ this._alphaElement = this._createAxisInput(cellElement, "device-orientation-override-alpha", "\u03B1: ", String(deviceOrientation.alpha));
+ this._betaElement = this._createAxisInput(cellElement, "device-orientation-override-beta", "\u03B2: ", String(deviceOrientation.beta));
+ this._gammaElement = this._createAxisInput(cellElement, "device-orientation-override-gamma", "\u03B3: ", String(deviceOrientation.gamma));
+
+ var resetButton = cellElement.createChild("button", "settings-tab-text-button accelerometer-reset-button");
+ resetButton.textContent = WebInspector.UIString("Reset");
+ resetButton.addEventListener("click", this._resetDeviceOrientation.bind(this), false);
+
+ this._stageElement = rowElement.createChild("td","accelerometer-stage");
+ this._boxElement = this._stageElement.createChild("section", "accelerometer-box");
+
+ this._boxElement.createChild("section", "front");
+ this._boxElement.createChild("section", "top");
+ this._boxElement.createChild("section", "back");
+ this._boxElement.createChild("section", "left");
+ this._boxElement.createChild("section", "right");
+ this._boxElement.createChild("section", "bottom");
+
+ WebInspector.installDragHandle(this._stageElement, this._onBoxDragStart.bind(this), this._onBoxDrag.bind(this), this._onBoxDragEnd.bind(this), "move");
+ this._setBoxOrientation(deviceOrientation);
+ return fieldsetElement;
+ },
+
+ /**
+ * @param {!WebInspector.OverridesSupport.DeviceOrientation} deviceOrientation
+ */
+ _setBoxOrientation: function(deviceOrientation)
+ {
+ var matrix = new WebKitCSSMatrix();
+ this._boxMatrix = matrix.rotate(-deviceOrientation.beta, deviceOrientation.gamma, -deviceOrientation.alpha);
+ this._boxElement.style.webkitTransform = this._boxMatrix.toString();
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ * @return {boolean}
+ */
+ _onBoxDrag: function(event)
+ {
+ var mouseMoveVector = this._calculateRadiusVector(event.x, event.y);
+ if (!mouseMoveVector)
+ return true;
+
+ event.consume(true);
+ var axis = WebInspector.Geometry.crossProduct(this._mouseDownVector, mouseMoveVector);
+ axis.normalize();
+ var angle = WebInspector.Geometry.calculateAngle(this._mouseDownVector, mouseMoveVector);
+ var matrix = new WebKitCSSMatrix();
+ var rotationMatrix = matrix.rotateAxisAngle(axis.x, axis.y, axis.z, angle);
+ this._currentMatrix = rotationMatrix.multiply(this._boxMatrix)
+ this._boxElement.style.webkitTransform = this._currentMatrix;
+ var eulerAngles = WebInspector.Geometry.EulerAngles.fromRotationMatrix(this._currentMatrix);
+ var newOrientation = new WebInspector.OverridesSupport.DeviceOrientation(-eulerAngles.alpha, -eulerAngles.beta, eulerAngles.gamma);
+ this._setDeviceOrientation(newOrientation, WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource.UserDrag);
+ return false;
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ * @return {boolean}
+ */
+ _onBoxDragStart: function(event)
+ {
+ if (!WebInspector.overridesSupport.settings.overrideDeviceOrientation.get())
+ return false;
+
+ this._mouseDownVector = this._calculateRadiusVector(event.x, event.y);
+
+ if (!this._mouseDownVector)
+ return false;
+
+ event.consume(true);
+ return true;
+ },
+
+ _onBoxDragEnd: function()
+ {
+ this._boxMatrix = this._currentMatrix;
+ },
+
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @return {?WebInspector.Geometry.Vector}
+ */
+ _calculateRadiusVector: function(x, y)
+ {
+ var rect = this._stageElement.getBoundingClientRect();
+ var radius = Math.max(rect.width, rect.height) / 2;
+ var sphereX = (x - rect.left - rect.width / 2) / radius;
+ var sphereY = (y - rect.top - rect.height / 2) / radius;
+ var sqrSum = sphereX * sphereX + sphereY * sphereY;
+ if (sqrSum > 0.5)
+ return new WebInspector.Geometry.Vector(sphereX, sphereY, 0.5 / Math.sqrt(sqrSum));
+
+ return new WebInspector.Geometry.Vector(sphereX, sphereY, Math.sqrt(1 - sqrSum));
+ },
+
+ __proto__ : WebInspector.OverridesView.Tab.prototype
+}
+
+/** @enum {string} */
+WebInspector.OverridesView.SensorsTab.DeviceOrientationModificationSource = {
+ UserInput: "userInput",
+ UserDrag: "userDrag",
+ ResetButton: "resetButton"
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.OverridesView.Revealer = function()
+{
+}
+
+WebInspector.OverridesView.Revealer.prototype = {
+ /**
+ * @param {!Object} overridesSupport
+ */
+ reveal: function(overridesSupport)
+ {
+ InspectorFrontendHost.bringToFront();
+ WebInspector.inspectorView.showViewInDrawer("emulation");
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PlatformFontsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/PlatformFontsSidebarPane.js
index 29db225e5b1..e6a9bada6d7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PlatformFontsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/PlatformFontsSidebarPane.js
@@ -36,9 +36,6 @@ WebInspector.PlatformFontsSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Fonts"));
this.element.classList.add("platform-fonts");
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._onNodeChange.bind(this));
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._onNodeChange.bind(this));
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._onNodeChange.bind(this));
this._sectionTitle = document.createElementWithClass("div", "sidebar-separator");
this.element.insertBefore(this._sectionTitle, this.bodyElement);
@@ -64,9 +61,28 @@ WebInspector.PlatformFontsSidebarPane.prototype = {
return;
}
this._node = node;
+ this._updateTarget(node.target());
this._innerUpdate();
},
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ _updateTarget: function(target)
+ {
+ if (this._target === target)
+ return;
+ if (this._target) {
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModified, this._onNodeChange, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._onNodeChange, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
+ }
+ this._target = target;
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._onNodeChange, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._onNodeChange, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.CharacterDataModified, this._onNodeChange, this);
+ },
+
_innerUpdate: function()
{
if (this._innerUpdateTimeout) {
@@ -75,7 +91,7 @@ WebInspector.PlatformFontsSidebarPane.prototype = {
}
if (!this._node)
return;
- WebInspector.cssModel.getPlatformFontsForNode(this._node.id, this._refreshUI.bind(this, this._node));
+ this._target.cssModel.getPlatformFontsForNode(this._node.id, this._refreshUI.bind(this, this._node));
},
/**
@@ -91,7 +107,7 @@ WebInspector.PlatformFontsSidebarPane.prototype = {
this._fontStatsSection.removeChildren();
var isEmptySection = !platformFonts || !platformFonts.length;
- this._sectionTitle.enableStyleClass("hidden", isEmptySection);
+ this._sectionTitle.classList.toggle("hidden", isEmptySection);
if (isEmptySection)
return;
platformFonts.sort(function (a, b) {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/PropertiesSidebarPane.js
index 46005f2fbe8..fce17598304 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PropertiesSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/PropertiesSidebarPane.js
@@ -48,7 +48,7 @@ WebInspector.PropertiesSidebarPane.prototype = {
return;
}
- WebInspector.RemoteObject.resolveNode(node, WebInspector.PropertiesSidebarPane._objectGroupName, nodeResolved.bind(this));
+ node.resolveToObject(WebInspector.PropertiesSidebarPane._objectGroupName, nodeResolved.bind(this));
/**
* @this {WebInspector.PropertiesSidebarPane}
@@ -59,7 +59,8 @@ WebInspector.PropertiesSidebarPane.prototype = {
return;
/**
- * @this {WebInspector.PropertiesSidebarPane}
+ * @suppressReceiverCheck
+ * @this {*}
*/
function protoList()
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RenderingOptionsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/RenderingOptionsView.js
index 2c2a3930121..6f785c34489 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RenderingOptionsView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/RenderingOptionsView.js
@@ -30,24 +30,24 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.RenderingOptionsView = function()
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("helpScreen.css");
this.element.classList.add("help-indent-labels");
- var div = this.element.createChild("div", "settings-tab help-content help-container");
- div.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show paint rectangles"), WebInspector.settings.showPaintRects));
- div.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show composited layer borders"), WebInspector.settings.showDebugBorders));
- div.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show FPS meter"), WebInspector.settings.showFPSCounter));
- div.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Enable continuous page repainting"), WebInspector.settings.continuousPainting));
- var child = WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show potential scroll bottlenecks"), WebInspector.settings.showScrollBottleneckRects);
+ var div = this.element.createChild("div", "settings-tab help-content help-container help-no-columns");
+ div.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show paint rectangles"), WebInspector.settings.showPaintRects));
+ div.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show composited layer borders"), WebInspector.settings.showDebugBorders));
+ div.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show FPS meter"), WebInspector.settings.showFPSCounter));
+ div.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Enable continuous page repainting"), WebInspector.settings.continuousPainting));
+ var child = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Show potential scroll bottlenecks"), WebInspector.settings.showScrollBottleneckRects);
child.title = WebInspector.UIString("Shows areas of the page that slow down scrolling:\nTouch and mousewheel event listeners can delay scrolling.\nSome areas need to repaint their content when scrolled.");
div.appendChild(child);
}
WebInspector.RenderingOptionsView.prototype = {
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Spectrum.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
index 0ed02b44021..8d77ef2bf1a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Spectrum.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/Spectrum.js
@@ -28,14 +28,14 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.Spectrum = function()
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("spectrum.css");
- this.element.className = "spectrum-container";
+ this.element.classList.add("spectrum-container");
this.element.tabIndex = 0;
var topElement = this.element.createChild("div", "spectrum-top");
@@ -56,6 +56,7 @@ WebInspector.Spectrum = function()
this._alphaElement.setAttribute("type", "range");
this._alphaElement.setAttribute("min", "0");
this._alphaElement.setAttribute("max", "100");
+ this._alphaElement.addEventListener("input", alphaDrag.bind(this), false);
this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);
var swatchElement = document.createElement("span");
@@ -130,6 +131,7 @@ WebInspector.Spectrum.Events = {
};
/**
+ * @param {!Element} element
* @param {function(!Element, number, number, !MouseEvent)=} onmove
* @param {function(!Element, !MouseEvent)=} onstart
* @param {function(!Element, !MouseEvent)=} onstop
@@ -296,8 +298,8 @@ WebInspector.Spectrum.prototype = {
{
this._updateHelperLocations();
- this._draggerElement.style.backgroundColor = WebInspector.Color.fromHSVA([this._hsv[0], 1, 1, 1]).toString(WebInspector.Color.Format.RGB);
- this._swatchInnerElement.style.backgroundColor = this.color().toString(WebInspector.Color.Format.RGBA);
+ this._draggerElement.style.backgroundColor = /** @type {string} */ (WebInspector.Color.fromHSVA([this._hsv[0], 1, 1, 1]).toString(WebInspector.Color.Format.RGB));
+ this._swatchInnerElement.style.backgroundColor = /** @type {string} */ (this.color().toString(WebInspector.Color.Format.RGBA));
this._alphaElement.value = this._hsv[3] * 100;
},
@@ -312,7 +314,7 @@ WebInspector.Spectrum.prototype = {
this._updateUI();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
@@ -344,6 +346,9 @@ WebInspector.SpectrumPopupHelper.prototype = {
return this._spectrum;
},
+ /**
+ * @return {boolean}
+ */
toggle: function(element, color, format)
{
if (this._popover.isShowing())
@@ -354,6 +359,9 @@ WebInspector.SpectrumPopupHelper.prototype = {
return this._popover.isShowing();
},
+ /**
+ * @return {boolean}
+ */
show: function(element, color, format)
{
if (this._popover.isShowing()) {
@@ -421,12 +429,14 @@ WebInspector.SpectrumPopupHelper.prototype = {
/**
* @constructor
+ * @param {boolean=} readOnly
*/
-WebInspector.ColorSwatch = function()
+WebInspector.ColorSwatch = function(readOnly)
{
this.element = document.createElement("span");
this._swatchInnerElement = this.element.createChild("span", "swatch-inner");
- this.element.title = WebInspector.UIString("Click to open a colorpicker. Shift-click to change color format");
+ var shiftClickMessage = WebInspector.UIString("Shift-click to change color format.");
+ this.element.title = readOnly ? shiftClickMessage : String.sprintf("%s\n%s", WebInspector.UIString("Click to open a colorpicker."), shiftClickMessage);
this.element.className = "swatch";
this.element.addEventListener("mousedown", consumeEvent, false);
this.element.addEventListener("dblclick", consumeEvent, false);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/StylesSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 3a2018b4b9c..51f5ddaf6ab 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/StylesSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -31,44 +31,12 @@
* @constructor
* @extends {WebInspector.SidebarPane}
* @param {!WebInspector.ComputedStyleSidebarPane} computedStylePane
- * @param {function(!DOMAgent.NodeId, string, boolean)} setPseudoClassCallback
+ * @param {function(!WebInspector.DOMNode, string, boolean)=} setPseudoClassCallback
*/
WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallback)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Styles"));
- this.settingsSelectElement = document.createElement("select");
- this.settingsSelectElement.className = "select-settings";
-
- var option = document.createElement("option");
- option.value = WebInspector.Color.Format.Original;
- option.label = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "As authored" : "As Authored");
- this.settingsSelectElement.appendChild(option);
-
- option = document.createElement("option");
- option.value = WebInspector.Color.Format.HEX;
- option.label = WebInspector.UIString("Hex Colors");
- this.settingsSelectElement.appendChild(option);
-
- option = document.createElement("option");
- option.value = WebInspector.Color.Format.RGB;
- option.label = WebInspector.UIString("RGB Colors");
- this.settingsSelectElement.appendChild(option);
-
- option = document.createElement("option");
- option.value = WebInspector.Color.Format.HSL;
- option.label = WebInspector.UIString("HSL Colors");
- this.settingsSelectElement.appendChild(option);
-
- // Prevent section from collapsing.
- var muteEventListener = function(event) { event.consume(true); };
-
- this.settingsSelectElement.addEventListener("click", muteEventListener, true);
- this.settingsSelectElement.addEventListener("change", this._changeSetting.bind(this), false);
- this._updateColorFormatFilter();
-
- this.titleElement.appendChild(this.settingsSelectElement);
-
this._elementStateButton = document.createElement("button");
this._elementStateButton.className = "pane-title-button element-state";
this._elementStateButton.title = WebInspector.UIString("Toggle Element State");
@@ -83,10 +51,11 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb
this.titleElement.appendChild(addButton);
this._computedStylePane = computedStylePane;
- computedStylePane._stylesSidebarPane = this;
+ computedStylePane.setHostingPane(this);
this._setPseudoClassCallback = setPseudoClassCallback;
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
WebInspector.settings.colorFormat.addChangeListener(this._colorFormatSettingChanged.bind(this));
+ WebInspector.settings.showUserAgentStyles.addChangeListener(this._showUserAgentStylesSettingChanged.bind(this));
this._createElementStatePane();
this.bodyElement.appendChild(this._elementStatePane);
@@ -96,16 +65,8 @@ WebInspector.StylesSidebarPane = function(computedStylePane, setPseudoClassCallb
this._spectrumHelper = new WebInspector.SpectrumPopupHelper();
this._linkifier = new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultCSSFormatter());
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributeChanged, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributeChanged, this);
- WebInspector.settings.showUserAgentStyles.addChangeListener(this._showUserAgentStylesSettingChanged.bind(this));
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
this.element.classList.add("styles-pane");
- this.element.enableStyleClass("show-user-styles", WebInspector.settings.showUserAgentStyles.get());
+ this.element.classList.toggle("show-user-styles", WebInspector.settings.showUserAgentStyles.get());
this.element.addEventListener("mousemove", this._mouseMovedOverElement.bind(this), false);
document.body.addEventListener("keydown", this._keyDown.bind(this), false);
document.body.addEventListener("keyup", this._keyUp.bind(this), false);
@@ -122,8 +83,7 @@ WebInspector.StylesSidebarPane.PseudoIdNames = [
"-webkit-media-controls-play-button", "-webkit-media-controls-mute-button", "-webkit-media-controls-timeline",
"-webkit-media-controls-timeline-container", "-webkit-media-controls-volume-slider",
"-webkit-media-controls-volume-slider-container", "-webkit-media-controls-current-time-display",
- "-webkit-media-controls-time-remaining-display", "-webkit-media-controls-seek-back-button", "-webkit-media-controls-seek-forward-button",
- "-webkit-media-controls-fullscreen-button", "-webkit-media-controls-rewind-button", "-webkit-media-controls-return-to-realtime-button",
+ "-webkit-media-controls-time-remaining-display", "-webkit-media-controls-fullscreen-button",
"-webkit-media-controls-toggle-closed-captions-button", "-webkit-media-controls-status-display", "-webkit-scrollbar-thumb",
"-webkit-scrollbar-button", "-webkit-scrollbar-track", "-webkit-scrollbar-track-piece", "-webkit-scrollbar-corner",
"-webkit-resizer", "-webkit-inner-spin-button", "-webkit-outer-spin-button"
@@ -133,6 +93,7 @@ WebInspector.StylesSidebarPane._colorRegex = /((?:rgb|hsl)a?\([^)]+\)|#[0-9a-fA-
/**
* @param {!WebInspector.CSSProperty} property
+ * @return {!Element}
*/
WebInspector.StylesSidebarPane.createExclamationMark = function(property)
{
@@ -202,6 +163,18 @@ WebInspector.StylesSidebarPane._ignoreErrorsForProperty = function(property) {
WebInspector.StylesSidebarPane.prototype = {
/**
+ * @param {!WebInspector.CSSRule} editedRule
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ _styleSheetRuleEdited: function(editedRule, oldRange, newRange)
+ {
+ var styleRuleSections = this.sections[0];
+ for (var i = 1; i < styleRuleSections.length; ++i)
+ styleRuleSections[i]._styleSheetRuleEdited(editedRule, oldRange, newRange);
+ },
+
+ /**
* @param {?Event} event
*/
_contextMenuEventFired: function(event)
@@ -213,19 +186,48 @@ WebInspector.StylesSidebarPane.prototype = {
contextMenu.show();
},
+ /**
+ * @param {!Element} matchedStylesElement
+ * @param {!Element} computedStylesElement
+ */
+ setFilterBoxContainers: function(matchedStylesElement, computedStylesElement)
+ {
+ matchedStylesElement.appendChild(this._createCSSFilterControl());
+ this._computedStylePane.setFilterBoxContainer(computedStylesElement);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ _createCSSFilterControl: function()
+ {
+ var filterInput = this._createPropertyFilterElement(false, searchHandler.bind(this));
+
+ /**
+ * @param {?RegExp} regex
+ * @this {WebInspector.StylesSidebarPane}
+ */
+ function searchHandler(regex)
+ {
+ this._filterRegex = regex;
+ }
+
+ return filterInput;
+ },
+
get _forcedPseudoClasses()
{
- return this.node ? (this.node.getUserProperty("pseudoState") || undefined) : undefined;
+ return this._node ? (this._node.getUserProperty(WebInspector.CSSStyleModel.PseudoStatePropertyName) || undefined) : undefined;
},
_updateForcedPseudoStateInputs: function()
{
- if (!this.node)
+ if (!this._node)
return;
- var hasPseudoType = !!this.node.pseudoType();
- this._elementStateButton.enableStyleClass("hidden", hasPseudoType);
- this._elementStatePane.enableStyleClass("expanded", !hasPseudoType && this._elementStateButton.classList.contains("toggled"));
+ var hasPseudoType = !!this._node.pseudoType();
+ this._elementStateButton.classList.toggle("hidden", hasPseudoType);
+ this._elementStatePane.classList.toggle("expanded", !hasPseudoType && this._elementStateButton.classList.contains("toggled"));
var nodePseudoState = this._forcedPseudoClasses;
if (!nodePseudoState)
@@ -248,9 +250,9 @@ WebInspector.StylesSidebarPane.prototype = {
var refresh = false;
if (forceUpdate)
- delete this.node;
+ delete this._node;
- if (!forceUpdate && (node === this.node))
+ if (!forceUpdate && (node === this._node))
refresh = true;
if (node && node.nodeType() === Node.TEXT_NODE && node.parentNode)
@@ -259,10 +261,11 @@ WebInspector.StylesSidebarPane.prototype = {
if (node && node.nodeType() !== Node.ELEMENT_NODE)
node = null;
- if (node)
- this.node = node;
- else
- node = this.node;
+ if (node) {
+ this._updateTarget(node.target());
+ this._node = node;
+ } else
+ node = this._node;
this._updateForcedPseudoStateInputs();
@@ -273,14 +276,48 @@ WebInspector.StylesSidebarPane.prototype = {
},
/**
+ * @param {!WebInspector.Target} target
+ */
+ _updateTarget: function(target)
+ {
+ if (this._target === target)
+ return;
+ if (this._target) {
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributeChanged, this);
+ this._target.domModel.removeEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributeChanged, this);
+ this._target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
+ }
+ this._target = target;
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged, this._styleSheetOrMediaQueryResultChanged, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrModified, this._attributeChanged, this);
+ this._target.domModel.addEventListener(WebInspector.DOMModel.Events.AttrRemoved, this._attributeChanged, this);
+ this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameResized, this._frameResized, this);
+ },
+
+ /**
* @param {!WebInspector.StylePropertiesSection=} editedSection
* @param {boolean=} forceFetchComputedStyle
* @param {function()=} userCallback
*/
_refreshUpdate: function(editedSection, forceFetchComputedStyle, userCallback)
{
+ var callbackWrapper = function()
+ {
+ if (this._filterRegex)
+ this._updateFilter(false);
+ if (userCallback)
+ userCallback();
+ }.bind(this);
+
if (this._refreshUpdateInProgress) {
- this._lastNodeForInnerRefresh = this.node;
+ this._lastNodeForInnerRefresh = this._node;
return;
}
@@ -298,31 +335,29 @@ WebInspector.StylesSidebarPane.prototype = {
if (this._lastNodeForInnerRefresh) {
delete this._lastNodeForInnerRefresh;
- this._refreshUpdate(editedSection, forceFetchComputedStyle, userCallback);
+ this._refreshUpdate(editedSection, forceFetchComputedStyle, callbackWrapper);
return;
}
- if (this.node === node && computedStyle)
+ if (this._node === node && computedStyle)
this._innerRefreshUpdate(node, computedStyle, editedSection);
- if (userCallback)
- userCallback();
+ callbackWrapper();
}
if (this._computedStylePane.isShowing() || forceFetchComputedStyle) {
this._refreshUpdateInProgress = true;
- WebInspector.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
+ this._target.cssModel.getComputedStyleAsync(node.id, computedStyleCallback.bind(this));
} else {
this._innerRefreshUpdate(node, null, editedSection);
- if (userCallback)
- userCallback();
+ callbackWrapper();
}
},
_rebuildUpdate: function()
{
if (this._rebuildUpdateInProgress) {
- this._lastNodeForInnerRebuild = this.node;
+ this._lastNodeForInnerRebuild = this._node;
return;
}
@@ -345,13 +380,13 @@ WebInspector.StylesSidebarPane.prototype = {
var lastNodeForRebuild = this._lastNodeForInnerRebuild;
if (lastNodeForRebuild) {
delete this._lastNodeForInnerRebuild;
- if (lastNodeForRebuild !== this.node) {
+ if (lastNodeForRebuild !== this._node) {
this._rebuildUpdate();
return;
}
}
- if (matchedResult && this.node === node) {
+ if (matchedResult && this._node === node) {
resultStyles.matchedCSSRules = matchedResult.matchedCSSRules;
resultStyles.pseudoElements = matchedResult.pseudoElements;
resultStyles.inherited = matchedResult.inherited;
@@ -384,9 +419,9 @@ WebInspector.StylesSidebarPane.prototype = {
}
if (this._computedStylePane.isShowing())
- WebInspector.cssModel.getComputedStyleAsync(node.id, computedCallback.bind(this));
- WebInspector.cssModel.getInlineStylesAsync(node.id, inlineCallback.bind(this));
- WebInspector.cssModel.getMatchedStylesAsync(node.id, true, true, stylesCallback.bind(this));
+ this._target.cssModel.getComputedStyleAsync(node.id, computedCallback);
+ this._target.cssModel.getInlineStylesAsync(node.id, inlineCallback);
+ this._target.cssModel.getMatchedStylesAsync(node.id, true, true, stylesCallback.bind(this));
},
/**
@@ -394,7 +429,7 @@ WebInspector.StylesSidebarPane.prototype = {
*/
_validateNode: function(userCallback)
{
- if (!this.node) {
+ if (!this._node) {
this._sectionsContainer.removeChildren();
this._computedStylePane.bodyElement.removeChildren();
this.sections = {};
@@ -402,7 +437,7 @@ WebInspector.StylesSidebarPane.prototype = {
userCallback();
return null;
}
- return this.node;
+ return this._node;
},
_styleSheetOrMediaQueryResultChanged: function()
@@ -420,7 +455,7 @@ WebInspector.StylesSidebarPane.prototype = {
*/
function refreshContents()
{
- this._rebuildUpdate();
+ this._styleSheetOrMediaQueryResultChanged();
delete this._activeTimer;
}
@@ -445,7 +480,7 @@ WebInspector.StylesSidebarPane.prototype = {
_canAffectCurrentStyles: function(node)
{
- return this.node && (this.node === node || node.parentNode === this.node.parentNode || node.isAncestor(this.node));
+ return this._node && (this._node === node || node.parentNode === this._node.parentNode || node.isAncestor(this._node));
},
_innerRefreshUpdate: function(node, computedStyle, editedSection)
@@ -489,13 +524,15 @@ WebInspector.StylesSidebarPane.prototype = {
// Add rules in reverse order to match the cascade order.
for (var j = pseudoElementCSSRules.rules.length - 1; j >= 0; --j) {
var rule = pseudoElementCSSRules.rules[j];
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.id) });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
}
usedProperties = {};
this._markUsedProperties(styleRules, usedProperties);
this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, anchorElement);
}
+ if (this._filterRegex)
+ this._updateFilter(false);
this._nodeStylesUpdatedForTest(node, true);
},
@@ -514,7 +551,7 @@ WebInspector.StylesSidebarPane.prototype = {
continue;
if (section.computedStyle)
section.styleRule.style = nodeComputedStyle;
- var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule, editable: !!(section.styleRule.style && section.styleRule.style.id),
+ var styleRule = { section: section, style: section.styleRule.style, computedStyle: section.computedStyle, rule: section.rule, editable: !!(section.styleRule.style && section.styleRule.style.styleSheetId),
isAttribute: section.styleRule.isAttribute, isInherited: section.styleRule.isInherited, parentNode: section.styleRule.parentNode };
styleRules.push(styleRule);
}
@@ -557,7 +594,7 @@ WebInspector.StylesSidebarPane.prototype = {
addedAttributesStyle = true;
addAttributesStyle();
}
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.id) });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, editable: !!(rule.style && rule.style.styleSheetId) });
}
if (!addedAttributesStyle)
@@ -597,7 +634,7 @@ WebInspector.StylesSidebarPane.prototype = {
insertInheritedNodeSeparator(parentNode);
separatorInserted = true;
}
- styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, isInherited: true, parentNode: parentNode, editable: !!(rule.style && rule.style.id) });
+ styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.resourceURL(), rule: rule, isInherited: true, parentNode: parentNode, editable: !!(rule.style && rule.style.styleSheetId) });
}
parentNode = parentNode.parentNode;
}
@@ -633,15 +670,14 @@ WebInspector.StylesSidebarPane.prototype = {
if (foundImportantProperties.hasOwnProperty(canonicalName))
continue;
- var isImportant = property.priority.length;
- if (!isImportant && usedProperties.hasOwnProperty(canonicalName))
+ if (!property.important && usedProperties.hasOwnProperty(canonicalName))
continue;
var isKnownProperty = propertyToEffectiveRule.hasOwnProperty(canonicalName);
if (!isKnownProperty && styleRule.isInherited && !inheritedPropertyToNode[canonicalName])
inheritedPropertyToNode[canonicalName] = styleRule.parentNode;
- if (isImportant) {
+ if (property.important) {
if (styleRule.isInherited && isKnownProperty && styleRule.parentNode !== inheritedPropertyToNode[canonicalName])
continue;
@@ -747,7 +783,6 @@ WebInspector.StylesSidebarPane.prototype = {
_colorFormatSettingChanged: function(event)
{
- this._updateColorFormatFilter();
for (var pseudoId in this.sections) {
var sections = this.sections[pseudoId];
for (var i = 0; i < sections.length; ++i)
@@ -755,28 +790,6 @@ WebInspector.StylesSidebarPane.prototype = {
}
},
- _updateColorFormatFilter: function()
- {
- // Select the correct color format setting again, since it needs to be selected.
- var selectedIndex = 0;
- var value = WebInspector.settings.colorFormat.get();
- var options = this.settingsSelectElement.options;
- for (var i = 0; i < options.length; ++i) {
- if (options[i].value === value) {
- selectedIndex = i;
- break;
- }
- }
- this.settingsSelectElement.selectedIndex = selectedIndex;
- },
-
- _changeSetting: function(event)
- {
- var options = this.settingsSelectElement.options;
- var selectedOption = options[this.settingsSelectElement.selectedIndex];
- WebInspector.settings.colorFormat.set(selectedOption.value);
- },
-
_createNewRule: function(event)
{
event.consume();
@@ -784,9 +797,12 @@ WebInspector.StylesSidebarPane.prototype = {
this.addBlankSection().startEditingSelector();
},
+ /**
+ * @return {!WebInspector.BlankStylePropertiesSection}
+ */
addBlankSection: function()
{
- var blankSection = new WebInspector.BlankStylePropertiesSection(this, this.node ? WebInspector.DOMPresentationUtils.appropriateSelectorFor(this.node, true) : "");
+ var blankSection = new WebInspector.BlankStylePropertiesSection(this, this._node ? WebInspector.DOMPresentationUtils.simpleSelector(this._node) : "");
var elementStyleSection = this.sections[0][1];
this._sectionsContainer.insertBefore(blankSection.element, elementStyleSection.element.nextSibling);
@@ -815,8 +831,8 @@ WebInspector.StylesSidebarPane.prototype = {
var buttonToggled = !this._elementStateButton.classList.contains("toggled");
if (buttonToggled)
this.expand();
- this._elementStateButton.enableStyleClass("toggled", buttonToggled);
- this._elementStatePane.enableStyleClass("expanded", buttonToggled);
+ this._elementStateButton.classList.toggle("toggled", buttonToggled);
+ this._elementStatePane.classList.toggle("expanded", buttonToggled);
},
_createElementStatePane: function()
@@ -837,7 +853,7 @@ WebInspector.StylesSidebarPane.prototype = {
var node = this._validateNode();
if (!node)
return;
- this._setPseudoClassCallback(node.id, event.target.state, event.target.checked);
+ this._setPseudoClassCallback(node, event.target.state, event.target.checked);
}
/**
@@ -860,26 +876,89 @@ WebInspector.StylesSidebarPane.prototype = {
return td;
}
- var tr = document.createElement("tr");
+ var tr = table.createChild("tr");
tr.appendChild(createCheckbox.call(this, "active"));
tr.appendChild(createCheckbox.call(this, "hover"));
- table.appendChild(tr);
- tr = document.createElement("tr");
+ tr = table.createChild("tr");
tr.appendChild(createCheckbox.call(this, "focus"));
tr.appendChild(createCheckbox.call(this, "visited"));
- table.appendChild(tr);
this._elementStatePane.appendChild(table);
},
/**
+ * @return {?RegExp}
+ */
+ filterRegex: function()
+ {
+ return this._filterRegex;
+ },
+
+ /**
+ * @param {boolean} isComputedStyleFilter
+ * @return {!Element}
+ * @param {function(?RegExp)} filterCallback
+ */
+ _createPropertyFilterElement: function(isComputedStyleFilter, filterCallback)
+ {
+ var input = document.createElement("input");
+ input.type = "text";
+ input.placeholder = isComputedStyleFilter ? WebInspector.UIString("Filter") : WebInspector.UIString("Find in Styles");
+ var boundSearchHandler = searchHandler.bind(this);
+
+ /**
+ * @this {WebInspector.StylesSidebarPane}
+ */
+ function searchHandler()
+ {
+ var regex = input.value ? new RegExp(input.value.escapeForRegExp(), "i") : null;
+ filterCallback(regex);
+ input.parentNode.classList.toggle("styles-filter-engaged", !!input.value);
+ this._updateFilter(isComputedStyleFilter);
+ }
+ input.addEventListener("input", boundSearchHandler, false);
+
+ /**
+ * @param {?Event} event
+ */
+ function keydownHandler(event)
+ {
+ var Esc = "U+001B";
+ if (event.keyIdentifier !== Esc || !input.value)
+ return;
+ event.consume(true);
+ input.value = "";
+ boundSearchHandler();
+ }
+ input.addEventListener("keydown", keydownHandler, false);
+
+ return input;
+ },
+
+ /**
+ * @param {boolean} isComputedStyleFilter
+ */
+ _updateFilter: function(isComputedStyleFilter)
+ {
+ for (var pseudoId in this.sections) {
+ var sections = this.sections[pseudoId];
+ for (var i = 0; i < sections.length; ++i) {
+ var section = sections[i];
+ if (isComputedStyleFilter !== !!section.computedStyle)
+ continue;
+ section._updateFilter();
+ }
+ }
+ },
+
+ /**
* @param {!WebInspector.Event} event
*/
_showUserAgentStylesSettingChanged: function(event)
{
var showStyles = /** @type {boolean} */ (event.data);
- this.element.enableStyleClass("show-user-styles", showStyles);
+ this.element.classList.toggle("show-user-styles", showStyles);
},
willHide: function()
@@ -931,31 +1010,31 @@ WebInspector.StylesSidebarPane.prototype = {
WebInspector.ComputedStyleSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Computed Style"));
- var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited"), "sidebar-pane-subtitle");
- this.titleElement.appendChild(showInheritedCheckbox.element);
- this._hasFreshContent = false;
-
- if (WebInspector.settings.showInheritedComputedStyleProperties.get()) {
- this.bodyElement.classList.add("show-inherited");
- showInheritedCheckbox.checked = true;
- }
+}
+WebInspector.ComputedStyleSidebarPane.prototype = {
/**
- * @this {WebInspector.ComputedStyleSidebarPane}
+ * @param {!WebInspector.StylesSidebarPane} pane
*/
- function showInheritedToggleFunction()
+ setHostingPane: function(pane)
{
- WebInspector.settings.showInheritedComputedStyleProperties.set(showInheritedCheckbox.checked);
- if (WebInspector.settings.showInheritedComputedStyleProperties.get())
- this.bodyElement.classList.add("show-inherited");
- else
- this.bodyElement.classList.remove("show-inherited");
- }
+ this._stylesSidebarPane = pane;
+ },
- showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
-}
+ setFilterBoxContainer: function(element)
+ {
+ element.appendChild(this._stylesSidebarPane._createPropertyFilterElement(true, filterCallback.bind(this)));
+
+ /**
+ * @param {?RegExp} regex
+ * @this {WebInspector.ComputedStyleSidebarPane}
+ */
+ function filterCallback(regex)
+ {
+ this._filterRegex = regex;
+ }
+ },
-WebInspector.ComputedStyleSidebarPane.prototype = {
wasShown: function()
{
WebInspector.SidebarPane.prototype.wasShown.call(this);
@@ -980,6 +1059,14 @@ WebInspector.ComputedStyleSidebarPane.prototype = {
this._stylesSidebarPane._refreshUpdate(null, true, wrappedCallback.bind(this));
},
+ /**
+ * @return {?RegExp}
+ */
+ filterRegex: function()
+ {
+ return this._filterRegex;
+ },
+
__proto__: WebInspector.SidebarPane.prototype
}
@@ -1006,56 +1093,6 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
// We don't really use properties' disclosure.
this.propertiesElement.classList.remove("properties-tree");
- if (styleRule.media) {
- for (var i = styleRule.media.length - 1; i >= 0; --i) {
- var media = styleRule.media[i];
- var mediaDataElement = this.titleElement.createChild("div", "media");
- var mediaText;
- switch (media.source) {
- case WebInspector.CSSMedia.Source.LINKED_SHEET:
- case WebInspector.CSSMedia.Source.INLINE_SHEET:
- mediaText = "media=\"" + media.text + "\"";
- break;
- case WebInspector.CSSMedia.Source.MEDIA_RULE:
- mediaText = "@media " + media.text;
- break;
- case WebInspector.CSSMedia.Source.IMPORT_RULE:
- mediaText = "@import " + media.text;
- break;
- }
-
- if (media.sourceURL) {
- var refElement = mediaDataElement.createChild("div", "subtitle");
- var rawLocation;
- var mediaHeader;
- if (media.range) {
- mediaHeader = media.header();
- if (mediaHeader) {
- var lineNumber = media.lineNumberInSource();
- var columnNumber = media.columnNumberInSource();
- console.assert(typeof lineNumber !== "undefined" && typeof columnNumber !== "undefined");
- rawLocation = new WebInspector.CSSLocation(media.sourceURL, lineNumber, columnNumber);
- }
- }
-
- var anchor;
- if (rawLocation)
- anchor = this._parentPane._linkifier.linkifyCSSLocation(mediaHeader.id, rawLocation);
- else {
- // The "linkedStylesheet" case.
- anchor = WebInspector.linkifyResourceAsNode(media.sourceURL, undefined, "subtitle", media.sourceURL);
- }
- anchor.preferredPanel = "sources";
- anchor.style.float = "right";
- refElement.appendChild(anchor);
- }
-
- var mediaTextElement = mediaDataElement.createChild("span");
- mediaTextElement.textContent = mediaText;
- mediaTextElement.title = media.text;
- }
- }
-
var selectorContainer = document.createElement("div");
this._selectorElement = document.createElement("span");
this._selectorElement.textContent = styleRule.selectorText;
@@ -1081,7 +1118,7 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
this.editable = false;
else {
// Check this is a real CSSRule, not a bogus object coming from WebInspector.BlankStylePropertiesSection.
- if (this.rule.id)
+ if (this.rule.styleSheetId)
this.navigable = !!this.rule.resourceURL();
}
this.titleElement.classList.add("styles-selector");
@@ -1091,13 +1128,15 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
this._selectorRefElement = document.createElement("div");
this._selectorRefElement.className = "subtitle";
+ this._mediaListElement = this.titleElement.createChild("div", "media-list");
+ this._updateMediaList();
this._updateRuleOrigin();
selectorContainer.insertBefore(this._selectorRefElement, selectorContainer.firstChild);
this.titleElement.appendChild(selectorContainer);
this._selectorContainer = selectorContainer;
if (isInherited)
- this.element.classList.add("show-inherited"); // This one is related to inherited rules, not computed style.
+ this.element.classList.add("styles-show-inherited"); // This one is related to inherited rules, not computed style.
if (this.navigable)
this.element.classList.add("navigable");
@@ -1107,9 +1146,80 @@ WebInspector.StylePropertiesSection = function(parentPane, styleRule, editable,
}
WebInspector.StylePropertiesSection.prototype = {
- get pane()
+ /**
+ * @param {!WebInspector.CSSRule} editedRule
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ _styleSheetRuleEdited: function(editedRule, oldRange, newRange)
{
- return this._parentPane;
+ if (!this.rule || !this.rule.styleSheetId)
+ return;
+ if (this.rule !== editedRule)
+ this.rule.sourceStyleSheetEdited(editedRule.styleSheetId, oldRange, newRange);
+ this._updateMediaList();
+ this._updateRuleOrigin();
+ },
+
+ /**
+ * @param {!Object} styleRule
+ */
+ _createMediaList: function(styleRule)
+ {
+ if (!styleRule.media)
+ return;
+ for (var i = styleRule.media.length - 1; i >= 0; --i) {
+ var media = styleRule.media[i];
+ var mediaDataElement = this._mediaListElement.createChild("div", "media");
+ var mediaText;
+ switch (media.source) {
+ case WebInspector.CSSMedia.Source.LINKED_SHEET:
+ case WebInspector.CSSMedia.Source.INLINE_SHEET:
+ mediaText = "media=\"" + media.text + "\"";
+ break;
+ case WebInspector.CSSMedia.Source.MEDIA_RULE:
+ mediaText = "@media " + media.text;
+ break;
+ case WebInspector.CSSMedia.Source.IMPORT_RULE:
+ mediaText = "@import " + media.text;
+ break;
+ }
+
+ if (media.sourceURL) {
+ var refElement = mediaDataElement.createChild("div", "subtitle");
+ var rawLocation;
+ var mediaHeader;
+ if (media.range) {
+ mediaHeader = media.header();
+ if (mediaHeader) {
+ var lineNumber = media.lineNumberInSource();
+ var columnNumber = media.columnNumberInSource();
+ console.assert(typeof lineNumber !== "undefined" && typeof columnNumber !== "undefined");
+ rawLocation = new WebInspector.CSSLocation(this._parentPane._target, media.sourceURL, lineNumber, columnNumber);
+ }
+ }
+
+ var anchor;
+ if (rawLocation)
+ anchor = this._parentPane._linkifier.linkifyCSSLocation(mediaHeader.id, rawLocation);
+ else {
+ // The "linkedStylesheet" case.
+ anchor = WebInspector.linkifyResourceAsNode(media.sourceURL, undefined, "subtitle", media.sourceURL);
+ }
+ anchor.style.float = "right";
+ refElement.appendChild(anchor);
+ }
+
+ var mediaTextElement = mediaDataElement.createChild("span");
+ mediaTextElement.textContent = mediaText;
+ mediaTextElement.title = media.text;
+ }
+ },
+
+ _updateMediaList: function()
+ {
+ this._mediaListElement.removeChildren();
+ this._createMediaList(this.styleRule);
},
collapse: function()
@@ -1117,6 +1227,15 @@ WebInspector.StylePropertiesSection.prototype = {
// Overriding with empty body.
},
+ handleClick: function()
+ {
+ // Avoid consuming events.
+ },
+
+ /**
+ * @param {string} propertyName
+ * @return {boolean}
+ */
isPropertyInherited: function(propertyName)
{
if (this.isInherited) {
@@ -1130,6 +1249,7 @@ WebInspector.StylePropertiesSection.prototype = {
/**
* @param {string} propertyName
* @param {boolean=} isShorthand
+ * @return {boolean}
*/
isPropertyOverloaded: function(propertyName, isShorthand)
{
@@ -1158,6 +1278,9 @@ WebInspector.StylePropertiesSection.prototype = {
return true;
},
+ /**
+ * @return {?WebInspector.StylePropertiesSection}
+ */
nextEditableSibling: function()
{
var curSection = this;
@@ -1174,6 +1297,9 @@ WebInspector.StylePropertiesSection.prototype = {
return (curSection && curSection.editable) ? curSection : null;
},
+ /**
+ * @return {?WebInspector.StylePropertiesSection}
+ */
previousEditableSibling: function()
{
var curSection = this;
@@ -1265,7 +1391,7 @@ WebInspector.StylePropertiesSection.prototype = {
}
// Generate synthetic shorthand we have a value for.
- var shorthandProperty = new WebInspector.CSSProperty(style, style.allProperties.length, shorthand, style.shorthandValue(shorthand), "", "style", true, true);
+ var shorthandProperty = new WebInspector.CSSProperty(style, style.allProperties.length, shorthand, style.shorthandValue(shorthand), false, false, true, true);
var overloaded = property.inactive || this.isPropertyOverloaded(property.name, true);
var item = new WebInspector.StylePropertyTreeElement(this._parentPane, this.styleRule, style, shorthandProperty, /* isShorthand */ true, /* inherited */ false, overloaded);
this.propertiesTreeOutline.appendChild(item);
@@ -1282,6 +1408,24 @@ WebInspector.StylePropertiesSection.prototype = {
}
},
+ _updateFilter: function()
+ {
+ if (this.styleRule.isAttribute)
+ return;
+ var regex = this._parentPane.filterRegex();
+ var hideRule = regex && !regex.test(this.element.textContent);
+ this.element.classList.toggle("hidden", hideRule);
+ if (hideRule)
+ return;
+
+ var children = this.propertiesTreeOutline.children;
+ for (var i = 0; i < children.length; ++i)
+ children[i]._updateFilter();
+
+ if (this.styleRule.rule)
+ this._markSelectorHighlights();
+ },
+
_markSelectorMatches: function()
{
var rule = this.styleRule.rule;
@@ -1304,11 +1448,11 @@ WebInspector.StylePropertiesSection.prototype = {
var isSelectorMatching = matchingSelectors[currentMatch] === i;
if (isSelectorMatching)
++currentMatch;
- var rawLocation = new WebInspector.CSSLocation(rule.sourceURL, rule.lineNumberInSource(i), rule.columnNumberInSource(i));
+ var rawLocation = new WebInspector.CSSLocation(this._parentPane._target, rule.sourceURL, rule.lineNumberInSource(i), rule.columnNumberInSource(i));
var matchingSelectorClass = isSelectorMatching ? " selector-matches" : "";
var selectorElement = document.createElement("span");
selectorElement.className = "simple-selector" + matchingSelectorClass;
- if (rule.id)
+ if (rule.styleSheetId)
selectorElement._selectorIndex = i;
selectorElement.textContent = selectors[i].value;
@@ -1317,6 +1461,17 @@ WebInspector.StylePropertiesSection.prototype = {
this._selectorElement.removeChildren();
this._selectorElement.appendChild(fragment);
+ this._markSelectorHighlights();
+ },
+
+ _markSelectorHighlights: function()
+ {
+ var selectors = this._selectorElement.getElementsByClassName("simple-selector");
+ var regex = this._parentPane.filterRegex();
+ for (var i = 0; i < selectors.length; ++i) {
+ var selectorMatchesFilter = regex && regex.test(selectors[i].textContent);
+ selectors[i].classList.toggle("filter-match", selectorMatchesFilter);
+ }
},
_checkWillCancelEditing: function()
@@ -1336,6 +1491,7 @@ WebInspector.StylePropertiesSection.prototype = {
/**
* @param {number=} index
+ * @return {!WebInspector.StylePropertyTreeElement}
*/
addNewBlankProperty: function(index)
{
@@ -1359,7 +1515,6 @@ WebInspector.StylePropertiesSection.prototype = {
function linkifyUncopyable(url, line)
{
var link = WebInspector.linkifyResourceAsNode(url, line, "", url + ":" + (line + 1));
- link.preferredPanel = "sources";
link.classList.add("webkit-html-resource-link");
link.setAttribute("data-uncopyable", link.textContent);
link.textContent = "";
@@ -1368,8 +1523,8 @@ WebInspector.StylePropertiesSection.prototype = {
if (this.styleRule.sourceURL) {
var firstMatchingIndex = this.styleRule.rule.matchingSelectors && this.rule.matchingSelectors.length ? this.rule.matchingSelectors[0] : 0;
- var matchingSelectorLocation = new WebInspector.CSSLocation(this.styleRule.sourceURL, this.rule.lineNumberInSource(firstMatchingIndex), this.rule.columnNumberInSource(firstMatchingIndex));
- return this._parentPane._linkifier.linkifyCSSLocation(this.rule.id.styleSheetId, matchingSelectorLocation) || linkifyUncopyable(this.styleRule.sourceURL, this.rule.lineNumberInSource());
+ var matchingSelectorLocation = new WebInspector.CSSLocation(this._parentPane._target, this.styleRule.sourceURL, this.rule.lineNumberInSource(firstMatchingIndex), this.rule.columnNumberInSource(firstMatchingIndex));
+ return this._parentPane._linkifier.linkifyCSSLocation(this.rule.styleSheetId, matchingSelectorLocation) || linkifyUncopyable(this.styleRule.sourceURL, this.rule.lineNumberInSource());
}
if (!this.rule)
@@ -1412,10 +1567,9 @@ WebInspector.StylePropertiesSection.prototype = {
{
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && this.navigable && event.target.classList.contains("simple-selector")) {
var index = event.target._selectorIndex;
- var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(this.rule.id.styleSheetId);
+ var styleSheetHeader = this._parentPane._target.cssModel.styleSheetHeaderForId(this.rule.styleSheetId);
var uiLocation = styleSheetHeader.rawLocationToUILocation(this.rule.lineNumberInSource(index), this.rule.columnNumberInSource(index));
- if (uiLocation)
- WebInspector.panel("sources").showUILocation(uiLocation);
+ WebInspector.Revealer.reveal(uiLocation);
return;
}
this._startEditingOnMouseEvent();
@@ -1448,8 +1602,8 @@ WebInspector.StylePropertiesSection.prototype = {
element.scrollIntoViewIfNeeded(false);
element.textContent = element.textContent; // Reset selector marks in group.
- var config = new WebInspector.EditingConfig(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
- WebInspector.startEditing(this._selectorElement, config);
+ var config = new WebInspector.InplaceEditor.Config(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
+ WebInspector.InplaceEditor.startEditing(this._selectorElement, config);
window.getSelection().setBaseAndExtent(element, 0, element, 1);
this._parentPane._isEditingStyle = true;
@@ -1489,10 +1643,11 @@ WebInspector.StylePropertiesSection.prototype = {
if (newContent === oldContent) {
// Revert to a trimmed version of the selector if need be.
this._selectorElement.textContent = newContent;
- return this._moveEditorFromSelector(moveDirection);
+ this._moveEditorFromSelector(moveDirection);
+ return;
}
- var selectedNode = this._parentPane.node;
+ var selectedNode = this._parentPane._node;
/**
* @param {!WebInspector.CSSRule} newRule
@@ -1509,11 +1664,12 @@ WebInspector.StylePropertiesSection.prototype = {
this.element.classList.remove("no-affect");
}
+ var oldSelectorRange = this.rule.selectorRange;
this.rule = newRule;
this.styleRule = { section: this, style: newRule.style, selectorText: newRule.selectorText, media: newRule.media, sourceURL: newRule.resourceURL(), rule: newRule };
this._parentPane.update(selectedNode);
- this._updateRuleOrigin();
+ this._parentPane._styleSheetRuleEdited(this.rule, oldSelectorRange, this.rule.selectorRange);
finishOperationAndMoveEditor.call(this, moveDirection);
}
@@ -1529,7 +1685,7 @@ WebInspector.StylePropertiesSection.prototype = {
// This gets deleted in finishOperationAndMoveEditor(), which is called both on success and failure.
this._parentPane._userOperation = true;
- WebInspector.cssModel.setRuleSelector(this.rule.id, selectedNode ? selectedNode.id : 0, newContent, successCallback.bind(this), finishOperationAndMoveEditor.bind(this, moveDirection));
+ this._parentPane._target.cssModel.setRuleSelector(this.rule, selectedNode ? selectedNode.id : 0, newContent, successCallback.bind(this), finishOperationAndMoveEditor.bind(this, moveDirection));
},
_updateRuleOrigin: function()
@@ -1565,8 +1721,34 @@ WebInspector.StylePropertiesSection.prototype = {
WebInspector.ComputedStylePropertiesSection = function(stylesPane, styleRule, usedProperties)
{
WebInspector.PropertiesSection.call(this, "");
- this.headerElement.classList.add("hidden");
+
+ var subtitle = this.headerElement.createChild("div", "sidebar-pane-subtitle vbox");
+ var showInheritedCheckbox = new WebInspector.Checkbox(WebInspector.UIString("Show inherited properties"), "hbox");
+ subtitle.appendChild(showInheritedCheckbox.element);
+
+ this._hasFreshContent = false;
+
+ /**
+ * @this {WebInspector.ComputedStylePropertiesSection}
+ */
+ function showInheritedToggleFunction()
+ {
+ var showInherited = showInheritedCheckbox.checked;
+ WebInspector.settings.showInheritedComputedStyleProperties.set(showInherited);
+ if (showInherited)
+ this.element.classList.add("styles-show-inherited");
+ else
+ this.element.classList.remove("styles-show-inherited");
+ }
+
+ showInheritedCheckbox.addEventListener(showInheritedToggleFunction.bind(this));
+
this.element.className = "styles-section monospace read-only computed-style";
+ if (WebInspector.settings.showInheritedComputedStyleProperties.get()) {
+ this.element.classList.add("styles-show-inherited");
+ showInheritedCheckbox.checked = true;
+ }
+
this._stylesPane = stylesPane;
this.styleRule = styleRule;
this._usedProperties = usedProperties;
@@ -1600,6 +1782,13 @@ WebInspector.ComputedStylePropertiesSection.prototype = {
this.populated = false;
},
+ _updateFilter: function()
+ {
+ var children = this.propertiesTreeOutline.children;
+ for (var i = 0; i < children.length; ++i)
+ children[i]._updateFilter();
+ },
+
onpopulate: function()
{
function sorter(a, b)
@@ -1734,7 +1923,22 @@ WebInspector.BlankStylePropertiesSection.prototype = {
if (newContent)
newContent = newContent.trim();
this._parentPane._userOperation = true;
- WebInspector.cssModel.addRule(this.pane.node.id, newContent, successCallback.bind(this), this.editingSelectorCancelled.bind(this));
+
+ var cssModel = this._parentPane._target.cssModel;
+ cssModel.requestViaInspectorStylesheet(this._parentPane._node, viaInspectorCallback.bind(this));
+
+ /**
+ * @this {WebInspector.BlankStylePropertiesSection}
+ * @param {?WebInspector.CSSStyleSheetHeader} styleSheetHeader
+ */
+ function viaInspectorCallback(styleSheetHeader)
+ {
+ if (!styleSheetHeader) {
+ this.editingSelectorCancelled();
+ return;
+ }
+ cssModel.addRule(styleSheetHeader.id, this._parentPane._node, newContent, successCallback.bind(this), this.editingSelectorCancelled.bind(this));
+ }
},
editingSelectorCancelled: function()
@@ -1746,7 +1950,7 @@ WebInspector.BlankStylePropertiesSection.prototype = {
}
this._editingSelectorEnded();
- this.pane.removeSection(this);
+ this._parentPane.removeSection(this);
},
makeNormal: function(styleRule)
@@ -1803,11 +2007,22 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
return null; // Overridden by ancestors.
},
+ /**
+ * @return {!WebInspector.StylesSidebarPane|!WebInspector.ComputedStyleSidebarPane}
+ */
+ parentPane: function()
+ {
+ throw "Not implemented";
+ },
+
get inherited()
{
return this._inherited;
},
+ /**
+ * @return {boolean}
+ */
hasIgnorableError: function()
{
return !this.parsedOk && WebInspector.StylesSidebarPane._ignoreErrorsForProperty(this.property);
@@ -1855,13 +2070,6 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
return text;
},
- get priority()
- {
- if (this.disabled)
- return ""; // rely upon raw text to render it in the value field
- return this.property.priority;
- },
-
get value()
{
if (!this.disabled || !this.property.text)
@@ -1910,6 +2118,9 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
/**
* @param {!RegExp} regex
+ * @param {function(string):!Node} processor
+ * @param {?function(string):!Node} nextProcessor
+ * @param {string} valueText
* @return {!DocumentFragment}
*/
function processValue(regex, processor, nextProcessor, valueText)
@@ -1958,7 +2169,7 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
}
if (value) {
- var colorProcessor = processValue.bind(this, WebInspector.StylesSidebarPane._colorRegex, this._processColor.bind(this, nameElement, valueElement), null);
+ var colorProcessor = processValue.bind(null, WebInspector.StylesSidebarPane._colorRegex, this._processColor.bind(this, nameElement, valueElement), null);
valueElement.appendChild(processValue(/url\(\s*([^)]+)\s*\)/g, linkifyURL.bind(this), WebInspector.CSSMetadata.isColorAwareProperty(this.name) && this.parsedOk ? colorProcessor : null, value));
}
@@ -1989,12 +2200,20 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
}
if (this.property.inactive)
this.listItemElement.classList.add("inactive");
+ this._updateFilter();
+ },
+
+ _updateFilter: function()
+ {
+ var regEx = this.parentPane().filterRegex();
+ this.listItemElement.classList.toggle("filter-match", !!regEx && (regEx.test(this.property.name) || regEx.test(this.property.value)));
},
/**
* @param {!Element} nameElement
* @param {!Element} valueElement
* @param {string} text
+ * @return {!Node}
*/
_processColor: function(nameElement, valueElement, text)
{
@@ -2008,7 +2227,8 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
var spectrumHelper = this.editablePane() && this.editablePane()._spectrumHelper;
var spectrum = spectrumHelper ? spectrumHelper.spectrum() : null;
- var colorSwatch = new WebInspector.ColorSwatch();
+ var isEditable = !!(this._styleRule && this._styleRule.editable !== false); // |editable| is true by default.
+ var colorSwatch = new WebInspector.ColorSwatch(!isEditable);
colorSwatch.setColorString(text);
colorSwatch.element.addEventListener("click", swatchClick.bind(this), false);
@@ -2058,28 +2278,32 @@ WebInspector.StylePropertyTreeElementBase.prototype = {
*/
function swatchClick(e)
{
+ e.consume(true);
+
// Shift + click toggles color formats.
// Click opens colorpicker, only if the element is not in computed styles section.
if (!spectrumHelper || e.shiftKey) {
changeColorDisplay();
- } else {
- var visible = spectrumHelper.toggle(colorSwatch.element, color, format);
-
- if (visible) {
- spectrum.displayText = color.toString(format);
- this.originalPropertyText = this.property.propertyText;
- this.editablePane()._isEditingStyle = true;
- spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, boundSpectrumChanged);
- spectrumHelper.addEventListener(WebInspector.SpectrumPopupHelper.Events.Hidden, boundSpectrumHidden);
-
- scrollerElement = colorSwatch.element.enclosingNodeOrSelfWithClass("scroll-target");
- if (scrollerElement)
- scrollerElement.addEventListener("scroll", repositionSpectrum, false);
- else
- console.error("Unable to handle color picker scrolling");
- }
+ return;
+ }
+
+ if (!isEditable)
+ return;
+
+ var visible = spectrumHelper.toggle(colorSwatch.element, color, format);
+ if (visible) {
+ spectrum.displayText = color.toString(format);
+ this.originalPropertyText = this.property.propertyText;
+ this.editablePane()._isEditingStyle = true;
+ spectrum.addEventListener(WebInspector.Spectrum.Events.ColorChanged, boundSpectrumChanged);
+ spectrumHelper.addEventListener(WebInspector.SpectrumPopupHelper.Events.Hidden, boundSpectrumHidden);
+
+ scrollerElement = colorSwatch.element.enclosingNodeOrSelfWithClass("scroll-target");
+ if (scrollerElement)
+ scrollerElement.addEventListener("scroll", repositionSpectrum, false);
+ else
+ console.error("Unable to handle color picker scrolling");
}
- e.consume(true);
}
var colorValueElement = document.createElement("span");
@@ -2204,7 +2428,7 @@ WebInspector.ComputedStylePropertyTreeElement.prototype = {
*/
node: function()
{
- return this._stylesPane.node;
+ return this._stylesPane._node;
},
/**
@@ -2215,6 +2439,20 @@ WebInspector.ComputedStylePropertyTreeElement.prototype = {
return null;
},
+ /**
+ * @return {!WebInspector.ComputedStyleSidebarPane}
+ */
+ parentPane: function()
+ {
+ return this._stylesPane._computedStylePane;
+ },
+
+ _updateFilter: function()
+ {
+ var regEx = this.parentPane().filterRegex();
+ this.listItemElement.classList.toggle("hidden", !!regEx && (!regEx.test(this.property.name) && !regEx.test(this.property.value)));
+ },
+
__proto__: WebInspector.StylePropertyTreeElementBase.prototype
}
@@ -2242,7 +2480,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
*/
node: function()
{
- return this._parentPane.node;
+ return this._parentPane._node;
},
/**
@@ -2254,6 +2492,14 @@ WebInspector.StylePropertyTreeElement.prototype = {
},
/**
+ * @return {!WebInspector.StylesSidebarPane}
+ */
+ parentPane: function()
+ {
+ return this._parentPane;
+ },
+
+ /**
* @return {?WebInspector.StylePropertiesSection}
*/
section: function()
@@ -2267,8 +2513,8 @@ WebInspector.StylePropertyTreeElement.prototype = {
_updatePane: function(userCallback)
{
var section = this.section();
- if (section && section.pane)
- section.pane._refreshUpdate(section, false, userCallback);
+ if (section && section._parentPane)
+ section._parentPane._refreshUpdate(section, false, userCallback);
else {
if (userCallback)
userCallback();
@@ -2276,6 +2522,22 @@ WebInspector.StylePropertyTreeElement.prototype = {
},
/**
+ * @param {!WebInspector.CSSStyleDeclaration} newStyle
+ */
+ _applyNewStyle: function(newStyle)
+ {
+ newStyle.parentRule = this.style.parentRule;
+ var oldStyleRange = /** @type {!WebInspector.TextRange} */ (this.style.range);
+ var newStyleRange = /** @type {!WebInspector.TextRange} */ (newStyle.range);
+ this.style = newStyle;
+ this._styleRule.style = newStyle;
+ if (this.style.parentRule) {
+ this.style.parentRule.style = this.style;
+ this._parentPane._styleSheetRuleEdited(this.style.parentRule, oldStyleRange, newStyleRange);
+ }
+ },
+
+ /**
* @param {?Event} event
*/
toggleEnabled: function(event)
@@ -2288,20 +2550,17 @@ WebInspector.StylePropertyTreeElement.prototype = {
*/
function callback(newStyle)
{
+ delete this._parentPane._userOperation;
+
if (!newStyle)
return;
-
- newStyle.parentRule = this.style.parentRule;
- this.style = newStyle;
- this._styleRule.style = newStyle;
+ this._applyNewStyle(newStyle);
var section = this.section();
- if (section && section.pane)
- section.pane.dispatchEventToListeners("style property toggled");
+ if (section && section._parentPane)
+ section._parentPane.dispatchEventToListeners("style property toggled");
this._updatePane();
-
- delete this._parentPane._userOperation;
}
this._parentPane._userOperation = true;
@@ -2318,11 +2577,13 @@ WebInspector.StylePropertyTreeElement.prototype = {
var longhandProperties = this.style.longhandProperties(this.name);
for (var i = 0; i < longhandProperties.length; ++i) {
var name = longhandProperties[i].name;
+ var inherited = false;
+ var overloaded = false;
var section = this.section();
if (section) {
- var inherited = section.isPropertyInherited(name);
- var overloaded = section.isPropertyOverloaded(name);
+ inherited = section.isPropertyInherited(name);
+ overloaded = section.isPropertyOverloaded(name);
}
var liveProperty = this.style.getLiveProperty(name);
@@ -2408,11 +2669,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
{
console.assert(this.section().navigable);
var propertyNameClicked = element === this.nameElement;
- var uiLocation = this.property.uiLocation(propertyNameClicked);
- if (!uiLocation)
- return;
-
- WebInspector.panel("sources").showUILocation(uiLocation);
+ WebInspector.Revealer.reveal(this.property.uiLocation(propertyNameClicked));
},
/**
@@ -2432,7 +2689,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
},
/**
- * @param {!Element=} selectElement
+ * @param {?Element=} selectElement
*/
startEditing: function(selectElement)
{
@@ -2554,8 +2811,9 @@ WebInspector.StylePropertyTreeElement.prototype = {
var proxyElement = this._prompt.attachAndStartEditing(selectElement, blurListener.bind(this, context));
proxyElement.addEventListener("keydown", this.editingNameValueKeyDown.bind(this, context), false);
+ proxyElement.addEventListener("keypress", this.editingNameValueKeyPress.bind(this, context), false);
if (isEditingName)
- proxyElement.addEventListener("paste", pasteHandler.bind(this, context));
+ proxyElement.addEventListener("paste", pasteHandler.bind(this, context), false);
window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
},
@@ -2568,27 +2826,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
var isEditingName = context.isEditingName;
var result;
- function shouldCommitValueSemicolon(text, cursorPosition)
- {
- // FIXME: should this account for semicolons inside comments?
- var openQuote = "";
- for (var i = 0; i < cursorPosition; ++i) {
- var ch = text[i];
- if (ch === "\\" && openQuote !== "")
- ++i; // skip next character inside string
- else if (!openQuote && (ch === "\"" || ch === "'"))
- openQuote = ch;
- else if (openQuote === ch)
- openQuote = "";
- }
- return !openQuote;
- }
-
- // FIXME: the ":"/";" detection does not work for non-US layouts due to the event being keydown rather than keypress.
- var isFieldInputTerminated = (event.keyCode === WebInspector.KeyboardShortcut.Keys.Semicolon.code) &&
- (isEditingName ? event.shiftKey : (!event.shiftKey && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset())));
- if (isEnterKey(event) || isFieldInputTerminated) {
- // Enter or colon (for name)/semicolon outside of string (for value).
+ if (isEnterKey(event)) {
event.preventDefault();
result = "forward";
} else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
@@ -2624,6 +2862,34 @@ WebInspector.StylePropertyTreeElement.prototype = {
this._applyFreeFlowStyleTextEdit(false);
},
+ editingNameValueKeyPress: function(context, event)
+ {
+ function shouldCommitValueSemicolon(text, cursorPosition)
+ {
+ // FIXME: should this account for semicolons inside comments?
+ var openQuote = "";
+ for (var i = 0; i < cursorPosition; ++i) {
+ var ch = text[i];
+ if (ch === "\\" && openQuote !== "")
+ ++i; // skip next character inside string
+ else if (!openQuote && (ch === "\"" || ch === "'"))
+ openQuote = ch;
+ else if (openQuote === ch)
+ openQuote = "";
+ }
+ return !openQuote;
+ }
+
+ var keyChar = String.fromCharCode(event.charCode);
+ var isFieldInputTerminated = (context.isEditingName ? keyChar === ":" : keyChar === ";" && shouldCommitValueSemicolon(event.target.textContent, event.target.selectionLeftOffset()));
+ if (isFieldInputTerminated) {
+ // Enter or colon (for name)/semicolon outside of string (for value).
+ event.consume(true);
+ this.editingCommitted(event.target.textContent, context, "forward");
+ return;
+ }
+ },
+
_applyFreeFlowStyleTextEdit: function(now)
{
if (this._applyFreeFlowStyleTextEditTimer)
@@ -2835,6 +3101,10 @@ WebInspector.StylePropertyTreeElement.prototype = {
return typeof this.originalPropertyText === "string" || (!!this.property.propertyText && this._newProperty);
},
+ styleTextAppliedForTest: function()
+ {
+ },
+
applyStyleText: function(styleText, updateInterface, majorChange, isRevert)
{
function userOperationFinishedCallback(parentPane, updateInterface)
@@ -2863,7 +3133,7 @@ WebInspector.StylePropertyTreeElement.prototype = {
return;
}
- var currentNode = this._parentPane.node;
+ var currentNode = this._parentPane._node;
if (updateInterface)
this._parentPane._userOperation = true;
@@ -2883,23 +3153,23 @@ WebInspector.StylePropertyTreeElement.prototype = {
userCallback();
return;
}
+ this._applyNewStyle(newStyle);
if (this._newProperty)
this._newPropertyInStyle = true;
- newStyle.parentRule = this.style.parentRule;
- this.style = newStyle;
- this.property = newStyle.propertyAt(this.property.index);
- this._styleRule.style = this.style;
- if (section && section.pane)
- section.pane.dispatchEventToListeners("style edited");
+ this.property = newStyle.propertyAt(this.property.index);
+ if (section && section._parentPane)
+ section._parentPane.dispatchEventToListeners("style edited");
if (updateInterface && currentNode === this.node()) {
this._updatePane(userCallback);
+ this.styleTextAppliedForTest();
return;
}
userCallback();
+ this.styleTextAppliedForTest();
}
// Append a ";" if the new text does not end in ";".
@@ -2910,11 +3180,18 @@ WebInspector.StylePropertyTreeElement.prototype = {
this.property.setText(styleText, majorChange, overwriteProperty, callback.bind(this, userOperationFinishedCallback.bind(null, this._parentPane, updateInterface), this.originalPropertyText));
},
+ /**
+ * @return {boolean}
+ */
ondblclick: function()
{
return true; // handled
},
+ /**
+ * @param {?Event} event
+ * @return {boolean}
+ */
isEventWithinDisclosureTriangle: function(event)
{
return event.target === this._expandElement;
@@ -2934,7 +3211,7 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(cssCompletions, side
{
// Use the same callback both for applyItemCallback and acceptItemCallback.
WebInspector.TextPrompt.call(this, this._buildPropertyCompletions.bind(this), WebInspector.StyleValueDelimiters);
- this.setSuggestBoxEnabled("generic-suggest");
+ this.setSuggestBoxEnabled(true);
this._cssCompletions = cssCompletions;
this._sidebarPane = sidebarPane;
this._isEditingName = isEditingName;
@@ -2944,6 +3221,9 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt = function(cssCompletions, side
}
WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
+ /**
+ * @param {?Event} event
+ */
onKeyDown: function(event)
{
switch (event.keyIdentifier) {
@@ -2976,7 +3256,10 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
WebInspector.TextPrompt.prototype.onMouseWheel.call(this, event);
},
- /** @override */
+ /**
+ * @override
+ * @return {boolean}
+ */
tabKeyPressed: function()
{
this.acceptAutoComplete();
@@ -2987,6 +3270,7 @@ WebInspector.StylesSidebarPane.CSSPropertyPrompt.prototype = {
/**
* @param {?Event} event
+ * @return {boolean}
*/
_handleNameOrValueUpDown: function(event)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/elements/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/elements/module.json
new file mode 100644
index 00000000000..d8b7d007ca8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elements/module.json
@@ -0,0 +1,92 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "elements",
+ "title": "Elements",
+ "order": 0,
+ "className": "WebInspector.ElementsPanel"
+ },
+ {
+ "type": "@WebInspector.ContextMenu.Provider",
+ "contextTypes": ["WebInspector.RemoteObject", "WebInspector.DOMNode"],
+ "className": "WebInspector.ElementsPanel.ContextMenuProvider"
+ },
+ {
+ "type": "drawer-view",
+ "name": "emulation",
+ "title": "Emulation",
+ "order": "10",
+ "className": "WebInspector.OverridesView"
+ },
+ {
+ "type": "drawer-view",
+ "name": "rendering",
+ "title": "Rendering",
+ "order": "11",
+ "className": "WebInspector.RenderingOptionsView"
+ },
+ {
+ "type": "@WebInspector.Renderer",
+ "contextTypes": ["WebInspector.DOMNode"],
+ "className": "WebInspector.ElementsTreeOutline.Renderer"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.DOMNode"],
+ "className": "WebInspector.ElementsPanel.DOMNodeRevealer"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.RemoteObject"],
+ "className": "WebInspector.ElementsPanel.NodeRemoteObjectRevealer"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.OverridesSupport"],
+ "className": "WebInspector.OverridesView.Revealer"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Elements",
+ "title": "Color format",
+ "settingName": "colorFormat",
+ "settingType": "select",
+ "options": [
+ [ "As authored", "original" ],
+ [ "HEX: #DAC0DE", "hex", true ],
+ [ "RGB: rgb(128, 255, 255)", "rgb", true ],
+ [ "HSL: hsl(300, 80%, 90%)", "hsl", true ]
+ ]
+ },
+ {
+ "type": "ui-setting",
+ "section": "Elements",
+ "title": "Show user agent styles",
+ "settingName": "showUserAgentStyles",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Elements",
+ "title": "Show user agent shadow DOM",
+ "settingName": "showUAShadowDOM",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Elements",
+ "title": "Word wrap",
+ "settingName": "domWordWrap",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Elements",
+ "title": "Show rulers",
+ "settingName": "showMetricsRulers",
+ "settingType": "checkbox"
+ }
+ ],
+ "scripts": [ "ElementsPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/elementsPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/elementsPanel.css
index 873067a2c0c..89aa19772a9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/elementsPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/elementsPanel.css
@@ -31,17 +31,22 @@
flex: 1 1;
overflow: auto;
padding-left: 0;
+ -webkit-transform: translateZ(0);
}
#elements-crumbs {
flex: 0 0 19px;
- background-color: rgb(236, 236, 236);
+ background-color: white;
border-top: 1px solid #ccc;
+ overflow: hidden;
+ height: 19px;
+ width: 100%;
}
#elements-content > ol {
display: inline-block;
min-height: 100%;
+ -webkit-transform: translateZ(0);
}
#elements-content .editing {
@@ -147,7 +152,6 @@
padding: 3px;
margin: 3px;
min-width: 80px;
- text-align: center;
overflow: visible;
}
@@ -205,7 +209,7 @@
height: 16px;
}
-.styles-section.read-only {
+.styles-section.read-only:not(.computed-style) {
background-color: rgb(240, 240, 240);
}
@@ -217,6 +221,15 @@
margin-left: -6px;
}
+.styles-section .properties li.filter-match,
+.styles-section .simple-selector.filter-match {
+ background-color: rgba(255, 255, 0, 0.5);
+}
+
+.styles-section .properties li.overloaded.filter-match {
+ background-color: rgba(255, 255, 0, 0.25);
+}
+
.styles-section .properties li.not-parsed-ok .exclamation-mark {
display: inline-block;
position: relative;
@@ -305,7 +318,6 @@
.styles-section .properties li {
margin-left: 12px;
padding-left: 22px;
- padding-top: 0;
white-space: normal;
text-overflow: ellipsis;
overflow: hidden;
@@ -364,7 +376,7 @@
.styles-section.matched-styles .properties li.parent .expand-element {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
margin-right: 2px;
margin-left: -6px;
opacity: 0.55;
@@ -375,7 +387,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.styles-section.matched-styles .properties li.parent .expand-element {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -443,7 +455,6 @@
}
.styles-element-state-pane {
- background-color: rgb(240, 240, 240);
overflow: hidden;
margin-top: -56px;
padding-top: 18px;
@@ -462,9 +473,9 @@
border-spacing: 0;
}
-.styles-element-state-pane input {
- margin: 2px;
- vertical-align: -2px;
+.styles-element-state-pane label {
+ display: flex;
+ margin: 1px;
}
.styles-selector {
@@ -475,7 +486,7 @@
display: none;
}
-.body.show-inherited .styles-section .properties .inherited {
+.styles-section.styles-show-inherited .properties .inherited {
display: block;
}
@@ -523,7 +534,7 @@
.event-bars .event-bar .header::before {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
content: "a";
color: transparent;
@@ -536,7 +547,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.event-bars .event-bar .header::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -563,7 +574,6 @@
}
.sidebar-pane.composite {
- overflow: hidden;
position: absolute;
}
@@ -574,12 +584,48 @@
.sidebar-pane.composite .metrics {
border-bottom: 1px solid rgb(64%, 64%, 64%);
height: 206px;
- display: -webkit-flex;
- -webkit-flex-direction: column;
+ display: flex;
+ flex-direction: column;
-webkit-align-items: center;
-webkit-justify-content: center;
}
+.sidebar-pane .metrics-and-styles,
+.sidebar-pane .metrics-and-computed {
+ display: flex !important;
+ flex-direction: column !important;
+ position: relative;
+}
+
+.sidebar-pane .style-panes-wrapper {
+ flex: 1;
+ overflow-y: auto;
+ position: relative;
+}
+
+.sidebar-pane.composite .metrics-and-computed .sidebar-pane-toolbar,
+.sidebar-pane.composite .metrics-and-styles .sidebar-pane-toolbar {
+ position: absolute;
+}
+
+.sidebar-pane-filter-box {
+ display: flex;
+ border-top: 1px solid rgb(191, 191, 191);
+ flex-basis: 19px;
+}
+
+.sidebar-pane-filter-box > input {
+ outline: none !important;
+ border: none;
+ width: 100%;
+ margin: 0 4px;
+ background: transparent;
+}
+
+.styles-filter-engaged {
+ background-color: rgba(255, 255, 0, 0.5);
+}
+
.sidebar-pane.composite .metrics-and-computed .sidebar-pane-toolbar {
margin-top: 4px;
margin-bottom: -4px;
@@ -615,12 +661,26 @@
border-bottom: none;
}
+.styles-section.computed-style > .header > .sidebar-pane-subtitle {
+ line-height: 17px;
+ margin: 2px;
+ -webkit-user-select: none;
+}
+
+.styles-section.computed-style > .header > .sidebar-pane-subtitle > input {
+ vertical-align: middle;
+}
+
.sidebar-pane.composite .sidebar-pane-toolbar > .sidebar-pane-subtitle {
left: 8px;
}
-.sidebar-pane.composite .styles-section.read-only {
- background-color: inherit;
+.sidebar-pane > .body > .split-view {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
}
.panel.elements .sidebar-pane-toolbar > select {
@@ -669,6 +729,7 @@
display: inline-block;
width: 0;
opacity: 0;
+ pointer-events: none;
}
li.child-editing .styles-clipboard-only {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAPI.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAPI.js
index ccf82cab297..419be055720 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAPI.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAPI.js
@@ -104,6 +104,10 @@ function defineCommonExtensionSymbols(apiPrivate)
};
}
+/**
+ * @param {number} injectedScriptId
+ * @return {!Object}
+ */
function injectedExtensionAPI(injectedScriptId)
{
@@ -245,12 +249,12 @@ Network.prototype = {
}
callback(result);
}
- return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
+ extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
},
addRequestHeaders: function(headers)
{
- return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
+ extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
}
}
@@ -360,15 +364,21 @@ function ExtensionViewImpl(id)
else
this._fire();
}
- this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
- this.onHidden = new EventSink(events.ViewHidden + id);
+
+ if (id) {
+ this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
+ this.onHidden = new EventSink(events.ViewHidden + id);
+ }
}
/**
* @constructor
+ * @extends {ExtensionViewImpl}
+ * @param {string} hostPanelName
*/
function PanelWithSidebarImpl(hostPanelName)
{
+ ExtensionViewImpl.call(this, null);
this._hostPanelName = hostPanelName;
this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPanelName);
}
@@ -393,6 +403,47 @@ PanelWithSidebarImpl.prototype = {
__proto__: ExtensionViewImpl.prototype
}
+function declareInterfaceClass(implConstructor)
+{
+ return function()
+ {
+ var impl = { __proto__: implConstructor.prototype };
+ implConstructor.apply(impl, arguments);
+ populateInterfaceClass(this, impl);
+ }
+}
+
+function defineDeprecatedProperty(object, className, oldName, newName)
+{
+ var warningGiven = false;
+ function getter()
+ {
+ if (!warningGiven) {
+ console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
+ warningGiven = true;
+ }
+ return object[newName];
+ }
+ object.__defineGetter__(oldName, getter);
+}
+
+function extractCallbackArgument(args)
+{
+ var lastArgument = args[args.length - 1];
+ return typeof lastArgument === "function" ? lastArgument : undefined;
+}
+
+var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
+var AuditResult = declareInterfaceClass(AuditResultImpl);
+var Button = declareInterfaceClass(ButtonImpl);
+var EventSink = declareInterfaceClass(EventSinkImpl);
+var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
+var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
+var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
+var Request = declareInterfaceClass(RequestImpl);
+var Resource = declareInterfaceClass(ResourceImpl);
+var Timeline = declareInterfaceClass(TimelineImpl);
+
/**
* @constructor
* @extends {PanelWithSidebar}
@@ -402,6 +453,10 @@ function ElementsPanel()
PanelWithSidebar.call(this, "elements");
}
+ElementsPanel.prototype = {
+ __proto__: PanelWithSidebar.prototype
+}
+
/**
* @constructor
* @extends {PanelWithSidebar}
@@ -411,6 +466,10 @@ function SourcesPanel()
PanelWithSidebar.call(this, "sources");
}
+SourcesPanel.prototype = {
+ __proto__: PanelWithSidebar.prototype
+}
+
/**
* @constructor
* @extends {ExtensionViewImpl}
@@ -422,6 +481,9 @@ function ExtensionPanelImpl(id)
}
ExtensionPanelImpl.prototype = {
+ /**
+ * @return {!Object}
+ */
createStatusBarButton: function(iconPath, tooltipText, disabled)
{
var id = "button-" + extensionServer.nextObjectId();
@@ -489,7 +551,9 @@ ExtensionSidebarPaneImpl.prototype = {
setPage: function(page)
{
extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
- }
+ },
+
+ __proto__: ExtensionViewImpl.prototype
}
/**
@@ -523,6 +587,9 @@ function Audits()
}
Audits.prototype = {
+ /**
+ * @return {!AuditCategory}
+ */
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
@@ -562,11 +629,11 @@ function AuditResultImpl(id)
{
this._id = id;
- this.createURL = this._nodeFactory.bind(null, "url");
- this.createSnippet = this._nodeFactory.bind(null, "snippet");
- this.createText = this._nodeFactory.bind(null, "text");
- this.createObject = this._nodeFactory.bind(null, "object");
- this.createNode = this._nodeFactory.bind(null, "node");
+ this.createURL = this._nodeFactory.bind(this, "url");
+ this.createSnippet = this._nodeFactory.bind(this, "snippet");
+ this.createText = this._nodeFactory.bind(this, "text");
+ this.createObject = this._nodeFactory.bind(this, "object");
+ this.createNode = this._nodeFactory.bind(this, "node");
}
AuditResultImpl.prototype = {
@@ -587,6 +654,9 @@ AuditResultImpl.prototype = {
extensionServer.sendRequest(request);
},
+ /**
+ * @return {!Object}
+ */
createResult: function()
{
return new AuditResultNode(Array.prototype.slice.call(arguments));
@@ -602,11 +672,17 @@ AuditResultImpl.prototype = {
extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
},
+ /**
+ * @type {!Object.<string, string>}
+ */
get Severity()
{
return apiPrivate.audits.Severity;
},
+ /**
+ * @return {!{type: string, arguments: !Array.<string|number>}}
+ */
createResourceLink: function(url, lineNumber)
{
return {
@@ -615,6 +691,9 @@ AuditResultImpl.prototype = {
};
},
+ /**
+ * @return {!{type: string, arguments: !Array.<string|number>}}
+ */
_nodeFactory: function(type)
{
return {
@@ -635,6 +714,9 @@ function AuditResultNode(contents)
}
AuditResultNode.prototype = {
+ /**
+ * @return {!Object}
+ */
addChild: function()
{
var node = new AuditResultNode(Array.prototype.slice.call(arguments));
@@ -679,9 +761,12 @@ InspectedWindow.prototype = {
console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
"Use inspectedWindow.reload({ userAgent: value}) instead.");
}
- return extensionServer.sendRequest({ command: commands.Reload, options: options });
+ extensionServer.sendRequest({ command: commands.Reload, options: options });
},
+ /**
+ * @return {?Object}
+ */
eval: function(expression, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
@@ -698,7 +783,8 @@ InspectedWindow.prototype = {
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
- return extensionServer.sendRequest(request, callback && callbackWrapper);
+ extensionServer.sendRequest(request, callback && callbackWrapper);
+ return null;
},
getResources: function(callback)
@@ -711,7 +797,7 @@ InspectedWindow.prototype = {
{
callback(resources.map(wrapResource));
}
- return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
+ extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
}
}
@@ -742,12 +828,12 @@ ResourceImpl.prototype = {
callback(response.content, response.encoding);
}
- return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
+ extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
},
setContent: function(content, commit, callback)
{
- return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
+ extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
}
}
@@ -759,22 +845,38 @@ function TimelineImpl()
this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
}
+var keyboardEventRequestQueue = [];
+var forwardTimer = null;
+
function forwardKeyboardEvent(event)
{
const Esc = "U+001B";
// We only care about global hotkeys, not about random text
if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.keyIdentifier) && event.keyIdentifier !== Esc)
return;
- var request = {
- command: commands.ForwardKeyboardEvent,
+ var requestPayload = {
eventType: event.type,
ctrlKey: event.ctrlKey,
altKey: event.altKey,
metaKey: event.metaKey,
keyIdentifier: event.keyIdentifier,
- location: event.location
+ location: event.location,
+ keyCode: event.keyCode
+ };
+ keyboardEventRequestQueue.push(requestPayload);
+ if (!forwardTimer)
+ forwardTimer = setTimeout(forwardEventQueue, 0);
+}
+
+function forwardEventQueue()
+{
+ forwardTimer = null;
+ var request = {
+ command: commands.ForwardKeyboardEvent,
+ entries: keyboardEventRequestQueue
};
extensionServer.sendRequest(request);
+ keyboardEventRequestQueue = [];
}
document.addEventListener("keydown", forwardKeyboardEvent, false);
@@ -802,15 +904,19 @@ function ExtensionServerClient()
ExtensionServerClient.prototype = {
/**
+ * @param {!Object} message
* @param {function()=} callback
*/
sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
- return this._port.postMessage(message);
+ this._port.postMessage(message);
},
+ /**
+ * @return {boolean}
+ */
hasHandler: function(command)
{
return !!this._handlers[command];
@@ -826,6 +932,9 @@ ExtensionServerClient.prototype = {
delete this._handlers[command];
},
+ /**
+ * @return {string}
+ */
nextObjectId: function()
{
return injectedScriptId + "_" + ++this._lastObjectId;
@@ -856,7 +965,7 @@ ExtensionServerClient.prototype = {
}
}
-function populateInterfaceClass(interface, implementation)
+function populateInterfaceClass(interfaze, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
@@ -868,60 +977,69 @@ function populateInterfaceClass(interface, implementation)
if (!descriptor)
continue;
if (typeof descriptor.value === "function")
- interface[member] = descriptor.value.bind(implementation);
+ interfaze[member] = descriptor.value.bind(implementation);
else if (typeof descriptor.get === "function")
- interface.__defineGetter__(member, descriptor.get.bind(implementation));
+ interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
else
- Object.defineProperty(interface, member, descriptor);
+ Object.defineProperty(interfaze, member, descriptor);
}
}
-function declareInterfaceClass(implConstructor)
-{
- return function()
- {
- var impl = { __proto__: implConstructor.prototype };
- implConstructor.apply(impl, arguments);
- populateInterfaceClass(this, impl);
- }
+// extensionServer is a closure variable defined by the glue below -- make sure we fail if it's not there.
+if (!extensionServer)
+ extensionServer = new ExtensionServerClient();
+
+return new InspectorExtensionAPI();
}
-function defineDeprecatedProperty(object, className, oldName, newName)
+/**
+ * @suppress {checkVars, checkTypes}
+ */
+function platformExtensionAPI(coreAPI)
{
- var warningGiven = false;
- function getter()
+ function getTabId()
{
- if (!warningGiven) {
- console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
- warningGiven = true;
+ return tabId;
+ }
+ chrome = window.chrome || {};
+ // Override chrome.devtools as a workaround for a error-throwing getter being exposed
+ // in extension pages loaded into a non-extension process (only happens for remote client
+ // extensions)
+ var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
+ if (!devtools_descriptor || devtools_descriptor.get)
+ Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });
+ // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
+ chrome.devtools.inspectedWindow = {};
+ chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
+ chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
+ chrome.devtools.network = coreAPI.network;
+ chrome.devtools.panels = coreAPI.panels;
+
+ // default to expose experimental APIs for now.
+ if (extensionInfo.exposeExperimentalAPIs !== false) {
+ chrome.experimental = chrome.experimental || {};
+ chrome.experimental.devtools = chrome.experimental.devtools || {};
+
+ var properties = Object.getOwnPropertyNames(coreAPI);
+ for (var i = 0; i < properties.length; ++i) {
+ var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
+ Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
}
- return object[newName];
+ chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
}
- object.__defineGetter__(oldName, getter);
+ if (extensionInfo.exposeWebInspectorNamespace)
+ window.webInspector = coreAPI;
}
-function extractCallbackArgument(args)
+/**
+ * @param {!ExtensionDescriptor} extensionInfo
+ * @return {string}
+ */
+function buildPlatformExtensionAPI(extensionInfo)
{
- var lastArgument = args[args.length - 1];
- return typeof lastArgument === "function" ? lastArgument : undefined;
-}
-
-var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
-var AuditResult = declareInterfaceClass(AuditResultImpl);
-var Button = declareInterfaceClass(ButtonImpl);
-var EventSink = declareInterfaceClass(EventSinkImpl);
-var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
-var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
-var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
-var Request = declareInterfaceClass(RequestImpl);
-var Resource = declareInterfaceClass(ResourceImpl);
-var Timeline = declareInterfaceClass(TimelineImpl);
-
-// extensionServer is a closure variable defined by the glue below -- make sure we fail if it's not there.
-if (!extensionServer)
- extensionServer = new ExtensionServerClient();
-
-return new InspectorExtensionAPI();
+ return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
+ "var tabId = " + WebInspector._inspectedTabId + ";" +
+ platformExtensionAPI.toString();
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAuditCategory.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAuditCategory.js
index e9bfdd9c0a4..d2bc12bfe9a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionAuditCategory.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionAuditCategory.js
@@ -30,7 +30,7 @@
/**
* @constructor
- * @extends {WebInspector.AuditCategory}
+ * @implements {WebInspector.AuditCategory}
* @param {string} extensionOrigin
* @param {string} id
* @param {string} displayName
@@ -45,26 +45,33 @@ WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName,
}
WebInspector.ExtensionAuditCategory.prototype = {
- // AuditCategory interface
+ /**
+ * @override
+ */
get id()
{
return this._id;
},
+ /**
+ * @override
+ */
get displayName()
{
return this._displayName;
},
/**
+ * @override
+ * @param {!WebInspector.Target} target
* @param {!Array.<!WebInspector.NetworkRequest>} requests
- * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
+ * @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {function()} categoryDoneCallback
* @param {!WebInspector.Progress} progress
*/
- run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
+ run: function(target, requests, ruleResultCallback, categoryDoneCallback, progress)
{
- var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
+ var results = new WebInspector.ExtensionAuditCategoryResults(this, target, ruleResultCallback, categoryDoneCallback, progress);
WebInspector.extensionServer.startAuditRun(this, results);
}
}
@@ -72,12 +79,14 @@ WebInspector.ExtensionAuditCategory.prototype = {
/**
* @constructor
* @param {!WebInspector.ExtensionAuditCategory} category
+ * @param {!WebInspector.Target} target
* @param {function(!WebInspector.AuditRuleResult)} ruleResultCallback
* @param {function()} categoryDoneCallback
* @param {!WebInspector.Progress} progress
*/
-WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
+WebInspector.ExtensionAuditCategoryResults = function(category, target, ruleResultCallback, categoryDoneCallback, progress)
{
+ this._target = target;
this._category = category;
this._ruleResultCallback = ruleResultCallback;
this._categoryDoneCallback = categoryDoneCallback;
@@ -147,15 +156,16 @@ WebInspector.ExtensionAuditCategoryResults.prototype = {
* @param {?string} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
+ * @this {WebInspector.ExtensionAuditCategoryResults}
*/
function onEvaluate(error, result, wasThrown)
{
if (wasThrown)
return;
- var object = WebInspector.RemoteObject.fromPayload(result);
+ var object = this._target.runtimeModel.createRemoteObject(result);
callback(object);
}
- WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
+ WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate.bind(this));
}
}
@@ -165,6 +175,7 @@ WebInspector.ExtensionAuditFormatters = {
* @param {string} expression
* @param {string} title
* @param {?Object} evaluateOptions
+ * @return {!Element}
*/
object: function(expression, title, evaluateOptions)
{
@@ -184,22 +195,23 @@ WebInspector.ExtensionAuditFormatters = {
* @this {WebInspector.ExtensionAuditCategoryResults}
* @param {string} expression
* @param {?Object} evaluateOptions
+ * @return {!Element}
*/
node: function(expression, evaluateOptions)
{
var parentElement = document.createElement("div");
/**
- * @param {?number} nodeId
+ * @param {?WebInspector.DOMNode} node
*/
- function onNodeAvailable(nodeId)
+ function onNodeAvailable(node)
{
- if (!nodeId)
+ if (!node)
return;
- var treeOutline = new WebInspector.ElementsTreeOutline(false, false);
- treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
- treeOutline.element.classList.add("outline-disclosure");
- treeOutline.setVisible(true);
- parentElement.appendChild(treeOutline.element);
+ var renderer = WebInspector.moduleManager.instance(WebInspector.Renderer, node);
+ if (renderer)
+ parentElement.appendChild(renderer.render(node));
+ else
+ console.error("No renderer for node found");
}
/**
* @param {!WebInspector.RemoteObject} remoteObject
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js
index 9f4315e9a21..636f642b48f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js
@@ -51,6 +51,9 @@ WebInspector.ExtensionPanel = function(id, pageURL)
}
WebInspector.ExtensionPanel.prototype = {
+ /**
+ * @return {!Element}
+ */
defaultFocusedElement: function()
{
return WebInspector.View.prototype.defaultFocusedElement.call(this);
@@ -82,8 +85,9 @@ WebInspector.ExtensionPanel.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump)
+ performSearch: function(query, shouldJump, jumpBackwards)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
},
@@ -167,12 +171,14 @@ WebInspector.ExtensionSidebarPane.prototype = {
/**
* @param {string} expression
* @param {string} title
+ * @param {!Object} evaluateOptions
+ * @param {string} securityOrigin
* @param {function(?string=)} callback
*/
setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
{
this._createObjectPropertiesView();
- return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
+ WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
},
/**
@@ -214,7 +220,7 @@ WebInspector.ExtensionSidebarPane.prototype = {
if (error)
callback(error.toString());
else
- this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback);
+ this._setObject(WebInspector.runtimeModel.createRemoteObject(result), title, callback);
},
_createObjectPropertiesView: function()
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionRegistryStub.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionRegistryStub.js
index 258088024c3..258088024c3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionRegistryStub.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionRegistryStub.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionServer.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
index 3f036001f04..b339ec7a311 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionServer.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
@@ -28,8 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+importScript("ExtensionAPI.js");
+importScript("ExtensionRegistryStub.js");
+importScript("ExtensionAuditCategory.js");
+
/**
* @constructor
+ * @implements {WebInspector.ExtensionServerAPI}
*/
WebInspector.ExtensionServer = function()
{
@@ -74,11 +80,15 @@ WebInspector.ExtensionServer = function()
this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));
-
window.addEventListener("message", this._onWindowMessage.bind(this), false);
+
+ this._initExtensions();
}
WebInspector.ExtensionServer.prototype = {
+ /**
+ * @return {boolean}
+ */
hasExtensions: function()
{
return !!Object.keys(this._registeredExtensions).length;
@@ -210,11 +220,11 @@ WebInspector.ExtensionServer.prototype = {
var id = message.id;
// The ids are generated on the client API side and must be unique, so the check below
// shouldn't be hit unless someone is bypassing the API.
- if (id in this._clientObjects || id in WebInspector.panels)
+ if (id in this._clientObjects || WebInspector.inspectorView.hasPanel(id))
return this._status.E_EXISTS(id);
var page = this._expandResourcePath(port._extensionOrigin, message.page);
- var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page));
+ var panelDescriptor = new WebInspector.ExtensionServerPanelDescriptor(id, message.title, new WebInspector.ExtensionPanel(id, page));
this._clientObjects[id] = panelDescriptor.panel();
WebInspector.inspectorView.addPanel(panelDescriptor);
return this._status.OK();
@@ -222,8 +232,8 @@ WebInspector.ExtensionServer.prototype = {
_onShowPanel: function(message)
{
- // Note: WebInspector.showPanel already sanitizes input.
- WebInspector.showPanel(message.id);
+ // Note: WebInspector.inspectorView.showPanel already sanitizes input.
+ WebInspector.inspectorView.showPanel(message.id);
},
_onCreateStatusBarButton: function(message, port)
@@ -248,7 +258,7 @@ WebInspector.ExtensionServer.prototype = {
_onCreateSidebarPane: function(message)
{
- var panel = WebInspector.panel(message.panel);
+ var panel = WebInspector.inspectorView.panel(message.panel);
if (!panel)
return this._status.E_NOTFOUND(message.panel);
if (!panel.addExtensionSidebarPane)
@@ -299,10 +309,25 @@ WebInspector.ExtensionServer.prototype = {
_onOpenResource: function(message)
{
- var a = document.createElement("a");
- a.href = message.url;
- a.lineNumber = message.lineNumber;
- return WebInspector.showAnchorLocation(a) ? this._status.OK() : this._status.E_NOTFOUND(message.url);
+ var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(message.url);
+ if (uiSourceCode) {
+ WebInspector.Revealer.reveal(uiSourceCode.uiLocation(message.lineNumber, 0));
+ return this._status.OK();
+ }
+
+ var resource = WebInspector.resourceForURL(message.url);
+ if (resource) {
+ WebInspector.Revealer.reveal(resource, message.lineNumber);
+ return this._status.OK();
+ }
+
+ var request = WebInspector.networkLog.requestForURL(message.url);
+ if (request) {
+ WebInspector.Revealer.reveal(request);
+ return this._status.OK();
+ }
+
+ return this._status.E_NOTFOUND(message.url);
},
_onSetOpenResourceHandler: function(message, port)
@@ -391,7 +416,8 @@ WebInspector.ExtensionServer.prototype = {
if (!level)
return this._status.E_BADARG("message.severity", message.severity);
- var consoleMessage = WebInspector.ConsoleMessage.create(
+ var consoleMessage = new WebInspector.ConsoleMessage(
+ WebInspector.console.target(),
WebInspector.ConsoleMessage.MessageSource.JS,
level,
message.text,
@@ -422,7 +448,7 @@ WebInspector.ExtensionServer.prototype = {
}
var result = {
severity: convertLevel(message.level),
- text: message.text,
+ text: message.messageText,
};
if (message.url)
result.url = message.url;
@@ -433,6 +459,8 @@ WebInspector.ExtensionServer.prototype = {
_onGetHAR: function()
{
+ // Wake up the "network" module for HAR operations.
+ WebInspector.inspectorView.panel("network");
var requests = WebInspector.networkLog.requests;
var harLog = (new WebInspector.HARLog(requests)).build();
for (var i = 0; i < harLog.entries.length; ++i)
@@ -467,6 +495,7 @@ WebInspector.ExtensionServer.prototype = {
resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
}
var uiSourceCodes = WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.Network);
+ uiSourceCodes = uiSourceCodes.concat(WebInspector.workspace.uiSourceCodesForProjectType(WebInspector.projectTypes.ContentScripts));
uiSourceCodes.forEach(pushResourceData.bind(this));
WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this));
return Object.values(resources);
@@ -474,6 +503,8 @@ WebInspector.ExtensionServer.prototype = {
/**
* @param {!WebInspector.ContentProvider} contentProvider
+ * @param {!Object} message
+ * @param {!MessagePort} port
*/
_getResourceContent: function(contentProvider, message, port)
{
@@ -554,10 +585,11 @@ WebInspector.ExtensionServer.prototype = {
_onAddAuditCategory: function(message, port)
{
var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
- if (WebInspector.panel("audits").getCategory(category.id))
+ if (WebInspector.inspectorView.panel("audits").getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[message.id] = category;
- WebInspector.panel("audits").addCategory(category);
+ // FIXME: register module manager extension instead of waking up audits module.
+ WebInspector.inspectorView.panel("audits").addCategory(category);
},
_onAddAuditResult: function(message)
@@ -592,20 +624,37 @@ WebInspector.ExtensionServer.prototype = {
_onForwardKeyboardEvent: function(message)
{
const Esc = "U+001B";
+ message.entries.forEach(handleEventEntry);
- if (!message.ctrlKey && !message.altKey && !message.metaKey && !/^F\d+$/.test(message.keyIdentifier) && message.keyIdentifier !== Esc)
- return;
- // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
- // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
- var event = new window.KeyboardEvent(message.eventType, {
- keyIdentifier: message.keyIdentifier,
- location: message.location,
- ctrlKey: message.ctrlKey,
- altKey: message.altKey,
- shiftKey: message.shiftKey,
- metaKey: message.metaKey
- });
- document.dispatchEvent(event);
+ function handleEventEntry(entry)
+ {
+ if (!entry.ctrlKey && !entry.altKey && !entry.metaKey && !/^F\d+$/.test(entry.keyIdentifier) && entry.keyIdentifier !== Esc)
+ return;
+ // Fool around closure compiler -- it has its own notion of both KeyboardEvent constructor
+ // and initKeyboardEvent methods and overriding these in externs.js does not have effect.
+ var event = new window.KeyboardEvent(entry.eventType, {
+ keyIdentifier: entry.keyIdentifier,
+ location: entry.location,
+ ctrlKey: entry.ctrlKey,
+ altKey: entry.altKey,
+ shiftKey: entry.shiftKey,
+ metaKey: entry.metaKey
+ });
+ event.__keyCode = keyCodeForEntry(entry);
+ document.dispatchEvent(event);
+ }
+
+ function keyCodeForEntry(entry)
+ {
+ var keyCode = entry.keyCode;
+ if (!keyCode) {
+ // This is required only for synthetic events (e.g. dispatched in tests).
+ var match = entry.keyIdentifier.match(/^U\+([\dA-Fa-f]+)$/);
+ if (match)
+ keyCode = parseInt(match[1], 16);
+ }
+ return keyCode || 0;
+ }
},
_dispatchCallback: function(requestId, port, result)
@@ -614,7 +663,7 @@ WebInspector.ExtensionServer.prototype = {
port.postMessage({ command: "callback", requestId: requestId, result: result });
},
- initExtensions: function()
+ _initExtensions: function()
{
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded,
WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded);
@@ -624,18 +673,31 @@ WebInspector.ExtensionServer.prototype = {
WebInspector.workspace,
WebInspector.Workspace.Events.UISourceCodeAdded,
this._notifyResourceAdded);
- this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements",
- WebInspector.notifications,
- WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged,
- this._notifyElementsSelectionChanged);
+
+ /**
+ * @this {WebInspector.ExtensionServer}
+ */
+ function onElementsSubscriptionStarted()
+ {
+ WebInspector.notifications.addEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, this._notifyElementsSelectionChanged, this);
+ }
+
+ /**
+ * @this {WebInspector.ExtensionServer}
+ */
+ function onElementsSubscriptionStopped()
+ {
+ WebInspector.notifications.removeEventListener(WebInspector.NotificationService.Events.SelectedNodeChanged, this._notifyElementsSelectionChanged, this);
+ }
+
+ this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected + "elements",
+ onElementsSubscriptionStarted.bind(this), onElementsSubscriptionStopped.bind(this));
+
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.PanelObjectSelected + "sources",
WebInspector.notifications,
WebInspector.SourceFrame.Events.SelectionChanged,
this._notifySourceFrameSelectionChanged);
- this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
- WebInspector.workspace,
- WebInspector.Workspace.Events.UISourceCodeContentCommitted,
- this._notifyUISourceCodeContentCommitted);
+ this._registerResourceContentCommittedHandler(this._notifyUISourceCodeContentCommitted);
/**
* @this {WebInspector.ExtensionServer}
@@ -652,7 +714,7 @@ WebInspector.ExtensionServer.prototype = {
*/
function onTimelineSubscriptionStopped()
{
- WebInspector.timelineManager.stop();
+ WebInspector.timelineManager.stop(function() {});
WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
}
@@ -663,11 +725,6 @@ WebInspector.ExtensionServer.prototype = {
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,
this._inspectedURLChanged, this);
- this._initDone = true;
- if (this._pendingExtensions) {
- this._pendingExtensions.forEach(this._innerAddExtension, this);
- delete this._pendingExtensions;
- }
InspectorExtensionRegistry.getExtensionsAsync();
},
@@ -682,7 +739,7 @@ WebInspector.ExtensionServer.prototype = {
startColumn: textRange.startColumn,
endLine: textRange.endLine,
endColumn: textRange.endColumn,
- url: sourcesPanel.tabbedEditorContainer.currentFile().uri()
+ url: sourcesPanel.sourcesView().currentUISourceCode().uri()
};
return selection;
@@ -714,6 +771,8 @@ WebInspector.ExtensionServer.prototype = {
_notifyRequestFinished: function(event)
{
var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
+ // Wake up the "network" module for HAR operations.
+ WebInspector.inspectorView.panel("network");
this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
},
@@ -728,11 +787,11 @@ WebInspector.ExtensionServer.prototype = {
},
/**
- * @param {!Array.<!ExtensionDescriptor>} extensions
+ * @param {!Array.<!ExtensionDescriptor>} extensionInfos
*/
- _addExtensions: function(extensions)
+ addExtensions: function(extensionInfos)
{
- extensions.forEach(this._addExtension, this);
+ extensionInfos.forEach(this._addExtension, this);
},
/**
@@ -740,21 +799,6 @@ WebInspector.ExtensionServer.prototype = {
*/
_addExtension: function(extensionInfo)
{
- if (this._initDone) {
- this._innerAddExtension(extensionInfo);
- return;
- }
- if (this._pendingExtensions)
- this._pendingExtensions.push(extensionInfo);
- else
- this._pendingExtensions = [extensionInfo];
- },
-
- /**
- * @param {!ExtensionDescriptor} extensionInfo
- */
- _innerAddExtension: function(extensionInfo)
- {
const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/"); // Can't use regexp literal here, MinJS chokes on it.
var startPage = extensionInfo.startPage;
var name = extensionInfo.name;
@@ -767,7 +811,7 @@ WebInspector.ExtensionServer.prototype = {
}
var extensionOrigin = originMatch[1];
if (!this._registeredExtensions[extensionOrigin]) {
- // See ExtensionAPI.js and ExtensionCommon.js for details.
+ // See ExtensionAPI.js for details.
InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo));
this._registeredExtensions[extensionOrigin] = { name: name };
}
@@ -782,12 +826,6 @@ WebInspector.ExtensionServer.prototype = {
return true;
},
- _onWindowMessage: function(event)
- {
- if (event.data === "registerExtension")
- this._registerExtension(event.origin, event.ports[0]);
- },
-
_registerExtension: function(origin, port)
{
if (!this._registeredExtensions.hasOwnProperty(origin)) {
@@ -800,6 +838,12 @@ WebInspector.ExtensionServer.prototype = {
port.start();
},
+ _onWindowMessage: function(event)
+ {
+ if (event.data === "registerExtension")
+ this._registerExtension(event.origin, event.ports[0]);
+ },
+
_onmessage: function(event)
{
var message = event.data;
@@ -822,8 +866,8 @@ WebInspector.ExtensionServer.prototype = {
_registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
{
- this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
- this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
+ this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
+ this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
},
_registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
@@ -833,6 +877,31 @@ WebInspector.ExtensionServer.prototype = {
eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
},
+ _registerResourceContentCommittedHandler: function(handler)
+ {
+ /**
+ * @this {WebInspector.ExtensionServer}
+ */
+ function addFirstEventListener()
+ {
+ WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeContentCommitted, handler, this);
+ WebInspector.workspace.setHasResourceContentTrackingExtensions(true);
+ }
+
+ /**
+ * @this {WebInspector.ExtensionServer}
+ */
+ function removeLastEventListener()
+ {
+ WebInspector.workspace.setHasResourceContentTrackingExtensions(false);
+ WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeContentCommitted, handler, this);
+ }
+
+ this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
+ addFirstEventListener.bind(this),
+ removeLastEventListener.bind(this));
+ },
+
_expandResourcePath: function(extensionPath, resourcePath)
{
if (!resourcePath)
@@ -866,6 +935,7 @@ WebInspector.ExtensionServer.prototype = {
* @param {?Object} options
* @param {string} securityOrigin
* @param {function(?string, !RuntimeAgent.RemoteObject, boolean=)} callback
+ * @return {!WebInspector.ExtensionStatus.Record|undefined}
*/
evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback)
{
@@ -903,16 +973,26 @@ WebInspector.ExtensionServer.prototype = {
else if (options.scriptExecutionContext)
contextSecurityOrigin = options.scriptExecutionContext;
- var frameContextList = WebInspector.runtimeModel.contextListByFrame(frame);
var context;
+ var executionContexts = WebInspector.runtimeModel.executionContexts();
if (contextSecurityOrigin) {
- context = frameContextList.contextBySecurityOrigin(contextSecurityOrigin);
+ for (var i = 0; i < executionContexts.length; ++i) {
+ var executionContext = executionContexts[i];
+ if (executionContext.frameId === frame.id && executionContext.name === contextSecurityOrigin && !executionContext.isMainWorldContext)
+ context = executionContext;
+
+ }
if (!context) {
- console.warn("The JS context " + contextSecurityOrigin + " was not found in the frame " + frame.url)
+ console.warn("The JavaScript context " + contextSecurityOrigin + " was not found in the frame " + frame.url)
return this._status.E_NOTFOUND(contextSecurityOrigin)
}
} else {
- context = frameContextList.mainWorldContext();
+ for (var i = 0; i < executionContexts.length; ++i) {
+ var executionContext = executionContexts[i];
+ if (executionContext.frameId === frame.id && executionContext.isMainWorldContext)
+ context = executionContext;
+
+ }
if (!context)
return this._status.E_FAILED(frame.url + " has no execution context");
}
@@ -925,9 +1005,54 @@ WebInspector.ExtensionServer.prototype = {
/**
* @constructor
+ * @param {string} name
+ * @param {string} title
+ * @param {!WebInspector.Panel} panel
+ * @implements {WebInspector.PanelDescriptor}
+ */
+WebInspector.ExtensionServerPanelDescriptor = function(name, title, panel)
+{
+ this._name = name;
+ this._title = title;
+ this._panel = panel;
+}
+
+WebInspector.ExtensionServerPanelDescriptor.prototype = {
+ /**
+ * @return {string}
+ */
+ name: function()
+ {
+ return this._name;
+ },
+
+ /**
+ * @return {string}
+ */
+ title: function()
+ {
+ return this._title;
+ },
+
+ /**
+ * @return {!WebInspector.Panel}
+ */
+ panel: function()
+ {
+ return this._panel;
+ }
+}
+
+/**
+ * @constructor
*/
WebInspector.ExtensionStatus = function()
{
+ /**
+ * @param {string} code
+ * @param {string} description
+ * @return {!WebInspector.ExtensionStatus.Record}
+ */
function makeStatus(code, description)
{
var details = Array.prototype.slice.call(arguments, 2);
@@ -949,20 +1074,13 @@ WebInspector.ExtensionStatus = function()
this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
}
-WebInspector.addExtensions = function(extensions)
-{
- WebInspector.extensionServer._addExtensions(extensions);
-}
+/**
+ * @typedef {{code: string, description: string, details: !Array.<*>}}
+ */
+WebInspector.ExtensionStatus.Record;
WebInspector.extensionAPI = {};
defineCommonExtensionSymbols(WebInspector.extensionAPI);
-WebInspector.extensionServer = new WebInspector.ExtensionServer();
-
-window.addExtension = function(page, name)
-{
- WebInspector.extensionServer._addExtension({
- startPage: page,
- name: name,
- });
-}
+importScript("ExtensionPanel.js");
+importScript("ExtensionView.js");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionView.js b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionView.js
index 08cad1d8038..d3eb764327e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ExtensionView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionView.js
@@ -38,7 +38,7 @@
WebInspector.ExtensionView = function(id, src, className)
{
WebInspector.View.call(this);
- this.element.className = "extension-view";
+ this.element.className = "extension-view fill"; // Override
this._id = id;
this._iframe = document.createElement("iframe");
@@ -76,12 +76,12 @@ WebInspector.ExtensionView.prototype = {
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {string} id
*/
WebInspector.ExtensionNotifierView = function(id)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._id = id;
}
@@ -97,5 +97,5 @@ WebInspector.ExtensionNotifierView.prototype = {
WebInspector.extensionServer.notifyViewHidden(this._id);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/extensions/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/module.json
new file mode 100644
index 00000000000..9b9f1a06c89
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/extensions/module.json
@@ -0,0 +1,10 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.ExtensionServerAPI",
+ "className": "WebInspector.ExtensionServer"
+ }
+ ],
+ "dependencies": [ "sources" ],
+ "scripts": [ "ExtensionServer.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/externs.js b/chromium/third_party/WebKit/Source/devtools/front_end/externs.js
index 725591ef995..8ab77052a16 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/externs.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/externs.js
@@ -31,55 +31,17 @@
// WebKit Web Facing API
/** @type {boolean} */
-Event.prototype.isMetaOrCtrlForTest = false;
-/** @param {...*} vararg */
-Event.prototype.initWebKitWheelEvent = function(vararg) {}
-Event.prototype.stopImmediatePropagation = function() {}
-
-/**
- * @constructor
- * @extends {KeyboardEvent}
- * @param {string} eventType
- * @param {!Object=} properties
- */
-window.KeyboardEvent = function(eventType, properties) {}
+Event.prototype.isMetaOrCtrlForTest;
/**
* @type {number}
*/
KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
-/** @param {?Element} element */
-window.getComputedStyle = function(element) {}
+// FIXME: Remove after the Closure compiler roll.
/** @param {*} message */
function postMessage(message) {}
-/** @type {*} */
-window.testRunner = null;
-
-/**
- * @constructor
- */
-function WebKitMutation(callback)
-{
- this.type = "";
- /** @type {Node} */ this.target = null;
- /** @type {!Array.<!Node>} */ this.addedNodes = [];
- /** @type {!Array.<!Node>} */ this.removedNodes = [];
-}
-
-/**
- * @constructor
- * @param {function(!Array.<!WebKitMutation>)} callback
- */
-function WebKitMutationObserver(callback) {}
-/**
- * @param {!Node} container
- * @param {!Object} options
- */
-WebKitMutationObserver.prototype.observe = function(container, options) {}
-WebKitMutationObserver.prototype.disconnect = function() {}
-
/**
* @param {string} eventName
* @param {!Function} listener
@@ -95,6 +57,12 @@ function addEventListener(eventName, listener, capturing) {}
*/
Array.prototype.remove = function(value, onlyFirst) {}
/**
+ * @param {!Array.<!T>} array
+ * @this {Array.<!T>}
+ * @template T
+ */
+Array.prototype.pushAll = function(array) {}
+/**
* @return {!Object.<string, boolean>}
* @this {Array.<T>}
* @template T
@@ -108,6 +76,10 @@ Array.prototype.keySet = function() {}
*/
Array.prototype.rotate = function(index) {}
/**
+ * @this {Array.<number>}
+ */
+Array.prototype.sortNumbers = function() {}
+/**
* @param {!T} object
* @param {function(!T,!S):number=} comparator
* @return {number}
@@ -201,13 +173,6 @@ Array.prototype.intersectOrdered = function(array, comparator) {}
*/
Array.prototype.mergeOrdered = function(array, comparator) {}
-DOMApplicationCache.prototype.UNCACHED = 0;
-DOMApplicationCache.prototype.IDLE = 1;
-DOMApplicationCache.prototype.CHECKING = 2;
-DOMApplicationCache.prototype.DOWNLOADING = 3;
-DOMApplicationCache.prototype.UPDATEREADY = 4;
-DOMApplicationCache.prototype.OBSOLETE = 5;
-
// File System API
/**
* @constructor
@@ -219,140 +184,84 @@ function DOMFileSystem() {}
*/
DOMFileSystem.prototype.root = null;
-/** @type {Node} */
-Range.prototype.startContainer;
-
-// Inspector Backend
-var InspectorBackend = {}
-InspectorBackend.runAfterPendingDispatches = function(message) {}
-
/** @interface */
function InspectorFrontendHostAPI() {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.addFileSystem = function(callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.append = function(url, content, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.indexPath = function(requestId, fileSystemPath, callback) {}
+/** @return {string} */
+InspectorFrontendHostAPI.prototype.getSelectionBackgroundColor = function() {}
+/** @return {string} */
+InspectorFrontendHostAPI.prototype.getSelectionForegroundColor = function() {}
+/** @return {boolean} */
+InspectorFrontendHost.isUnderTest = function() {}
/**
- * @param top
- * @param left
- * @param bottom
- * @param right
+ * Requests inspected page to be placed atop of the inspector frontend with specified bounds.
+ * @param {{x: number, y: number, width: number, height: number}} bounds
*/
-InspectorFrontendHostAPI.prototype.setContentsInsets = function(top, left, bottom, right) {}
-/** @param {!Function=} callback callback */
+InspectorFrontendHostAPI.prototype.setInspectedPageBounds = function(bounds) {}
+/**
+ * Requests inspected page to be placed atop of the inspector frontend
+ * with passed insets from the frontend sides, respecting minimum size passed.
+ * @param {{top: number, left: number, right: number, bottom: number}} insets
+ * @param {{width: number, height: number}} minSize
+ */
+InspectorFrontendHostAPI.prototype.setContentsResizingStrategy = function(insets, minSize) {}
+/** @param {string} shortcuts */
+InspectorFrontendHostAPI.prototype.setWhitelistedShortcuts = function(shortcuts) {}
+InspectorFrontendHostAPI.prototype.inspectElementCompleted = function() {}
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.moveWindowBy = function(x, y, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.openInNewTab = function(url, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.removeFileSystem = function(fileSystemPath, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.requestFileSystems = function(callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.save = function(url, content, forceSaveAs, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.searchInPath = function(requestId, fileSystemPath, query, callback) {}
-/** @param {!Function=} callback callback */
+/** @param {!Function=} callback */
InspectorFrontendHostAPI.prototype.stopIndexing = function(requestId, callback) {}
InspectorFrontendHostAPI.prototype.bringToFront = function() {}
-InspectorFrontendHostAPI.prototype.close = function(url) {}
+InspectorFrontendHostAPI.prototype.openUrlOnRemoteDeviceAndInspect = function(browserId, url) {}
InspectorFrontendHostAPI.prototype.closeWindow = function() {}
InspectorFrontendHostAPI.prototype.copyText = function(text) {}
InspectorFrontendHostAPI.prototype.inspectedURLChanged = function(url) {}
InspectorFrontendHostAPI.prototype.isolatedFileSystem = function(fileSystemId, registeredName) {}
InspectorFrontendHostAPI.prototype.upgradeDraggedFileSystemPermissions = function(DOMFileSystem) {}
-InspectorFrontendHostAPI.prototype.loaded = function() {}
-InspectorFrontendHostAPI.prototype.localizedStringsURL = function() {}
InspectorFrontendHostAPI.prototype.platform = function() {}
InspectorFrontendHostAPI.prototype.port = function() {}
InspectorFrontendHostAPI.prototype.recordActionTaken = function(actionCode) {}
InspectorFrontendHostAPI.prototype.recordPanelShown = function(panelCode) {}
-InspectorFrontendHostAPI.prototype.recordSettingChanged = function(settingCode) {}
-InspectorFrontendHostAPI.prototype.requestSetDockSide = function(dockSide) {}
InspectorFrontendHostAPI.prototype.sendMessageToBackend = function(message) {}
InspectorFrontendHostAPI.prototype.sendMessageToEmbedder = function(message) {}
InspectorFrontendHostAPI.prototype.setInjectedScriptForOrigin = function(origin, script) {}
+InspectorFrontendHostAPI.prototype.setIsDocked = function(isDocked, callback) {}
InspectorFrontendHostAPI.prototype.setZoomFactor = function(zoom) {}
-InspectorFrontendHostAPI.prototype.supportsFileSystems = function() {}
+InspectorFrontendHostAPI.prototype.subscribe = function(eventType) {}
+InspectorFrontendHostAPI.prototype.unsubscribe = function(eventType) {}
+InspectorFrontendHostAPI.prototype.zoomFactor = function() {}
+InspectorFrontendHostAPI.prototype.zoomIn = function() {}
+InspectorFrontendHostAPI.prototype.zoomOut = function() {}
+InspectorFrontendHostAPI.prototype.resetZoom = function() {}
/** @type {InspectorFrontendHostAPI} */
var InspectorFrontendHost;
-
-/** @constructor */
-function SourceMapV3()
-{
- /** @type {number} */ this.version;
- /** @type {string} */ this.file;
- /** @type {!Array.<string>} */ this.sources;
- /** @type {!Array.<!SourceMapV3.Section>} */ this.sections;
- /** @type {string} */ this.mappings;
- /** @type {string} */ this.sourceRoot;
-}
-
-/** @constructor */
-SourceMapV3.Section = function()
-{
- /** @type {SourceMapV3} */ this.map;
- /** @type {SourceMapV3.Offset} */ this.offset;
-}
-
-/** @constructor */
-SourceMapV3.Offset = function()
-{
- /** @type {number} */ this.line;
- /** @type {number} */ this.column;
-}
+InspectorFrontendHost.embedderMessageAck = function(id, error) {}
// FIXME: remove everything below.
var FormatterWorker = {}
var WebInspector = {}
-WebInspector.queryParamsObject = {}
-WebInspector.toggleSearchingForNode = function() {}
WebInspector.panels = {};
+WebInspector.inspectorFrontendEventSink = {};
-/**
- * @param {string=} messageLevel
- * @param {boolean=} showConsole
- */
-WebInspector.log = function(message, messageLevel, showConsole) {}
-
-WebInspector.showErrorMessage = function(error) {}
-
-WebInspector.addMainEventListeners = function(doc) {}
-
-WebInspector.openResource = function(url, external) {}
-
-WebInspector.showConsole = function() {}
-
-/**
- * @param {string} expression
- * @param {boolean=} showResultOnly
- */
-WebInspector.evaluateInConsole = function(expression, showResultOnly) {}
-
-WebInspector.queryParamsObject = {}
-
-/**
- * @param {!Element} element
- * @return {boolean}
- */
-WebInspector.showAnchorLocation = function(element) {}
-
-WebInspector.Events = {
- InspectorLoaded: "InspectorLoaded",
- InspectorClosing: "InspectorClosing"
-}
-
-/** @type {!WebInspector.SettingsController} */
-WebInspector.settingsController;
-
-
-/**
- * @return {number}
- */
-WebInspector.zoomFactor = function() {}
+WebInspector.reload = function() { }
/** Extensions API */
@@ -377,9 +286,6 @@ function Timeline() {}
var extensionServer;
-/** @type {string} */
-Location.prototype.origin = "";
-
/**
* @constructor
*/
@@ -398,31 +304,6 @@ function ExtensionReloadOptions() {
this.userAgent = "";
}
-WebInspector.showPanel = function(panel)
-{
-}
-
-/**
- * @param {!ExtensionDescriptor} extensionInfo
- * @return {string}
- */
-function buildPlatformExtensionAPI(extensionInfo) {}
-
-/**
- * @type {string}
- */
-WebInspector.inspectedPageDomain;
-
-WebInspector.SourceJavaScriptTokenizer = {}
-WebInspector.SourceJavaScriptTokenizer.Keywords = {}
-
-/**
- * @return {boolean}
- */
-WebInspector.isInspectingDevice = function() {}
-
-var InspectorTest = {}
-
/* jsdifflib API */
var difflib = {};
difflib.stringAsLines = function(text) { return []; }
@@ -431,11 +312,23 @@ difflib.SequenceMatcher = function(baseText, newText) { }
difflib.SequenceMatcher.prototype.get_opcodes = function() { return []; }
/** @constructor */
-var CodeMirror = function() { }
+var Doc = function() { }
+Doc.prototype = {
+ /** @type {number} */
+ scrollLeft: 0,
+ /** @type {number} */
+ scrollTop: 0
+}
+
+/** @constructor */
+var CodeMirror = function(element, config) { }
CodeMirror.on = function(obj, type, handler) { }
CodeMirror.prototype = {
+ /** @type {!Doc} */
+ doc: null,
addKeyMap: function(map) { },
addLineClass: function(handle, where, cls) { },
+ /** @param {?Object=} options */
addLineWidget: function(handle, node, options) { },
/**
* @param {string|!Object} spec
@@ -447,11 +340,17 @@ CodeMirror.prototype = {
clearGutter: function(gutterID) { },
clearHistory: function() { },
clipPos: function(pos) { },
+ /** @param {string=} mode */
coordsChar: function(coords, mode) { },
+ /** @param {string=} mode */
cursorCoords: function(start, mode) { },
defaultCharWidth: function() { },
defaultTextHeight: function() { },
deleteH: function(dir, unit) { },
+ /**
+ * @param {*=} to
+ * @param {*=} op
+ */
eachLine: function(from, to, op) { },
execCommand: function(cmd) { },
extendSelection: function(from, to) { },
@@ -476,6 +375,7 @@ CodeMirror.prototype = {
getLineNumber: function(line) { },
getMode: function() { },
getOption: function(option) { },
+ /** @param {*=} lineSep */
getRange: function(from, to, lineSep) { },
/**
* @return {!{left: number, top: number, width: number, height: number, clientWidth: number, clientHeight: number}}
@@ -483,8 +383,10 @@ CodeMirror.prototype = {
getScrollInfo: function() { },
getScrollerElement: function() { },
getSelection: function() { },
+ getSelections: function() { },
getStateAfter: function(line) { },
getTokenAt: function(pos) { },
+ /** @param {*=} lineSep */
getValue: function(lineSep) { },
getViewport: function() { },
getWrapperElement: function() { },
@@ -504,6 +406,7 @@ CodeMirror.prototype = {
*/
lineAtHeight: function(height, mode) { },
linkedDoc: function(options) { },
+ listSelections: function() { },
markClean: function() { },
markText: function(from, to, options) { },
moveH: function(dir, unit) { },
@@ -519,8 +422,10 @@ CodeMirror.prototype = {
removeLineClass: function(handle, where, cls) { },
removeLineWidget: function(widget) { },
removeOverlay: function(spec) { },
+ /** @param {*=} origin */
replaceRange: function(code, from, to, origin) { },
replaceSelection: function(code, collapse, origin) { },
+ /** @param {*=} margin */
scrollIntoView: function(pos, margin) { },
scrollTo: function(x, y) { },
setBookmark: function(pos, options) { },
@@ -531,6 +436,11 @@ CodeMirror.prototype = {
setLine: function(line, text) { },
setOption: function(option, value) { },
setSelection: function(anchor, head) { },
+ /**
+ * @param {number=} primaryIndex
+ * @param {?Object=} config
+ */
+ setSelections: function(selections, primaryIndex, config) { },
setSize: function(width, height) { },
setValue: function(code) { },
somethingSelected: function() { },
@@ -538,8 +448,9 @@ CodeMirror.prototype = {
undo: function() { },
unlinkDoc: function(other) { }
}
-/** @type {number} */
-CodeMirror.prototype.lineCount;
+/** @type {!{cursorDiv: Element}} */
+CodeMirror.prototype.display;
+/** @type {!Object} */
CodeMirror.Pass;
CodeMirror.showHint = function(codeMirror, hintintFunction) { };
CodeMirror.commands = {};
@@ -552,9 +463,9 @@ CodeMirror.startState = function(mode) { };
/** @constructor */
CodeMirror.Pos = function(line, ch) { }
-/** type {number} */
+/** @type {number} */
CodeMirror.Pos.prototype.line;
-/** type {number} */
+/** @type {number} */
CodeMirror.Pos.prototype.ch;
/** @constructor */
@@ -588,15 +499,17 @@ CodeMirror.StringStream.prototype = {
/** @type {Object.<string, !Object.<string, string>>} */
CodeMirror.keyMap;
-WebInspector.suggestReload = function() { }
-WebInspector.reload = function() { }
+/** @type {{scrollLeft: number, scrollTop: number}} */
+CodeMirror.doc;
-WebInspector.settings.continuousPainting = /** type {WebInspector.Setting} */ { }
-WebInspector.settings.showDebugBorders = /** type {WebInspector.Setting} */ { }
-WebInspector.settings.showScrollBottleneckRects = /** type {WebInspector.Setting} */ { }
-WebInspector.settings.forceCompositingMode = /** type {WebInspector.Setting} */ { }
-WebInspector.settings.showFPSCounter = /** type {WebInspector.Setting} */ { }
-WebInspector.settings.showPaintRects = /** type {WebInspector.Setting} */ { }
+/**
+ * @constructor
+ * @extends {Event}
+ */
+function ErrorEvent() {}
+
+/** @type {string} */
+ErrorEvent.prototype.message;
/** @type {boolean} */
window.dispatchStandaloneTestRunnerMessages;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/filter.css b/chromium/third_party/WebKit/Source/devtools/front_end/filter.css
index 05d31f91d3c..251ab007b2e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/filter.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/filter.css
@@ -30,26 +30,30 @@
.filter-text-filter {
display: flex;
- margin-top: 1px;
- margin-left: 1px;
- margin-right: 1px;
- flex: 0 0 100px;
+ margin-left: 2px;
+ margin-right: 2px;
+ flex: 0 1 120px;
+ min-width: 40px;
}
.filter-text-filter.supports-regex {
flex: 0 0 155px;
}
+.filter-text-filter label {
+ margin: auto 0;
+}
+
.filter-bitset-filter {
- line-height: 19px;
- padding-right: 10px !important;
+ padding: 0 10px !important;
overflow: hidden;
+ display: flex !important;
}
.filter-bitset-filter li {
display: inline-block;
- margin: 2px;
- padding: 0px 6px;
+ margin: auto 2px;
+ padding: 4px 6px 3px 6px;
background: transparent;
text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
border-radius: 8px;
@@ -59,7 +63,7 @@
background-color: #ccc;
height: 16px;
width: 1px;
- vertical-align: middle;
+ margin: auto 2px;
display: inline-block;
}
@@ -70,10 +74,6 @@
text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
}
-.filter-bitset-filter li.all {
- margin: 1px 8px;
-}
-
.filter-bitset-filter li:hover {
background: rgba(0, 0, 0, 0.2);
}
@@ -93,12 +93,17 @@
}
.filter-checkbox-filter {
- line-height: 22px;
padding-left: 4px;
padding-right: 2px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
+ display: flex;
+}
+
+.filter-checkbox-filter > label {
+ display: flex;
+ margin: auto 0;
}
.filter-text-invalid {
@@ -108,14 +113,14 @@
.filter-checkbox-filter .checkbox-filter-checkbox {
width: 10px;
height: 10px;
- margin: 0 3px 0 3px;
+ margin: auto 3px;
padding: 0;
border-radius: 2px;
border: solid 1px;
display: inline-block;
overflow: visible;
opacity: 0.8;
- vertical-align: -1px;
+ flex-shrink: 0;
}
@@ -129,7 +134,7 @@
.filter-checkbox-filter .checkbox-filter-checkbox-checked {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
background-position: -129px -110px;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/filteredItemSelectionDialog.css b/chromium/third_party/WebKit/Source/devtools/front_end/filteredItemSelectionDialog.css
index a1bfed022d6..0d1d1a4bb23 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/filteredItemSelectionDialog.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/filteredItemSelectionDialog.css
@@ -23,23 +23,32 @@
color: rgb(95, 95, 95);
}
-.filtered-item-list-dialog-subtitle {
- color: rgb(155, 155, 155);
+.filtered-item-list-dialog-item.selected {
+ background-color: rgb(224, 224, 224);
}
-.filtered-item-list-dialog-item.one-row .filtered-item-list-dialog-subtitle {
- float: right;
+.filtered-item-list-dialog-item span.highlight {
+ color: #222;
+ font-weight: bold;
}
-.filtered-item-list-dialog-item.two-rows {
- border-bottom: 1px solid rgb(235, 235, 235);
+.filtered-item-list-dialog-item .filtered-item-list-dialog-title {
+ flex: auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
-.filtered-item-list-dialog-item.selected {
- background-color: rgb(224, 224, 224);
+.filtered-item-list-dialog-item .filtered-item-list-dialog-subtitle {
+ flex: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ color: rgb(155, 155, 155);
}
-.filtered-item-list-dialog-item span.highlight {
- color: #222;
- font-weight: bold;
+.filtered-item-list-dialog-item.one-row {
+ display: flex;
+}
+
+.filtered-item-list-dialog-item.two-rows {
+ border-bottom: 1px solid rgb(235, 235, 235);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/flameChart.css b/chromium/third_party/WebKit/Source/devtools/front_end/flameChart.css
index bc35be6f916..3155a3f7929 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/flameChart.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/flameChart.css
@@ -7,17 +7,21 @@
}
.chart-container {
- overflow: hidden;
- position: absolute;
- top: 80px;
- width: 100%;
- bottom: 0;
+ flex: auto;
}
#flame-chart-overview-grid .resources-dividers-label-bar {
pointer-events: auto;
}
+.flame-chart-main-pane {
+ overflow: hidden;
+}
+
+.flame-chart-overview-pane {
+ flex: 0 0 80px !important;
+}
+
#flame-chart-overview-container {
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
@@ -40,4 +44,33 @@
.chart-container .entry-info .title {
font-weight: bold;
-} \ No newline at end of file
+}
+
+.flame-chart-highlight-element {
+ background-color: black;
+ position: absolute;
+ opacity: 0.2;
+ pointer-events: none;
+}
+
+.flame-chart-selected-element {
+ position: absolute;
+ pointer-events: none;
+ border-color: rgb(56, 121, 217);
+ border-width: 2px;
+ border-style: solid;
+ background-color: rgba(56, 121, 217, 0.2);
+}
+
+.flame-chart-v-scroll {
+ flex: 0 0 14px;
+ overflow-x: hidden;
+}
+
+body.platform-mac .flame-chart-v-scroll {
+ position: absolute;
+ width: 14px;
+ top: 0;
+ right: 0;
+ bottom: 0;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/heapProfiler.css b/chromium/third_party/WebKit/Source/devtools/front_end/heapProfiler.css
index d74ea2d051e..7965818341f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/heapProfiler.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/heapProfiler.css
@@ -33,22 +33,6 @@
content: url(Images/profileIcon.png);
}
-.heap-snapshot-sidebar-tree-item.wait .icon {
- content: url(Images/spinnerActive.gif);
-}
-
-.heap-snapshot-sidebar-tree-item.wait.selected .icon {
- content: url(Images/spinnerActiveSelected.gif);
-}
-
-body.inactive .heap-snapshot-sidebar-tree-item.wait .icon {
- content: url(Images/spinnerInactive.gif);
-}
-
-body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
- content: url(Images/spinnerInactiveSelected.gif);
-}
-
.heap-snapshot-sidebar-tree-item.small .icon {
content: url(Images/profileSmallIcon.png);
}
@@ -63,16 +47,12 @@ body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
bottom: 0;
}
-.heap-snapshot-view.visible {
- display: block;
+.heap-snapshot-view .pie-chart {
+ margin: 12px 30px;
}
-.heap-snapshot-view .view {
- display: none;
-}
-
-.heap-snapshot-view .view.visible {
- display: block;
+.heap-snapshot-view .data-grid {
+ border: none;
}
.heap-snapshot-view .data-grid tr:empty {
@@ -80,58 +60,8 @@ body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
visibility: hidden;
}
-.heap-snapshot-view .data-grid {
- border: none;
-}
-
-.heap-snapshot-view .data-grid td.count-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.addedCount-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.removedCount-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.countDelta-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.addedSize-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.removedSize-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.sizeDelta-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.shallowSize-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.retainedSize-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid td.distanceToWindow-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid div.heap-snapshot-multiple-values {
- float: right;
-}
-
.heap-snapshot-view .data-grid span.percent-column {
- color: #999;
width: 32px;
- display: inline-block;
}
.heap-snapshot-view .console-formatted-object,
@@ -148,97 +78,38 @@ body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
white-space: nowrap;
}
-.heap-snapshot-view .console-formatted-id {
+.heap-snapshot-view tr:not(.selected) .console-formatted-id {
color: grey;
}
-.heap-snapshot-view .data-grid tr.selected * {
- color: inherit;
-}
-
-.heap-snapshot-view .data-grid:focus tr.selected * {
- color: white;
-}
-
.heap-snapshot-view .delimiter {
height: 24px;
background-color: #d6dde5;
}
.heap-snapshot-view .data-grid {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
+ flex: auto;
}
-.heap-snapshot-view .views-container {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 173px;
-}
-
-.reserve-80px-at-top {
- top: 80px !important;
-}
-
-.heap-snapshot-view .views-container .view {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
+.heap-snapshot-view .heap-tracking-overview {
+ flex: 0 0 80px;
+ height: 80px;
}
.heap-snapshot-view .retaining-paths-view {
- height: 150px;
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
-}
-
-.heap-snapshot-view .class-view-grid {
- top: 22px;
-}
-
-.heap-snapshot-view .class-view-toolbar {
- height: 22px;
- background-color: #DDD;
- display: block;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
-}
-
-.heap-snapshot-view .class-view-toolbar input.class-name-filter {
- width: 200px;
- height: 18px;
- font-size: 11px;
- padding: 2px;
- margin: 2px 10px;
- background-color: white;
- border: solid 1px #BBB;
+ overflow: hidden;
}
-.heap-snapshot-view .retainers-view-header {
- background-image: url(Images/statusbarResizerVertical.png), -webkit-linear-gradient(rgb(253,253,253), rgb(230,230,230) 75%, rgb(230,230,230));
- border-top: 1px solid rgb(202, 202, 202);
+.heap-snapshot-view .heap-snapshot-view-resizer {
+ background-image: url(Images/statusbarResizerVertical.png);
+ background-color: rgb(236, 236, 236);
+ border-bottom: 1px solid rgb(179, 179, 179);
background-repeat: no-repeat;
background-position: right center, center;
- height: 23px;
- display: block;
- position: absolute;
- left: 0;
- right: 0;
- bottom: 150px;
+ flex: 0 0 21px;
}
-.heap-snapshot-view .retainers-view-header .title > span {
+.heap-snapshot-view .heap-snapshot-view-resizer .title > span {
display: inline-block;
padding-top: 3px;
vertical-align: middle;
@@ -246,6 +117,14 @@ body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
margin-right: 8px;
}
+.heap-snapshot-view .heap-snapshot-view-resizer * {
+ pointer-events: none;
+}
+
+.heap-snapshot-view .heap-object-details-header {
+ background-color: rgb(236, 236, 236);
+}
+
.heap-snapshot-view tr:not(.selected) td.object-column span.highlight {
background-color: rgb(255, 255, 200);
}
@@ -254,10 +133,6 @@ body.inactive .heap-snapshot-sidebar-tree-item.wait.selected .icon {
color: gray;
}
-.heap-snapshot-help-status-bar-item .glyph {
- -webkit-mask-position: -160px -2px;
-}
-
table.heap-snapshot-help {
border-spacing: 12px 2px;
}
@@ -293,3 +168,49 @@ table.heap-snapshot-help {
right: 0;
bottom: 0;
}
+
+.heap-snapshot-stats-legend {
+ margin-left: 24px;
+}
+
+.heap-snapshot-stats-legend > div {
+ margin-top: 1px;
+ width: 170px;
+}
+
+.heap-snapshot-stats-swatch {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ border: 1px solid rgba(100, 100, 100, 0.3);
+}
+
+.heap-snapshot-stats-swatch.heap-snapshot-stats-empty-swatch {
+ border: none;
+}
+
+.heap-snapshot-stats-name,
+.heap-snapshot-stats-size {
+ display: inline-block;
+ margin-left: 6px;
+}
+
+.heap-snapshot-stats-size {
+ float: right;
+ text-align: right;
+}
+
+.heap-allocation-stack .stack-frame {
+ display: flex;
+ justify-content: space-between;
+ border-bottom: 1px solid rgb(240, 240, 240);
+ padding: 2px;
+}
+
+.heap-allocation-stack .stack-frame a {
+ color: rgb(33%, 33%, 33%);
+}
+
+.no-heap-allocation-stack {
+ padding: 5px;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/helpScreen.css b/chromium/third_party/WebKit/Source/devtools/front_end/helpScreen.css
index e060e40bd33..5ca7e8a437a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/helpScreen.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/helpScreen.css
@@ -1,5 +1,5 @@
.help-window-outer {
- position: absolute;
+ position: absolute !important;
top: 0;
left: 0;
right: 0;
@@ -8,7 +8,6 @@
}
.help-window-main {
- max-height: 100%;
color: white;
background-color: rgba(17, 17, 17, 0.85);
display: -webkit-flex;
@@ -40,6 +39,7 @@
overflow-x: hidden;
margin: 8px;
padding: 0 4px;
+ flex: auto;
}
.help-footnote {
@@ -58,18 +58,18 @@
}
.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical {
- background: -webkit-gradient(linear, left top, right top, from(rgb(128, 128, 128)), to(rgb(128, 128, 128)), color-stop(40%, rgb(96, 96, 96)));
+ background: linear-gradient(to right, rgb(128, 128, 128), rgb(96, 96, 96) 40%, rgb(128, 128, 128));
border-radius: 5px;
min-height: 20px;
}
.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical:hover,
.help-window-main .help-container-wrapper::-webkit-scrollbar-thumb:vertical:active {
- background: -webkit-gradient(linear, left top, right top, from(rgb(176, 176, 176)), to(rgb(176, 176, 176)), color-stop(40%, rgb(144, 144, 144)));
+ background: linear-gradient(to right, rgb(176, 176, 176), rgb(144, 144, 144) 40%, rgb(176, 176, 176));
}
.help-window-main .help-container-wrapper::-webkit-scrollbar-track:vertical {
- background: -webkit-gradient(linear, left top, right top, from(rgb(10, 10, 10)), to(rgb(32, 32, 32)), color-stop(25%, rgb(32, 32, 32)));
+ background: linear-gradient(to right, rgb(10, 10, 10), rgb(32, 32, 32) 25%, rgb(32, 32, 32));
border-radius: 5px;
}
@@ -105,6 +105,10 @@ body.platform-mac .help-container {
-webkit-column-width: 361px;
}
+.help-no-columns {
+ -webkit-column-width: initial !important;
+}
+
.help-block {
display: block;
padding-bottom: 9px;
@@ -127,6 +131,7 @@ body.platform-mac .settings-tab .help-block {
.settings-tab .field-error-message {
color: DarkRed;
+ height: 0px; // Avoid changing element height when content is set.
}
.help-line {
@@ -192,6 +197,7 @@ body.platform-mac .help-key {
.settings-tab label {
padding-right: 4px;
+ display: inline-flex;
}
#general-tab-content .help-block fieldset legend {
@@ -224,22 +230,7 @@ body.platform-mac .help-key {
}
.help-content input[type=checkbox] {
- height: 13px;
- width: 13px;
- margin: 0 7px 0 0;
- vertical-align: -2px;
-}
-
-body.platform-mac .help-content input[type=checkbox] {
- vertical-align: -1px;
-}
-
-.help-content input[type=radio] {
- vertical-align: -2px;
-}
-
-body.platform-mac .help-content input[type=radio] {
- vertical-align: -1px;
+ margin-right: 7px;
}
.help-content select {
@@ -359,6 +350,7 @@ body.platform-mac .help-content input[type=radio] {
.settings-tab-container {
flex: auto;
+ overflow: hidden;
}
.settings-tab-container header {
@@ -456,7 +448,7 @@ body.platform-mac .help-content input[type=radio] {
}
.settings-tab-text-button {
- background-image: -webkit-linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));
+ background-image: linear-gradient(hsl(0, 0%, 93%), hsl(0, 0%, 93%) 38%, hsl(0, 0%, 87%));
border: 1px solid hsla(0, 0%, 0%, 0.25);
border-radius: 2px;
box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.08), inset 0 1px 2px hsla(0, 100%, 100%, 0.75);
@@ -470,21 +462,21 @@ body.platform-mac .help-content input[type=radio] {
}
.settings-tab-text-button:disabled {
- background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
+ background-image: linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
border-color: rgba(80, 80, 80, 0.2);
box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.75);
color: #aaa;
}
.settings-tab-text-button:not(:disabled):hover {
- background-image: -webkit-linear-gradient(hsl(0, 0%, 94%), hsl(0, 0%, 94%) 38%, hsl(0, 0%, 88%));
+ background-image: linear-gradient(hsl(0, 0%, 94%), hsl(0, 0%, 94%) 38%, hsl(0, 0%, 88%));
border-color: hsla(0, 0%, 0%, 0.3);
box-shadow: 0 1px 0 hsla(0, 0%, 0%, 0.12), inset 0 1px 2px hsla(0, 100%, 100%, 0.95);
color: hsl(0, 0%, 0%);
}
.settings-tab-text-button:not(:disabled):active {
- background-image: -webkit-linear-gradient(hsl(0, 0%, 91%), hsl(0, 0%, 91%) 38%, hsl(0, 0%, 84%));
+ background-image: linear-gradient(hsl(0, 0%, 91%), hsl(0, 0%, 91%) 38%, hsl(0, 0%, 84%));
box-shadow: none;
text-shadow: none;
}
@@ -653,7 +645,6 @@ body.platform-mac .help-content input[type=radio] {
flex: 1 1 auto;
padding: 0 17px;
overflow: auto;
- margin-bottom: 10px;
}
.settings-dialog .block-header {
@@ -684,3 +675,19 @@ body.platform-mac .help-content input[type=radio] {
opacity: 0.6;
padding-left: 19px;
}
+
+.edit-file-system-dialog .section {
+ min-width: 400px;
+}
+
+.settings-experiment-hidden {
+ display: none;
+}
+
+.settings-experiment-hidden label {
+ background-color: #ddd;
+}
+
+.settings-developer-mode .settings-experiment-hidden {
+ display: block;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.css b/chromium/third_party/WebKit/Source/devtools/front_end/inspector.css
index 547c368c895..43ec7c56357 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/inspector.css
@@ -32,6 +32,25 @@ input[type="text"]:focus {
outline: auto 5px -webkit-focus-ring-color;
}
+input[type="checkbox"] {
+ height: 12px;
+ width: 12px;
+ margin: auto 3px;
+ flex-shrink: 0;
+}
+
+label:hover {
+ cursor: pointer;
+}
+
+label:hover input {
+ box-shadow: 0 0 3px highlight;
+}
+
+fieldset[disabled] label:hover input {
+ box-shadow: none;
+}
+
.fill {
position: absolute;
top: 0;
@@ -40,14 +59,25 @@ input[type="text"]:focus {
bottom: 0;
}
+.view {
+ position: relative;
+ flex: auto;
+}
+
.hbox {
- display: flex !important;
- flex-direction: row;
+ display: flex;
+ flex-direction: row !important;
+ position: relative;
}
.vbox {
- display: flex !important;
- flex-direction: column;
+ display: flex;
+ flex-direction: column !important;
+ position: relative;
+}
+
+.flex-auto {
+ flex: auto;
}
.inline-block {
@@ -58,6 +88,14 @@ input[type="text"]:focus {
display: none !important;
}
+.white-background {
+ background-color: white;
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
.nowrap,
.nowrap-below,
.nowrap-below div,
@@ -66,15 +104,15 @@ input[type="text"]:focus {
}
.toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(191, 191, 191)), to(rgb(151, 151, 151)));
- padding: 1px 0 0 1px;
- border-bottom: 1px solid rgb(80, 80, 80);
+ background-image: linear-gradient(to bottom, rgb(191, 191, 191), rgb(151, 151, 151));
+ padding-left: 1px;
+ border-bottom: 1px solid rgb(64%, 64%, 64%);
background-origin: padding-box;
background-clip: padding-box;
}
.toolbar {
- flex: 0 0 25px;
+ flex: 0 0 24px;
display: flex;
flex-direction: row;
position: relative;
@@ -112,32 +150,18 @@ select {
}
body.inactive .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(233, 233, 233)), to(rgb(207, 207, 207)));
- border-bottom: 1px solid rgb(64%, 64%, 64%);
+ background-image: linear-gradient(to bottom, rgb(233, 233, 233), rgb(207, 207, 207));
}
body.dock-to-bottom .toolbar-background {
padding-top: 0;
}
-body.dock-to-bottom.platform-mac:not(.overlay-contents) .toolbar-background {
- border-top-color: white;
-}
-
-body.dock-to-bottom:not(.overlay-contents) .toolbar-background {
- border-top: 1px solid rgb(100, 100, 100);
- cursor: default;
-}
-
-body.dock-to-bottom.inactive:not(.overlay-contents) .toolbar-background {
- border-top: 1px solid rgb(64%, 64%, 64%);
-}
-
-body.dock-to-bottom.overlay-contents .toolbar-background .tabbed-pane-header {
+body.dock-to-bottom .toolbar-background .tabbed-pane-header {
cursor: ns-resize;
}
-body.dock-to-bottom.overlay-contents .toolbar-background .tabbed-pane-header .tabbed-pane-header-tabs {
+body.dock-to-bottom .toolbar-background .tabbed-pane-header .tabbed-pane-header-tabs {
cursor: default;
}
@@ -147,32 +171,32 @@ body.platform-windows.inactive .toolbar-background {
}
body.undocked.platform-mac-leopard .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(175, 175, 175)), to(rgb(151, 151, 151))) !important;
+ background-image: linear-gradient(to bottom, rgb(175, 175, 175), rgb(151, 151, 151)) !important;
color: #333 !important;
}
body.undocked.platform-mac-leopard.inactive .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(221, 221, 221)), to(rgb(207, 207, 207))) !important;
+ background-image: linear-gradient(to bottom, rgb(221, 221, 221), rgb(207, 207, 207)) !important;
color: #555 !important;
}
body.undocked.platform-mac-snowleopard .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(189, 189, 189)), to(rgb(167, 167, 167))) !important;
+ background-image: linear-gradient(to bottom, rgb(189, 189, 189), rgb(167, 167, 167)) !important;
color: #333 !important;
}
body.undocked.platform-mac-snowleopard.inactive .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(228, 228, 228)), to(rgb(216, 216, 216))) !important;
+ background-image: linear-gradient(to bottom, rgb(228, 228, 228), rgb(216, 216, 216)) !important;
color: #555 !important;
}
-body.undocked.platform-mac-mountain-lion .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(208, 208, 208)), to(rgb(200, 200, 200))) !important;
+body.undocked.platform-mac .toolbar-background {
+ background-image: linear-gradient(to bottom, rgb(208, 208, 208), rgb(200, 200, 200)) !important;
color: #333 !important;
}
-body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(238, 238, 238)), to(rgb(224, 224, 224))) !important;
+body.undocked.platform-mac.inactive .toolbar-background {
+ background-image: linear-gradient(to bottom, rgb(238, 238, 238), rgb(224, 224, 224)) !important;
color: #555 !important;
}
@@ -192,6 +216,7 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
padding-top: 1px;
}
+.toolbar-controls-right #remote-device-count,
.toolbar-controls-right #error-warning-count,
.toolbar-controls-right .console-status-bar-item,
.toolbar-controls-right .settings-status-bar-item,
@@ -219,33 +244,37 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
}
.scrollable-content::-webkit-scrollbar-thumb:vertical {
- background: -webkit-gradient(linear, left top, right top, from(rgb(192, 192, 192)), to(rgb(192, 192, 192)), color-stop(40%, rgb(214, 214, 214)));
+ background: linear-gradient(to right, rgb(192, 192, 192), rgb(214, 214, 214) 40%, rgb(192, 192, 192));
border-radius: 5px;
min-height: 20px;
}
.scrollable-content::-webkit-scrollbar-thumb:vertical:hover,
.scrollable-content::-webkit-scrollbar-thumb:vertical:active {
- background: -webkit-gradient(linear, left top, right top, from(rgb(230, 230, 230)), to(rgb(230, 230, 230)), color-stop(40%, rgb(252, 252, 252)));
+ background: linear-gradient(to right, rgb(230, 230, 230), rgb(252, 252, 252) 40%, rgb(230, 230, 230));
}
.scrollable-content::-webkit-scrollbar-track:vertical {
- background: -webkit-gradient(linear, left top, right top, from(rgb(128, 128, 128)), to(rgb(164, 164, 164)), color-stop(25%, rgb(164, 164, 164)));
+ background: linear-gradient(to right, rgb(128, 128, 128), rgb(164, 164, 164) 25%, rgb(164, 164, 164));
border-radius: 5px;
}
.search-replace {
-webkit-appearance: none;
border: 0;
- padding: 0 2px;
+ padding: 0 3px;
margin: 0;
- -webkit-flex: 1;
+ flex: 1;
}
.search-replace:focus {
outline: none;
}
+#search-input-field {
+ height: 18px;
+}
+
.toolbar-search {
border-spacing: 1px;
}
@@ -254,9 +283,13 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
padding: 0 5px 0 0;
}
+.toolbar-search td > span {
+ display: flex;
+}
+
.toolbar-search-navigation-controls {
vertical-align: top;
- background-image: -webkit-linear-gradient(rgb(228, 228, 228), rgb(206, 206, 206));
+ background-image: linear-gradient(rgb(228, 228, 228), rgb(206, 206, 206));
}
.toolbar-search-navigation {
@@ -274,27 +307,20 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
}
.toolbar-search label {
- vertical-align: bottom;
-}
-
-.toolbar-search input[type="checkbox"] {
- position: relative;
- margin-top: -1px;
- margin-left: 15px;
- top: 2px;
+ margin: auto 0;
}
.toolbar-search button {
border: 1px solid rgb(163, 163, 163);
border-radius: 8px;
margin: 0;
- background-image: -webkit-linear-gradient(rgb(241, 241, 241), rgb(220, 220, 220));
+ background-image: linear-gradient(rgb(241, 241, 241), rgb(220, 220, 220));
width: 100%;
height: 20px;
}
.toolbar-search button:active {
- background-image: -webkit-linear-gradient(rgb(185, 185, 185), rgb(156, 156, 156));
+ background-image: linear-gradient(rgb(185, 185, 185), rgb(156, 156, 156));
}
.toolbar-search-control {
@@ -305,6 +331,7 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
border: 1px solid rgb(163, 163, 163);
height: 20px;
border-radius: 2px;
+ margin-left: 1px;
}
.toolbar-replace-control {
@@ -312,6 +339,7 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
height: 20px;
border-radius: 2px;
width: 100%;
+ margin: auto 0;
}
.toolbar-search-navigation.enabled:active {
@@ -324,7 +352,7 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
}
.toolbar-search-navigation.toolbar-search-navigation-prev.enabled:active {
- background-image: url(Images/searchPrev.png), -webkit-linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));
+ background-image: url(Images/searchPrev.png), linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));
}
.toolbar-search-navigation.toolbar-search-navigation-next {
@@ -333,7 +361,7 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
}
.toolbar-search-navigation.toolbar-search-navigation-next.enabled:active {
- background-image: url(Images/searchNext.png), -webkit-linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));
+ background-image: url(Images/searchNext.png), linear-gradient(rgb(168, 168, 168), rgb(116, 116, 116));
}
.search-results-matches {
@@ -348,43 +376,43 @@ body.undocked.platform-mac-mountain-lion.inactive .toolbar-background {
.close-button,
.close-button-gray {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
display: inline-block;
}
.close-button {
width: 14px;
height: 14px;
- background-position: -128px -216px;
+ background-position: -128px -96px;
}
.close-button-gray {
width: 13px;
height: 13px;
- background-position: -175px -216px;
+ background-position: -175px -96px;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
.close-button,
.close-button-gray {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
.close-button:hover {
- background-position: -96px -216px;
+ background-position: -96px -96px;
}
.close-button:active {
- background-position: -111px -216px;
+ background-position: -111px -96px;
}
.close-button-gray:hover {
- background-position: -143px -216px;
+ background-position: -143px -96px;
}
.close-button-gray:active {
- background-position: -160px -216px;
+ background-position: -160px -96px;
}
body.undocked .toolbar-item .close-button {
@@ -403,14 +431,16 @@ body.remote .toolbar-item .close-button {
position: relative;
}
-.panel-status-bar label {
- margin: 2px 20px 0 0;
+.panel-status-bar > div {
+ margin: auto 0;
}
-.panel-status-bar label > input {
- height: 13px;
- width: 13px;
- vertical-align: -2px;
+.panel-status-bar label {
+ margin: auto 0;
+ margin-right: 20px;
+ display: flex;
+ white-space: nowrap;
+ overflow: hidden;
}
.status-bar {
@@ -425,14 +455,12 @@ body.remote .toolbar-item .close-button {
}
.status-bar > div {
- display: inline-block;
- vertical-align: top;
+ display: inline-flex;
overflow: visible;
}
.status-bar-item {
display: inline-block;
- cursor: default;
height: 22px;
padding: 0;
margin-left: -1px;
@@ -446,7 +474,10 @@ body.remote .toolbar-item .close-button {
.status-bar-text {
padding-left: 5px;
padding-right: 15px;
- padding-top: 3px;
+ height: auto;
+ margin: auto 0;
+ white-space: nowrap;
+ overflow: hidden;
}
#drawer-view-anchor {
@@ -479,13 +510,13 @@ body.remote .toolbar-item .close-button {
background-color: rgba(0, 0, 0, 0.75);
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
-webkit-mask-position: -288px -48px;
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
z-index: 1;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
.long-click-glyph {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -516,6 +547,10 @@ button.status-bar-item:hover .glyph {
opacity: 1;
}
+button.status-bar-item:active .glyph {
+ opacity: 0.8;
+}
+
button.status-bar-item:disabled {
background-position: 0 0 !important;
}
@@ -529,29 +564,42 @@ button.status-bar-item.extension {
}
.status-bar-select-container {
- display: inline-block;
+ display: inline-flex;
+ flex-shrink: 0;
}
.status-bar-select-arrow {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.7;
- width: 10px;
- height: 10px;
- background-position: -20px -96px;
+ width: 12px;
+ height: 12px;
+ background-position: -18px -96px;
display: inline-block;
pointer-events: none;
- position: relative;
- top: 3px;
- left: -3px;
+ margin: auto 0;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
.status-bar-select-arrow {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
+input.status-bar-item {
+ width: 200px;
+ height: 20px;
+ padding: 3px;
+ margin: 1px 3px;
+ background-color: white;
+ border: solid 1px rgb(236, 236, 236);
+}
+
+input.status-bar-item:focus,
+input.status-bar-item:hover {
+ border: solid 1px rgb(202, 202, 202);
+}
+
select.status-bar-item {
min-width: 48px;
color: rgb(48, 48, 48);
@@ -562,16 +610,18 @@ select.status-bar-item {
padding: 0 15px 0 5px;
margin-right: -10px;
position: relative;
- line-height: 20px;
+ line-height: 22px;
}
.status-bar-item.checkbox {
- margin: 2px 0 0 0;
+ margin: auto 6px auto 0;
+ height: auto;
+ display: flex;
}
.status-bar-item > .glyph {
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
opacity: 0.8;
}
@@ -581,11 +631,11 @@ select.status-bar-item {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.status-bar-item > .glyph {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
-button.status-bar-item.dock-status-bar-item.toggled-undock .glyph {
+button.status-bar-item.dock-status-bar-item.toggled-undocked .glyph {
-webkit-mask-position: 0 -48px;
}
@@ -597,6 +647,10 @@ button.status-bar-item.dock-status-bar-item.toggled-right .glyph {
-webkit-mask-position: -256px -48px;
}
+button.status-bar-item.dock-status-bar-item.toggled-left .glyph {
+ -webkit-mask-position: -32px -120px;
+}
+
body.undocked .alternate-status-bar-buttons-bar {
margin-left: 1px;
}
@@ -624,43 +678,6 @@ button.status-bar-item.settings-status-bar-item:active {
border-right: 0 transparent none;
}
-button.status-bar-item.left-sidebar-show-hide-button,
-button.status-bar-item.right-sidebar-show-hide-button {
- position: absolute;
- top: 0;
- background-image: none;
- height: 16px;
- width: 16px;
- margin: 4px 2px 2px 2px;
- border: none;
- z-index: 10;
-}
-
-button.status-bar-item.left-sidebar-show-hide-button:active,
-button.status-bar-item.right-sidebar-show-hide-button:active {
- margin: 5px 1px 1px 3px;
-}
-
-button.status-bar-item.left-sidebar-show-hide-button.toggled-left > .glyph {
- -webkit-mask-position: -199px -76px;
-}
-
-button.status-bar-item.left-sidebar-show-hide-button.toggled-right > .glyph {
- -webkit-mask-position: -168px -76px;
-}
-
-button.status-bar-item.right-sidebar-show-hide-button.toggled-left > .glyph {
- -webkit-mask-position: -296px -76px;
-}
-
-button.status-bar-item.right-sidebar-show-hide-button.toggled-right > .glyph {
- -webkit-mask-position: -264px -76px;
-}
-
-button.status-bar-item.left-sidebar-show-hide-button.toggled-overlay > .glyph {
- -webkit-mask-position: -231px -76px;
-}
-
div.resizer-widget {
position: absolute;
top: 0;
@@ -673,6 +690,14 @@ div.resizer-widget {
z-index: 13;
}
+.ns-resizer-widget {
+ cursor: ns-resize;
+}
+
+.ew-resizer-widget {
+ cursor: ew-resize;
+}
+
.settings-status-bar-item .glyph {
-webkit-mask-position: -160px -24px;
}
@@ -685,21 +710,30 @@ body.remote .dock-status-bar-item {
-webkit-mask-position: -64px -24px;
}
-.screencast-status-bar-item .glyph {
+.screencast-status-bar-item.toggled-left .glyph {
-webkit-mask-position: -256px -96px;
}
+.screencast-status-bar-item.toggled-top .glyph {
+ -webkit-mask-position: -288px -96px;
+}
+
+.screencast-status-bar-item.toggled-disabled .glyph {
+ -webkit-mask-position: 0px -120px;
+}
+
.clear-status-bar-item .glyph {
-webkit-mask-position: -64px 0;
}
.error-icon-small,
.warning-icon-small,
+.device-icon-small,
.red-ball,
.green-ball,
.orange-ball {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
width: 10px;
height: 10px;
display: inline-block;
@@ -708,10 +742,11 @@ body.remote .dock-status-bar-item {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.error-icon-small,
.warning-icon-small,
+.device-icon-small,
.red-ball,
.green-ball,
.orange-ball {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -723,6 +758,10 @@ body.remote .dock-status-bar-item {
background-position: -202px -107px;
}
+.device-icon-small {
+ background-position: -224px -107px;
+}
+
.red-ball {
background-position: -224px -96px;
}
@@ -735,7 +774,7 @@ body.remote .dock-status-bar-item {
background-position: -246px -96px;
}
-#error-warning-count {
+#error-warning-count, #remote-device-count {
display: inline-block;
padding: 4px 6px 6px 0;
font-size: 11px;
@@ -744,12 +783,13 @@ body.remote .dock-status-bar-item {
line-height: 14px;
}
-#error-warning-count:hover {
+#error-warning-count:hover, #remote-device-count:hover {
border-bottom: 1px solid rgb(96, 96, 96);
}
#error-warning-count .error-icon-small,
-#error-warning-count .warning-icon-small {
+#error-warning-count .warning-icon-small,
+#remote-device-count .device-icon-small{
vertical-align: -1px;
margin-right: 2px;
}
@@ -758,60 +798,14 @@ body.remote .dock-status-bar-item {
margin-left: 6px;
}
-.drawer {
- display: none;
- flex: 0 0 200px;
- position: relative;
- background-color: white;
- z-index: 1;
-}
-
-#drawer-contents {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
-}
-
-#drawer-contents > .tabbed-pane > .tabbed-pane-header {
+#drawer-tabbed-pane > .tabbed-pane-header {
background-color: rgb(236, 236, 236);
- border-top: 1px solid rgb(124, 124, 124);
- border-bottom: 1px solid rgb(203, 203, 203);
-}
-
-body.inactive #drawer-contents .tabbed-pane-header {
- border-top: 1px solid rgb(64%, 64%, 64%);
}
#drawer-contents .tabbed-pane-header .tabbed-pane-header-tab {
cursor: default;
}
-.drawer-resizer {
- position: absolute;
- right: 0;
- top: 8px;
- content: url(Images/statusbarResizerVertical.png);
- height: 8px;
- pointer-events: none;
-}
-
-#drawer-footer {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- font-size: 11px;
- height: 23px;
- background-color: rgb(236, 236, 236);
-}
-
-body.drawer-visible .drawer {
- display: block;
-}
-
body.platform-mac .monospace,
body.platform-mac .source-code {
font-size: 11px !important;
@@ -838,17 +832,23 @@ body.platform-linux .source-code {
.console-view {
background-color: white;
+ overflow: hidden;
}
.console-view-wrapper {
background-color: rgb(236, 236, 236);
}
-.console-status-bar {
+.console-status-bar,
+.console-filters-header {
flex: 0 0 23px;
overflow: hidden;
}
+.console-status-bar {
+ display: flex;
+}
+
#console-messages {
flex: 1 1;
padding: 2px 0;
@@ -856,6 +856,7 @@ body.platform-linux .source-code {
word-wrap: break-word;
-webkit-user-select: text;
border-top: 1px solid rgb(230, 230, 230);
+ -webkit-transform: translateZ(0);
}
#console-prompt {
@@ -898,6 +899,12 @@ body.platform-linux .source-code {
background-image: none;
}
+.console-timestamp {
+ color: gray;
+ margin-right: 10px;
+ -webkit-user-select: none;
+}
+
.console-message::before,
.console-user-command::before,
#console-prompt::before,
@@ -912,7 +919,7 @@ body.platform-linux .source-code {
margin-top: -6px;
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
@@ -920,7 +927,7 @@ body.platform-linux .source-code {
.console-user-command::before,
#console-prompt::before,
.console-group-title::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -983,7 +990,7 @@ body.platform-linux .source-code {
.console-group-title::before {
-webkit-user-select: none;
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
float: left;
width: 8px;
content: "a";
@@ -995,7 +1002,7 @@ body.platform-linux .source-code {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.console-group-title::before {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -1004,31 +1011,48 @@ body.platform-linux .source-code {
background-color: rgb(110, 110, 110);
}
-.console-group.collapsed .console-group-title::before {
+.console-message-wrapper.collapsed .console-group-title::before {
-webkit-mask-position: -4px -96px;
}
-.console-group.collapsed > .console-group-messages {
- display: none;
+.console-group {
+ position: relative;
}
-.console-group {
+.console-message-wrapper {
+ display: flex;
+}
+
+.console-message-wrapper .nesting-level-marker {
+ width: 14px;
+ flex: 0 0 auto;
+ border-right: 1px solid #A3A3A3;
position: relative;
}
-.console-group-bracket {
- position:absolute;
- top: 15px;
- left: 13px;
- bottom: 5px;
+.console-message-wrapper:last-child .nesting-level-marker,
+.console-message-wrapper .nesting-level-marker.group-closed {
+ margin-bottom: 4px;
+}
+
+.console-message-wrapper:last-child .nesting-level-marker::before,
+.console-message-wrapper .nesting-level-marker.group-closed::before
+{
+ content: "";
+}
+
+.console-message-wrapper .nesting-level-marker::before {
+ border-bottom: 1px solid #A3A3A3;
+ position: absolute;
+ top: 0;
+ left: 0;
+ margin-left: 100%;
width: 3px;
- border-style: solid;
- border-color: #A3A3A3;
- border-width: 0 0 1px 1px;
+ height: 100%;
}
-.console-group.collapsed > .console-group-bracket {
- display: none;
+.console-message {
+ flex: 1 1 auto;
}
.console-error-level .console-message-text,
@@ -1045,7 +1069,7 @@ body.platform-linux .source-code {
.console-debug-level::before,
.console-info-level::before {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
width: 10px;
height: 10px;
}
@@ -1055,7 +1079,7 @@ body.platform-linux .source-code {
.console-warning-level::before,
.console-debug-level::before,
.console-info-level::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -1085,11 +1109,17 @@ body.platform-linux .source-code {
color: rgb(0, 128, 255);
}
+#console-messages .link {
+ text-decoration: underline;
+}
+
+#console-messages .link,
#console-messages a {
color: rgb(33%, 33%, 33%);
cursor: pointer;
}
+#console-messages .link:hover,
#console-messages a:hover {
color: rgb(15%, 15%, 15%);
}
@@ -1165,7 +1195,7 @@ ol.watch-expressions > li.hovered {
position: relative;
display: inline-block;
vertical-align: top;
- color: #222;
+ color: inherit;
}
.console-formatted-node:hover {
@@ -1187,14 +1217,17 @@ ol.watch-expressions > li.hovered {
padding-left: 0 !important;
}
-.console-formatted-number {
+.console-formatted-number,
+.console-formatted-boolean {
color: rgb(28, 0, 207);
}
.console-formatted-string,
-.console-formatted-regexp {
+.console-formatted-regexp,
+.console-formatted-symbol {
color: rgb(196, 26, 22);
white-space: pre;
+ unicode-bidi: -webkit-isolate;
}
.console-formatted-null,
@@ -1212,7 +1245,7 @@ ol.watch-expressions > li.hovered {
}
.object-info-state-note {
- display: none;
+ display: inline-block;
width: 11px;
height: 11px;
background-color: rgb(179, 203, 247);
@@ -1228,8 +1261,8 @@ ol.watch-expressions > li.hovered {
content: "i";
}
-.section.expanded .object-info-state-note {
- display: inline-block;
+.section:not(.expanded) .object-info-state-note {
+ display: none;
}
.error-message {
@@ -1375,14 +1408,14 @@ iframe.panel.extension {
.outline-disclosure li.parent::before {
float: left;
- width: 8px;
+ width: 10px;
padding-right: 2px;
}
.outline-disclosure li.parent::before {
-webkit-user-select: none;
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
content: "a";
color: transparent;
text-shadow: none;
@@ -1394,7 +1427,7 @@ iframe.panel.extension {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.outline-disclosure li.parent::before {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -1423,24 +1456,20 @@ iframe.panel.extension {
white-space: nowrap;
}
-.placard.grouped {
- padding-left: 36px;
-}
-
.placard:nth-of-type(2n) {
background-color: rgb(234, 243, 255);
}
.placard.selected {
border-top: 1px solid rgb(172, 172, 172);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(182, 182, 182)), to(rgb(162, 162, 162)));
+ background-image: linear-gradient(to bottom, rgb(182, 182, 182), rgb(162, 162, 162));
background-origin: padding-box;
background-clip: padding-box;
}
:focus .placard.selected {
border-top: 1px solid rgb(70, 103, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(56, 121, 217)));
+ background-image: linear-gradient(to bottom, rgb(92, 147, 213), rgb(56, 121, 217));
}
.placard .title {
@@ -1471,6 +1500,17 @@ iframe.panel.extension {
color: inherit;
}
+.placard-label {
+ text-align: center;
+}
+
+.placard-label .title,
+.placard-label .subtitle {
+ font-style: italic;
+ font-weight: bold;
+ color: #999;
+}
+
.section {
position: relative;
margin-top: 1px;
@@ -1484,7 +1524,7 @@ iframe.panel.extension {
}
.section > .header {
- padding: 0 8px 0 5px;
+ padding: 0px 8px 0 5px;
min-height: 18px;
white-space: nowrap;
background-origin: padding-box;
@@ -1494,7 +1534,7 @@ iframe.panel.extension {
.section > .header::before {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
content: "a";
color: transparent;
@@ -1507,7 +1547,7 @@ iframe.panel.extension {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.section > .header::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -1602,7 +1642,7 @@ iframe.panel.extension {
.properties-tree li.parent::before {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
content: "a";
width: 8px;
@@ -1622,7 +1662,7 @@ iframe.panel.extension {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.properties-tree li.parent::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -1721,6 +1761,7 @@ li.editing-sub-part .delete-button {
.watch-expressions > li.editing-sub-part .text-prompt {
display: block;
width: 100%;
+ overflow: hidden;
}
.watch-expressions > li.editing-sub-part .value,
@@ -1730,7 +1771,7 @@ li.editing-sub-part .delete-button {
.section .properties li.editing-sub-part {
padding: 3px 6px 8px 18px;
- margin: -3px -6px -8px -6px;
+ margin: -1px -6px -8px -6px;
text-overflow: clip;
}
@@ -1783,8 +1824,8 @@ li.editing-sub-part .delete-button {
.swatch {
margin-left: 1px;
margin-right: 2px;
- width: 1em;
- height: 1em;
+ width: 10px;
+ height: 10px;
position: relative;
top: 1px;
display: inline-block;
@@ -1805,10 +1846,6 @@ li.editing-sub-part .delete-button {
.sidebar {
overflow-x: hidden;
- background-color: rgb(214, 221, 229);
-}
-
-body.inactive .sidebar {
background-color: rgb(232, 232, 232);
}
@@ -1817,14 +1854,14 @@ body.inactive .sidebar {
background-color: transparent;
border: 1px solid rgb(165, 165, 165);
background-color: rgb(237, 237, 237);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
border-radius: 12px;
-webkit-appearance: none;
}
.pane-title-button:active {
background-color: rgb(215, 215, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
button.show-all-nodes {
@@ -1836,7 +1873,7 @@ button.show-all-nodes {
background-color: transparent;
border: 1px solid rgb(165, 165, 165);
background-color: rgb(237, 237, 237);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
border-radius: 12px;
-webkit-appearance: none;
}
@@ -1845,20 +1882,12 @@ body.inactive button.show-all-nodes {
color: rgb(130, 130, 130);
border-color: rgb(212, 212, 212);
background-color: rgb(239, 239, 239);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(250, 250, 250)), to(rgb(235, 235, 235)));
+ background-image: linear-gradient(to bottom, rgb(250, 250, 250), rgb(235, 235, 235));
}
button.show-all-nodes:active {
background-color: rgb(215, 215, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
-}
-
-button.enable-toggle-status-bar-item .glyph {
- -webkit-mask-position: -192px 0;
-}
-
-button.enable-toggle-status-bar-item.toggled-on .glyph {
- -webkit-mask-position: -96px -24px;
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
#console-messages.console-filter-top {
@@ -2011,7 +2040,7 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
height: 10px;
border: 0;
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
-webkit-appearance: none;
background-color: rgba(0, 0, 0, 0.75);
position: relative;
@@ -2020,7 +2049,7 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
@media (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar-tree-item .disclosure-button {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -2054,6 +2083,42 @@ button.enable-toggle-status-bar-item.toggled-on .glyph {
margin-right: 3px;
}
+.sidebar-tree-item.wait .icon {
+ content: none;
+}
+
+.spinner-icon::before,
+.sidebar-tree-item.wait .icon::before {
+ display: block;
+ width: 24px;
+ height: 24px;
+ margin: 4px;
+ border: 3px solid grey;
+ border-radius: 12px;
+ clip: rect(0px, 15px, 15px, 0px);
+ content: "";
+ position: absolute;
+ -webkit-animation: spinner-animation 1s linear infinite;
+}
+
+.spinner-icon.small::before,
+.sidebar-tree-item.wait.small .icon::before {
+ width: 14px;
+ height: 14px;
+ margin: 1px;
+ clip: rect(0px, 9px, 9px, 0px);
+ border-width: 2px;
+}
+
+.sidebar-tree-item.wait.selected .icon::before {
+ border-color: white;
+}
+
+@-webkit-keyframes spinner-animation {
+ from { -webkit-transform: rotate(0); }
+ to { -webkit-transform: rotate(360deg); }
+}
+
li .status {
float: right;
height: 16px;
@@ -2138,6 +2203,8 @@ body.inactive .sidebar-tree-item.selected {
}
.sidebar-tree-item .titles {
+ display: flex;
+ flex-direction: column;
position: relative;
top: 5px;
line-height: 12px;
@@ -2147,6 +2214,10 @@ body.inactive .sidebar-tree-item.selected {
white-space: nowrap;
}
+.titles > .title-container {
+ display: flex;
+}
+
.sidebar-tree-item .titles.no-subtitle {
top: 10px;
}
@@ -2224,6 +2295,10 @@ body.inactive .sidebar-tree-item.selected {
-webkit-mask-position: -224px -24px;
}
+.emulation-status-bar-item .glyph {
+ -webkit-mask-position: -164px 0px;
+}
+
.delete-storage-status-bar-item .glyph {
-webkit-mask-position: -128px 0;
}
@@ -2294,17 +2369,6 @@ body.inactive .sidebar-tree-item.selected {
background-color: rgb(255, 255, 194);
}
-.source-frame-stepin-mark {
- cursor: pointer;
- text-decoration: underline;
-}
-
-.source-frame-stepin-mark-highlighted {
- font-weight: 800;
- cursor: pointer;
- text-decoration: underline;
-}
-
.workers-list {
list-style: none;
margin: 0;
@@ -2409,7 +2473,7 @@ body.inactive .sidebar-tree-item.selected {
body.platform-mac .soft-context-menu-item-mouse-over {
border-top: 1px solid rgb(90, 131, 236);
border-bottom: 1px solid rgb(18, 88, 233);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(100, 140, 243)), to(rgb(36, 101, 243)));
+ background-image: linear-gradient(to bottom, rgb(100, 140, 243), rgb(36, 101, 243));
}
.soft-context-menu-item-checkmark {
@@ -2438,11 +2502,12 @@ body.platform-mac .soft-context-menu-item-mouse-over {
.search-drawer-header {
flex: none;
padding: 4px;
+ display: flex;
}
.search-drawer-header input[type="text"].search-config-search {
-webkit-appearance: none;
- padding: 0 2px;
+ padding: 0 3px;
margin: 0;
border: 1px solid rgb(163, 163, 163);
height: 20px;
@@ -2460,20 +2525,10 @@ body.platform-mac .search-drawer-header input[type="search"].search-config-searc
}
.search-drawer-header label.search-config-label {
+ margin: auto 0;
margin-left: 8px;
color: #303030;
-}
-
-.search-drawer-header input[type="checkbox"].search-config-checkbox {
- vertical-align: bottom;
-}
-
-body:not(.platform-mac) .search-drawer-header input[type="checkbox"].search-config-checkbox {
- margin-bottom: 5px;
-}
-
-body.platform-mac .search-drawer-header input[type="checkbox"].search-config-checkbox {
- margin-bottom: 4px;
+ display: flex;
}
#bottom-status-bar-container {
@@ -2529,18 +2584,19 @@ body.platform-mac .search-drawer-header input[type="checkbox"].search-config-che
#search-results-pane-file-based li.parent::before {
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
- width: 8px;
+ width: 12px;
content: "a";
color: transparent;
margin-left: -5px;
padding-right: 4px;
+ display: inline-block;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
#search-results-pane-file-based li.parent::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -2653,21 +2709,6 @@ button.record-profile-status-bar-item.toggled-on .glyph:not(.shadow) {
white-space: pre-wrap;
}
-/* Generic suggest box style */
-
-.suggest-box.generic-suggest {
- margin-left: -1px;
- border-color: rgb(66%, 66%, 66%);
-}
-
-.suggest-box.generic-suggest.above-anchor {
- border-radius: 5px 5px 5px 0;
-}
-
-.suggest-box.generic-suggest.under-anchor {
- border-radius: 0 5px 5px 5px;
-}
-
/* Custom popup scrollers */
.custom-popup-horizontal-scroll ::-webkit-scrollbar,
@@ -2785,14 +2826,20 @@ button.record-profile-status-bar-item.toggled-on .glyph:not(.shadow) {
max-width: 200px;
}
-.inspector-view {
+.root-view {
overflow: hidden;
+ position: absolute !important;
+ left: 0;
+ top: 0;
}
-.inspector-footer.status-bar {
- flex: 0 0 auto;
+.search-bar {
+ flex: 0 0 23px;
background-color: rgb(236, 236, 236);
- height: auto;
+}
+
+.search-bar.replaceable {
+ flex: 0 0 44px;
}
.progress-bar-container {
@@ -2845,6 +2892,15 @@ body.undocked .toolbar-close-button-item {
display: none;
}
-body.dock-to-bottom.overlay-contents #inspector-split-view .split-view-resizer {
- display: none;
+.root-view > .split-view > .split-view-sidebar {
+ position: relative;
+}
+
+select.drop-down-menu {
+ border: none;
+ -webkit-appearance: none;
+}
+
+.viewport-control-gap-element {
+ color: transparent;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.html b/chromium/third_party/WebKit/Source/devtools/front_end/inspector.html
index 9b01cb18e8b..ed39773c354 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.html
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/inspector.html
@@ -36,159 +36,165 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<link rel="stylesheet" type="text/css" href="inspectorCommon.css">
<link rel="stylesheet" type="text/css" href="inspectorSyntaxHighlight.css">
<link rel="stylesheet" type="text/css" href="popover.css">
- <script type="text/javascript" src="utilities.js"></script>
+ <script type="text/javascript" src="common/utilities.js"></script>
+ <script type="text/javascript" src="common/modules.js"></script>
+ <script type="text/javascript" src="common/WebInspector.js"></script>
+ <script type="text/javascript" src="common/Object.js"></script>
+ <script type="text/javascript" src="common/ModuleManager.js"></script>
+ <script type="text/javascript" src="common/UIString.js"></script>
+ <script type="text/javascript" src="common/MessageSink.js"></script>
+ <script type="text/javascript" src="common/ParsedURL.js"></script>
+ <script type="text/javascript" src="common/Color.js"></script>
+ <script type="text/javascript" src="common/TextRange.js"></script>
+ <script type="text/javascript" src="common/Throttler.js"></script>
+ <script type="text/javascript" src="common/Platform.js"></script>
+ <script type="text/javascript" src="common/Geometry.js"></script>
+ <script type="text/javascript" src="common/Settings.js"></script>
+ <script type="text/javascript" src="common/Progress.js"></script>
+ <script type="text/javascript" src="common/UserMetrics.js"></script>
<script type="text/javascript" src="jsdifflib.js"></script>
- <script type="text/javascript" src="DOMExtension.js"></script>
- <script type="text/javascript" src="treeoutline.js"></script>
- <script type="text/javascript" src="inspector.js"></script>
- <script type="text/javascript" src="Geometry.js"></script>
- <script type="text/javascript" src="UIString.js"></script>
- <script type="text/javascript" src="InspectorBackend.js"></script>
+ <script type="text/javascript" src="common/DOMExtension.js"></script>
+ <script type="text/javascript" src="ui/treeoutline.js"></script>
+ <script type="text/javascript" src="ui/SettingsUI.js"></script>
+ <script type="text/javascript" src="main/Main.js"></script>
+ <script type="text/javascript" src="sdk/InspectorBackend.js"></script>
<script type="text/javascript" src="InspectorBackendCommands.js"></script>
- <script type="text/javascript" src="ExtensionRegistryStub.js"></script>
<script type="text/javascript" src="InspectorFrontendAPI.js"></script>
- <script type="text/javascript" src="Object.js"></script>
- <script type="text/javascript" src="Settings.js"></script>
- <script type="text/javascript" src="View.js"></script>
- <script type="text/javascript" src="UIUtils.js"></script>
- <script type="text/javascript" src="HelpScreen.js"></script>
+ <script type="text/javascript" src="InspectorFrontendEventSink.js"></script>
+ <script type="text/javascript" src="sdk/Target.js"></script>
+ <script type="text/javascript" src="ui/Context.js"></script>
+ <script type="text/javascript" src="components/ExecutionContextSelector.js"></script>
+ <script type="text/javascript" src="sdk/NotificationService.js"></script>
+ <script type="text/javascript" src="ui/View.js"></script>
+ <script type="text/javascript" src="ui/UIUtils.js"></script>
+ <script type="text/javascript" src="components/HelpScreen.js"></script>
<script type="text/javascript" src="InspectorFrontendHostStub.js"></script>
- <script type="text/javascript" src="FileManager.js"></script>
- <script type="text/javascript" src="Checkbox.js"></script>
- <script type="text/javascript" src="ContextMenu.js"></script>
- <script type="text/javascript" src="SoftContextMenu.js"></script>
- <script type="text/javascript" src="KeyboardShortcut.js"></script>
- <script type="text/javascript" src="SuggestBox.js"></script>
- <script type="text/javascript" src="TextPrompt.js"></script>
- <script type="text/javascript" src="Popover.js"></script>
- <script type="text/javascript" src="Placard.js"></script>
- <script type="text/javascript" src="TabbedPane.js"></script>
- <script type="text/javascript" src="ViewportControl.js"></script>
- <script type="text/javascript" src="Drawer.js"></script>
- <script type="text/javascript" src="ConsoleModel.js"></script>
- <script type="text/javascript" src="ConsoleMessage.js"></script>
- <script type="text/javascript" src="ConsoleView.js"></script>
- <script type="text/javascript" src="Panel.js"></script>
- <script type="text/javascript" src="InspectorView.js"></script>
- <script type="text/javascript" src="AdvancedSearchController.js"></script>
- <script type="text/javascript" src="TimelineGrid.js"></script>
- <script type="text/javascript" src="OverviewGrid.js"></script>
- <script type="text/javascript" src="ContentProvider.js"></script>
- <script type="text/javascript" src="Resource.js"></script>
- <script type="text/javascript" src="NetworkRequest.js"></script>
- <script type="text/javascript" src="UISourceCode.js"></script>
- <script type="text/javascript" src="CSSStyleModel.js"></script>
- <script type="text/javascript" src="NetworkManager.js"></script>
- <script type="text/javascript" src="NetworkLog.js"></script>
- <script type="text/javascript" src="ResourceTreeModel.js"></script>
- <script type="text/javascript" src="ParsedURL.js"></script>
- <script type="text/javascript" src="ResourceUtils.js"></script>
- <script type="text/javascript" src="ResourceType.js"></script>
- <script type="text/javascript" src="TimelineManager.js"></script>
- <script type="text/javascript" src="OverridesSupport.js"></script>
- <script type="text/javascript" src="Database.js"></script>
- <script type="text/javascript" src="DOMStorage.js"></script>
- <script type="text/javascript" src="DataGrid.js"></script>
- <script type="text/javascript" src="ShowMoreDataGridNode.js"></script>
- <script type="text/javascript" src="CookiesTable.js"></script>
- <script type="text/javascript" src="CookieItemsView.js"></script>
- <script type="text/javascript" src="ApplicationCacheModel.js"></script>
- <script type="text/javascript" src="IndexedDBModel.js"></script>
- <script type="text/javascript" src="Spectrum.js"></script>
- <script type="text/javascript" src="SidebarPane.js"></script>
- <script type="text/javascript" src="ElementsTreeOutline.js"></script>
- <script type="text/javascript" src="DOMPresentationUtils.js"></script>
- <script type="text/javascript" src="SidebarTreeElement.js"></script>
- <script type="text/javascript" src="Section.js"></script>
- <script type="text/javascript" src="PropertiesSection.js"></script>
- <script type="text/javascript" src="RemoteObject.js"></script>
- <script type="text/javascript" src="ObjectPropertiesSection.js"></script>
- <script type="text/javascript" src="ObjectPopoverHelper.js"></script>
- <script type="text/javascript" src="NativeBreakpointsSidebarPane.js"></script>
- <script type="text/javascript" src="DOMBreakpointsSidebarPane.js"></script>
- <script type="text/javascript" src="Color.js"></script>
- <script type="text/javascript" src="CSSMetadata.js"></script>
- <script type="text/javascript" src="StatusBarButton.js"></script>
- <script type="text/javascript" src="CompletionDictionary.js"></script>
- <script type="text/javascript" src="TextEditor.js"></script>
- <script type="text/javascript" src="SourceFrame.js"></script>
- <script type="text/javascript" src="ResourceView.js"></script>
- <script type="text/javascript" src="FontView.js"></script>
- <script type="text/javascript" src="ImageView.js"></script>
- <script type="text/javascript" src="SplitView.js"></script>
- <script type="text/javascript" src="SidebarView.js"></script>
- <script type="text/javascript" src="ConsolePanel.js"></script>
- <script type="text/javascript" src="ExtensionAPI.js"></script>
- <script type="text/javascript" src="ExtensionAuditCategory.js"></script>
- <script type="text/javascript" src="ExtensionServer.js"></script>
- <script type="text/javascript" src="ExtensionView.js"></script>
- <script type="text/javascript" src="ExtensionPanel.js"></script>
- <script type="text/javascript" src="EmptyView.js"></script>
- <script type="text/javascript" src="ScriptFormatter.js"></script>
- <script type="text/javascript" src="DOMSyntaxHighlighter.js"></script>
- <script type="text/javascript" src="TempFile.js"></script>
- <script type="text/javascript" src="TextRange.js"></script>
- <script type="text/javascript" src="TextUtils.js"></script>
- <script type="text/javascript" src="FileSystemModel.js"></script>
- <script type="text/javascript" src="FileUtils.js"></script>
- <script type="text/javascript" src="DebuggerModel.js"></script>
- <script type="text/javascript" src="SourceMap.js"></script>
- <script type="text/javascript" src="SourceMapping.js"></script>
- <script type="text/javascript" src="Script.js"></script>
- <script type="text/javascript" src="Linkifier.js"></script>
- <script type="text/javascript" src="DebuggerScriptMapping.js"></script>
- <script type="text/javascript" src="PresentationConsoleMessageHelper.js"></script>
- <script type="text/javascript" src="FileSystemProjectDelegate.js"></script>
- <script type="text/javascript" src="FileSystemMapping.js"></script>
- <script type="text/javascript" src="IsolatedFileSystem.js"></script>
- <script type="text/javascript" src="IsolatedFileSystemManager.js"></script>
- <script type="text/javascript" src="Workspace.js"></script>
- <script type="text/javascript" src="WorkspaceController.js"></script>
- <script type="text/javascript" src="ContentProviderBasedProjectDelegate.js"></script>
- <script type="text/javascript" src="SimpleWorkspaceProvider.js"></script>
- <script type="text/javascript" src="BreakpointManager.js"></script>
- <script type="text/javascript" src="ContentProviders.js"></script>
- <script type="text/javascript" src="DefaultScriptMapping.js"></script>
- <script type="text/javascript" src="ResourceScriptMapping.js"></script>
- <script type="text/javascript" src="CompilerScriptMapping.js"></script>
- <script type="text/javascript" src="LiveEditSupport.js"></script>
- <script type="text/javascript" src="CSSStyleSheetMapping.js"></script>
- <script type="text/javascript" src="SASSSourceMapping.js"></script>
- <script type="text/javascript" src="DOMAgent.js"></script>
+ <script type="text/javascript" src="sdk/FileManager.js"></script>
+ <script type="text/javascript" src="ui/Checkbox.js"></script>
+ <script type="text/javascript" src="ui/ContextMenu.js"></script>
+ <script type="text/javascript" src="ui/SoftContextMenu.js"></script>
+ <script type="text/javascript" src="ui/ActionRegistry.js"></script>
+ <script type="text/javascript" src="ui/KeyboardShortcut.js"></script>
+ <script type="text/javascript" src="ui/ShortcutRegistry.js"></script>
+ <script type="text/javascript" src="ui/SuggestBox.js"></script>
+ <script type="text/javascript" src="ui/TextPrompt.js"></script>
+ <script type="text/javascript" src="ui/Popover.js"></script>
+ <script type="text/javascript" src="ui/TabbedPane.js"></script>
+ <script type="text/javascript" src="ui/ViewportControl.js"></script>
+ <script type="text/javascript" src="components/Drawer.js"></script>
+ <script type="text/javascript" src="sdk/ConsoleModel.js"></script>
+ <script type="text/javascript" src="components/Panel.js"></script>
+ <script type="text/javascript" src="components/InspectorView.js"></script>
+ <script type="text/javascript" src="components/InspectedPagePlaceholder.js"></script>
+ <script type="text/javascript" src="components/TimelineGrid.js"></script>
+ <script type="text/javascript" src="components/OverviewGrid.js"></script>
+ <script type="text/javascript" src="sdk/SearchConfig.js"></script>
+ <script type="text/javascript" src="sdk/ContentProvider.js"></script>
+ <script type="text/javascript" src="sdk/Resource.js"></script>
+ <script type="text/javascript" src="sdk/NetworkRequest.js"></script>
+ <script type="text/javascript" src="sdk/UISourceCode.js"></script>
+ <script type="text/javascript" src="sdk/CSSStyleModel.js"></script>
+ <script type="text/javascript" src="sdk/CSSParser.js"></script>
+ <script type="text/javascript" src="sdk/NetworkManager.js"></script>
+ <script type="text/javascript" src="sdk/NetworkLog.js"></script>
+ <script type="text/javascript" src="sdk/ResourceTreeModel.js"></script>
+ <script type="text/javascript" src="sdk/ResourceUtils.js"></script>
+ <script type="text/javascript" src="sdk/ResourceType.js"></script>
+ <script type="text/javascript" src="sdk/TimelineManager.js"></script>
+ <script type="text/javascript" src="sdk/PowerProfiler.js"></script>
+ <script type="text/javascript" src="sdk/OverridesSupport.js"></script>
+ <script type="text/javascript" src="sdk/Database.js"></script>
+ <script type="text/javascript" src="sdk/DOMStorage.js"></script>
+ <script type="text/javascript" src="ui/DataGrid.js"></script>
+ <script type="text/javascript" src="ui/ShowMoreDataGridNode.js"></script>
+ <script type="text/javascript" src="components/CookiesTable.js"></script>
+ <script type="text/javascript" src="sdk/ApplicationCacheModel.js"></script>
+ <script type="text/javascript" src="sdk/IndexedDBModel.js"></script>
+ <script type="text/javascript" src="ui/SidebarPane.js"></script>
+ <script type="text/javascript" src="components/DOMPresentationUtils.js"></script>
+ <script type="text/javascript" src="ui/SidebarTreeElement.js"></script>
+ <script type="text/javascript" src="components/Section.js"></script>
+ <script type="text/javascript" src="components/PropertiesSection.js"></script>
+ <script type="text/javascript" src="sdk/RemoteObject.js"></script>
+ <script type="text/javascript" src="components/ObjectPropertiesSection.js"></script>
+ <script type="text/javascript" src="components/ObjectPopoverHelper.js"></script>
+ <script type="text/javascript" src="components/NativeBreakpointsSidebarPane.js"></script>
+ <script type="text/javascript" src="components/DOMBreakpointsSidebarPane.js"></script>
+ <script type="text/javascript" src="sdk/CSSMetadata.js"></script>
+ <script type="text/javascript" src="SupportedCSSProperties.js"></script>
+ <script type="text/javascript" src="ui/StatusBarButton.js"></script>
+ <script type="text/javascript" src="ui/DropDownMenu.js"></script>
+ <script type="text/javascript" src="common/CompletionDictionary.js"></script>
+ <script type="text/javascript" src="ui/InplaceEditor.js"></script>
+ <script type="text/javascript" src="ui/TextEditor.js"></script>
+ <script type="text/javascript" src="ui/SplitView.js"></script>
+ <script type="text/javascript" src="ui/StackView.js"></script>
+ <script type="text/javascript" src="ui/EmptyView.js"></script>
+ <script type="text/javascript" src="sdk/TempFile.js"></script>
+ <script type="text/javascript" src="ui/TextUtils.js"></script>
+ <script type="text/javascript" src="sdk/FileSystemModel.js"></script>
+ <script type="text/javascript" src="sdk/FileUtils.js"></script>
+ <script type="text/javascript" src="sdk/DebuggerModel.js"></script>
+ <script type="text/javascript" src="sdk/SourceMap.js"></script>
+ <script type="text/javascript" src="sdk/SourceMapping.js"></script>
+ <script type="text/javascript" src="sdk/LayerTreeModel.js"></script>
+ <script type="text/javascript" src="sdk/Script.js"></script>
+ <script type="text/javascript" src="sdk/Linkifier.js"></script>
+ <script type="text/javascript" src="sdk/DebuggerScriptMapping.js"></script>
+ <script type="text/javascript" src="sdk/PresentationConsoleMessageHelper.js"></script>
+ <script type="text/javascript" src="sdk/FileSystemWorkspaceBinding.js"></script>
+ <script type="text/javascript" src="sdk/FileSystemMapping.js"></script>
+ <script type="text/javascript" src="sdk/IsolatedFileSystem.js"></script>
+ <script type="text/javascript" src="sdk/IsolatedFileSystemManager.js"></script>
+ <script type="text/javascript" src="sdk/Workspace.js"></script>
+ <script type="text/javascript" src="sdk/WorkspaceController.js"></script>
+ <script type="text/javascript" src="sdk/ContentProviderBasedProjectDelegate.js"></script>
+ <script type="text/javascript" src="sdk/NetworkWorkspaceBinding.js"></script>
+ <script type="text/javascript" src="sdk/BreakpointManager.js"></script>
+ <script type="text/javascript" src="sdk/ContentProviders.js"></script>
+ <script type="text/javascript" src="sdk/DefaultScriptMapping.js"></script>
+ <script type="text/javascript" src="sdk/ResourceScriptMapping.js"></script>
+ <script type="text/javascript" src="sdk/CompilerScriptMapping.js"></script>
+ <script type="text/javascript" src="sdk/LiveEditSupport.js"></script>
+ <script type="text/javascript" src="sdk/CSSStyleSheetMapping.js"></script>
+ <script type="text/javascript" src="sdk/SASSSourceMapping.js"></script>
+ <script type="text/javascript" src="ForwardedInputEventHandler.js"></script>
+ <script type="text/javascript" src="sdk/DOMModel.js"></script>
<script type="text/javascript" src="TestController.js"></script>
- <script type="text/javascript" src="Dialog.js"></script>
- <script type="text/javascript" src="GoToLineDialog.js"></script>
- <script type="text/javascript" src="SidebarOverlay.js"></script>
- <script type="text/javascript" src="SettingsScreen.js"></script>
- <script type="text/javascript" src="EditFileSystemDialog.js"></script>
- <script type="text/javascript" src="ShortcutsScreen.js"></script>
- <script type="text/javascript" src="HAREntry.js"></script>
- <script type="text/javascript" src="CookieParser.js"></script>
- <script type="text/javascript" src="SearchableView.js"></script>
- <script type="text/javascript" src="FilterBar.js"></script>
- <script type="text/javascript" src="InspectElementModeController.js"></script>
- <script type="text/javascript" src="WorkerManager.js"></script>
- <script type="text/javascript" src="UserMetrics.js"></script>
- <script type="text/javascript" src="RuntimeModel.js"></script>
- <script type="text/javascript" src="HandlerRegistry.js"></script>
- <script type="text/javascript" src="SnippetStorage.js"></script>
- <script type="text/javascript" src="ScriptSnippetModel.js"></script>
- <script type="text/javascript" src="Progress.js"></script>
- <script type="text/javascript" src="ProgressIndicator.js"></script>
- <script type="text/javascript" src="StylesSourceMapping.js"></script>
- <script type="text/javascript" src="NetworkUISourceCodeProvider.js"></script>
- <script type="text/javascript" src="ElementsPanelDescriptor.js"></script>
- <script type="text/javascript" src="NetworkPanelDescriptor.js"></script>
- <script type="text/javascript" src="ProfilesPanelDescriptor.js"></script>
- <script type="text/javascript" src="SourcesPanelDescriptor.js"></script>
- <script type="text/javascript" src="TimelinePanelDescriptor.js"></script>
- <script type="text/javascript" src="LayersPanelDescriptor.js"></script>
- <script type="text/javascript" src="DockController.js"></script>
- <script type="text/javascript" src="TracingAgent.js"></script>
+ <script type="text/javascript" src="ui/Dialog.js"></script>
+ <script type="text/javascript" src="components/ShortcutsScreen.js"></script>
+ <script type="text/javascript" src="sdk/CookieParser.js"></script>
+ <script type="text/javascript" src="components/SearchableView.js"></script>
+ <script type="text/javascript" src="components/FilterBar.js"></script>
+ <script type="text/javascript" src="components/FilterSuggestionBuilder.js"></script>
+ <script type="text/javascript" src="components/InspectElementModeController.js"></script>
+ <script type="text/javascript" src="sdk/WorkerManager.js"></script>
+ <script type="text/javascript" src="components/WorkerFrontendManager.js"></script>
+ <script type="text/javascript" src="sdk/WorkerTargetManager.js"></script>
+ <script type="text/javascript" src="sdk/RuntimeModel.js"></script>
+ <script type="text/javascript" src="components/HandlerRegistry.js"></script>
+ <script type="text/javascript" src="sdk/SnippetStorage.js"></script>
+ <script type="text/javascript" src="sdk/ScriptSnippetModel.js"></script>
+ <script type="text/javascript" src="ui/ProgressIndicator.js"></script>
+ <script type="text/javascript" src="sdk/StylesSourceMapping.js"></script>
+ <script type="text/javascript" src="sdk/NetworkUISourceCodeProvider.js"></script>
+ <script type="text/javascript" src="sdk/CPUProfilerModel.js"></script>
+ <script type="text/javascript" src="ui/PieChart.js"></script>
+ <script type="text/javascript" src="components/FlameChart.js"></script>
+ <script type="text/javascript" src="components/DockController.js"></script>
+ <script type="text/javascript" src="sdk/PaintProfiler.js"></script>
+ <script type="text/javascript" src="components/ExtensionServerProxy.js"></script>
+ <script type="text/javascript" src="main/HelpScreenUntilReload.js"></script>
+ <script type="text/javascript" src="main/App.js"></script>
+ <script type="text/javascript" src="main/SimpleApp.js"></script>
+ <script type="text/javascript" src="main/AdvancedApp.js"></script>
+ <script type="text/javascript" src="main/ScreencastApp.js"></script>
+ <script type="text/javascript" src="ui/ZoomManager.js"></script>
<script type="text/javascript" src="ScreencastView.js"></script>
- <script type="text/javascript" src="DevToolsExtensionAPI.js"></script>
+ <script type="text/javascript" src="ui/ResizerWidget.js"></script>
+ <script type="text/javascript" src="MediaQueryInspector.js"></script>
+ <script type="text/javascript" src="ResponsiveDesignView.js"></script>
<script type="text/javascript" src="Tests.js"></script>
- <script type="text/javascript" src="FlameChart.js"></script>
</head>
<body class="undocked" id="-blink-dev-tools"></body>
</html>
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.js b/chromium/third_party/WebKit/Source/devtools/front_end/inspector.js
deleted file mode 100644
index f274fb2f613..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/inspector.js
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
- * Copyright (C) 2009 Joseph Pecoraro
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-var WebInspector = {
- _panelDescriptors: function()
- {
- this.panels = {};
- WebInspector.inspectorView = new WebInspector.InspectorView();
- WebInspector.inspectorView.show(document.body);
-
- var elements = new WebInspector.ElementsPanelDescriptor();
- var network = new WebInspector.NetworkPanelDescriptor();
- var sources = new WebInspector.SourcesPanelDescriptor();
- var timeline = new WebInspector.TimelinePanelDescriptor();
- var profiles = new WebInspector.ProfilesPanelDescriptor();
- var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js");
- var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
- var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
-
- if (WebInspector.WorkerManager.isWorkerFrontend())
- return [sources, timeline, profiles, console];
-
- var panelDescriptors = [elements, network, sources, timeline, profiles, resources, audits, console];
- if (WebInspector.experimentsSettings.layersPanel.isEnabled()) {
- var layers = new WebInspector.LayersPanelDescriptor();
- panelDescriptors.push(layers);
- }
- return panelDescriptors;
- },
-
- _createGlobalStatusBarItems: function()
- {
- if (this.inspectElementModeController)
- this.inspectorView.appendToLeftToolbar(this.inspectElementModeController.toggleSearchButton.element);
-
- if (Capabilities.canScreencast) {
- this._toggleScreencastButton = new WebInspector.StatusBarButton(WebInspector.UIString("Toggle screencast."), "screencast-status-bar-item");
- this._toggleScreencastButton.addEventListener("click", this._toggleScreencastButtonClicked.bind(this), false);
- this.inspectorView.appendToLeftToolbar(this._toggleScreencastButton.element);
- }
-
- this.inspectorView.appendToRightToolbar(this.settingsController.statusBarItem);
- if (WebInspector.queryParamsObject["can_dock"])
- this.inspectorView.appendToRightToolbar(this.dockController.element);
-
- var closeButtonToolbarItem = document.createElementWithClass("div", "toolbar-close-button-item");
- var closeButtonElement = closeButtonToolbarItem.createChild("div", "close-button");
- closeButtonElement.addEventListener("click", WebInspector.close.bind(WebInspector), true);
- this.inspectorView.appendToRightToolbar(closeButtonToolbarItem);
- },
-
- /**
- * @return {boolean}
- */
- isInspectingDevice: function()
- {
- return !!WebInspector.queryParamsObject["remoteFrontend"];
- },
-
- _toggleScreencastButtonClicked: function()
- {
- this._toggleScreencastButton.toggled = !this._toggleScreencastButton.toggled;
- WebInspector.settings.screencastEnabled.set(this._toggleScreencastButton.toggled);
-
- if (this._toggleScreencastButton.toggled) {
- if (!this._screencastView) {
- // Rebuild the UI upon first invocation.
- this._screencastView = new WebInspector.ScreencastView();
- this._screencastSplitView = new WebInspector.SplitView(true, WebInspector.settings.screencastSidebarWidth.name);
- this._screencastSplitView.markAsRoot();
- this._screencastSplitView.show(document.body);
-
- this._screencastView.show(this._screencastSplitView.firstElement());
-
- this.inspectorView.element.remove();
- this.inspectorView.show(this._screencastSplitView.secondElement());
- }
- this._screencastSplitView.showBoth();
- } else {
- this._screencastSplitView.showOnlySecond();
- }
- },
-
-
- showConsole: function()
- {
- if (this.consoleView.isShowing() && !WebInspector.inspectorView.drawer().isHiding())
- return;
- this.inspectorView.showViewInDrawer("console");
- },
-
- _resetErrorAndWarningCounts: function()
- {
- WebInspector.inspectorView.setErrorAndWarningCounts(0, 0);
- },
-
- _updateErrorAndWarningCounts: function()
- {
- var errors = WebInspector.console.errors;
- var warnings = WebInspector.console.warnings;
- WebInspector.inspectorView.setErrorAndWarningCounts(errors, warnings);
- },
-
- get inspectedPageDomain()
- {
- var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
- return parsedURL ? parsedURL.host : "";
- },
-
- _initializeCapability: function(name, callback, error, result)
- {
- Capabilities[name] = result;
- if (callback)
- callback();
- },
-
- _zoomIn: function()
- {
- this._zoomLevel = Math.min(this._zoomLevel + 1, WebInspector.Zoom.Table.length - WebInspector.Zoom.DefaultOffset - 1);
- this._requestZoom();
- },
-
- _zoomOut: function()
- {
- this._zoomLevel = Math.max(this._zoomLevel - 1, -WebInspector.Zoom.DefaultOffset);
- this._requestZoom();
- },
-
- _resetZoom: function()
- {
- this._zoomLevel = 0;
- this._requestZoom();
- },
-
- /**
- * @return {number}
- * @this {WebInspector}
- */
- zoomFactor: function()
- {
- // For backwards compatibility, zoomLevel takes integers (with 0 being default zoom).
- var index = this._zoomLevel + WebInspector.Zoom.DefaultOffset;
- index = Math.min(WebInspector.Zoom.Table.length - 1, index);
- index = Math.max(0, index);
- return WebInspector.Zoom.Table[index];
- },
-
- _requestZoom: function()
- {
- WebInspector.settings.zoomLevel.set(this._zoomLevel);
- InspectorFrontendHost.setZoomFactor(this.zoomFactor());
- },
-
- _debuggerPaused: function()
- {
- this.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
- WebInspector.showPanel("sources");
- }
-}
-
-WebInspector.Events = {
- InspectorLoaded: "InspectorLoaded"
-}
-
-{(function parseQueryParameters()
-{
- WebInspector.queryParamsObject = {};
- var queryParams = window.location.search;
- if (!queryParams)
- return;
- var params = queryParams.substring(1).split("&");
- for (var i = 0; i < params.length; ++i) {
- var pair = params[i].split("=");
- WebInspector.queryParamsObject[pair[0]] = pair[1];
- }
-})();}
-
-WebInspector.suggestReload = function()
-{
- if (window.confirm(WebInspector.UIString("It is recommended to restart inspector after making these changes. Would you like to restart it?")))
- this.reload();
-}
-
-WebInspector.reload = function()
-{
- InspectorAgent.reset();
-
- var queryParams = window.location.search;
- var url = window.location.href;
- url = url.substring(0, url.length - queryParams.length);
- var queryParamsObject = {};
- for (var name in WebInspector.queryParamsObject)
- queryParamsObject[name] = WebInspector.queryParamsObject[name];
- if (this.dockController)
- queryParamsObject["dockSide"] = this.dockController.dockSide();
- var names = Object.keys(queryParamsObject);
- for (var i = 0; i < names.length; ++i)
- url += (i ? "&" : "?") + names[i] + "=" + queryParamsObject[names[i]];
- document.location = url;
-}
-
-WebInspector.loaded = function()
-{
- if (!InspectorFrontendHost.sendMessageToEmbedder) {
- var helpScreen = new WebInspector.HelpScreen(WebInspector.UIString("Incompatible Chrome version"));
- var p = helpScreen.contentElement.createChild("p", "help-section");
- p.textContent = WebInspector.UIString("Please upgrade to a newer Chrome version (you might need a Dev or Canary build).");
- helpScreen.showModal();
- return;
- }
-
- InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
- WebInspector.dockController = new WebInspector.DockController();
-
- if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) {
- // Do not create socket for the worker front-end.
- WebInspector.doLoadedDone();
- return;
- }
-
- var ws;
- if ("ws" in WebInspector.queryParamsObject)
- ws = "ws://" + WebInspector.queryParamsObject.ws;
- else if ("page" in WebInspector.queryParamsObject) {
- var page = WebInspector.queryParamsObject.page;
- var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
- ws = "ws://" + host + "/devtools/page/" + page;
- }
-
- if (ws) {
- WebInspector.socket = new WebSocket(ws);
- WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
- WebInspector.socket.onerror = function(error) { console.error(error); }
- WebInspector.socket.onopen = function() {
- InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
- WebInspector.doLoadedDone();
- }
- WebInspector.socket.onclose = function() {
- if (!WebInspector.socket._detachReason)
- (new WebInspector.RemoteDebuggingTerminatedScreen("websocket_closed")).showModal();
- }
- return;
- }
-
- WebInspector.doLoadedDone();
-
- // In case of loading as a web page with no bindings / harness, kick off initialization manually.
- if (InspectorFrontendHost.isStub) {
- InspectorFrontendAPI.dispatchQueryParameters(WebInspector.queryParamsObject);
- WebInspector._doLoadedDoneWithCapabilities();
- }
-}
-
-WebInspector.doLoadedDone = function()
-{
- // Install styles and themes
- WebInspector.installPortStyles();
- if (WebInspector.socket)
- document.body.classList.add("remote");
- if (WebInspector.queryParamsObject["overlayContents"])
- document.body.classList.add("overlay-contents");
-
- if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
- WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);
-
- WebInspector.WorkerManager.loaded();
-
- PageAgent.canScreencast(WebInspector._initializeCapability.bind(WebInspector, "canScreencast", null));
- WorkerAgent.canInspectWorkers(WebInspector._initializeCapability.bind(WebInspector, "canInspectWorkers", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
-}
-
-WebInspector._doLoadedDoneWithCapabilities = function()
-{
- new WebInspector.VersionController().updateVersion();
-
- WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
- this._registerShortcuts();
-
- // set order of some sections explicitly
- WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
- WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
-
- this.console = new WebInspector.ConsoleModel();
- this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._resetErrorAndWarningCounts, this);
- this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
- this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);
- this.networkManager = new WebInspector.NetworkManager();
- this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
- this.debuggerModel = new WebInspector.DebuggerModel();
- this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
- this.networkLog = new WebInspector.NetworkLog();
- this.domAgent = new WebInspector.DOMAgent();
- this.domAgent.addEventListener(WebInspector.DOMAgent.Events.InspectNodeRequested, this._inspectNodeRequested, this);
- this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel);
-
- var panelDescriptors = this._panelDescriptors();
- this.advancedSearchController = new WebInspector.AdvancedSearchController();
- for (var i = 0; i < panelDescriptors.length; ++i)
- panelDescriptors[i].registerShortcuts();
-
- WebInspector.CSSMetadata.requestCSSShorthandData();
-
- this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());
-
- InspectorBackend.registerInspectorDispatcher(this);
-
- this.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
- this.isolatedFileSystemDispatcher = new WebInspector.IsolatedFileSystemDispatcher(this.isolatedFileSystemManager);
- this.workspace = new WebInspector.Workspace(this.isolatedFileSystemManager.mapping());
-
- this.cssModel = new WebInspector.CSSStyleModel(this.workspace);
- this.timelineManager = new WebInspector.TimelineManager();
- this.tracingAgent = new WebInspector.TracingAgent();
-
- if (!WebInspector.WorkerManager.isWorkerFrontend())
- this.inspectElementModeController = new WebInspector.InspectElementModeController();
-
- this.settingsController = new WebInspector.SettingsController();
-
- this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
-
- this._zoomLevel = WebInspector.settings.zoomLevel.get();
- if (this._zoomLevel)
- this._requestZoom();
-
- var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
- var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
- this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
- this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
-
- new WebInspector.WorkspaceController(this.workspace);
-
- this.fileSystemWorkspaceProvider = new WebInspector.FileSystemWorkspaceProvider(this.isolatedFileSystemManager, this.workspace);
-
- this.networkWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(this.workspace, WebInspector.projectTypes.Network);
- new WebInspector.NetworkUISourceCodeProvider(this.networkWorkspaceProvider, this.workspace);
-
- this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace);
-
- this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace);
-
- this.overridesSupport = new WebInspector.OverridesSupport();
- this.overridesSupport.applyInitialOverrides();
-
- new WebInspector.DebuggerScriptMapping(this.workspace, this.networkWorkspaceProvider);
- this.liveEditSupport = new WebInspector.LiveEditSupport(this.workspace);
- new WebInspector.CSSStyleSheetMapping(this.cssModel, this.workspace, this.networkWorkspaceProvider);
- new WebInspector.PresentationConsoleMessageHelper(this.workspace);
-
- this._createGlobalStatusBarItems();
-
- WebInspector.startBatchUpdate();
- for (var i = 0; i < panelDescriptors.length; ++i)
- WebInspector.inspectorView.addPanel(panelDescriptors[i]);
- WebInspector.endBatchUpdate();
-
- this.addMainEventListeners(document);
-
- window.addEventListener("resize", this.windowResize.bind(this), true);
-
- var errorWarningCount = document.getElementById("error-warning-count");
- errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
- this._updateErrorAndWarningCounts();
-
- this.extensionServer.initExtensions();
-
- this.console.enableAgent();
-
- InspectorAgent.enable(WebInspector.inspectorView.showInitialPanel.bind(WebInspector.inspectorView));
- this.databaseModel = new WebInspector.DatabaseModel();
- this.domStorageModel = new WebInspector.DOMStorageModel();
-
- this.cpuProfilerModel = new WebInspector.CPUProfilerModel();
- HeapProfilerAgent.enable();
-
- WebInspector.settings.showPaintRects = WebInspector.settings.createBackendSetting("showPaintRects", false, PageAgent.setShowPaintRects.bind(PageAgent));
- WebInspector.settings.showDebugBorders = WebInspector.settings.createBackendSetting("showDebugBorders", false, PageAgent.setShowDebugBorders.bind(PageAgent));
- WebInspector.settings.continuousPainting = WebInspector.settings.createBackendSetting("continuousPainting", false, PageAgent.setContinuousPaintingEnabled.bind(PageAgent));
- WebInspector.settings.showFPSCounter = WebInspector.settings.createBackendSetting("showFPSCounter", false, PageAgent.setShowFPSCounter.bind(PageAgent));
- WebInspector.settings.showScrollBottleneckRects = WebInspector.settings.createBackendSetting("showScrollBottleneckRects", false, PageAgent.setShowScrollBottleneckRects.bind(PageAgent));
-
- if (WebInspector.settings.showPaintRects.get() || WebInspector.settings.showDebugBorders.get() || WebInspector.settings.continuousPainting.get() ||
- WebInspector.settings.showFPSCounter.get() || WebInspector.settings.showScrollBottleneckRects.get()) {
- WebInspector.settings.showRenderingViewInDrawer.set(true);
- }
-
- WebInspector.settings.showMetricsRulers.addChangeListener(showRulersChanged);
- function showRulersChanged()
- {
- PageAgent.setShowViewportSizeOnResize(true, WebInspector.settings.showMetricsRulers.get());
- }
- showRulersChanged();
-
- WebInspector.WorkerManager.loadCompleted();
- InspectorFrontendAPI.loadCompleted();
-
- if (Capabilities.canScreencast && WebInspector.settings.screencastEnabled.get())
- this._toggleScreencastButtonClicked();
-
- WebInspector.notifications.dispatchEventToListeners(WebInspector.Events.InspectorLoaded);
-}
-
-var windowLoaded = function()
-{
- WebInspector.loaded();
- window.removeEventListener("DOMContentLoaded", windowLoaded, false);
- delete windowLoaded;
-};
-
-window.addEventListener("DOMContentLoaded", windowLoaded, false);
-
-// We'd like to enforce asynchronous interaction between the inspector controller and the frontend.
-// It is needed to prevent re-entering the backend code.
-// Also, native dispatches do not guarantee setTimeouts to be serialized, so we
-// enforce serialization using 'messagesToDispatch' queue. It is also important that JSC debugger
-// tests require that each command was dispatch within individual timeout callback, so we don't batch them.
-
-var messagesToDispatch = [];
-
-WebInspector.dispatchQueueIsEmpty = function() {
- return messagesToDispatch.length == 0;
-}
-
-WebInspector.dispatch = function(message) {
- messagesToDispatch.push(message);
- setTimeout(function() {
- InspectorBackend.dispatch(messagesToDispatch.shift());
- }, 0);
-}
-
-WebInspector.windowResize = function(event)
-{
- if (WebInspector.inspectorView)
- WebInspector.inspectorView.onResize();
- if (WebInspector.settingsController)
- WebInspector.settingsController.resize();
- if (WebInspector._screencastSplitView)
- WebInspector._screencastSplitView.doResize();
-}
-
-WebInspector.close = function(event)
-{
- InspectorFrontendHost.closeWindow();
-}
-
-WebInspector.documentClick = function(event)
-{
- var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
- if (!anchor || (anchor.target === "_blank"))
- return;
-
- // Prevent the link from navigating, since we don't do any navigation by following links normally.
- event.consume(true);
-
- function followLink()
- {
- if (WebInspector.isBeingEdited(event.target))
- return;
- if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
- return;
- if (WebInspector.showAnchorLocation(anchor))
- return;
-
- const profileMatch = WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp.exec(anchor.href);
- if (profileMatch) {
- WebInspector.showPanel("profiles").showProfile(profileMatch[1], profileMatch[2]);
- return;
- }
-
- var parsedURL = anchor.href.asParsedURL();
- if (parsedURL && parsedURL.scheme === "webkit-link-action") {
- if (parsedURL.host === "show-panel") {
- var panel = parsedURL.path.substring(1);
- if (WebInspector.panel(panel))
- WebInspector.showPanel(panel);
- }
- return;
- }
-
- InspectorFrontendHost.openInNewTab(anchor.href);
- }
-
- if (WebInspector.followLinkTimeout)
- clearTimeout(WebInspector.followLinkTimeout);
-
- if (anchor.preventFollowOnDoubleClick) {
- // Start a timeout if this is the first click, if the timeout is canceled
- // before it fires, then a double clicked happened or another link was clicked.
- if (event.detail === 1)
- WebInspector.followLinkTimeout = setTimeout(followLink, 333);
- return;
- }
-
- followLink();
-}
-
-WebInspector.openResource = function(resourceURL, inResourcesPanel)
-{
- var resource = WebInspector.resourceForURL(resourceURL);
- if (inResourcesPanel && resource)
- WebInspector.showPanel("resources").showResource(resource);
- else
- InspectorFrontendHost.openInNewTab(resourceURL);
-}
-
-WebInspector._registerShortcuts = function()
-{
- var shortcut = WebInspector.KeyboardShortcut;
- var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
- var keys = [
- shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
- shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
- ];
- section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
-
- keys = [
- shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
- shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
- ];
- section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
-
- var toggleConsoleLabel = WebInspector.UIString("Show console");
- section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
- var doNotOpenDrawerOnEsc = WebInspector.experimentsSettings.doNotOpenDrawerOnEsc.isEnabled();
- var toggleDrawerLabel = doNotOpenDrawerOnEsc ? WebInspector.UIString("Hide drawer") : WebInspector.UIString("Toggle drawer");
- section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), toggleDrawerLabel);
- section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
-
- var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
- section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
-
- var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
- section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));
-
- var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
- section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
-
- if (WebInspector.isMac()) {
- keys = [
- shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
- shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
- ];
- section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
- }
-
- var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
- section.addKey(goToShortcut, WebInspector.UIString("Go to line"));
-
- keys = [
- shortcut.Keys.F1,
- shortcut.makeDescriptor("?")
- ];
- section.addAlternateKeys(keys, WebInspector.UIString("Show general settings"));
-}
-
-WebInspector.documentKeyDown = function(event)
-{
- if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
- WebInspector.currentFocusElement().handleKeyEvent(event);
- if (event.handled) {
- event.consume(true);
- return;
- }
- }
-
- if (WebInspector.inspectorView.currentPanel()) {
- WebInspector.inspectorView.currentPanel().handleShortcut(event);
- if (event.handled) {
- event.consume(true);
- return;
- }
- }
-
- if (WebInspector.advancedSearchController.handleShortcut(event))
- return;
- if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.handleShortcut(event))
- return;
-
- switch (event.keyIdentifier) {
- case "U+004F": // O key
- case "U+0050": // P key
- if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
- WebInspector.showPanel("sources").showGoToSourceDialog();
- event.consume(true);
- }
- break;
- case "U+0052": // R key
- if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
- WebInspector.debuggerModel.skipAllPauses(true, true);
- WebInspector.resourceTreeModel.reloadPage(event.shiftKey);
- event.consume(true);
- }
- if (window.DEBUG && event.altKey) {
- WebInspector.reload();
- return;
- }
- break;
- case "F5":
- if (!WebInspector.isMac()) {
- WebInspector.resourceTreeModel.reloadPage(event.ctrlKey || event.shiftKey);
- event.consume(true);
- }
- break;
- }
-
- var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
- !event.altKey &&
- !InspectorFrontendHost.isStub;
- switch (event.keyCode) {
- case 107: // +
- case 187: // +
- if (isValidZoomShortcut) {
- WebInspector._zoomIn();
- event.consume(true);
- }
- break;
- case 109: // -
- case 189: // -
- if (isValidZoomShortcut) {
- WebInspector._zoomOut();
- event.consume(true);
- }
- break;
- case 48: // 0
- case 96: // Numpad 0
- // Zoom reset shortcut does not allow "Shift" when handled by the browser.
- if (isValidZoomShortcut && !event.shiftKey) {
- WebInspector._resetZoom();
- event.consume(true);
- }
- break;
- }
-
-}
-
-WebInspector.postDocumentKeyDown = function(event)
-{
- const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF"; // "?" for both platforms
-
- if (event.keyIdentifier === "F1" ||
- (event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
- this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.General);
- event.consume(true);
- return;
- }
-
- const Esc = "U+001B";
-
- if (event.handled)
- return;
-
- var doNotOpenDrawerOnEsc = WebInspector.experimentsSettings.doNotOpenDrawerOnEsc.isEnabled();
- if (event.keyIdentifier === Esc) {
- if (this.inspectorView.drawer().visible())
- this.inspectorView.drawer().hide();
- else if (!doNotOpenDrawerOnEsc)
- this.inspectorView.drawer().show();
- }
-
- if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Tilde.code && event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey)
- this.showConsole();
-}
-
-WebInspector.documentCanCopy = function(event)
-{
- if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
- event.preventDefault();
-}
-
-WebInspector.documentCopy = function(event)
-{
- if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
- WebInspector.inspectorView.currentPanel().handleCopyEvent(event);
-}
-
-WebInspector.contextMenuEventFired = function(event)
-{
- if (event.handled || event.target.classList.contains("popup-glasspane"))
- event.preventDefault();
-}
-
-WebInspector.showPanel = function(panel)
-{
- return WebInspector.inspectorView.showPanel(panel);
-}
-
-WebInspector.panel = function(panel)
-{
- return WebInspector.inspectorView.panel(panel);
-}
-
-WebInspector.bringToFront = function()
-{
- InspectorFrontendHost.bringToFront();
-}
-
-/**
- * @param {string=} messageLevel
- * @param {boolean=} showConsole
- */
-WebInspector.log = function(message, messageLevel, showConsole)
-{
- // remember 'this' for setInterval() callback
- var self = this;
-
- // return indication if we can actually log a message
- function isLogAvailable()
- {
- return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
- }
-
- // flush the queue of pending messages
- function flushQueue()
- {
- var queued = WebInspector.log.queued;
- if (!queued)
- return;
-
- for (var i = 0; i < queued.length; ++i)
- logMessage(queued[i]);
-
- delete WebInspector.log.queued;
- }
-
- // flush the queue if it console is available
- // - this function is run on an interval
- function flushQueueIfAvailable()
- {
- if (!isLogAvailable())
- return;
-
- clearInterval(WebInspector.log.interval);
- delete WebInspector.log.interval;
-
- flushQueue();
- }
-
- // actually log the message
- function logMessage(message)
- {
- // post the message
- var msg = WebInspector.ConsoleMessage.create(
- WebInspector.ConsoleMessage.MessageSource.Other,
- messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
- message);
-
- self.console.addMessage(msg);
- if (showConsole)
- WebInspector.showConsole();
- }
-
- // if we can't log the message, queue it
- if (!isLogAvailable()) {
- if (!WebInspector.log.queued)
- WebInspector.log.queued = [];
-
- WebInspector.log.queued.push(message);
-
- if (!WebInspector.log.interval)
- WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);
-
- return;
- }
-
- // flush the pending queue if any
- flushQueue();
-
- // log the message
- logMessage(message);
-}
-
-WebInspector.showErrorMessage = function(error)
-{
- WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
-}
-
-// Inspector.inspect protocol event
-WebInspector.inspect = function(payload, hints)
-{
- var object = WebInspector.RemoteObject.fromPayload(payload);
- if (object.subtype === "node") {
- function callback(nodeId)
- {
- WebInspector._updateFocusedNode(nodeId);
- object.release();
- }
- object.pushNodeToFrontend(callback);
- WebInspector.showPanel("elements");
- return;
- }
-
- if (object.type === "function") {
- /**
- * @param {?Protocol.Error} error
- * @param {!DebuggerAgent.FunctionDetails} response
- */
- function didGetDetails(error, response)
- {
- object.release();
-
- if (error) {
- console.error(error);
- return;
- }
-
- var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(response.location);
- if (!uiLocation)
- return;
-
- WebInspector.panel("sources").showUILocation(uiLocation, true);
- }
- DebuggerAgent.getFunctionDetails(object.objectId, didGetDetails.bind(this));
- return;
- }
-
- if (hints.databaseId)
- WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId));
- else if (hints.domStorageId)
- WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId));
- else if (hints.copyToClipboard)
- InspectorFrontendHost.copyText(object.value);
- object.release();
-}
-
-// Inspector.detached protocol event
-WebInspector.detached = function(reason)
-{
- WebInspector.socket._detachReason = reason;
- (new WebInspector.RemoteDebuggingTerminatedScreen(reason)).showModal();
-}
-
-WebInspector.targetCrashed = function()
-{
- (new WebInspector.HelpScreenUntilReload(
- WebInspector.UIString("Inspected target crashed"),
- WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal();
-}
-
-WebInspector._inspectNodeRequested = function(event)
-{
- WebInspector._updateFocusedNode(event.data);
-}
-
-WebInspector._updateFocusedNode = function(nodeId)
-{
- if (WebInspector.inspectElementModeController && WebInspector.inspectElementModeController.enabled()) {
- InspectorFrontendHost.bringToFront();
- WebInspector.inspectElementModeController.disable();
- }
- WebInspector.showPanel("elements").revealAndSelectNode(nodeId);
-}
-
-WebInspector.showAnchorLocation = function(anchor)
-{
- var preferredPanel = this.panels[anchor.preferredPanel];
- if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel))
- return true;
- if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("sources")))
- return true;
- if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources")))
- return true;
- if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network")))
- return true;
- return false;
-}
-
-WebInspector._showAnchorLocationInPanel = function(anchor, panel)
-{
- if (!panel)
- return false;
-
- var result = panel.showAnchorLocation(anchor);
- if (result) {
- // FIXME: support webkit-html-external-link links here.
- if (anchor.classList.contains("webkit-html-external-link")) {
- anchor.classList.remove("webkit-html-external-link");
- anchor.classList.add("webkit-html-resource-link");
- }
- }
- return result;
-}
-
-WebInspector.evaluateInConsole = function(expression, showResultOnly)
-{
- this.showConsole();
- this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
-}
-
-WebInspector.addMainEventListeners = function(doc)
-{
- doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
- doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
- doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
- doc.addEventListener("copy", this.documentCopy.bind(this), false);
- doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
- doc.addEventListener("click", this.documentClick.bind(this), true);
-}
-
-WebInspector.Zoom = {
- Table: [0.25, 0.33, 0.5, 0.66, 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5],
- DefaultOffset: 6
-}
-
-
-// Ex-DevTools.js content
-
-/**
- * @param {!ExtensionDescriptor} extensionInfo
- * @return {string}
- */
-function buildPlatformExtensionAPI(extensionInfo)
-{
- return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
- "var tabId = " + WebInspector._inspectedTabId + ";" +
- platformExtensionAPI.toString();
-}
-
-WebInspector.setInspectedTabId = function(tabId)
-{
- WebInspector._inspectedTabId = tabId;
-}
-
-/**
- * @return {string}
- */
-WebInspector.getSelectionBackgroundColor = function()
-{
- return InspectorFrontendHost.getSelectionBackgroundColor();
-}
-
-/**
- * @return {string}
- */
-WebInspector.getSelectionForegroundColor = function()
-{
- return InspectorFrontendHost.getSelectionForegroundColor();
-}
-
-window.DEBUG = true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/inspectorCommon.css b/chromium/third_party/WebKit/Source/devtools/front_end/inspectorCommon.css
index 9e794795ec7..d719f1006e4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/inspectorCommon.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/inspectorCommon.css
@@ -4,11 +4,9 @@ html {
body {
cursor: default;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
+ position: relative;
+ height: 100%;
+ width: 100%;
overflow: hidden;
font-family: Lucida Grande, sans-serif;
font-size: 12px;
@@ -28,19 +26,11 @@ body.platform-mac {
font-family: 'Lucida Grande', sans-serif;
}
-body.dock-to-right:not(.undocked):not(.overlay-contents) {
- border-left: 1px solid rgb(80, 80, 80);
-}
-
-body.dock-to-right.inactive:not(.undocked):not(.overlay-contents) {
- border-left: 1px solid rgb(64%, 64%, 64%);
-}
-
body.platform-windows {
font-family: 'Segoe UI', Tahoma, sans-serif;
}
-* {
+*, *::before, *::after {
box-sizing: border-box;
}
@@ -204,6 +194,12 @@ iframe.view {
padding: 0;
}
+.network-timing-table td.caution {
+ font-weight: bold;
+ color: rgb(255, 128, 0);
+ padding: 2px 0;
+}
+
.network-timing-row {
position: relative;
height: 16px;
@@ -247,3 +243,15 @@ iframe.view {
font-size: 11px;
}
+.pie-chart {
+ position: relative;
+}
+
+.pie-chart-foreground {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ z-index: 10;
+ top: 0;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/inspectorSyntaxHighlight.css b/chromium/third_party/WebKit/Source/devtools/front_end/inspectorSyntaxHighlight.css
index 7d904c0d075..e29896c55c4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/inspectorSyntaxHighlight.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/inspectorSyntaxHighlight.css
@@ -66,9 +66,14 @@
color: brown;
}
+.webkit-html-text-node {
+ unicode-bidi: -webkit-isolate;
+}
+
.webkit-html-entity-value {
/* This one is non-standard. */
background-color: rgba(0, 0, 0, 0.15);
+ unicode-bidi: -webkit-isolate;
}
.webkit-html-doctype {
@@ -79,11 +84,13 @@
.webkit-html-attribute-name {
/* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
color: rgb(153, 69, 0);
+ unicode-bidi: -webkit-isolate;
}
.webkit-html-attribute-value {
/* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
color: rgb(26, 26, 166);
+ unicode-bidi: -webkit-isolate;
}
.webkit-html-external-link,
@@ -92,6 +99,12 @@
color: #00e;
}
+.webkit-html-resource-link {
+ /* Required for consistency with view-source.css, since anchors may not have href attributes */
+ text-decoration: underline;
+ cursor: pointer;
+}
+
.webkit-html-external-link {
/* Keep this in sync with view-source.css (.webkit-html-external-link) */
text-decoration: none;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LayerDetailsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerDetailsView.js
index 9ae00bf9d7c..714d37ea1d4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LayerDetailsView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerDetailsView.js
@@ -30,19 +30,21 @@
/**
* @constructor
- * @param {!WebInspector.LayerTreeModel} model
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
-WebInspector.LayerDetailsView = function(model)
+WebInspector.LayerDetailsView = function()
{
- WebInspector.View.call(this);
- this.element.classList.add("fill");
+ WebInspector.VBox.call(this);
this.element.classList.add("layer-details-view");
this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Select a layer to see its details"));
this._createTable();
- this._model = model;
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.LayerDetailsView.Events = {
+ ObjectSelected: "ObjectSelected"
}
/**
@@ -85,38 +87,49 @@ WebInspector.LayerDetailsView.CompositingReasonDetail = {
WebInspector.LayerDetailsView.prototype = {
/**
- * @param {?WebInspector.Layer} layer
+ * @param {!WebInspector.Layers3DView.ActiveObject} activeObject
*/
- setLayer: function(layer)
+ setObject: function(activeObject)
{
- this._layer = layer;
+ this._layer = activeObject ? activeObject.layer : null;
+ this._scrollRectIndex = activeObject ? activeObject.scrollRectIndex : null;
if (this.isShowing())
- this._update();
+ this.update();
},
wasShown: function()
{
WebInspector.View.prototype.wasShown.call(this);
- this._update();
+ this.update();
},
- _onLayerTreeUpdated: function()
+ /**
+ * @param {number} index
+ * @param {?Event} event
+ */
+ _onScrollRectClicked: function(index, event)
{
- if (this.isShowing())
- this._update();
+ if (event.which !== 1)
+ return;
+ this.dispatchEventToListeners(WebInspector.LayerDetailsView.Events.ObjectSelected, {layer: this._layer, scrollRectIndex: index});
},
/**
- * @param {!WebInspector.Event} event
+ * @param {!LayerTreeAgent.ScrollRect} scrollRect
+ * @param {number} index
*/
- _onLayerPainted: function(event)
+ _createScrollRectElement: function(scrollRect, index)
{
- var layer = /** @type {!WebInspector.Layer} */ (event.data);
- if (this._layer === layer)
- this._paintCountCell.textContent = layer.paintCount();
+ if (index)
+ this._scrollRectsCell.createTextChild(", ");
+ var element = this._scrollRectsCell.createChild("span");
+ element.className = index === this._scrollRectIndex ? "scroll-rect active" : "scroll-rect";
+ element.textContent = WebInspector.LayerTreeModel.ScrollRectType[scrollRect.type].description + " (" + scrollRect.rect.x + ", " + scrollRect.rect.y +
+ ", " + scrollRect.rect.width + ", " + scrollRect.rect.height + ")";
+ element.addEventListener("click", this._onScrollRectClicked.bind(this, index), false);
},
- _update: function()
+ update: function()
{
if (!this._layer) {
this._tableElement.remove();
@@ -131,6 +144,8 @@ WebInspector.LayerDetailsView.prototype = {
const bytesPerPixel = 4;
this._memoryEstimateCell.textContent = Number.bytesToString(this._layer.invisible() ? 0 : this._layer.width() * this._layer.height() * bytesPerPixel);
this._layer.requestCompositingReasons(this._updateCompositingReasons.bind(this));
+ this._scrollRectsCell.removeChildren();
+ this._layer.scrollRects().forEach(this._createScrollRectElement.bind(this));
},
_createTable: function()
@@ -142,6 +157,7 @@ WebInspector.LayerDetailsView.prototype = {
this._compositingReasonsCell = this._createRow(WebInspector.UIString("Compositing Reasons:"));
this._memoryEstimateCell = this._createRow(WebInspector.UIString("Memory estimate:"));
this._paintCountCell = this._createRow(WebInspector.UIString("Paint count:"));
+ this._scrollRectsCell = this._createRow(WebInspector.UIString("Slow scroll regions:"));
},
/**
@@ -177,5 +193,5 @@ WebInspector.LayerDetailsView.prototype = {
this._compositingReasonsCell.appendChild(fragment);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerPaintProfilerView.js b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerPaintProfilerView.js
new file mode 100644
index 00000000000..7977c56f25b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerPaintProfilerView.js
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @param {function(!WebInspector.Layer, string=)} showImageForLayerCallback
+ * @extends {WebInspector.SplitView}
+ */
+WebInspector.LayerPaintProfilerView = function(showImageForLayerCallback)
+{
+ WebInspector.SplitView.call(this, true, false);
+
+ this._showImageForLayerCallback = showImageForLayerCallback;
+ this._logTreeView = new WebInspector.PaintProfilerCommandLogView();
+ this._logTreeView.show(this.sidebarElement());
+ this._paintProfilerView = new WebInspector.PaintProfilerView(this._showImage.bind(this));
+ this._paintProfilerView.show(this.mainElement());
+
+ this._paintProfilerView.addEventListener(WebInspector.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this);
+}
+
+WebInspector.LayerPaintProfilerView.prototype = {
+ /**
+ * @param {!WebInspector.Layer} layer
+ */
+ profileLayer: function(layer)
+ {
+ layer.requestSnapshot(onSnapshotDone.bind(this));
+
+ /**
+ * @param {!WebInspector.PaintProfilerSnapshot=} snapshot
+ * @this {WebInspector.LayerPaintProfilerView}
+ */
+ function onSnapshotDone(snapshot)
+ {
+ this._layer = layer;
+ this._paintProfilerView.setSnapshot(snapshot || null);
+ this._logTreeView.setSnapshot(snapshot || null);
+ }
+ },
+
+ _onWindowChanged: function()
+ {
+ var window = this._paintProfilerView.windowBoundaries();
+ this._logTreeView.updateWindow(window.left, window.right);
+ },
+
+ /**
+ * @param {string=} imageURL
+ */
+ _showImage: function(imageURL)
+ {
+ this._showImageForLayerCallback(this._layer, imageURL);
+ },
+
+ __proto__: WebInspector.SplitView.prototype
+};
+
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LayerTree.js b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeOutline.js
index 6b409376367..1a35a8efe7f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LayerTree.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayerTreeOutline.js
@@ -31,32 +31,29 @@
/**
* @constructor
* @extends {WebInspector.Object}
- * @param {!WebInspector.LayerTreeModel} model
* @param {!TreeOutline} treeOutline
*/
-WebInspector.LayerTree = function(model, treeOutline)
+WebInspector.LayerTreeOutline = function(treeOutline)
{
WebInspector.Object.call(this);
- this._model = model;
this._treeOutline = treeOutline;
this._treeOutline.childrenListElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
this._treeOutline.childrenListElement.addEventListener("mouseout", this._onMouseMove.bind(this), false);
this._treeOutline.childrenListElement.addEventListener("contextmenu", this._onContextMenu.bind(this), true);
- this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update.bind(this));
this._lastHoveredNode = null;
}
/**
* @enum {string}
*/
-WebInspector.LayerTree.Events = {
+WebInspector.LayerTreeOutline.Events = {
LayerHovered: "LayerHovered",
LayerSelected: "LayerSelected"
}
-WebInspector.LayerTree.prototype = {
+WebInspector.LayerTreeOutline.prototype = {
/**
- * @param {!WebInspector.Layer} layer
+ * @param {?WebInspector.Layer} layer
*/
selectLayer: function(layer)
{
@@ -83,41 +80,42 @@ WebInspector.LayerTree.prototype = {
this._lastHoveredNode = node;
},
- _update: function()
+ /**
+ * @param {?WebInspector.LayerTreeBase} layerTree
+ */
+ update: function(layerTree)
{
- var seenLayers = {};
+ var seenLayers = new Map();
/**
* @param {!WebInspector.Layer} layer
- * @this {WebInspector.LayerTree}
+ * @this {WebInspector.LayerTreeOutline}
*/
function updateLayer(layer)
{
- var id = layer.id();
- if (seenLayers[id])
- console.assert(false, "Duplicate layer id: " + id);
- seenLayers[id] = true;
+ if (seenLayers.get(layer))
+ console.assert(false, "Duplicate layer: " + layer.id());
+ seenLayers.put(layer, true);
var node = this._treeOutline.getCachedTreeElement(layer);
- var parent = layer === this._model.contentRoot() ? this._treeOutline : this._treeOutline.getCachedTreeElement(layer.parent());
+ var parent = layer === layerTree.contentRoot() ? this._treeOutline : this._treeOutline.getCachedTreeElement(layer.parent());
if (!parent)
console.assert(false, "Parent is not in the tree");
if (!node) {
node = new WebInspector.LayerTreeElement(this, layer);
parent.appendChild(node);
} else {
- var oldParentId = node.parent.representedObject && node.parent.representedObject.id();
- if (oldParentId !== layer.parentId()) {
- (node.parent || this._treeOutline).removeChild(node);
+ if (node.parent !== parent) {
+ node.parent.removeChild(node);
parent.appendChild(node);
}
node._update();
}
}
- if (this._model.contentRoot())
- this._model.forEachLayer(updateLayer.bind(this), this._model.contentRoot());
+ if (layerTree && layerTree.contentRoot())
+ layerTree.forEachLayer(updateLayer.bind(this), layerTree.contentRoot());
// Cleanup layers that don't exist anymore from tree.
- for (var node = /** @type {!TreeElement|!TreeOutline|null} */(this._treeOutline.children[0]); node && !node.root;) {
- if (seenLayers[node.representedObject.id()]) {
+ for (var node = /** @type {!TreeElement|!TreeOutline|null} */ (this._treeOutline.children[0]); node && !node.root;) {
+ if (seenLayers.get(node.representedObject)) {
node = node.traverseNextTreeElement(false);
} else {
var nextNode = node.nextSibling || node.parent;
@@ -137,7 +135,7 @@ WebInspector.LayerTree.prototype = {
var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
if (node === this._lastHoveredNode)
return;
- this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerHovered, node && node.representedObject);
+ this.dispatchEventToListeners(WebInspector.LayerTreeOutline.Events.LayerHovered, node && node.representedObject ? {layer: node.representedObject} : null);
},
/**
@@ -146,7 +144,7 @@ WebInspector.LayerTree.prototype = {
_selectedNodeChanged: function(node)
{
var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
- this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerSelected, layer);
+ this.dispatchEventToListeners(WebInspector.LayerTreeOutline.Events.LayerSelected, {layer: layer});
},
/**
@@ -160,10 +158,7 @@ WebInspector.LayerTree.prototype = {
var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
if (!layer)
return;
- var nodeId = layer.nodeId();
- if (!nodeId)
- return;
- var domNode = WebInspector.domAgent.nodeForId(nodeId);
+ var domNode = layer.nodeForSelfOrAncestor();
if (!domNode)
return;
var contextMenu = new WebInspector.ContextMenu(event);
@@ -176,14 +171,14 @@ WebInspector.LayerTree.prototype = {
/**
* @constructor
- * @param {!WebInspector.LayerTree} tree
+ * @param {!WebInspector.LayerTreeOutline} tree
* @param {!WebInspector.Layer} layer
* @extends {TreeElement}
*/
WebInspector.LayerTreeElement = function(tree, layer)
{
TreeElement.call(this, "", layer);
- this._layerTree = tree;
+ this._treeOutline = tree;
this._update();
}
@@ -198,11 +193,10 @@ WebInspector.LayerTreeElement.prototype = {
_update: function()
{
var layer = /** @type {!WebInspector.Layer} */ (this.representedObject);
- var nodeId = layer.nodeIdForSelfOrAncestor();
- var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null;
+ var node = layer.nodeForSelfOrAncestor();
var title = document.createDocumentFragment();
title.createChild("div", "selection");
- title.appendChild(document.createTextNode(node ? WebInspector.DOMPresentationUtils.appropriateSelectorFor(node, false) : "#" + layer.id()));
+ title.appendChild(document.createTextNode(node ? WebInspector.DOMPresentationUtils.simpleSelector(node) : "#" + layer.id()));
var details = title.createChild("span", "dimmed");
details.textContent = WebInspector.UIString(" (%d × %d)", layer.width(), layer.height());
this.title = title;
@@ -210,10 +204,11 @@ WebInspector.LayerTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function()
{
- this._layerTree._selectedNodeChanged(this);
+ this._treeOutline._selectedNodeChanged(this);
return false;
},
@@ -222,7 +217,7 @@ WebInspector.LayerTreeElement.prototype = {
*/
setHovered: function(hovered)
{
- this.listItemElement.enableStyleClass("hovered", hovered);
+ this.listItemElement.classList.toggle("hovered", hovered);
},
__proto__: TreeElement.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayersPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayersPanel.js
new file mode 100644
index 00000000000..3bd508164f0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/LayersPanel.js
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+importScript("LayerTreeOutline.js");
+importScript("LayerDetailsView.js");
+importScript("PaintProfilerView.js");
+importScript("LayerPaintProfilerView.js");
+
+/**
+ * @constructor
+ * @extends {WebInspector.PanelWithSidebarTree}
+ */
+WebInspector.LayersPanel = function()
+{
+ WebInspector.PanelWithSidebarTree.call(this, "layers", 225);
+ this.registerRequiredCSS("layersPanel.css");
+
+ this.sidebarElement().classList.add("outline-disclosure");
+ this.sidebarTree.element.classList.remove("sidebar-tree");
+
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._model = new WebInspector.LayerTreeModel(this._target);
+ this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._onLayerTreeUpdated, this);
+ this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted, this._onLayerPainted, this);
+ this._currentlySelectedLayer = null;
+ this._currentlyHoveredLayer = null;
+
+ this._layerTreeOutline = new WebInspector.LayerTreeOutline(this.sidebarTree);
+ this._layerTreeOutline.addEventListener(WebInspector.LayerTreeOutline.Events.LayerSelected, this._onObjectSelected, this);
+ this._layerTreeOutline.addEventListener(WebInspector.LayerTreeOutline.Events.LayerHovered, this._onObjectHovered, this);
+
+ this._rightSplitView = new WebInspector.SplitView(false, true, "layerDetailsSplitViewState");
+ this._rightSplitView.show(this.mainElement());
+
+ this._layers3DView = new WebInspector.Layers3DView();
+ this._layers3DView.show(this._rightSplitView.mainElement());
+ this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectSelected, this._onObjectSelected, this);
+ this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectHovered, this._onObjectHovered, this);
+ this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.LayerSnapshotRequested, this._onSnapshotRequested, this);
+ this._layers3DView.registerShortcuts(this.registerShortcuts.bind(this));
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.show(this._rightSplitView.sidebarElement());
+
+ this._layerDetailsView = new WebInspector.LayerDetailsView();
+ this._layerDetailsView.addEventListener(WebInspector.LayerDetailsView.Events.ObjectSelected, this._onObjectSelected, this);
+ this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Details, WebInspector.UIString("Details"), this._layerDetailsView);
+
+ this._paintProfilerView = new WebInspector.LayerPaintProfilerView(this._layers3DView.showImageForLayer.bind(this._layers3DView));
+ this._tabbedPane.appendTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler, WebInspector.UIString("Profiler"), this._paintProfilerView);
+}
+
+WebInspector.LayersPanel.DetailsViewTabs = {
+ Details: "details",
+ Profiler: "profiler"
+};
+
+WebInspector.LayersPanel.prototype = {
+ wasShown: function()
+ {
+ WebInspector.Panel.prototype.wasShown.call(this);
+ this.sidebarTree.element.focus();
+ this._model.enable();
+ },
+
+ willHide: function()
+ {
+ this._model.disable();
+ WebInspector.Panel.prototype.willHide.call(this);
+ },
+
+ /**
+ * @param {!WebInspector.DeferredLayerTree} deferredLayerTree
+ */
+ _showLayerTree: function(deferredLayerTree)
+ {
+ deferredLayerTree.resolve(onLayersReady.bind(this));
+ /**
+ * @param {!WebInspector.LayerTreeBase} layerTree
+ * @this {WebInspector.LayersPanel} this
+ */
+ function onLayersReady(layerTree)
+ {
+ this._model.setLayerTree(layerTree);
+ }
+ },
+
+ _onLayerTreeUpdated: function()
+ {
+ var layerTree = this._model.layerTree();
+ this._layers3DView.setLayerTree(layerTree);
+ this._layerTreeOutline.update(layerTree);
+ if (this._currentlySelectedLayer && (!layerTree || !layerTree.layerById(this._currentlySelectedLayer.layer.id())))
+ this._selectObject(null);
+ if (this._currentlyHoveredLayer && (!layerTree || !layerTree.layerById(this._currentlyHoveredLayer.layer.id())))
+ this._hoverObject(null);
+ this._layerDetailsView.update();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onLayerPainted: function(event)
+ {
+ this._layers3DView.setLayerTree(this._model.layerTree());
+ if (this._currentlySelectedLayer && this._currentlySelectedLayer.layer === event.data)
+ this._layerDetailsView.update();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onObjectSelected: function(event)
+ {
+ var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data);
+ this._selectObject(activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onObjectHovered: function(event)
+ {
+ var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data);
+ this._hoverObject(activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onSnapshotRequested: function(event)
+ {
+ var layer = /** @type {!WebInspector.Layer} */ (event.data);
+ this._tabbedPane.selectTab(WebInspector.LayersPanel.DetailsViewTabs.Profiler);
+ this._paintProfilerView.profileLayer(layer);
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ _selectObject: function(activeObject)
+ {
+ var layer = activeObject && activeObject.layer;
+ if (this._currentlySelectedLayer === activeObject)
+ return;
+ this._currentlySelectedLayer = activeObject;
+ var node = layer ? layer.nodeForSelfOrAncestor() : null;
+ if (node)
+ node.highlightForTwoSeconds();
+ else
+ this._target.domModel.hideDOMNodeHighlight();
+ this._layerTreeOutline.selectLayer(layer);
+ this._layers3DView.selectObject(activeObject);
+ this._layerDetailsView.setObject(activeObject);
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ _hoverObject: function(activeObject)
+ {
+ var layer = activeObject && activeObject.layer;
+ if (this._currentlyHoveredLayer === activeObject)
+ return;
+ this._currentlyHoveredLayer = activeObject;
+ var node = layer ? layer.nodeForSelfOrAncestor() : null;
+ if (node)
+ node.highlight();
+ else
+ this._target.domModel.hideDOMNodeHighlight();
+ this._layerTreeOutline.hoverLayer(layer);
+ this._layers3DView.hoverObject(activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {string=} imageURL
+ */
+ _showImageForLayer: function(layer, imageURL)
+ {
+ this._layers3DView.showImageForLayer(layer, imageURL);
+ },
+
+ __proto__: WebInspector.PanelWithSidebarTree.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.LayersPanel.LayerTreeRevealer = function()
+{
+}
+
+WebInspector.LayersPanel.LayerTreeRevealer.prototype = {
+ /**
+ * @param {!Object} snapshotData
+ */
+ reveal: function(snapshotData)
+ {
+ if (!(snapshotData instanceof WebInspector.DeferredLayerTree))
+ return;
+ var panel = /** @type {!WebInspector.LayersPanel} */ (WebInspector.inspectorView.showPanel("layers"));
+ panel._showLayerTree(/** @type {!WebInspector.DeferredLayerTree} */ (snapshotData));
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PaintProfilerView.js b/chromium/third_party/WebKit/Source/devtools/front_end/layers/PaintProfilerView.js
index b1fa48e1849..1e3bf4ce1e6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PaintProfilerView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/PaintProfilerView.js
@@ -30,17 +30,15 @@
/**
* @constructor
- * @param {!WebInspector.LayerTreeModel} model
- * @param {!WebInspector.Layers3DView} layers3DView
- * @extends {WebInspector.View}
+ * @param {function(string=)} showImageCallback
+ * @extends {WebInspector.HBox}
*/
-WebInspector.PaintProfilerView = function(model, layers3DView)
+WebInspector.PaintProfilerView = function(showImageCallback)
{
WebInspector.View.call(this);
- this.element.classList.add("fill", "paint-profiler-view");
+ this.element.classList.add("paint-profiler-view");
- this._model = model;
- this._layers3DView = layers3DView;
+ this._showImageCallback = showImageCallback;
this._canvas = this.element.createChild("canvas", "fill");
this._context = this._canvas.getContext("2d");
@@ -55,12 +53,40 @@ WebInspector.PaintProfilerView = function(model, layers3DView)
this._reset();
}
+WebInspector.PaintProfilerView.Events = {
+ WindowChanged: "WindowChanged"
+};
+
WebInspector.PaintProfilerView.prototype = {
onResize: function()
{
this._update();
},
+ /**
+ * @param {?WebInspector.PaintProfilerSnapshot} snapshot
+ */
+ setSnapshot: function(snapshot)
+ {
+ this._reset();
+ this._snapshot = snapshot;
+ if (!this._snapshot) {
+ this._update();
+ return;
+ }
+ snapshot.requestImage(null, null, this._showImageCallback);
+ snapshot.profile(onProfileDone.bind(this));
+ /**
+ * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles
+ * @this {WebInspector.PaintProfilerView}
+ */
+ function onProfileDone(profiles)
+ {
+ this._profiles = profiles;
+ this._update();
+ }
+ },
+
_update: function()
{
this._canvas.width = this.element.clientWidth * window.devicePixelRatio;
@@ -113,23 +139,32 @@ WebInspector.PaintProfilerView.prototype = {
if (this._updateImageTimer)
return;
this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
+ this.dispatchEventToListeners(WebInspector.PaintProfilerView.Events.WindowChanged);
},
- _updateImage: function()
+ /**
+ * @return {{left: number, right: number}}
+ */
+ windowBoundaries: function()
{
- delete this._updateImageTimer;
- if (!this._profiles || !this._profiles.length)
- return;
-
var screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
var screenRight = this._selectionWindow.windowRight * this._canvas.width;
-
var barLeft = Math.floor((screenLeft - this._barPaddingWidth) / this._outerBarWidth);
var barRight = Math.floor((screenRight - this._barPaddingWidth + this._innerBarWidth)/ this._outerBarWidth);
-
var stepLeft = Math.max(0, barLeft * this._samplesPerBar);
var stepRight = Math.min(barRight * this._samplesPerBar, this._profiles[0].length);
- this._snapshot.requestImage(stepLeft, stepRight, this._layers3DView.showImageForLayer.bind(this._layers3DView, this._layer));
+
+ return {left: stepLeft, right: stepRight};
+ },
+
+ _updateImage: function()
+ {
+ delete this._updateImageTimer;
+ if (!this._profiles || !this._profiles.length)
+ return;
+
+ var window = this.windowBoundaries();
+ this._snapshot.requestImage(window.left, window.right, this._showImageCallback);
},
_reset: function()
@@ -139,41 +174,163 @@ WebInspector.PaintProfilerView.prototype = {
this._selectionWindow.reset();
},
+ __proto__: WebInspector.HBox.prototype
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.PaintProfilerCommandLogView = function()
+{
+ WebInspector.VBox.call(this);
+ this.setMinimumSize(100, 25);
+ this.element.classList.add("outline-disclosure");
+ var sidebarTreeElement = this.element.createChild("ol", "sidebar-tree");
+ this.sidebarTree = new TreeOutline(sidebarTreeElement);
+ this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true);
+ this._reset();
+}
+
+WebInspector.PaintProfilerCommandLogView.prototype = {
/**
- * @param {!WebInspector.Layer} layer
+ * @param {?WebInspector.PaintProfilerSnapshot} snapshot
*/
- profile: function(layer)
+ setSnapshot: function(snapshot)
{
this._reset();
- this._layer = layer;
- this._layer.requestSnapshot(onSnapshotDone.bind(this));
+ if (!snapshot) {
+ this.updateWindow();
+ return;
+ }
+ snapshot.commandLog(onCommandLogDone.bind(this));
/**
- * @param {!WebInspector.LayerSnapshot=} snapshot
- * @this {WebInspector.PaintProfilerView}
+ * @param {!Array.<!Object>=} log
+ * @this {WebInspector.PaintProfilerCommandLogView}
*/
- function onSnapshotDone(snapshot)
+ function onCommandLogDone(log)
{
- this._snapshot = snapshot;
- if (!snapshot) {
- this._profiles = null;
- this._update();
- return;
- }
- snapshot.requestImage(null, null, this._layers3DView.showImageForLayer.bind(this._layers3DView, this._layer));
- snapshot.profile(onProfileDone.bind(this));
+ this._log = log;
+ this.updateWindow();
}
+ },
- /**
- * @param {!Array.<!LayerTreeAgent.PaintProfile>=} profiles
- * @this {WebInspector.PaintProfilerView}
- */
- function onProfileDone(profiles)
- {
- this._profiles = profiles;
- this._update();
+ /**
+ * @param {number=} stepLeft
+ * @param {number=} stepRight
+ */
+ updateWindow: function(stepLeft, stepRight)
+ {
+ var log = this._log;
+ stepLeft = stepLeft || 0;
+ stepRight = stepRight || log.length - 1;
+ this.sidebarTree.removeChildren();
+ for (var i = stepLeft; i <= stepRight; ++i) {
+ var node = new WebInspector.LogTreeElement(log[i]);
+ this.sidebarTree.appendChild(node);
}
},
- __proto__: WebInspector.View.prototype
+ _reset: function()
+ {
+ this._log = [];
+ },
+
+ /**
+ * @param {!Element} target
+ * @return {!Element}
+ */
+ _getHoverAnchor: function(target)
+ {
+ return /** @type {!Element} */ (target.enclosingNodeOrSelfWithNodeName("span"));
+ },
+
+ /**
+ * @param {!Element} element
+ * @param {function(!WebInspector.RemoteObject, boolean, !Element=):undefined} showCallback
+ */
+ _resolveObjectForPopover: function(element, showCallback)
+ {
+ var liElement = element.enclosingNodeOrSelfWithNodeName("li");
+ var logItem = liElement.treeElement.representedObject;
+ var obj = {"method": logItem.method};
+ if (logItem.params)
+ obj.params = logItem.params;
+ showCallback(WebInspector.RemoteObject.fromLocalObject(obj), false);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
+
+/**
+ * @constructor
+ * @param {!Object} logItem
+ * @extends {TreeElement}
+ */
+WebInspector.LogTreeElement = function(logItem)
+{
+ TreeElement.call(this, "", logItem);
+ this._update();
+}
+
+WebInspector.LogTreeElement.prototype = {
+ /**
+ * @param {!Object} param
+ * @param {string} name
+ * @return {string}
+ */
+ _paramToString: function(param, name)
+ {
+ if (typeof param !== "object")
+ return typeof param === "string" && param.length > 100 ? name : JSON.stringify(param);
+ var str = "";
+ var keyCount = 0;
+ for (var key in param) {
+ if (++keyCount > 4 || typeof param[key] === "object" || (typeof param[key] === "string" && param[key].length > 100))
+ return name;
+ if (str)
+ str += ", ";
+ str += param[key];
+ }
+ return str;
+ },
+
+ /**
+ * @param {!Object} params
+ * @return {string}
+ */
+ _paramsToString: function(params)
+ {
+ var str = "";
+ for (var key in params) {
+ if (str)
+ str += ", ";
+ str += this._paramToString(params[key], key);
+ }
+ return str;
+ },
+
+ _update: function()
+ {
+ var logItem = this.representedObject;
+ var title = document.createDocumentFragment();
+ title.createChild("div", "selection");
+ var span = title.createChild("span");
+ var textContent = logItem.method;
+ if (logItem.params)
+ textContent += "(" + this._paramsToString(logItem.params) + ")";
+ span.textContent = textContent;
+ this.title = title;
+ },
+
+ /**
+ * @param {boolean} hovered
+ */
+ setHovered: function(hovered)
+ {
+ this.listItemElement.classList.toggle("hovered", hovered);
+ },
+
+ __proto__: TreeElement.prototype
};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/layers/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/layers/module.json
new file mode 100644
index 00000000000..e37e987c903
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layers/module.json
@@ -0,0 +1,18 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "layers",
+ "title": "Layers",
+ "order": 7,
+ "className": "WebInspector.LayersPanel"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.DeferredLayerTree"],
+ "className": "WebInspector.LayersPanel.LayerTreeRevealer"
+ }
+ ],
+ "dependencies": [ "timeline" ],
+ "scripts": [ "LayersPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/layersPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/layersPanel.css
index ea058eb2784..d70e30553e9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/layersPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/layersPanel.css
@@ -57,78 +57,8 @@
overflow: hidden;
}
-.layers-3d-view .rotating-container {
- -webkit-transform-style: preserve-3d;
-}
-
-.layers-3d-view .rotating-container > .layer-container {
- -webkit-transform-origin: 0 0;
-}
-
-.layers-3d-view .layer-container {
- position: absolute;
- border: 1px solid rgba(40, 40, 40, 0.8);
- -webkit-transform-style: preserve-3d;
-}
-
-.layers-3d-view .layer-container.invisible {
- opacity: 0.4;
- border-type: dashed;
-}
-
-.layer-container .side-wall {
- position: absolute;
- background-color: inherit;
- top: 0px;
- right: 0px;
- bottom: 0px;
- left: 0px;
- -webkit-transform-origin: 0 0;
- border: inherit;
- border-width: 1px;
-}
-
-.layer-container .back-wall {
- background-color: inherit;
- border: inherit;
- border-width: 1px;
-}
-
-.layer-container .side-wall.top {
- width: auto;
- bottom: auto;
- -webkit-transform: rotateX(-90deg);
-}
-
-.layer-container .side-wall.bottom {
- width: auto;
- top: auto;
- -webkit-transform: translateY(100%) rotateX(-90deg);
-}
-
-.layer-container .side-wall.left {
- height: auto;
- right: auto;
- -webkit-transform: rotateY(90deg);
-}
-
-.layer-container .side-wall.right {
- height: auto;
- left: auto;
- -webkit-transform: translateX(100%) rotateY(90deg);
-}
-
-.layer-container.selected {
- border-color: black;
-}
-
-.layer-container.hovered:not(.selected) {
- border-color: rgb(150, 150, 255);
-}
-
-.layer-container .paint-rect {
- position: absolute;
- border-style: solid;
+.layers-3d-view canvas {
+ flex: 1 1;
}
.layer-details-view .empty-view {
@@ -143,6 +73,10 @@
font-weight: bold;
}
+.layer-details-view .scroll-rect.active {
+ background-color: rgba(100, 100, 100, 0.2);
+}
+
.paint-profiler-view canvas {
z-index: 200;
opacity: 0.8;
@@ -162,5 +96,3 @@
.paint-profiler-view .overview-grid-window-resizer {
z-index: 2000;
}
-
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/AdvancedApp.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/AdvancedApp.js
new file mode 100644
index 00000000000..3c74972f378
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/AdvancedApp.js
@@ -0,0 +1,198 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.App}
+ */
+WebInspector.AdvancedApp = function()
+{
+ WebInspector.App.call(this);
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged, this._openToolboxWindow, this);
+};
+
+WebInspector.AdvancedApp.prototype = {
+ createRootView: function()
+ {
+ var rootView = new WebInspector.RootView();
+
+ this._rootSplitView = new WebInspector.SplitView(false, true, WebInspector.dockController.canDock() ? "InspectorView.splitViewState" : "InspectorView.dummySplitViewState", 300, 300, true);
+ this._rootSplitView.show(rootView.element);
+
+ WebInspector.inspectorView.show(this._rootSplitView.sidebarElement());
+
+ this._inspectedPagePlaceholder = new WebInspector.InspectedPagePlaceholder();
+ this._inspectedPagePlaceholder.addEventListener(WebInspector.InspectedPagePlaceholder.Events.Update, this._onSetInspectedPageBounds.bind(this, false), this);
+ if (WebInspector.experimentsSettings.responsiveDesign.isEnabled()) {
+ this._responsiveDesignView = new WebInspector.ResponsiveDesignView(this._inspectedPagePlaceholder);
+ this._responsiveDesignView.show(this._rootSplitView.mainElement());
+ } else {
+ this._inspectedPagePlaceholder.show(this._rootSplitView.mainElement());
+ }
+
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.BeforeDockSideChanged, this._onBeforeDockSideChange, this);
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._onDockSideChange, this);
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.AfterDockSideChanged, this._onAfterDockSideChange, this);
+ this._onDockSideChange();
+
+ rootView.attachToBody();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _openToolboxWindow: function(event)
+ {
+ if (/** @type {string} */ (event.data.to) !== WebInspector.DockController.State.Undocked)
+ return;
+
+ if (this._toolboxWindow || !WebInspector.experimentsSettings.responsiveDesign.isEnabled())
+ return;
+
+ var toolbox = (window.location.search ? "&" : "?") + "toolbox=true";
+ var hash = window.location.hash;
+ var url = window.location.href.replace(hash, "") + toolbox + hash;
+ this._toolboxWindow = window.open(url, undefined);
+ },
+
+ /**
+ * @param {!WebInspector.Toolbox} toolbox
+ */
+ _toolboxLoaded: function(toolbox)
+ {
+ this._toolbox = toolbox;
+ this._updatePageResizer();
+ },
+
+ _updatePageResizer: function()
+ {
+ if (!WebInspector.experimentsSettings.responsiveDesign.isEnabled())
+ return;
+
+ if (this._isDocked())
+ this._responsiveDesignView.updatePageResizer();
+ else if (this._toolbox)
+ this._toolbox._responsiveDesignView.updatePageResizer();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onBeforeDockSideChange: function(event)
+ {
+ if (/** @type {string} */ (event.data.to) === WebInspector.DockController.State.Undocked && this._toolbox) {
+ // Hide inspectorView and force layout to mimic the undocked state.
+ this._rootSplitView.hideSidebar();
+ this._inspectedPagePlaceholder.update();
+ }
+
+ this._changingDockSide = true;
+ },
+
+ /**
+ * @param {!WebInspector.Event=} event
+ */
+ _onDockSideChange: function(event)
+ {
+ this._updatePageResizer();
+
+ var toDockSide = event ? /** @type {string} */ (event.data.to) : WebInspector.dockController.dockSide();
+ if (toDockSide === WebInspector.DockController.State.Undocked) {
+ this._updateForUndocked();
+ } else if (this._toolbox && event && /** @type {string} */ (event.data.from) === WebInspector.DockController.State.Undocked) {
+ // Don't update yet for smooth transition.
+ this._rootSplitView.hideSidebar();
+ } else {
+ this._updateForDocked(toDockSide);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onAfterDockSideChange: function(event)
+ {
+ // We may get here on the first dock side change while loading without BeforeDockSideChange.
+ if (!this._changingDockSide)
+ return;
+ this._changingDockSide = false;
+ if (/** @type {string} */ (event.data.from) === WebInspector.DockController.State.Undocked) {
+ // Restore docked layout in case of smooth transition.
+ this._updateForDocked(/** @type {string} */ (event.data.to));
+ }
+ this._inspectedPagePlaceholder.update();
+ },
+
+ /**
+ * @param {string} dockSide
+ */
+ _updateForDocked: function(dockSide)
+ {
+ this._rootSplitView.setVertical(dockSide === WebInspector.DockController.State.DockedToLeft || dockSide === WebInspector.DockController.State.DockedToRight);
+ this._rootSplitView.setSecondIsSidebar(dockSide === WebInspector.DockController.State.DockedToRight || dockSide === WebInspector.DockController.State.DockedToBottom);
+ this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), true);
+ this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), dockSide === WebInspector.DockController.State.DockedToBottom);
+ this._rootSplitView.showBoth();
+ },
+
+ _updateForUndocked: function()
+ {
+ this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), false);
+ this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), false);
+ this._rootSplitView.hideMain();
+ },
+
+ _isDocked: function()
+ {
+ return WebInspector.dockController.dockSide() !== WebInspector.DockController.State.Undocked;
+ },
+
+ /**
+ * @param {boolean} toolbox
+ * @param {!WebInspector.Event} event
+ */
+ _onSetInspectedPageBounds: function(toolbox, event)
+ {
+ if (this._changingDockSide || (this._isDocked() === toolbox))
+ return;
+ if (!window.innerWidth || !window.innerHeight)
+ return;
+ var bounds = /** @type {{x: number, y: number, width: number, height: number}} */ (event.data);
+ InspectorFrontendHost.setInspectedPageBounds(bounds);
+ },
+
+ __proto__: WebInspector.App.prototype
+};
+
+/**
+ * @constructor
+ */
+WebInspector.Toolbox = function()
+{
+ if (!window.opener)
+ return;
+
+ WebInspector.zoomManager = window.opener.WebInspector.zoomManager;
+ WebInspector.overridesSupport = window.opener.WebInspector.overridesSupport;
+ WebInspector.settings = window.opener.WebInspector.settings;
+ WebInspector.experimentsSettings = window.opener.WebInspector.experimentsSettings;
+ WebInspector.cssModel = window.opener.WebInspector.cssModel;
+ WebInspector.domModel = window.opener.WebInspector.domModel;
+ WebInspector.workspace = window.opener.WebInspector.workspace;
+ WebInspector.Revealer = window.opener.WebInspector.Revealer;
+ WebInspector.installPortStyles();
+
+ var advancedApp = /** @type {!WebInspector.AdvancedApp} */ (window.opener.WebInspector.app);
+ var rootView = new WebInspector.RootView();
+ this._inspectedPagePlaceholder = new WebInspector.InspectedPagePlaceholder();
+ this._inspectedPagePlaceholder.addEventListener(WebInspector.InspectedPagePlaceholder.Events.Update, advancedApp._onSetInspectedPageBounds.bind(advancedApp, true));
+ if (WebInspector.experimentsSettings.responsiveDesign.isEnabled()) {
+ this._responsiveDesignView = new WebInspector.ResponsiveDesignView(this._inspectedPagePlaceholder);
+ this._responsiveDesignView.show(rootView.element);
+ } else {
+ this._inspectedPagePlaceholder.show(rootView.element);
+ }
+ rootView.attachToBody();
+ advancedApp._toolboxLoaded(this);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/App.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/App.js
new file mode 100644
index 00000000000..e52b27ef3ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/App.js
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ */
+WebInspector.App = function()
+{
+ if (WebInspector.overridesSupport.canEmulate()) {
+ this._toggleEmulationButton = new WebInspector.StatusBarButton(WebInspector.UIString("Toggle emulation enabled."), "emulation-status-bar-item");
+ this._toggleEmulationButton.toggled = WebInspector.overridesSupport.emulationEnabled();
+ this._toggleEmulationButton.addEventListener("click", this._toggleEmulationEnabled, this);
+ WebInspector.overridesSupport.addEventListener(WebInspector.OverridesSupport.Events.EmulationStateChanged, this._emulationEnabledChanged, this);
+ }
+};
+
+WebInspector.App.prototype = {
+ _toggleEmulationEnabled: function()
+ {
+ WebInspector.overridesSupport.setEmulationEnabled(!this._toggleEmulationButton.toggled);
+ },
+
+ _emulationEnabledChanged: function()
+ {
+ this._toggleEmulationButton.toggled = WebInspector.overridesSupport.emulationEnabled();
+ if (!WebInspector.overridesSupport.responsiveDesignAvailable() && WebInspector.overridesSupport.emulationEnabled())
+ WebInspector.inspectorView.showViewInDrawer("emulation", true);
+ },
+
+ createRootView: function()
+ {
+ },
+
+ presentUI: function()
+ {
+ WebInspector.inspectorView.showInitialPanel();
+
+ WebInspector.overridesSupport.applyInitialOverrides();
+ if (!WebInspector.overridesSupport.responsiveDesignAvailable() && WebInspector.overridesSupport.emulationEnabled())
+ WebInspector.inspectorView.showViewInDrawer("emulation", true);
+ }
+};
+
+/**
+ * @constructor
+ * @implements {WebInspector.StatusBarButton.Provider}
+ */
+WebInspector.App.EmulationButtonProvider = function()
+{
+}
+
+WebInspector.App.EmulationButtonProvider.prototype = {
+ /**
+ * @return {?WebInspector.StatusBarButton}
+ */
+ button: function()
+ {
+ if (!(WebInspector.app instanceof WebInspector.App))
+ return null;
+ return WebInspector.app._toggleEmulationButton || null;
+ }
+}
+
+/**
+ * @type {!WebInspector.App}
+ */
+WebInspector.app;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/HelpScreenUntilReload.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/HelpScreenUntilReload.js
new file mode 100644
index 00000000000..44bc4795e15
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/HelpScreenUntilReload.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {string=} title
+ * @param {string=} message
+ * @extends {WebInspector.HelpScreen}
+ */
+WebInspector.HelpScreenUntilReload = function(title, message)
+{
+ WebInspector.HelpScreen.call(this, title);
+ var p = this.contentElement.createChild("p");
+ p.classList.add("help-section");
+ p.textContent = message;
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
+}
+
+WebInspector.HelpScreenUntilReload.prototype = {
+ /**
+ * @override
+ */
+ willHide: function()
+ {
+ WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this.hide, this);
+ WebInspector.HelpScreen.prototype.willHide.call(this);
+ },
+
+ __proto__: WebInspector.HelpScreen.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/Main.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/Main.js
new file mode 100644
index 00000000000..db71adc3378
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -0,0 +1,830 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Matt Lilek (pewtermoose@gmail.com).
+ * Copyright (C) 2009 Joseph Pecoraro
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @implements {InspectorAgent.Dispatcher}
+ */
+WebInspector.Main = function()
+{
+ var boundListener = windowLoaded.bind(this);
+
+ /**
+ * @this {WebInspector.Main}
+ */
+ function windowLoaded()
+ {
+ this._loaded();
+ window.removeEventListener("DOMContentLoaded", boundListener, false);
+ }
+ window.addEventListener("DOMContentLoaded", boundListener, false);
+}
+
+WebInspector.Main.prototype = {
+ _registerModules: function()
+ {
+ var configuration;
+ if (!Capabilities.isMainFrontend) {
+ configuration = ["main", "sources", "timeline", "profiler", "console", "source_frame", "search"];
+ } else {
+ configuration = ["main", "elements", "network", "sources", "timeline", "profiler", "resources", "audits", "console", "source_frame", "extensions", "settings", "search"];
+ if (WebInspector.experimentsSettings.layersPanel.isEnabled())
+ configuration.push("layers");
+ if (WebInspector.experimentsSettings.devicesPanel.isEnabled())
+ configuration.push("devices");
+ }
+ WebInspector.moduleManager.registerModules(configuration);
+ },
+
+ _createGlobalStatusBarItems: function()
+ {
+ var extensions = WebInspector.moduleManager.extensions(WebInspector.StatusBarButton.Provider);
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} left
+ * @param {!WebInspector.ModuleManager.Extension} right
+ */
+ function orderComparator(left, right)
+ {
+ return left.descriptor()["order"] - right.descriptor()["order"];
+ }
+ extensions.sort(orderComparator);
+ extensions.forEach(function(extension) {
+ var button;
+ switch (extension.descriptor()["location"]) {
+ case "toolbar-left":
+ button = createButton(extension);
+ if (button)
+ WebInspector.inspectorView.appendToLeftToolbar(button.element);
+ break;
+ case "toolbar-right":
+ button = createButton(extension);
+ if (button)
+ WebInspector.inspectorView.appendToRightToolbar(button.element);
+ break;
+ }
+ if (button && extension.descriptor()["actionId"]) {
+ button.addEventListener("click", function() {
+ WebInspector.actionRegistry.execute(extension.descriptor()["actionId"]);
+ });
+ }
+ });
+
+ function createButton(extension)
+ {
+ var descriptor = extension.descriptor();
+ if (descriptor.className)
+ return extension.instance().button();
+ return new WebInspector.StatusBarButton(WebInspector.UIString(descriptor["title"]), descriptor["elementClass"]);
+ }
+ },
+
+ _calculateWorkerInspectorTitle: function()
+ {
+ var expression = "location.href";
+ if (WebInspector.queryParam("isSharedWorker"))
+ expression += " + (this.name ? ' (' + this.name + ')' : '')";
+ RuntimeAgent.invoke_evaluate({expression:expression, doNotPauseOnExceptionsAndMuteConsole:true, returnByValue: true}, evalCallback);
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!RuntimeAgent.RemoteObject} result
+ * @param {boolean=} wasThrown
+ */
+ function evalCallback(error, result, wasThrown)
+ {
+ if (error || wasThrown) {
+ console.error(error);
+ return;
+ }
+ InspectorFrontendHost.inspectedURLChanged(result.value);
+ }
+ },
+
+ _loadCompletedForWorkers: function()
+ {
+ // Make sure script execution of dedicated worker or service worker is
+ // resumed and then paused on the first script statement in case we
+ // autoattached to it.
+ if (WebInspector.queryParam("workerPaused")) {
+ pauseAndResume.call(this);
+ } else{
+ RuntimeAgent.isRunRequired(isRunRequiredCallback.bind(this));
+ }
+
+ /**
+ * @this {WebInspector.Main}
+ */
+ function isRunRequiredCallback(error, result)
+ {
+ if (result) {
+ pauseAndResume.call(this);
+ } else if (!Capabilities.isMainFrontend) {
+ calculateTitle.call(this);
+ }
+ }
+
+ /**
+ * @this {WebInspector.Main}
+ */
+ function pauseAndResume()
+ {
+ DebuggerAgent.pause();
+ RuntimeAgent.run(calculateTitle.bind(this));
+ }
+
+ /**
+ * @this {WebInspector.Main}
+ */
+ function calculateTitle()
+ {
+ this._calculateWorkerInspectorTitle();
+ }
+ },
+
+ _resetErrorAndWarningCounts: function()
+ {
+ WebInspector.inspectorView.setErrorAndWarningCounts(0, 0);
+ },
+
+ _updateErrorAndWarningCounts: function()
+ {
+ var errors = WebInspector.console.errors;
+ var warnings = WebInspector.console.warnings;
+ WebInspector.inspectorView.setErrorAndWarningCounts(errors, warnings);
+ },
+
+ _debuggerPaused: function()
+ {
+ WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+ WebInspector.inspectorView.showPanel("sources");
+ },
+
+ _loaded: function()
+ {
+ if (WebInspector.queryParam("toolbox")) {
+ new WebInspector.Toolbox();
+ return;
+ }
+
+ WebInspector.settings = new WebInspector.Settings();
+ WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings(WebInspector.queryParam("experiments") !== null);
+ // This setting is needed for backwards compatibility with Devtools CodeSchool extension. DO NOT REMOVE
+ WebInspector.settings.pauseOnExceptionStateString = new WebInspector.PauseOnExceptionStateSetting();
+
+ if (!InspectorFrontendHost.sendMessageToEmbedder) {
+ var helpScreen = new WebInspector.HelpScreen(WebInspector.UIString("Incompatible Chrome version"));
+ var p = helpScreen.contentElement.createChild("p", "help-section");
+ p.textContent = WebInspector.UIString("Please upgrade to a newer Chrome version (you might need a Dev or Canary build).");
+ helpScreen.showModal();
+ return;
+ }
+
+ InspectorBackend.loadFromJSONIfNeeded("../protocol.json");
+
+ var onConnectionReady = this._doLoadedDone.bind(this);
+
+ var workerId = WebInspector.queryParam("dedicatedWorkerId");
+ if (workerId) {
+ new WebInspector.ExternalWorkerConnection(workerId, onConnectionReady);
+ return;
+ }
+
+ var ws;
+ if (WebInspector.queryParam("ws")) {
+ ws = "ws://" + WebInspector.queryParam("ws");
+ } else if (WebInspector.queryParam("page")) {
+ var page = WebInspector.queryParam("page");
+ var host = WebInspector.queryParam("host") || window.location.host;
+ ws = "ws://" + host + "/devtools/page/" + page;
+ }
+
+ if (ws) {
+ document.body.classList.add("remote");
+ new InspectorBackendClass.WebSocketConnection(ws, onConnectionReady);
+ return;
+ }
+
+ if (!InspectorFrontendHost.isStub) {
+ new InspectorBackendClass.MainConnection(onConnectionReady);
+ return;
+ }
+
+ new InspectorBackendClass.StubConnection(onConnectionReady);
+ },
+
+ /**
+ * @param {!InspectorBackendClass.Connection} connection
+ */
+ _doLoadedDone: function(connection)
+ {
+ connection.addEventListener(InspectorBackendClass.Connection.Events.Disconnected, onDisconnected);
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ function onDisconnected(event)
+ {
+ if (WebInspector._disconnectedScreenWithReasonWasShown)
+ return;
+ new WebInspector.RemoteDebuggingTerminatedScreen(event.data.reason).showModal();
+ }
+
+ InspectorBackend.setConnection(connection);
+
+ // Install styles and themes
+ WebInspector.installPortStyles();
+
+ if (WebInspector.queryParam("toolbarColor") && WebInspector.queryParam("textColor"))
+ WebInspector.setToolbarColors(WebInspector.queryParam("toolbarColor"), WebInspector.queryParam("textColor"));
+
+ WebInspector.targetManager = new WebInspector.TargetManager();
+ WebInspector.targetManager.createTarget(WebInspector.UIString("Main"), connection, this._doLoadedDoneWithCapabilities.bind(this));
+ WebInspector.isolatedFileSystemManager = new WebInspector.IsolatedFileSystemManager();
+ WebInspector.isolatedFileSystemDispatcher = new WebInspector.IsolatedFileSystemDispatcher(WebInspector.isolatedFileSystemManager);
+ WebInspector.workspace = new WebInspector.Workspace(WebInspector.isolatedFileSystemManager.mapping());
+ WebInspector.networkWorkspaceBinding = new WebInspector.NetworkWorkspaceBinding(WebInspector.workspace);
+ new WebInspector.NetworkUISourceCodeProvider(WebInspector.networkWorkspaceBinding, WebInspector.workspace);
+ new WebInspector.PresentationConsoleMessageHelper(WebInspector.workspace);
+ WebInspector.fileSystemWorkspaceBinding = new WebInspector.FileSystemWorkspaceBinding(WebInspector.isolatedFileSystemManager, WebInspector.workspace);
+ WebInspector.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, WebInspector.workspace, WebInspector.targetManager);
+ WebInspector.scriptSnippetModel = new WebInspector.ScriptSnippetModel(WebInspector.workspace);
+ this._executionContextSelector = new WebInspector.ExecutionContextSelector();
+ },
+
+ _doLoadedDoneWithCapabilities: function(mainTarget)
+ {
+ WebInspector.dockController = new WebInspector.DockController(!!WebInspector.queryParam("can_dock"));
+ WebInspector.overridesSupport = new WebInspector.OverridesSupport(WebInspector.experimentsSettings.responsiveDesign.isEnabled() && WebInspector.dockController.canDock());
+
+ if (mainTarget.canScreencast)
+ WebInspector.app = new WebInspector.ScreencastApp();
+ else if (WebInspector.dockController.canDock())
+ WebInspector.app = new WebInspector.AdvancedApp();
+ else
+ WebInspector.app = new WebInspector.SimpleApp();
+
+ WebInspector.dockController.initialize();
+
+ new WebInspector.VersionController().updateVersion();
+ WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
+ this._registerShortcuts();
+
+ // set order of some sections explicitly
+ WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
+ WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
+ WebInspector.ShortcutsScreen.registerShortcuts();
+
+ if (WebInspector.experimentsSettings.workersInMainWindow.isEnabled())
+ new WebInspector.WorkerTargetManager(mainTarget, WebInspector.targetManager);
+
+ WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._resetErrorAndWarningCounts, this);
+ WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
+
+ WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+
+ WebInspector.inspectorFrontendEventSink = new WebInspector.InspectorFrontendEventSink();
+ InspectorBackend.registerInspectorDispatcher(this);
+
+ if (Capabilities.isMainFrontend) {
+ WebInspector.inspectElementModeController = new WebInspector.InspectElementModeController();
+ WebInspector.workerFrontendManager = new WebInspector.WorkerFrontendManager();
+ } else {
+ mainTarget.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerDisconnected, onWorkerDisconnected);
+ }
+
+ function onWorkerDisconnected()
+ {
+ var screen = new WebInspector.WorkerTerminatedScreen();
+ var listener = hideScreen.bind(null, screen);
+ mainTarget.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
+
+ /**
+ * @param {!WebInspector.WorkerTerminatedScreen} screen
+ */
+ function hideScreen(screen)
+ {
+ mainTarget.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, listener);
+ screen.hide();
+ }
+
+ screen.showModal();
+ }
+
+ WebInspector.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
+
+ var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
+ var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
+ WebInspector.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
+ WebInspector.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
+ WebInspector.Linkifier.setLinkHandler(new WebInspector.HandlerRegistry.LinkHandler());
+
+ new WebInspector.WorkspaceController(WebInspector.workspace);
+
+ WebInspector.liveEditSupport = new WebInspector.LiveEditSupport(WebInspector.workspace);
+ new WebInspector.CSSStyleSheetMapping(WebInspector.cssModel, WebInspector.workspace, WebInspector.networkWorkspaceBinding);
+
+ // Create settings before loading modules.
+ WebInspector.settings.initializeBackendSettings();
+
+ this._registerModules();
+ WebInspector.actionRegistry = new WebInspector.ActionRegistry();
+ WebInspector.shortcutRegistry = new WebInspector.ShortcutRegistry(WebInspector.actionRegistry);
+ this._registerForwardedShortcuts();
+ this._registerMessageSinkListener();
+
+ WebInspector.zoomManager = new WebInspector.ZoomManager();
+ WebInspector.inspectorView = new WebInspector.InspectorView();
+ WebInspector.app.createRootView();
+ this._createGlobalStatusBarItems();
+
+ this._addMainEventListeners(document);
+
+ var errorWarningCount = document.getElementById("error-warning-count");
+
+ function showConsole()
+ {
+ WebInspector.console.show();
+ }
+ errorWarningCount.addEventListener("click", showConsole, false);
+ this._updateErrorAndWarningCounts();
+
+ WebInspector.extensionServerProxy.setFrontendReady();
+
+ InspectorAgent.enable(inspectorAgentEnableCallback);
+
+ function inspectorAgentEnableCallback()
+ {
+ WebInspector.app.presentUI();
+ }
+
+ this._loadCompletedForWorkers();
+ InspectorFrontendAPI.loadCompleted();
+ WebInspector.notifications.dispatchEventToListeners(WebInspector.NotificationService.Events.InspectorLoaded);
+ },
+
+ _registerForwardedShortcuts: function()
+ {
+ /** @const */ var forwardedActions = ["main.reload", "main.hard-reload"];
+ var actionKeys = WebInspector.shortcutRegistry.keysForActions(forwardedActions).map(WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey);
+
+ actionKeys.push({keyCode: WebInspector.KeyboardShortcut.Keys.F8.code});
+ InspectorFrontendHost.setWhitelistedShortcuts(JSON.stringify(actionKeys));
+ },
+
+ _registerMessageSinkListener: function()
+ {
+ WebInspector.messageSink.addEventListener(WebInspector.MessageSink.Events.MessageAdded, messageAdded);
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ function messageAdded(event)
+ {
+ var message = /** @type {!WebInspector.MessageSink.Message} */ (event.data);
+ if (message.show)
+ WebInspector.actionRegistry.execute("console.show");
+ }
+ },
+
+ _documentClick: function(event)
+ {
+ var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
+ if (!anchor || !anchor.href)
+ return;
+
+ // Prevent the link from navigating, since we don't do any navigation by following links normally.
+ event.consume(true);
+
+ if (anchor.target === "_blank") {
+ InspectorFrontendHost.openInNewTab(anchor.href);
+ return;
+ }
+
+ function followLink()
+ {
+ if (WebInspector.isBeingEdited(event.target))
+ return;
+ if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
+ return;
+
+ var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(anchor.href);
+ if (uiSourceCode) {
+ WebInspector.Revealer.reveal(uiSourceCode.uiLocation(anchor.lineNumber || 0, anchor.columnNumber || 0));
+ return;
+ }
+
+ var resource = WebInspector.resourceForURL(anchor.href);
+ if (resource) {
+ WebInspector.Revealer.reveal(resource);
+ return;
+ }
+
+ var request = WebInspector.networkLog.requestForURL(anchor.href);
+ if (request) {
+ WebInspector.Revealer.reveal(request);
+ return;
+ }
+ InspectorFrontendHost.openInNewTab(anchor.href);
+ }
+
+ if (WebInspector.followLinkTimeout)
+ clearTimeout(WebInspector.followLinkTimeout);
+
+ if (anchor.preventFollowOnDoubleClick) {
+ // Start a timeout if this is the first click, if the timeout is canceled
+ // before it fires, then a double clicked happened or another link was clicked.
+ if (event.detail === 1)
+ WebInspector.followLinkTimeout = setTimeout(followLink, 333);
+ return;
+ }
+
+ followLink();
+ },
+
+ _registerShortcuts: function()
+ {
+ var shortcut = WebInspector.KeyboardShortcut;
+ var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
+ var keys = [
+ shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta),
+ shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta)
+ ];
+ section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
+
+ keys = [
+ shortcut.makeDescriptor("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
+ shortcut.makeDescriptor("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
+ ];
+ section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
+
+ var toggleConsoleLabel = WebInspector.UIString("Show console");
+ section.addKey(shortcut.makeDescriptor(shortcut.Keys.Tilde, shortcut.Modifiers.Ctrl), toggleConsoleLabel);
+ section.addKey(shortcut.makeDescriptor(shortcut.Keys.Esc), WebInspector.UIString("Toggle drawer"));
+ section.addKey(shortcut.makeDescriptor("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
+
+ var advancedSearchShortcutModifier = WebInspector.isMac()
+ ? WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt
+ : WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift;
+ var advancedSearchShortcut = shortcut.makeDescriptor("f", advancedSearchShortcutModifier);
+ section.addKey(advancedSearchShortcut, WebInspector.UIString("Search across all sources"));
+
+ var inspectElementModeShortcut = WebInspector.InspectElementModeController.createShortcut();
+ section.addKey(inspectElementModeShortcut, WebInspector.UIString("Select node to inspect"));
+
+ var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("p", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
+ section.addKey(openResourceShortcut, WebInspector.UIString("Go to source"));
+
+ if (WebInspector.isMac()) {
+ keys = [
+ shortcut.makeDescriptor("g", shortcut.Modifiers.Meta),
+ shortcut.makeDescriptor("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
+ ];
+ section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
+ }
+ },
+
+ _postDocumentKeyDown: function(event)
+ {
+ if (event.handled)
+ return;
+
+ if (!WebInspector.Dialog.currentInstance() && WebInspector.inspectorView.currentPanel()) {
+ WebInspector.inspectorView.currentPanel().handleShortcut(event);
+ if (event.handled) {
+ event.consume(true);
+ return;
+ }
+ }
+
+ WebInspector.shortcutRegistry.handleShortcut(event);
+ },
+
+ _documentCanCopy: function(event)
+ {
+ if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel()["handleCopyEvent"])
+ event.preventDefault();
+ },
+
+ _documentCopy: function(event)
+ {
+ if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel()["handleCopyEvent"])
+ WebInspector.inspectorView.currentPanel()["handleCopyEvent"](event);
+ },
+
+ _contextMenuEventFired: function(event)
+ {
+ if (event.handled || event.target.classList.contains("popup-glasspane"))
+ event.preventDefault();
+ },
+
+ _addMainEventListeners: function(doc)
+ {
+ doc.addEventListener("keydown", this._postDocumentKeyDown.bind(this), false);
+ doc.addEventListener("beforecopy", this._documentCanCopy.bind(this), true);
+ doc.addEventListener("copy", this._documentCopy.bind(this), false);
+ doc.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
+ doc.addEventListener("click", this._documentClick.bind(this), false);
+ },
+
+ /**
+ * @override
+ * @param {!RuntimeAgent.RemoteObject} payload
+ * @param {!Object=} hints
+ */
+ inspect: function(payload, hints)
+ {
+ var object = WebInspector.runtimeModel.createRemoteObject(payload);
+ if (object.isNode()) {
+ object.pushNodeToFrontend(callback);
+ var elementsPanel = /** @type {!WebInspector.ElementsPanel} */ (WebInspector.inspectorView.panel("elements"));
+ elementsPanel.omitDefaultSelection();
+ WebInspector.inspectorView.setCurrentPanel(elementsPanel);
+ return;
+ }
+
+ /**
+ * @param {!WebInspector.DOMNode} node
+ */
+ function callback(node)
+ {
+ elementsPanel.stopOmittingDefaultSelection();
+ node.reveal();
+ if (!WebInspector.inspectorView.drawerVisible() && !WebInspector._notFirstInspectElement)
+ InspectorFrontendHost.inspectElementCompleted();
+ WebInspector._notFirstInspectElement = true;
+ object.release();
+ }
+
+ if (object.type === "function") {
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!DebuggerAgent.FunctionDetails} response
+ */
+ object.functionDetails(didGetDetails);
+ return;
+ }
+
+ /**
+ * @param {?DebuggerAgent.FunctionDetails} response
+ */
+ function didGetDetails(response)
+ {
+ object.release();
+
+ if (!response)
+ return;
+
+ WebInspector.Revealer.reveal(WebInspector.DebuggerModel.Location.fromPayload(object.target(), response.location).toUILocation());
+ }
+
+ if (hints.copyToClipboard)
+ InspectorFrontendHost.copyText(object.value);
+ object.release();
+ },
+
+ /**
+ * @override
+ * @param {string} reason
+ */
+ detached: function(reason)
+ {
+ WebInspector._disconnectedScreenWithReasonWasShown = true;
+ new WebInspector.RemoteDebuggingTerminatedScreen(reason).showModal();
+ },
+
+ /**
+ * @override
+ */
+ targetCrashed: function()
+ {
+ (new WebInspector.HelpScreenUntilReload(
+ WebInspector.UIString("Inspected target crashed"),
+ WebInspector.UIString("Inspected target has crashed. Once it reloads we will attach to it automatically."))).showModal();
+ },
+
+ /**
+ * @override
+ * @param {number} callId
+ * @param {string} script
+ */
+ evaluateForTestInFrontend: function(callId, script)
+ {
+ WebInspector.evaluateForTestInFrontend(callId, script);
+ }
+}
+
+WebInspector.reload = function()
+{
+ InspectorAgent.reset();
+ window.location.reload();
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.ReloadActionDelegate = function()
+{
+}
+
+WebInspector.Main.ReloadActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ WebInspector.debuggerModel.skipAllPauses(true, true);
+ WebInspector.resourceTreeModel.reloadPage(false);
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.HardReloadActionDelegate = function()
+{
+}
+
+WebInspector.Main.HardReloadActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ WebInspector.debuggerModel.skipAllPauses(true, true);
+ WebInspector.resourceTreeModel.reloadPage(true);
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.DebugReloadActionDelegate = function()
+{
+}
+
+WebInspector.Main.DebugReloadActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ WebInspector.reload();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.ZoomInActionDelegate = function()
+{
+}
+
+WebInspector.Main.ZoomInActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ if (InspectorFrontendHost.isStub)
+ return false;
+
+ InspectorFrontendHost.zoomIn();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.ZoomOutActionDelegate = function()
+{
+}
+
+WebInspector.Main.ZoomOutActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ if (InspectorFrontendHost.isStub)
+ return false;
+
+ InspectorFrontendHost.zoomOut();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.Main.ZoomResetActionDelegate = function()
+{
+}
+
+WebInspector.Main.ZoomResetActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ if (InspectorFrontendHost.isStub)
+ return false;
+
+ InspectorFrontendHost.resetZoom();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.UISettingDelegate}
+ */
+WebInspector.Main.ShortcutPanelSwitchSettingDelegate = function()
+{
+ WebInspector.UISettingDelegate.call(this);
+}
+
+WebInspector.Main.ShortcutPanelSwitchSettingDelegate.prototype = {
+ /**
+ * @override
+ * @return {!Element}
+ */
+ settingElement: function()
+ {
+ var modifier = WebInspector.platform() === "mac" ? "Cmd" : "Ctrl";
+ return WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Enable %s + 1-9 shortcut to switch panels", modifier), WebInspector.settings.shortcutPanelSwitch);
+ },
+
+ __proto__: WebInspector.UISettingDelegate.prototype
+}
+
+/**
+ * @param {string} ws
+ */
+WebInspector.Main._addWebSocketTarget = function(ws)
+{
+ /**
+ * @param {!InspectorBackendClass.Connection} connection
+ */
+ function callback(connection)
+ {
+ WebInspector.targetManager.createTarget(ws, connection);
+ }
+ new InspectorBackendClass.WebSocketConnection(ws, callback);
+}
+
+new WebInspector.Main();
+
+// These methods are added for backwards compatibility with Devtools CodeSchool extension.
+// DO NOT REMOVE
+
+WebInspector.__defineGetter__("inspectedPageURL", function()
+{
+ return WebInspector.resourceTreeModel.inspectedPageURL();
+});
+
+/**
+ * @param {string} name
+ * @return {?WebInspector.Panel}
+ */
+WebInspector.panel = function(name)
+{
+ return WebInspector.inspectorView.panel(name);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/ScreencastApp.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/ScreencastApp.js
new file mode 100644
index 00000000000..eb348b837e4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/ScreencastApp.js
@@ -0,0 +1,90 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.App}
+ */
+WebInspector.ScreencastApp = function()
+{
+ WebInspector.App.call(this);
+
+ var lastScreencastState = WebInspector.settings.createSetting("lastScreencastState", "left");
+ this._currentScreencastState = WebInspector.settings.createSetting("currentScreencastState", "disabled");
+ this._toggleScreencastButton = new WebInspector.StatusBarStatesSettingButton(
+ "screencast-status-bar-item",
+ ["disabled", "left", "top"],
+ [WebInspector.UIString("Disable screencast."), WebInspector.UIString("Switch to portrait screencast."), WebInspector.UIString("Switch to landscape screencast.")],
+ this._currentScreencastState.get(),
+ this._currentScreencastState,
+ lastScreencastState,
+ this._onStatusBarButtonStateChanged.bind(this));
+};
+
+WebInspector.ScreencastApp.prototype = {
+ createRootView: function()
+ {
+ var rootView = new WebInspector.RootView();
+
+ this._rootSplitView = new WebInspector.SplitView(false, true, "InspectorView.screencastSplitViewState", 300, 300);
+ this._rootSplitView.show(rootView.element);
+
+ WebInspector.inspectorView.show(this._rootSplitView.sidebarElement());
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._screencastView = new WebInspector.ScreencastView(target);
+ this._screencastView.show(this._rootSplitView.mainElement());
+
+ this._onStatusBarButtonStateChanged(this._currentScreencastState.get());
+ rootView.attachToBody();
+ },
+
+ presentUI: function()
+ {
+ WebInspector.App.prototype.presentUI.call(this);
+ this._screencastView.initialize();
+ },
+
+ /**
+ * @param {string} state
+ */
+ _onStatusBarButtonStateChanged: function(state)
+ {
+ if (!this._rootSplitView)
+ return;
+ if (state === "disabled") {
+ this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), false);
+ this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), false);
+ this._rootSplitView.hideMain();
+ return;
+ }
+
+ this._rootSplitView.setVertical(state === "left");
+ this._rootSplitView.setSecondIsSidebar(true);
+ this._rootSplitView.toggleResizer(this._rootSplitView.resizerElement(), true);
+ this._rootSplitView.toggleResizer(WebInspector.inspectorView.topResizerElement(), state === "top");
+ this._rootSplitView.showBoth();
+ },
+
+ __proto__: WebInspector.App.prototype
+};
+
+/**
+ * @constructor
+ * @implements {WebInspector.StatusBarButton.Provider}
+ */
+WebInspector.ScreencastApp.StatusBarButtonProvider = function()
+{
+}
+
+WebInspector.ScreencastApp.StatusBarButtonProvider.prototype = {
+ /**
+ * @return {?WebInspector.StatusBarButton}
+ */
+ button: function()
+ {
+ if (!(WebInspector.app instanceof WebInspector.ScreencastApp))
+ return null;
+ return /** @type {!WebInspector.ScreencastApp} */ (WebInspector.app)._toggleScreencastButton;
+ }
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/SimpleApp.js b/chromium/third_party/WebKit/Source/devtools/front_end/main/SimpleApp.js
new file mode 100644
index 00000000000..4eb54aef599
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/SimpleApp.js
@@ -0,0 +1,23 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.App}
+ */
+WebInspector.SimpleApp = function()
+{
+ WebInspector.App.call(this);
+};
+
+WebInspector.SimpleApp.prototype = {
+ createRootView: function()
+ {
+ var rootView = new WebInspector.RootView();
+ WebInspector.inspectorView.show(rootView.element);
+ rootView.attachToBody();
+ },
+
+ __proto__: WebInspector.App.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/main/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/main/module.json
new file mode 100644
index 00000000000..46ed1d57fa6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/main/module.json
@@ -0,0 +1,169 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.ContextMenu.Provider",
+ "contextTypes": ["WebInspector.UISourceCode", "WebInspector.Resource", "WebInspector.NetworkRequest", "Node"],
+ "className": "WebInspector.HandlerRegistry.ContextMenuProvider"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.reload",
+ "className": "WebInspector.Main.ReloadActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "F5 Ctrl+R"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+R"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.hard-reload",
+ "className": "WebInspector.Main.HardReloadActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Shift+F5 Ctrl+F5 Ctrl+Shift+F5 Shift+Ctrl+R"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Shift+Meta+R"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.toggle-drawer",
+ "className": "WebInspector.InspectorView.DrawerToggleActionDelegate",
+ "bindings": [
+ {
+ "shortcut": "Esc"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.debug-reload",
+ "className": "WebInspector.Main.DebugReloadActionDelegate",
+ "bindings": [
+ {
+ "shortcut": "Alt+R"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.toggle-element-search",
+ "className": "WebInspector.InspectElementModeController.ToggleSearchActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+Shift+C"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+Shift+C"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.zoom-in",
+ "className": "WebInspector.Main.ZoomInActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+Plus Ctrl+Shift+Plus Ctrl+NumpadPlus Ctrl+Shift+NumpadPlus"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+Plus Meta+Shift+Plus Meta+NumpadPlus Meta+Shift+NumpadPlus"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.zoom-out",
+ "className": "WebInspector.Main.ZoomOutActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+Minus Ctrl+Shift+Minus Ctrl+NumpadMinus Ctrl+Shift+NumpadMinus"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+Minus Meta+Shift+Minus Meta+NumpadMinus Meta+Shift+NumpadMinus"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "main.zoom-reset",
+ "className": "WebInspector.Main.ZoomResetActionDelegate",
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+0 Ctrl+Numpad0"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "Meta+0 Meta+Numpad0"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.StatusBarButton.Provider",
+ "className": "WebInspector.InspectElementModeController.ToggleButtonProvider",
+ "location": "toolbar-left",
+ "order": 0,
+ "actionId": "main.toggle-element-search"
+ },
+ {
+ "type": "@WebInspector.StatusBarButton.Provider",
+ "className": "WebInspector.App.EmulationButtonProvider",
+ "order": 1,
+ "location": "toolbar-left"
+ },
+ {
+ "type": "@WebInspector.StatusBarButton.Provider",
+ "className": "WebInspector.DockController.ButtonProvider",
+ "order": 1,
+ "location": "toolbar-right"
+ },
+ {
+ "type": "@WebInspector.StatusBarButton.Provider",
+ "className": "WebInspector.ScreencastApp.StatusBarButtonProvider",
+ "order": 2,
+ "location": "toolbar-right"
+ },
+ {
+ "type": "ui-setting",
+ "title": "Disable cache (while DevTools is open)",
+ "settingName": "cacheDisabled",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Appearance",
+ "title": "Split panels vertically when docked to right",
+ "settingName": "splitVerticallyWhenDockedToRight",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Appearance",
+ "settingType": "custom",
+ "className": "WebInspector.Main.ShortcutPanelSwitchSettingDelegate"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Extensions",
+ "settingType": "custom",
+ "className": "WebInspector.HandlerRegistry.OpenAnchorLocationSettingDelegate"
+ }
+ ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/navigatorView.css b/chromium/third_party/WebKit/Source/devtools/front_end/navigatorView.css
index 598090d9a5e..7a318d8795e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/navigatorView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/navigatorView.css
@@ -102,13 +102,14 @@
.navigator-tabbed-pane .navigator-container {
overflow: auto;
+ -webkit-transform: translateZ(0);
}
.navigator-tabbed-pane .navigator {
padding-left: 0;
+ -webkit-transform: translateZ(0);
}
.navigator-tabbed-pane .tabbed-pane-header-contents {
margin-left: 2px;
- margin-right: 28px;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HAREntry.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/HAREntry.js
index c3d2ed33777..dd3def264c1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HAREntry.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/HAREntry.js
@@ -60,7 +60,7 @@ WebInspector.HAREntry.prototype = {
if (this._request.connectionId)
entry.connection = String(this._request.connectionId);
- var page = WebInspector.networkLog.pageLoadForRequest(this._request);
+ var page = this._request.target().networkLog.pageLoadForRequest(this._request);
if (page)
entry.pageref = "page_" + page.id;
return entry;
@@ -93,6 +93,7 @@ WebInspector.HAREntry.prototype = {
*/
_buildResponse: function()
{
+ var headersText = this._request.responseHeadersText;
return {
status: this._request.statusCode,
statusText: this._request.statusText,
@@ -101,8 +102,9 @@ WebInspector.HAREntry.prototype = {
cookies: this._buildCookies(this._request.responseCookies || []),
content: this._buildContent(),
redirectURL: this._request.responseHeaderValue("Location") || "",
- headersSize: this._request.responseHeadersSize,
- bodySize: this.responseBodySize
+ headersSize: headersText ? headersText.length : -1,
+ bodySize: this.responseBodySize,
+ _error: this._request.localizedFailDescription
};
},
@@ -113,7 +115,7 @@ WebInspector.HAREntry.prototype = {
{
var content = {
size: this._request.resourceSize,
- mimeType: this._request.mimeType,
+ mimeType: this._request.mimeType || "x-unknown",
// text: this._request.content // TODO: pull out into a boolean flag, as content can be huge (and needs to be requested with an async call)
};
var compression = this.responseCompression;
@@ -237,7 +239,9 @@ WebInspector.HAREntry.prototype = {
{
if (this._request.cached || this._request.statusCode === 304)
return 0;
- return this._request.transferSize - this._request.responseHeadersSize;
+ if (!this._request.responseHeadersText)
+ return -1;
+ return this._request.transferSize - this._request.responseHeadersText.length;
},
/**
@@ -247,6 +251,8 @@ WebInspector.HAREntry.prototype = {
{
if (this._request.cached || this._request.statusCode === 304 || this._request.statusCode === 206)
return;
+ if (!this._request.responseHeadersText)
+ return;
return this._request.resourceSize - this.responseBodySize;
}
}
@@ -301,7 +307,7 @@ WebInspector.HARLog.prototype = {
var seenIdentifiers = {};
var pages = [];
for (var i = 0; i < this._requests.length; ++i) {
- var page = WebInspector.networkLog.pageLoadForRequest(this._requests[i]);
+ var page = this._requests[i].target().networkLog.pageLoadForRequest(this._requests[i]);
if (!page || seenIdentifiers[page.id])
continue;
seenIdentifiers[page.id] = true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkItemView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js
index 37ce89dd237..676048a6603 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkItemView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkItemView.js
@@ -73,6 +73,17 @@ WebInspector.NetworkItemView.prototype = {
},
/**
+ * @return {?WebInspector.SourceFrame}
+ */
+ currentSourceFrame: function()
+ {
+ var view = this.visibleView;
+ if (view && view instanceof WebInspector.SourceFrame)
+ return /** @type {!WebInspector.SourceFrame} */ (view);
+ return null;
+ },
+
+ /**
* @param {string=} tabId
*/
_selectTab: function(tabId)
@@ -80,11 +91,8 @@ WebInspector.NetworkItemView.prototype = {
if (!tabId)
tabId = WebInspector.settings.resourceViewTab.get();
- if (!this.selectTab(tabId)) {
- this._isInFallbackSelection = true;
+ if (!this.selectTab(tabId))
this.selectTab("headers");
- delete this._isInFallbackSelection;
- }
},
_tabSelected: function(event)
@@ -123,11 +131,17 @@ WebInspector.RequestContentView = function(request)
}
WebInspector.RequestContentView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
},
+ /**
+ * @return {!WebInspector.View}
+ */
get innerView()
{
return this._innerView;
@@ -167,22 +181,5 @@ WebInspector.RequestContentView.prototype = {
// Should be implemented by subclasses.
},
- /**
- * @override
- */
- canHighlightPosition: function()
- {
- return this._innerView && this._innerView.canHighlightPosition();
- },
-
- /**
- * @override
- */
- highlightPosition: function(line, column)
- {
- if (this.canHighlightPosition())
- this._innerView.highlightPosition(line, column);
- },
-
__proto__: WebInspector.RequestView.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
index ad816ec1f8a..84ceac2db6f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -28,6 +28,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+importScript("HAREntry.js");
importScript("RequestView.js");
importScript("NetworkItemView.js");
importScript("RequestCookiesView.js");
@@ -42,16 +43,17 @@ importScript("ResourceWebSocketFrameView.js");
/**
* @constructor
* @implements {WebInspector.Searchable}
- * @extends {WebInspector.View}
+ * @implements {WebInspector.TargetManager.Observer}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.FilterBar} filterBar
* @param {!WebInspector.Setting} coulmnsVisibilitySetting
*/
WebInspector.NetworkLogView = function(filterBar, coulmnsVisibilitySetting)
{
- WebInspector.View.call(this);
- this.element.classList.add("vbox", "fill");
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("networkLogView.css");
this.registerRequiredCSS("filter.css");
+ this.registerRequiredCSS("suggestBox.css");
this._filterBar = filterBar;
this._coulmnsVisibilitySetting = coulmnsVisibilitySetting;
@@ -68,6 +70,9 @@ WebInspector.NetworkLogView = function(filterBar, coulmnsVisibilitySetting)
this._highlightedSubstringChanges = [];
this._filteredOutRequests = new Map();
+ /** @type {!Array.<!WebInspector.NetworkLogView.Filter>} */
+ this._filters = [];
+
this._matchedRequestsMap = {};
this._currentMatchedRequestIndex = -1;
@@ -75,41 +80,95 @@ WebInspector.NetworkLogView = function(filterBar, coulmnsVisibilitySetting)
this._createStatusBarItems();
this._linkifier = new WebInspector.Linkifier();
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this);
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, this);
-
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
-
this._addFilters();
+ this._resetSuggestionBuilder();
this._initializeView();
this._recordButton.toggled = true;
- WebInspector.networkLog.requests.forEach(this._appendRequest.bind(this));
+
+ WebInspector.targetManager.observeTargets(this);
}
WebInspector.NetworkLogView.HTTPSchemas = {"http": true, "https": true, "ws": true, "wss": true};
WebInspector.NetworkLogView._responseHeaderColumns = ["Cache-Control", "Connection", "Content-Encoding", "Content-Length", "ETag", "Keep-Alive", "Last-Modified", "Server", "Vary"];
WebInspector.NetworkLogView._defaultColumnsVisibility = {
- method: true, status: true, scheme: false, domain: false, type: true, initiator: true, cookies: false, setCookies: false, size: true, time: true,
+ method: true, status: true, scheme: false, domain: false, remoteAddress: false, type: true, initiator: true, cookies: false, setCookies: false, size: true, time: true,
"Cache-Control": false, "Connection": false, "Content-Encoding": false, "Content-Length": false, "ETag": false, "Keep-Alive": false, "Last-Modified": false, "Server": false, "Vary": false
};
WebInspector.NetworkLogView._defaultRefreshDelay = 500;
+/** @type {!Object.<string, string>} */
+WebInspector.NetworkLogView._columnTitles = {
+ "name": WebInspector.UIString("Name"),
+ "method": WebInspector.UIString("Method"),
+ "status": WebInspector.UIString("Status"),
+ "scheme": WebInspector.UIString("Scheme"),
+ "domain": WebInspector.UIString("Domain"),
+ "remoteAddress": WebInspector.UIString("Remote Address"),
+ "type": WebInspector.UIString("Type"),
+ "initiator": WebInspector.UIString("Initiator"),
+ "cookies": WebInspector.UIString("Cookies"),
+ "setCookies": WebInspector.UIString("Set-Cookies"),
+ "size": WebInspector.UIString("Size"),
+ "time": WebInspector.UIString("Time"),
+ "timeline": WebInspector.UIString("Timeline"),
+
+ // Response header columns
+ "Cache-Control": WebInspector.UIString("Cache-Control"),
+ "Connection": WebInspector.UIString("Connection"),
+ "Content-Encoding": WebInspector.UIString("Content-Encoding"),
+ "Content-Length": WebInspector.UIString("Content-Length"),
+ "ETag": WebInspector.UIString("ETag"),
+ "Keep-Alive": WebInspector.UIString("Keep-Alive"),
+ "Last-Modified": WebInspector.UIString("Last-Modified"),
+ "Server": WebInspector.UIString("Server"),
+ "Vary": WebInspector.UIString("Vary")
+};
+
WebInspector.NetworkLogView.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, this);
+
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
+
+ target.networkLog.requests.forEach(this._appendRequest.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.networkManager.removeEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
+ target.networkManager.removeEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdated, this._onRequestUpdated, this);
+ target.networkManager.removeEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestUpdated, this);
+
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._domContentLoadedEventFired, this);
+ },
+
_addFilters: function()
{
this._textFilterUI = new WebInspector.TextFilterUI();
this._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged, this);
this._filterBar.addFilter(this._textFilterUI);
- this._resourceTypeFilterUI = new WebInspector.NamedBitSetFilterUI();
+ var types = [];
for (var typeId in WebInspector.resourceTypes) {
var resourceType = WebInspector.resourceTypes[typeId];
- this._resourceTypeFilterUI.addBit(resourceType.name(), resourceType.categoryTitle());
+ types.push({name: resourceType.name(), label: resourceType.categoryTitle()});
}
+ this._resourceTypeFilterUI = new WebInspector.NamedBitSetFilterUI(types, WebInspector.settings.networkResourceTypeFilters);
this._resourceTypeFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._filterChanged.bind(this), this);
this._filterBar.addFilter(this._resourceTypeFilterUI);
@@ -119,10 +178,17 @@ WebInspector.NetworkLogView.prototype = {
this._filterBar.addFilter(this._dataURLFilterUI);
},
+ _resetSuggestionBuilder: function()
+ {
+ this._suggestionBuilder = new WebInspector.FilterSuggestionBuilder(WebInspector.NetworkPanel._searchKeys);
+ this._textFilterUI.setSuggestionBuilder(this._suggestionBuilder);
+ },
+
_filterChanged: function(event)
{
this._removeAllNodeHighlights();
this.searchCanceled();
+ this._parseFilterQuery(this._textFilterUI.value());
this._filterRequests();
},
@@ -150,7 +216,14 @@ WebInspector.NetworkLogView.prototype = {
get statusBarItems()
{
- return [this._recordButton.element, this._clearButton.element, this._filterBar.filterButton().element, this._largerRequestsButton.element, this._preserveLogCheckbox.element, this._progressBarContainer];
+ return [
+ this._recordButton.element,
+ this._clearButton.element,
+ this._filterBar.filterButton().element,
+ this._largerRequestsButton.element,
+ this._preserveLogCheckbox.element,
+ this._disableCacheCheckbox.element,
+ this._progressBarContainer];
},
get useLargeRows()
@@ -163,6 +236,9 @@ WebInspector.NetworkLogView.prototype = {
this._allowPopover = flag;
},
+ /**
+ * @return {!Array.<!Element>}
+ */
elementsToRestoreScrollPositionsFor: function()
{
if (!this._dataGrid) // Not initialized yet.
@@ -170,11 +246,6 @@ WebInspector.NetworkLogView.prototype = {
return [this._dataGrid.scrollContainer];
},
- onResize: function()
- {
- this._updateOffscreenRows();
- },
-
_createTimelineGrid: function()
{
this._timelineGrid = new WebInspector.TimelineGrid();
@@ -186,9 +257,9 @@ WebInspector.NetworkLogView.prototype = {
{
var columns = [];
columns.push({
- id: "name",
+ id: "name",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Name"), WebInspector.UIString("Path")),
- title: WebInspector.UIString("Name"),
+ title: WebInspector.NetworkLogView._columnTitles["name"],
sortable: true,
weight: 20,
disclosure: true
@@ -196,7 +267,7 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "method",
- title: WebInspector.UIString("Method"),
+ title: WebInspector.NetworkLogView._columnTitles["method"],
sortable: true,
weight: 6
});
@@ -204,42 +275,50 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "status",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Status"), WebInspector.UIString("Text")),
- title: WebInspector.UIString("Status"),
+ title: WebInspector.NetworkLogView._columnTitles["status"],
sortable: true,
weight: 6
});
columns.push({
id: "scheme",
- title: WebInspector.UIString("Scheme"),
+ title: WebInspector.NetworkLogView._columnTitles["scheme"],
sortable: true,
weight: 6
});
columns.push({
id: "domain",
- title: WebInspector.UIString("Domain"),
+ title: WebInspector.NetworkLogView._columnTitles["domain"],
sortable: true,
weight: 6
});
columns.push({
+ id: "remoteAddress",
+ title: WebInspector.NetworkLogView._columnTitles["remoteAddress"],
+ sortable: true,
+ weight: 10,
+ align: WebInspector.DataGrid.Align.Right
+ });
+
+ columns.push({
id: "type",
- title: WebInspector.UIString("Type"),
+ title: WebInspector.NetworkLogView._columnTitles["type"],
sortable: true,
weight: 6
});
columns.push({
id: "initiator",
- title: WebInspector.UIString("Initiator"),
+ title: WebInspector.NetworkLogView._columnTitles["initiator"],
sortable: true,
weight: 10
});
columns.push({
id: "cookies",
- title: WebInspector.UIString("Cookies"),
+ title: WebInspector.NetworkLogView._columnTitles["cookies"],
sortable: true,
weight: 6,
align: WebInspector.DataGrid.Align.Right
@@ -247,7 +326,7 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "setCookies",
- title: WebInspector.UIString("Set-Cookies"),
+ title: WebInspector.NetworkLogView._columnTitles["setCookies"],
sortable: true,
weight: 6,
align: WebInspector.DataGrid.Align.Right
@@ -256,7 +335,7 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "size",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Size"), WebInspector.UIString("Content")),
- title: WebInspector.UIString("Size"),
+ title: WebInspector.NetworkLogView._columnTitles["size"],
sortable: true,
weight: 6,
align: WebInspector.DataGrid.Align.Right
@@ -265,7 +344,7 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "time",
titleDOMFragment: this._makeHeaderFragment(WebInspector.UIString("Time"), WebInspector.UIString("Latency")),
- title: WebInspector.UIString("Time"),
+ title: WebInspector.NetworkLogView._columnTitles["time"],
sortable: true,
weight: 6,
align: WebInspector.DataGrid.Align.Right
@@ -276,7 +355,7 @@ WebInspector.NetworkLogView.prototype = {
var headerName = responseHeaderColumns[i];
var descriptor = {
id: headerName,
- title: WebInspector.UIString(headerName),
+ title: WebInspector.NetworkLogView._columnTitles[headerName],
weight: 6
}
if (headerName === "Content-Length")
@@ -287,13 +366,14 @@ WebInspector.NetworkLogView.prototype = {
columns.push({
id: "timeline",
titleDOMFragment: document.createDocumentFragment(),
- title: WebInspector.UIString("Timeline"),
+ title: WebInspector.NetworkLogView._columnTitles["timeline"],
sortable: false,
weight: 40,
sort: WebInspector.DataGrid.Order.Ascending
});
this._dataGrid = new WebInspector.DataGrid(columns);
+ this._updateColumns();
this._dataGrid.setName("networkLog");
this._dataGrid.resizeMethod = WebInspector.DataGrid.ResizeMethod.Last;
this._dataGrid.element.classList.add("network-log-grid");
@@ -303,7 +383,6 @@ WebInspector.NetworkLogView.prototype = {
// Event listeners need to be added _after_ we attach to the document, so that owner document is properly update.
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortItems, this);
this._dataGrid.addEventListener(WebInspector.DataGrid.Events.ColumnsResized, this._updateDividersIfNeeded, this);
- this._dataGrid.scrollContainer.addEventListener("scroll", this._updateOffscreenRows.bind(this));
this._patchTimelineHeader();
},
@@ -367,6 +446,7 @@ WebInspector.NetworkLogView.prototype = {
this._sortingFunctions.status = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "statusCode", false);
this._sortingFunctions.scheme = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "scheme", false);
this._sortingFunctions.domain = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "domain", false);
+ this._sortingFunctions.remoteAddress = WebInspector.NetworkDataGridNode.RemoteAddressComparator;
this._sortingFunctions.type = WebInspector.NetworkDataGridNode.RequestPropertyComparator.bind(null, "mimeType", false);
this._sortingFunctions.initiator = WebInspector.NetworkDataGridNode.InitiatorComparator;
this._sortingFunctions.cookies = WebInspector.NetworkDataGridNode.RequestCookiesCountComparator;
@@ -406,7 +486,6 @@ WebInspector.NetworkLogView.prototype = {
this._dataGrid.sortNodes(sortingFunction, !this._dataGrid.isSortOrderAscending());
this._timelineSortSelector.selectedIndex = 0;
- this._updateOffscreenRows();
this.searchCanceled();
@@ -434,7 +513,6 @@ WebInspector.NetworkLogView.prototype = {
else
this._timelineGrid.showEventDividers();
this._dataGrid.markColumnAsSortedBy("timeline", WebInspector.DataGrid.Order.Ascending);
- this._updateOffscreenRows();
},
_createStatusBarItems: function()
@@ -473,7 +551,7 @@ WebInspector.NetworkLogView.prototype = {
selectedRequestsNumber++;
selectedTransferSize += requestTransferSize;
}
- if (request.url === WebInspector.inspectedPageURL)
+ if (request.url === request.target().resourceTreeModel.inspectedPageURL())
baseTime = request.startTime;
if (request.endTime > maxTime)
maxTime = request.endTime;
@@ -511,13 +589,10 @@ WebInspector.NetworkLogView.prototype = {
{
if (!this._dataGrid)
return;
- var timelineColumn = this._dataGrid.columns.timeline;
- for (var i = 0; i < this._dataGrid.resizers.length; ++i) {
- if (timelineColumn.ordinal === this._dataGrid.resizers[i].rightNeighboringColumnIndex) {
- // Position timline grid location.
- this._timelineGrid.element.style.left = this._dataGrid.resizers[i].style.left;
- }
- }
+ var timelineOffset = this._dataGrid.columnOffset("timeline");
+ // Position timline grid location.
+ if (timelineOffset)
+ this._timelineGrid.element.style.left = timelineOffset + "px";
var proceed = true;
if (!this.isShowing()) {
@@ -549,7 +624,7 @@ WebInspector.NetworkLogView.prototype = {
var loadDividerPadding = document.createElement("div");
loadDividerPadding.className = "network-event-divider-padding";
- loadDividerPadding.title = WebInspector.UIString("Load event fired");
+ loadDividerPadding.title = WebInspector.UIString("Load event");
loadDividerPadding.appendChild(loadDivider);
loadDividerPadding.style.left = percent + "%";
this._timelineGrid.addEventDivider(loadDividerPadding);
@@ -563,7 +638,7 @@ WebInspector.NetworkLogView.prototype = {
var domContentLoadedDividerPadding = document.createElement("div");
domContentLoadedDividerPadding.className = "network-event-divider-padding";
- domContentLoadedDividerPadding.title = WebInspector.UIString("DOMContentLoaded event fired");
+ domContentLoadedDividerPadding.title = WebInspector.UIString("DOMContentLoaded event");
domContentLoadedDividerPadding.appendChild(domContentLoadedDivider);
domContentLoadedDividerPadding.style.left = percent + "%";
this._timelineGrid.addEventDivider(domContentLoadedDividerPadding);
@@ -627,6 +702,11 @@ WebInspector.NetworkLogView.prototype = {
this._largerRequestsButton.addEventListener("click", this._toggleLargerRequests, this);
this._preserveLogCheckbox = new WebInspector.StatusBarCheckbox(WebInspector.UIString("Preserve log"));
+ this._preserveLogCheckbox.element.title = WebInspector.UIString("Do not clear log on page reload / navigation.");
+
+ this._disableCacheCheckbox = new WebInspector.StatusBarCheckbox(WebInspector.UIString("Disable cache"));
+ WebInspector.SettingsUI.bindCheckbox(this._disableCacheCheckbox.inputElement, WebInspector.settings.cacheDisabled);
+ this._disableCacheCheckbox.element.title = WebInspector.UIString("Disable cache (while DevTools is open).");
},
_loadEventFired: function(event)
@@ -682,7 +762,7 @@ WebInspector.NetworkLogView.prototype = {
node = this._createRequestGridNode(request);
this._dataGrid.rootNode().appendChild(node);
}
- node.refreshRequest();
+ node.refresh();
this._applyFilter(node);
if (this.calculator.updateBoundaries(request))
@@ -709,7 +789,7 @@ WebInspector.NetworkLogView.prototype = {
this._dataGrid.scrollToLastRow();
},
- _onRecordButtonClicked: function(e)
+ _onRecordButtonClicked: function()
{
if (!this._recordButton.toggled)
this._reset();
@@ -732,6 +812,7 @@ WebInspector.NetworkLogView.prototype = {
this._requestsByURL = {};
this._staleRequests = {};
this._requestGridNodes = {};
+ this._resetSuggestionBuilder();
if (this._dataGrid) {
this._dataGrid.rootNode().removeChildren();
@@ -748,11 +829,6 @@ WebInspector.NetworkLogView.prototype = {
return this._requests;
},
- requestById: function(id)
- {
- return this._requestsById[id];
- },
-
_onRequestStarted: function(event)
{
if (this._recordButton.toggled)
@@ -800,6 +876,23 @@ WebInspector.NetworkLogView.prototype = {
{
if (!this._requestsById[request.requestId])
return;
+
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.Domain, request.domain);
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.Method, request.requestMethod);
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.MimeType, request.mimeType);
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.StatusCode, "" + request.statusCode);
+
+ var responseHeaders = request.responseHeaders;
+ for (var i = 0, l = responseHeaders.length; i < l; ++i)
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.HasResponseHeader, responseHeaders[i].name);
+ var cookies = request.responseCookies;
+ for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
+ var cookie = cookies[i];
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.SetCookieDomain, cookie.domain());
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.SetCookieName, cookie.name());
+ this._suggestionBuilder.addItem(WebInspector.NetworkPanel.FilterType.SetCookieValue, cookie.value());
+ }
+
this._staleRequests[request.requestId] = request;
this._scheduleRefresh();
},
@@ -824,7 +917,7 @@ WebInspector.NetworkLogView.prototype = {
// Pick provisional load requests.
var requestsToPick = [];
- var requests = WebInspector.networkLog.requests;
+ var requests = frame.target().networkLog.requests;
for (var i = 0; i < requests.length; ++i) {
var request = requests[i];
if (request.loaderId === loaderId)
@@ -877,7 +970,6 @@ WebInspector.NetworkLogView.prototype = {
this._timelineGrid.element.classList.remove("small");
}
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.RowSizeChanged, { largeRows: enabled });
- this._updateOffscreenRows();
},
_getPopoverAnchor: function(element)
@@ -926,7 +1018,7 @@ WebInspector.NetworkLogView.prototype = {
var row = document.createElement("tr");
row.createChild("td").textContent = stackFrame.functionName || WebInspector.UIString("(anonymous function)");
row.createChild("td").textContent = " @ ";
- row.createChild("td").appendChild(this._linkifier.linkifyLocation(stackFrame.url, stackFrame.lineNumber - 1, stackFrame.columnNumber - 1));
+ row.createChild("td").appendChild(this._linkifier.linkifyLocation(request.target(), stackFrame.url, stackFrame.lineNumber - 1, stackFrame.columnNumber - 1));
framesTable.appendChild(row);
}
return framesTable;
@@ -934,14 +1026,16 @@ WebInspector.NetworkLogView.prototype = {
_updateColumns: function()
{
- var columnsVisibility = this._coulmnsVisibilitySetting.get();
var detailedMode = !!this._detailedMode;
- for (var columnIdentifier in columnsVisibility) {
- var visible = detailedMode && columnsVisibility[columnIdentifier];
- this._dataGrid.setColumnVisible(columnIdentifier, visible);
+ var visibleColumns = {"name": true};
+ if (detailedMode) {
+ visibleColumns["timeline"] = true;
+ var columnsVisibility = this._coulmnsVisibilitySetting.get();
+ for (var columnIdentifier in columnsVisibility)
+ visibleColumns[columnIdentifier] = columnsVisibility[columnIdentifier];
}
- this._dataGrid.setColumnVisible("timeline", detailedMode);
- this._dataGrid.applyColumnWeights();
+
+ this._dataGrid.setColumnsVisiblity(visibleColumns);
},
/**
@@ -964,10 +1058,10 @@ WebInspector.NetworkLogView.prototype = {
if (this._configurableColumnIDs)
return this._configurableColumnIDs;
- var columns = this._dataGrid.columns;
+ var columnTitles = WebInspector.NetworkLogView._columnTitles;
function compare(id1, id2)
{
- return columns[id1].title.compareTo(columns[id2].title);
+ return columnTitles[id1].compareTo(columnTitles[id2]);
}
var columnIDs = Object.keys(this._coulmnsVisibilitySetting.get());
@@ -982,10 +1076,10 @@ WebInspector.NetworkLogView.prototype = {
if (this._detailedMode && event.target.isSelfOrDescendant(this._dataGrid.headerTableBody)) {
var columnsVisibility = this._coulmnsVisibilitySetting.get();
var columnIDs = this._getConfigurableColumnIDs();
+ var columnTitles = WebInspector.NetworkLogView._columnTitles;
for (var i = 0; i < columnIDs.length; ++i) {
var columnIdentifier = columnIDs[i];
- var column = this._dataGrid.columns[columnIdentifier];
- contextMenu.appendCheckboxItem(column.title, this._toggleColumnVisibility.bind(this, columnIdentifier), !!columnsVisibility[columnIdentifier]);
+ contextMenu.appendCheckboxItem(columnTitles[columnIdentifier], this._toggleColumnVisibility.bind(this, columnIdentifier), !!columnsVisibility[columnIdentifier]);
}
contextMenu.show();
return;
@@ -994,14 +1088,24 @@ WebInspector.NetworkLogView.prototype = {
var gridNode = this._dataGrid.dataGridNodeFromNode(event.target);
var request = gridNode && gridNode._request;
+ /**
+ * @param {string} url
+ */
+ function openResourceInNewTab(url)
+ {
+ InspectorFrontendHost.openInNewTab(url);
+ }
+
if (request) {
- contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), WebInspector.openResource.bind(WebInspector, request.url, false));
+ contextMenu.appendItem(WebInspector.openLinkExternallyLabel(), openResourceInNewTab.bind(null, request.url));
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.copyLinkAddressLabel(), this._copyLocation.bind(this, request));
if (request.requestHeadersText())
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy request headers" : "Copy Request Headers"), this._copyRequestHeaders.bind(this, request));
if (request.responseHeadersText)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy response headers" : "Copy Response Headers"), this._copyResponseHeaders.bind(this, request));
+ if (request.finished)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy response" : "Copy Response"), this._copyResponse.bind(this, request));
contextMenu.appendItem(WebInspector.UIString("Copy as cURL"), this._copyCurlCommand.bind(this, request));
}
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy all as HAR" : "Copy All as HAR"), this._copyAll.bind(this));
@@ -1027,10 +1131,17 @@ WebInspector.NetworkLogView.prototype = {
NetworkAgent.replayXHR(requestId);
},
+ _harRequests: function()
+ {
+ var httpRequests = this._requests.filter(WebInspector.NetworkLogView.HTTPRequestsFilter);
+ httpRequests = httpRequests.filter(WebInspector.NetworkLogView.FinishedRequestsFilter);
+ return httpRequests.filter(WebInspector.NetworkLogView.NonDevToolsRequestsFilter);
+ },
+
_copyAll: function()
{
var harArchive = {
- log: (new WebInspector.HARLog(this._requests.filter(WebInspector.NetworkLogView.HTTPRequestsFilter))).build()
+ log: (new WebInspector.HARLog(this._harRequests())).build()
};
InspectorFrontendHost.copyText(JSON.stringify(harArchive, null, 2));
},
@@ -1045,6 +1156,17 @@ WebInspector.NetworkLogView.prototype = {
InspectorFrontendHost.copyText(request.requestHeadersText());
},
+ _copyResponse: function(request)
+ {
+ function callback(content)
+ {
+ if (request.contentEncoded)
+ content = request.asDataURL();
+ InspectorFrontendHost.copyText(content || "");
+ }
+ request.requestContent(callback);
+ },
+
_copyResponseHeaders: function(request)
{
InspectorFrontendHost.copyText(request.responseHeadersText);
@@ -1060,7 +1182,7 @@ WebInspector.NetworkLogView.prototype = {
_exportAll: function()
{
- var filename = WebInspector.inspectedPageDomain + ".har";
+ var filename = WebInspector.resourceTreeModel.inspectedPageDomain() + ".har";
var stream = new WebInspector.FileOutputStream();
stream.open(filename, openCallback.bind(this));
@@ -1075,7 +1197,7 @@ WebInspector.NetworkLogView.prototype = {
var progressIndicator = new WebInspector.ProgressIndicator();
this._progressBarContainer.appendChild(progressIndicator.element);
var harWriter = new WebInspector.HARWriter();
- harWriter.write(stream, this._requests.filter(WebInspector.NetworkLogView.HTTPRequestsFilter), progressIndicator);
+ harWriter.write(stream, this._harRequests(), progressIndicator);
}
},
@@ -1091,42 +1213,6 @@ WebInspector.NetworkLogView.prototype = {
NetworkAgent.clearBrowserCookies();
},
- _updateOffscreenRows: function()
- {
- var dataTableBody = this._dataGrid.dataTableBody;
- var rows = dataTableBody.children;
- var recordsCount = rows.length;
- if (recordsCount < 2)
- return; // Filler row only.
-
- var visibleTop = this._dataGrid.scrollContainer.scrollTop;
- var visibleBottom = visibleTop + this._dataGrid.scrollContainer.offsetHeight;
-
- var rowHeight = 0;
-
- // Filler is at recordsCount - 1.
- var unfilteredRowIndex = 0;
- for (var i = 0; i < recordsCount - 1; ++i) {
- var row = rows[i];
-
- var dataGridNode = this._dataGrid.dataGridNodeFromNode(row);
- if (dataGridNode.isFilteredOut()) {
- row.classList.remove("offscreen");
- continue;
- }
-
- if (!rowHeight)
- rowHeight = row.offsetHeight;
-
- var rowIsVisible = unfilteredRowIndex * rowHeight < visibleBottom && (unfilteredRowIndex + 1) * rowHeight > visibleTop;
- if (rowIsVisible !== row.rowIsVisible) {
- row.enableStyleClass("offscreen", !rowIsVisible);
- row.rowIsVisible = rowIsVisible;
- }
- unfilteredRowIndex++;
- }
- },
-
_matchRequest: function(request)
{
if (!this._searchRegExp)
@@ -1214,7 +1300,7 @@ WebInspector.NetworkLogView.prototype = {
*/
_highlightNthMatchedRequestForSearch: function(matchedRequestIndex, reveal)
{
- var request = this.requestById(this._matchedRequests[matchedRequestIndex]);
+ var request = this._requestsById[this._matchedRequests[matchedRequestIndex]];
if (!request)
return;
this._removeAllHighlights();
@@ -1229,10 +1315,11 @@ WebInspector.NetworkLogView.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump)
+ performSearch: function(query, shouldJump, jumpBackwards)
{
- var newMatchedRequestIndex = 0;
+ var newMatchedRequestIndex = jumpBackwards ? -1 : 0;
var currentMatchedRequestId;
if (this._currentMatchedRequestIndex !== -1)
currentMatchedRequestId = this._matchedRequests[this._currentMatchedRequestIndex];
@@ -1247,13 +1334,22 @@ WebInspector.NetworkLogView.prototype = {
var dataGridNode = this._dataGrid.dataGridNodeFromNode(requestNodes[i]);
if (dataGridNode.isFilteredOut())
continue;
- if (this._matchRequest(dataGridNode._request) !== -1 && dataGridNode._request.requestId === currentMatchedRequestId)
+ if (this._matchRequest(dataGridNode._request) !== -1 && dataGridNode._request.requestId === currentMatchedRequestId) {
+ // Keep current search result the same if it still matches.
newMatchedRequestIndex = this._matchedRequests.length - 1;
+ }
}
this.dispatchEventToListeners(WebInspector.NetworkLogView.EventTypes.SearchCountUpdated, this._matchedRequests.length);
- if (shouldJump)
- this._highlightNthMatchedRequestForSearch(newMatchedRequestIndex, true);
+ if (shouldJump) {
+ var index = this._normalizeSearchResultIndex(newMatchedRequestIndex);
+ this._highlightNthMatchedRequestForSearch(index, true);
+ }
+ },
+
+ _normalizeSearchResultIndex: function(index)
+ {
+ return (index + this._matchedRequests.length) % this._matchedRequests.length;
},
/**
@@ -1261,28 +1357,77 @@ WebInspector.NetworkLogView.prototype = {
*/
_applyFilter: function(node)
{
- var filter = this._textFilterUI.regex();
var request = node._request;
-
- var matches = true;
+ var matches = this._resourceTypeFilterUI.accept(request.type.name());
if (this._dataURLFilterUI.checked() && request.parsedURL.isDataURL())
matches = false;
- if (matches && !this._resourceTypeFilterUI.accept(request.type.name()))
- matches = false;
-
- if (matches && filter) {
- matches = filter.test(request.name()) || filter.test(request.path());
- if (matches)
- this._highlightMatchedRequest(request, false, filter);
- }
+ for (var i = 0; matches && (i < this._filters.length); ++i)
+ matches = this._filters[i](request);
- node.element.enableStyleClass("filtered-out", !matches);
+ node.element.classList.toggle("filtered-out", !matches);
if (matches)
this._filteredOutRequests.remove(request);
else
this._filteredOutRequests.put(request, true);
},
+ /**
+ * @param {string} query
+ */
+ _parseFilterQuery: function(query)
+ {
+ var parsedQuery = this._suggestionBuilder.parseQuery(query);
+ this._filters = parsedQuery.text.map(this._createTextFilter);
+ for (var key in parsedQuery.filters) {
+ var filterType = /** @type {!WebInspector.NetworkPanel.FilterType} */ (key);
+ this._filters.push(this._createFilter(filterType, parsedQuery.filters[key]));
+ }
+ },
+
+ /**
+ * @param {string} text
+ * @return {!WebInspector.NetworkLogView.Filter}
+ */
+ _createTextFilter: function(text)
+ {
+ var regexp = new RegExp(text.escapeForRegExp(), "i");
+ return WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null, regexp);
+ },
+
+ /**
+ * @param {!WebInspector.NetworkPanel.FilterType} type
+ * @param {string} value
+ * @return {!WebInspector.NetworkLogView.Filter}
+ */
+ _createFilter: function(type, value) {
+ switch (type) {
+ case WebInspector.NetworkPanel.FilterType.Domain:
+ return WebInspector.NetworkLogView._requestDomainFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.HasResponseHeader:
+ return WebInspector.NetworkLogView._requestResponseHeaderFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.Method:
+ return WebInspector.NetworkLogView._requestMethodFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.MimeType:
+ return WebInspector.NetworkLogView._requestMimeTypeFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.SetCookieDomain:
+ return WebInspector.NetworkLogView._requestSetCookieDomainFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.SetCookieName:
+ return WebInspector.NetworkLogView._requestSetCookieNameFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.SetCookieValue:
+ return WebInspector.NetworkLogView._requestSetCookieValueFilter.bind(null, value);
+
+ case WebInspector.NetworkPanel.FilterType.StatusCode:
+ return WebInspector.NetworkLogView._statusCodeFilter.bind(null, value);
+ }
+ return this._createTextFilter(type + ":" + value);
+ },
+
_filterRequests: function()
{
this._removeAllHighlights();
@@ -1292,21 +1437,22 @@ WebInspector.NetworkLogView.prototype = {
for (var i = 0; i < nodes.length; ++i)
this._applyFilter(nodes[i]);
this._updateSummaryBar();
- this._updateOffscreenRows();
},
jumpToPreviousSearchResult: function()
{
if (!this._matchedRequests.length)
return;
- this._highlightNthMatchedRequestForSearch((this._currentMatchedRequestIndex + this._matchedRequests.length - 1) % this._matchedRequests.length, true);
+ var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex - 1);
+ this._highlightNthMatchedRequestForSearch(index, true);
},
jumpToNextSearchResult: function()
{
if (!this._matchedRequests.length)
return;
- this._highlightNthMatchedRequestForSearch((this._currentMatchedRequestIndex + 1) % this._matchedRequests.length, true);
+ var index = this._normalizeSearchResultIndex(this._currentMatchedRequestIndex + 1);
+ this._highlightNthMatchedRequestForSearch(index, true);
},
searchCanceled: function()
@@ -1337,7 +1483,7 @@ WebInspector.NetworkLogView.prototype = {
_highlightNode: function(node)
{
- node.element.classList.add("highlighted-row");
+ WebInspector.runCSSAnimationOnce(node.element, "highlighted-row");
this._highlightedNode = node;
},
@@ -1439,7 +1585,115 @@ WebInspector.NetworkLogView.prototype = {
return command.join(" ");
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
+}
+
+/** @typedef {function(!WebInspector.NetworkRequest): boolean} */
+WebInspector.NetworkLogView.Filter;
+
+/**
+ * @param {!RegExp} regex
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestNameOrPathFilter = function(regex, request)
+{
+ return regex.test(request.name()) || regex.test(request.path());
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestDomainFilter = function(value, request)
+{
+ return request.domain === value;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestResponseHeaderFilter = function(value, request)
+{
+ return request.responseHeaderValue(value) !== undefined;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestMethodFilter = function(value, request)
+{
+ return request.requestMethod === value;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestMimeTypeFilter = function(value, request)
+{
+ return request.mimeType === value;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestSetCookieDomainFilter = function(value, request)
+{
+ var cookies = request.responseCookies;
+ for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
+ if (cookies[i].domain() === value)
+ return false;
+ }
+ return false;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestSetCookieNameFilter = function(value, request)
+{
+ var cookies = request.responseCookies;
+ for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
+ if (cookies[i].name() === value)
+ return false;
+ }
+ return false;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._requestSetCookieValueFilter = function(value, request)
+{
+ var cookies = request.responseCookies;
+ for (var i = 0, l = cookies ? cookies.length : 0; i < l; ++i) {
+ if (cookies[i].value() === value)
+ return false;
+ }
+ return false;
+}
+
+/**
+ * @param {string} value
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView._statusCodeFilter = function(value, request)
+{
+ return ("" + request.statusCode) === value;
}
/**
@@ -1451,6 +1705,23 @@ WebInspector.NetworkLogView.HTTPRequestsFilter = function(request)
return request.parsedURL.isValid && (request.scheme in WebInspector.NetworkLogView.HTTPSchemas);
}
+/**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView.NonDevToolsRequestsFilter = function(request)
+{
+ return !WebInspector.NetworkManager.hasDevToolsRequestHeader(request);
+}
+
+/**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkLogView.FinishedRequestsFilter = function(request)
+{
+ return request.finished;
+}
WebInspector.NetworkLogView.EventTypes = {
ViewCleared: "ViewCleared",
@@ -1472,21 +1743,20 @@ WebInspector.NetworkPanel = function()
this.registerRequiredCSS("networkPanel.css");
this._injectStyles();
- this.element.classList.add("vbox");
-
this._panelStatusBarElement = this.element.createChild("div", "panel-status-bar");
this._filterBar = new WebInspector.FilterBar();
this._filtersContainer = this.element.createChild("div", "network-filters-header hidden");
this._filtersContainer.appendChild(this._filterBar.filtersElement());
this._filterBar.addEventListener(WebInspector.FilterBar.Events.FiltersToggled, this._onFiltersToggled, this);
+ this._filterBar.setName("networkPanel");
this._searchableView = new WebInspector.SearchableView(this);
this._searchableView.show(this.element);
this._contentsElement = this._searchableView.element;
- this.createSidebarView(this._contentsElement);
- this.splitView.element.classList.remove("fill");
- this.splitView.hideMainElement();
+ this._splitView = new WebInspector.SplitView(true, false, "networkPanelSplitViewState");
+ this._splitView.show(this._contentsElement);
+ this._splitView.hideMain();
var defaultColumnsVisibility = WebInspector.NetworkLogView._defaultColumnsVisibility;
var networkLogColumnsVisibilitySetting = WebInspector.settings.createSetting("networkLogColumnsVisibility", defaultColumnsVisibility);
@@ -1497,13 +1767,14 @@ WebInspector.NetworkPanel = function()
networkLogColumnsVisibilitySetting.set(columnsVisibility);
this._networkLogView = new WebInspector.NetworkLogView(this._filterBar, networkLogColumnsVisibilitySetting);
- this._networkLogView.show(this.sidebarElement);
+ this._networkLogView.show(this._splitView.sidebarElement());
- this._viewsContainerElement = this.splitView.mainElement;
+ var viewsContainerView = new WebInspector.VBox();
+ this._viewsContainerElement = viewsContainerView.element;
this._viewsContainerElement.id = "network-views";
- this._viewsContainerElement.classList.add("hidden");
if (!this._networkLogView.useLargeRows)
this._viewsContainerElement.classList.add("small");
+ viewsContainerView.show(this._splitView.mainElement());
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.ViewCleared, this._onViewCleared, this);
this._networkLogView.addEventListener(WebInspector.NetworkLogView.EventTypes.RowSizeChanged, this._onRowSizeChanged, this);
@@ -1521,22 +1792,42 @@ WebInspector.NetworkPanel = function()
/**
* @this {WebInspector.NetworkPanel}
+ * @return {?WebInspector.SourceFrame}
*/
- function viewGetter()
+ function sourceFrameGetter()
{
- return this.visibleView;
+ return this._networkItemView.currentSourceFrame();
}
- WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
+ WebInspector.GoToLineDialog.install(this, sourceFrameGetter.bind(this));
}
+/** @enum {string} */
+WebInspector.NetworkPanel.FilterType = {
+ Domain: "Domain",
+ HasResponseHeader: "HasResponseHeader",
+ Method: "Method",
+ MimeType: "MimeType",
+ SetCookieDomain: "SetCookieDomain",
+ SetCookieName: "SetCookieName",
+ SetCookieValue: "SetCookieValue",
+ StatusCode: "StatusCode"
+};
+
+/** @type {!Array.<string>} */
+WebInspector.NetworkPanel._searchKeys = Object.values(WebInspector.NetworkPanel.FilterType);
+
WebInspector.NetworkPanel.prototype = {
_onFiltersToggled: function(event)
{
var toggled = /** @type {boolean} */ (event.data);
- this._filtersContainer.enableStyleClass("hidden", !toggled);
- this.element.enableStyleClass("filters-toggled", toggled);
+ this._filtersContainer.classList.toggle("hidden", !toggled);
+ this.element.classList.toggle("filters-toggled", toggled);
+ this.doResize();
},
+ /**
+ * @return {!Array.<!Element>}
+ */
elementsToRestoreScrollPositionsFor: function()
{
return this._networkLogView.elementsToRestoreScrollPositionsFor();
@@ -1577,30 +1868,9 @@ WebInspector.NetworkPanel.prototype = {
return this._networkLogView.requests;
},
- requestById: function(id)
- {
- return this._networkLogView.requestById(id);
- },
-
- _requestByAnchor: function(anchor)
- {
- return anchor.requestId ? this.requestById(anchor.requestId) : this._networkLogView._requestsByURL[anchor.href];
- },
-
/**
- * @param {!Element} anchor
- * @return {boolean}
+ * @param {!WebInspector.NetworkRequest} request
*/
- showAnchorLocation: function(anchor)
- {
- var request = this._requestByAnchor(anchor);
- if (!request)
- return false;
- this.revealAndHighlightRequest(request)
- WebInspector.inspectorView.setCurrentPanel(this);
- return true;
- },
-
revealAndHighlightRequest: function(request)
{
this._toggleGridMode();
@@ -1618,7 +1888,7 @@ WebInspector.NetworkPanel.prototype = {
_onRowSizeChanged: function(event)
{
- this._viewsContainerElement.enableStyleClass("small", !event.data.largeRows);
+ this._viewsContainerElement.classList.toggle("small", !event.data.largeRows);
},
_onSearchCountUpdated: function(event)
@@ -1636,6 +1906,9 @@ WebInspector.NetworkPanel.prototype = {
this._showRequest(event.data);
},
+ /**
+ * @param {?WebInspector.NetworkRequest} request
+ */
_showRequest: function(request)
{
if (!request)
@@ -1643,23 +1916,23 @@ WebInspector.NetworkPanel.prototype = {
this._toggleViewingRequestMode();
- if (this.visibleView) {
- this.visibleView.detach();
- delete this.visibleView;
+ if (this._networkItemView) {
+ this._networkItemView.detach();
+ delete this._networkItemView;
}
var view = new WebInspector.NetworkItemView(request);
view.show(this._viewsContainerElement);
- this.visibleView = view;
+ this._networkItemView = view;
},
_closeVisibleRequest: function()
{
this.element.classList.remove("viewing-resource");
- if (this.visibleView) {
- this.visibleView.detach();
- delete this.visibleView;
+ if (this._networkItemView) {
+ this._networkItemView.detach();
+ delete this._networkItemView;
}
},
@@ -1668,7 +1941,7 @@ WebInspector.NetworkPanel.prototype = {
if (this._viewingRequestMode) {
this._viewingRequestMode = false;
this.element.classList.remove("viewing-resource");
- this.splitView.hideMainElement();
+ this._splitView.hideMain();
}
this._networkLogView.switchToDetailedView();
@@ -1683,7 +1956,7 @@ WebInspector.NetworkPanel.prototype = {
this._viewingRequestMode = true;
this.element.classList.add("viewing-resource");
- this.splitView.showMainElement();
+ this._splitView.showBoth();
this._networkLogView.allowPopover = false;
this._networkLogView._allowRequestSelection = true;
this._networkLogView.switchToBriefView();
@@ -1692,10 +1965,11 @@ WebInspector.NetworkPanel.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump)
+ performSearch: function(query, shouldJump, jumpBackwards)
{
- this._networkLogView.performSearch(query, shouldJump);
+ this._networkLogView.performSearch(query, shouldJump, jumpBackwards);
},
jumpToPreviousSearchResult: function()
@@ -1713,7 +1987,8 @@ WebInspector.NetworkPanel.prototype = {
this._networkLogView.searchCanceled();
},
- /**
+ /**
+ * @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
* @this {WebInspector.NetworkPanel}
@@ -1755,7 +2030,7 @@ WebInspector.NetworkPanel.prototype = {
if (!(target instanceof WebInspector.NetworkRequest))
return;
var request = /** @type {!WebInspector.NetworkRequest} */ (target);
- if (this.visibleView && this.visibleView.isShowing() && this.visibleView.request() === request)
+ if (this._networkItemView && this._networkItemView.isShowing() && this._networkItemView.request() === request)
return;
appendRevealItem.call(this, request);
@@ -1786,6 +2061,45 @@ WebInspector.NetworkPanel.prototype = {
/**
* @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ */
+WebInspector.NetworkPanel.ContextMenuProvider = function()
+{
+}
+
+WebInspector.NetworkPanel.ContextMenuProvider.prototype = {
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ WebInspector.inspectorView.panel("network").appendApplicableItems(event, contextMenu, target);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.NetworkPanel.RequestRevealer = function()
+{
+}
+
+WebInspector.NetworkPanel.RequestRevealer.prototype = {
+ /**
+ * @param {!Object} request
+ */
+ reveal: function(request)
+ {
+ if (request instanceof WebInspector.NetworkRequest)
+ /** @type {!WebInspector.NetworkPanel} */ (WebInspector.inspectorView.showPanel("network")).revealAndHighlightRequest(request);
+ }
+}
+
+/**
+ * @constructor
* @implements {WebInspector.TimelineGrid.Calculator}
*/
WebInspector.NetworkBaseCalculator = function()
@@ -1793,27 +2107,43 @@ WebInspector.NetworkBaseCalculator = function()
}
WebInspector.NetworkBaseCalculator.prototype = {
+ /**
+ * @param {number} time
+ * @return {number}
+ */
computePosition: function(time)
{
return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea;
},
+ /**
+ * @return {!{start: number, middle: number, end: number}}
+ */
computeBarGraphPercentages: function(item)
{
return {start: 0, middle: 0, end: (this._value(item) / this.boundarySpan()) * 100};
},
+ /**
+ * @return {!{left: string, right: string, tooltip: string}}
+ */
computeBarGraphLabels: function(item)
{
const label = this.formatTime(this._value(item));
return {left: label, right: label, tooltip: label};
},
+ /**
+ * @return {number}
+ */
boundarySpan: function()
{
return this._maximumBoundary - this._minimumBoundary;
},
+ /**
+ * @return {boolean}
+ */
updateBoundaries: function(item)
{
this._minimumBoundary = 0;
@@ -1832,21 +2162,33 @@ WebInspector.NetworkBaseCalculator.prototype = {
delete this._maximumBoundary;
},
+ /**
+ * @return {number}
+ */
maximumBoundary: function()
{
return this._maximumBoundary;
},
+ /**
+ * @return {number}
+ */
minimumBoundary: function()
{
return this._minimumBoundary;
},
+ /**
+ * @return {number}
+ */
zeroTime: function()
{
return this._minimumBoundary;
},
+ /**
+ * @return {number}
+ */
_value: function(item)
{
return 0;
@@ -1854,10 +2196,10 @@ WebInspector.NetworkBaseCalculator.prototype = {
/**
* @param {number} value
- * @param {boolean=} hires
+ * @param {number=} precision
* @return {string}
*/
- formatTime: function(value, hires)
+ formatTime: function(value, precision)
{
return value.toString();
},
@@ -1865,7 +2207,14 @@ WebInspector.NetworkBaseCalculator.prototype = {
setDisplayWindow: function(clientWidth)
{
this._workingArea = clientWidth;
- this.paddingLeft = 0;
+ },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
}
}
@@ -1880,6 +2229,10 @@ WebInspector.NetworkTimeCalculator = function(startAtZero)
}
WebInspector.NetworkTimeCalculator.prototype = {
+ /**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {!{start: number, middle: number, end: number}}
+ */
computeBarGraphPercentages: function(request)
{
if (request.startTime !== -1)
@@ -1906,6 +2259,9 @@ WebInspector.NetworkTimeCalculator.prototype = {
return {start: start, middle: middle, end: end};
},
+ /**
+ * @return {number}
+ */
computePercentageFromEventTime: function(eventTime)
{
// This function computes a percentage in terms of the total loading time
@@ -1917,6 +2273,9 @@ WebInspector.NetworkTimeCalculator.prototype = {
return 0;
},
+ /**
+ * @return {boolean}
+ */
updateBoundariesForEventTime: function(eventTime)
{
if (eventTime === -1 || this.startAtZero)
@@ -1929,15 +2288,18 @@ WebInspector.NetworkTimeCalculator.prototype = {
return false;
},
+ /**
+ * @return {!{left: string, right: string, tooltip: (string|undefined)}}
+ */
computeBarGraphLabels: function(request)
{
var rightLabel = "";
if (request.responseReceivedTime !== -1 && request.endTime !== -1)
- rightLabel = this.formatTime(request.endTime - request.responseReceivedTime);
+ rightLabel = Number.secondsToString(request.endTime - request.responseReceivedTime);
var hasLatency = request.latency > 0;
if (hasLatency)
- var leftLabel = this.formatTime(request.latency);
+ var leftLabel = Number.secondsToString(request.latency);
else
var leftLabel = rightLabel;
@@ -1945,7 +2307,7 @@ WebInspector.NetworkTimeCalculator.prototype = {
return {left: leftLabel, right: rightLabel};
if (hasLatency && rightLabel) {
- var total = this.formatTime(request.duration);
+ var total = Number.secondsToString(request.duration);
var tooltip = WebInspector.UIString("%s latency, %s download (%s total)", leftLabel, rightLabel, total);
} else if (hasLatency)
var tooltip = WebInspector.UIString("%s latency", leftLabel);
@@ -1957,6 +2319,9 @@ WebInspector.NetworkTimeCalculator.prototype = {
return {left: leftLabel, right: rightLabel, tooltip: tooltip};
},
+ /**
+ * @return {boolean}
+ */
updateBoundaries: function(request)
{
var didChange = false;
@@ -1981,6 +2346,9 @@ WebInspector.NetworkTimeCalculator.prototype = {
return didChange;
},
+ /**
+ * @return {string}
+ */
formatTime: function(value)
{
return Number.secondsToString(value);
@@ -2009,9 +2377,13 @@ WebInspector.NetworkTransferTimeCalculator = function()
}
WebInspector.NetworkTransferTimeCalculator.prototype = {
+ /**
+ * @param {number} value
+ * @return {string}
+ */
formatTime: function(value)
{
- return Number.secondsToString(value);
+ return Number.secondsToString(value - this.zeroTime());
},
_lowerBound: function(request)
@@ -2037,6 +2409,10 @@ WebInspector.NetworkTransferDurationCalculator = function()
}
WebInspector.NetworkTransferDurationCalculator.prototype = {
+ /**
+ * @param {number} value
+ * @return {string}
+ */
formatTime: function(value)
{
return Number.secondsToString(value);
@@ -2068,29 +2444,58 @@ WebInspector.NetworkDataGridNode.prototype = {
/** override */
createCells: function()
{
- // Out of sight, out of mind: create nodes offscreen to save on render tree update times when running updateOffscreenRows()
- this._element.classList.add("offscreen");
- this._nameCell = this._createDivInTD("name");
- this._methodCell = this._createDivInTD("method");
- this._statusCell = this._createDivInTD("status");
- this._schemeCell = this._createDivInTD("scheme");
- this._domainCell = this._createDivInTD("domain");
- this._typeCell = this._createDivInTD("type");
- this._initiatorCell = this._createDivInTD("initiator");
- this._cookiesCell = this._createDivInTD("cookies");
- this._setCookiesCell = this._createDivInTD("setCookies");
- this._sizeCell = this._createDivInTD("size");
- this._timeCell = this._createDivInTD("time");
-
- this._responseHeaderCells = {};
- var responseHeaderColumns = WebInspector.NetworkLogView._responseHeaderColumns;
- for (var i = 0; i < responseHeaderColumns.length; ++i)
- this._responseHeaderCells[responseHeaderColumns[i]] = this._createDivInTD(responseHeaderColumns[i]);
+ this._nameCell = null;
+ this._timelineCell = null;
+
+ var element = this._element;
+ element.classList.toggle("network-error-row", this._isFailed());
+ element.classList.toggle("resource-cached", this._request.cached);
+ var typeClassName = "network-type-" + this._request.type.name();
+ if (!element.classList.contains(typeClassName)) {
+ element.removeMatchingStyleClasses("network-type-\\w+");
+ element.classList.add(typeClassName);
+ }
+
+ WebInspector.DataGridNode.prototype.createCells.call(this);
- this._timelineCell = this._createDivInTD("timeline");
- this._createTimelineBar(this._timelineCell);
- this._nameCell.addEventListener("click", this._onClick.bind(this), false);
- this._nameCell.addEventListener("dblclick", this._openInNewTab.bind(this), false);
+ this.refreshGraph(this._parentView.calculator);
+ },
+
+ /**
+ * @override
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
+ createCell: function(columnIdentifier)
+ {
+ var cell = this.createTD(columnIdentifier);
+ switch (columnIdentifier) {
+ case "name": this._renderNameCell(cell); break;
+ case "timeline": this._createTimelineBar(cell); break;
+ case "method": cell.setTextAndTitle(this._request.requestMethod); break;
+ case "status": this._renderStatusCell(cell); break;
+ case "scheme": cell.setTextAndTitle(this._request.scheme); break;
+ case "domain": cell.setTextAndTitle(this._request.domain); break;
+ case "remoteAddress": cell.setTextAndTitle(this._request.remoteAddress()); break;
+ case "cookies": cell.setTextAndTitle(this._arrayLength(this._request.requestCookies)); break;
+ case "setCookies": cell.setTextAndTitle(this._arrayLength(this._request.responseCookies)); break;
+ case "type": this._renderTypeCell(cell); break;
+ case "initiator": this._renderInitiatorCell(cell); break;
+ case "size": this._renderSizeCell(cell); break;
+ case "time": this._renderTimeCell(cell); break;
+ default: cell.setTextAndTitle(this._request.responseHeaderValue(columnIdentifier) || ""); break;
+ }
+
+ return cell;
+ },
+
+ /**
+ * @param {?Array} array
+ * @return {string}
+ */
+ _arrayLength: function(array)
+ {
+ return array ? "" + array.length : "";
},
wasDetached: function()
@@ -2098,6 +2503,9 @@ WebInspector.NetworkDataGridNode.prototype = {
this._linkifier.reset();
},
+ /**
+ * @return {boolean}
+ */
isFilteredOut: function()
{
return !!this._parentView._filteredOutRequests.get(this._request);
@@ -2139,19 +2547,14 @@ WebInspector.NetworkDataGridNode.prototype = {
return this._parentView._allowRequestSelection && !this.isFilteredOut();
},
- _createDivInTD: function(columnIdentifier)
- {
- var td = this.createTD(columnIdentifier);
- var div = td.createChild("div");
- this._element.appendChild(td);
- return div;
- },
-
/**
* @param {!Element} cell
*/
_createTimelineBar: function(cell)
{
+ cell = cell.createChild("div");
+ this._timelineCell = cell;
+
cell.className = "network-graph-side";
this._barAreaElement = document.createElement("div");
@@ -2180,54 +2583,22 @@ WebInspector.NetworkDataGridNode.prototype = {
cell.addEventListener("mouseover", this._refreshLabelPositions.bind(this), false);
},
- refreshRequest: function()
- {
- this._refreshNameCell();
- this._refreshMethodCell();
- this._refreshStatusCell();
- this._refreshSchemeCell();
- this._refreshDomainCell();
- this._refreshTypeCell();
- this._refreshInitiatorCell();
- this._refreshCookiesCell();
- this._refreshSetCookiesCell();
- this._refreshSizeCell();
- this._refreshTimeCell();
-
- var responseHeaderColumns = WebInspector.NetworkLogView._responseHeaderColumns;
- for (var i = 0; i < responseHeaderColumns.length; ++i)
- this._refreshResponseHeaderCell(responseHeaderColumns[i]);
-
- if (this._request.cached)
- this._timelineCell.classList.add("resource-cached");
-
- this._element.classList.add("network-item");
- this._element.enableStyleClass("network-error-row", this._request.failed || (this._request.statusCode >= 400));
- this._updateElementStyleClasses(this._element);
- },
-
/**
- * @param {!Element} element
+ * @return {boolean}
*/
- _updateElementStyleClasses: function(element)
- {
- var typeClassName = "network-type-" + this._request.type.name();
- if (!element.classList.contains(typeClassName)) {
- element.removeMatchingStyleClasses("network-type-\\w+");
- element.classList.add(typeClassName);
- }
- },
-
- _refreshResponseHeaderCell: function(headerName)
+ _isFailed: function()
{
- var cell = this._responseHeaderCells[headerName];
- var value = this._request.responseHeaderValue(headerName);
- cell.setTextAndTitle(value ? value : "");
+ return !!this._request.failed || (this._request.statusCode >= 400);
},
- _refreshNameCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderNameCell: function(cell)
{
- this._nameCell.removeChildren();
+ this._nameCell = cell;
+ cell.addEventListener("click", this._onClick.bind(this), false);
+ cell.addEventListener("dblclick", this._openInNewTab.bind(this), false);
if (this._request.type === WebInspector.resourceTypes.Image) {
var previewImage = document.createElement("img");
@@ -2241,151 +2612,123 @@ WebInspector.NetworkDataGridNode.prototype = {
var iconElement = document.createElement("img");
iconElement.className = "icon";
}
- this._nameCell.appendChild(iconElement);
- this._nameCell.appendChild(document.createTextNode(this._request.name()));
- this._appendSubtitle(this._nameCell, this._request.path());
- this._nameCell.title = this._request.url;
- },
-
- _refreshMethodCell: function()
- {
- this._methodCell.setTextAndTitle(this._request.requestMethod);
+ cell.appendChild(iconElement);
+ cell.appendChild(document.createTextNode(this._request.name()));
+ this._appendSubtitle(cell, this._request.path());
+ cell.title = this._request.url;
},
- _refreshStatusCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderStatusCell: function(cell)
{
- this._statusCell.removeChildren();
+ cell.classList.toggle("network-dim-cell", !this._isFailed() && (this._request.cached || !this._request.statusCode));
- if (this._request.failed) {
- var failText = this._request.canceled ? WebInspector.UIString("(canceled)") : WebInspector.UIString("(failed)");
+ if (this._request.failed && !this._request.canceled) {
+ var failText = WebInspector.UIString("(failed)");
if (this._request.localizedFailDescription) {
- this._statusCell.appendChild(document.createTextNode(failText));
- this._appendSubtitle(this._statusCell, this._request.localizedFailDescription);
- this._statusCell.title = failText + " " + this._request.localizedFailDescription;
+ cell.appendChild(document.createTextNode(failText));
+ this._appendSubtitle(cell, this._request.localizedFailDescription);
+ cell.title = failText + " " + this._request.localizedFailDescription;
} else
- this._statusCell.setTextAndTitle(failText);
- this._statusCell.classList.add("network-dim-cell");
- return;
- }
-
- this._statusCell.classList.remove("network-dim-cell");
-
- if (this._request.statusCode) {
- this._statusCell.appendChild(document.createTextNode("" + this._request.statusCode));
- this._appendSubtitle(this._statusCell, this._request.statusText);
- this._statusCell.title = this._request.statusCode + " " + this._request.statusText;
- if (this._request.cached)
- this._statusCell.classList.add("network-dim-cell");
+ cell.setTextAndTitle(failText);
+ } else if (this._request.statusCode) {
+ cell.appendChild(document.createTextNode("" + this._request.statusCode));
+ this._appendSubtitle(cell, this._request.statusText);
+ cell.title = this._request.statusCode + " " + this._request.statusText;
+ } else if (this._request.parsedURL.isDataURL()) {
+ cell.setTextAndTitle(WebInspector.UIString("(data)"));
+ } else if (this._request.isPingRequest()) {
+ cell.setTextAndTitle(WebInspector.UIString("(ping)"));
+ } else if (this._request.canceled) {
+ cell.setTextAndTitle(WebInspector.UIString("(canceled)"));
+ } else if (this._request.finished) {
+ cell.setTextAndTitle(WebInspector.UIString("Finished"));
} else {
- if (this._request.parsedURL.isDataURL())
- this._statusCell.setTextAndTitle(WebInspector.UIString("(data)"));
- else if (this._request.isPingRequest())
- this._statusCell.setTextAndTitle(WebInspector.UIString("(ping)"));
- else if (this._request.finished)
- this._statusCell.setTextAndTitle(WebInspector.UIString("Finished"));
- else
- this._statusCell.setTextAndTitle(WebInspector.UIString("(pending)"));
- this._statusCell.classList.add("network-dim-cell");
+ cell.setTextAndTitle(WebInspector.UIString("(pending)"));
}
},
- _refreshSchemeCell: function()
- {
- this._schemeCell.setTextAndTitle(this._request.scheme);
- },
-
- _refreshDomainCell: function()
- {
- this._domainCell.setTextAndTitle(this._request.domain);
- },
-
- _refreshTypeCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderTypeCell: function(cell)
{
if (this._request.mimeType) {
- this._typeCell.classList.remove("network-dim-cell");
- this._typeCell.setTextAndTitle(this._request.mimeType);
+ cell.setTextAndTitle(this._request.mimeType);
} else {
- this._typeCell.enableStyleClass("network-dim-cell", !this._request.isPingRequest());
- this._typeCell.setTextAndTitle(this._request.requestContentType() || "");
+ cell.classList.toggle("network-dim-cell", !this._request.isPingRequest());
+ cell.setTextAndTitle(this._request.requestContentType() || "");
}
},
- _refreshInitiatorCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderInitiatorCell: function(cell)
{
- this._initiatorCell.removeChildren();
- this._initiatorCell.classList.remove("network-dim-cell");
- this._initiatorCell.classList.remove("network-script-initiated");
- delete this._initiatorCell.request;
-
var request = this._request;
var initiator = request.initiatorInfo();
switch (initiator.type) {
case WebInspector.NetworkRequest.InitiatorType.Parser:
- this._initiatorCell.title = initiator.url + ":" + initiator.lineNumber;
- this._initiatorCell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url, initiator.lineNumber - 1));
- this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Parser"));
+ cell.title = initiator.url + ":" + initiator.lineNumber;
+ cell.appendChild(WebInspector.linkifyResourceAsNode(initiator.url, initiator.lineNumber - 1));
+ this._appendSubtitle(cell, WebInspector.UIString("Parser"));
break;
case WebInspector.NetworkRequest.InitiatorType.Redirect:
- this._initiatorCell.title = initiator.url;
+ cell.title = initiator.url;
console.assert(request.redirectSource);
var redirectSource = /** @type {!WebInspector.NetworkRequest} */ (request.redirectSource);
- this._initiatorCell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));
- this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Redirect"));
+ cell.appendChild(WebInspector.linkifyRequestAsNode(redirectSource));
+ this._appendSubtitle(cell, WebInspector.UIString("Redirect"));
break;
case WebInspector.NetworkRequest.InitiatorType.Script:
- var urlElement = this._linkifier.linkifyLocation(initiator.url, initiator.lineNumber - 1, initiator.columnNumber - 1);
+ var urlElement = this._linkifier.linkifyLocation(request.target(), initiator.url, initiator.lineNumber - 1, initiator.columnNumber - 1);
urlElement.title = "";
- this._initiatorCell.appendChild(urlElement);
- this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Script"));
- this._initiatorCell.classList.add("network-script-initiated");
- this._initiatorCell.request = request;
+ cell.appendChild(urlElement);
+ this._appendSubtitle(cell, WebInspector.UIString("Script"));
+ cell.classList.add("network-script-initiated");
+ cell.request = request;
break;
default:
- this._initiatorCell.title = "";
- this._initiatorCell.classList.add("network-dim-cell");
- this._initiatorCell.setTextAndTitle(WebInspector.UIString("Other"));
+ cell.title = "";
+ cell.classList.add("network-dim-cell");
+ cell.setTextAndTitle(WebInspector.UIString("Other"));
}
},
- _refreshCookiesCell: function()
- {
- var requestCookies = this._request.requestCookies;
- this._cookiesCell.setTextAndTitle(requestCookies ? "" + requestCookies.length : "");
- },
-
- _refreshSetCookiesCell: function()
- {
- var responseCookies = this._request.responseCookies;
- this._setCookiesCell.setTextAndTitle(responseCookies ? "" + responseCookies.length : "");
- },
-
- _refreshSizeCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderSizeCell: function(cell)
{
if (this._request.cached) {
- this._sizeCell.setTextAndTitle(WebInspector.UIString("(from cache)"));
- this._sizeCell.classList.add("network-dim-cell");
+ cell.setTextAndTitle(WebInspector.UIString("(from cache)"));
+ cell.classList.add("network-dim-cell");
} else {
var resourceSize = Number.bytesToString(this._request.resourceSize);
var transferSize = Number.bytesToString(this._request.transferSize);
- this._sizeCell.setTextAndTitle(transferSize);
- this._sizeCell.classList.remove("network-dim-cell");
- this._appendSubtitle(this._sizeCell, resourceSize);
+ cell.setTextAndTitle(transferSize);
+ this._appendSubtitle(cell, resourceSize);
}
},
- _refreshTimeCell: function()
+ /**
+ * @param {!Element} cell
+ */
+ _renderTimeCell: function(cell)
{
if (this._request.duration > 0) {
- this._timeCell.classList.remove("network-dim-cell");
- this._timeCell.setTextAndTitle(Number.secondsToString(this._request.duration));
- this._appendSubtitle(this._timeCell, Number.secondsToString(this._request.latency));
+ cell.setTextAndTitle(Number.secondsToString(this._request.duration));
+ this._appendSubtitle(cell, Number.secondsToString(this._request.latency));
} else {
- this._timeCell.classList.add("network-dim-cell");
- this._timeCell.setTextAndTitle(WebInspector.UIString("Pending"));
+ cell.classList.add("network-dim-cell");
+ cell.setTextAndTitle(WebInspector.UIString("Pending"));
}
},
@@ -2399,11 +2742,13 @@ WebInspector.NetworkDataGridNode.prototype = {
refreshGraph: function(calculator)
{
+ if (!this._timelineCell)
+ return;
+
var percentages = calculator.computeBarGraphPercentages(this._request);
this._percentages = percentages;
this._barAreaElement.classList.remove("hidden");
- this._updateElementStyleClasses(this._timelineCell);
this._barLeftElement.style.setProperty("left", percentages.start + "%");
this._barRightElement.style.setProperty("right", (100 - percentages.end) + "%");
@@ -2493,6 +2838,11 @@ WebInspector.NetworkDataGridNode.prototype = {
__proto__: WebInspector.DataGridNode.prototype
}
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
{
var aFileName = a._request.name();
@@ -2504,6 +2854,27 @@ WebInspector.NetworkDataGridNode.NameComparator = function(a, b)
return 0;
}
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
+WebInspector.NetworkDataGridNode.RemoteAddressComparator = function(a, b)
+{
+ var aRemoteAddress = a._request.remoteAddress();
+ var bRemoteAddress = b._request.remoteAddress();
+ if (aRemoteAddress > bRemoteAddress)
+ return 1;
+ if (bRemoteAddress > aRemoteAddress)
+ return -1;
+ return 0;
+}
+
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
{
if (b._request.cached && !a._request.cached)
@@ -2514,6 +2885,11 @@ WebInspector.NetworkDataGridNode.SizeComparator = function(a, b)
return a._request.transferSize - b._request.transferSize;
}
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
{
var aInitiator = a._request.initiatorInfo();
@@ -2524,9 +2900,14 @@ WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
if (aInitiator.type > bInitiator.type)
return 1;
- if (aInitiator.source < bInitiator.source)
+ if (typeof aInitiator.__source === "undefined")
+ aInitiator.__source = WebInspector.displayNameForURL(aInitiator.url);
+ if (typeof bInitiator.__source === "undefined")
+ bInitiator.__source = WebInspector.displayNameForURL(bInitiator.url);
+
+ if (aInitiator.__source < bInitiator.__source)
return -1;
- if (aInitiator.source > bInitiator.source)
+ if (aInitiator.__source > bInitiator.__source)
return 1;
if (aInitiator.lineNumber < bInitiator.lineNumber)
@@ -2542,6 +2923,11 @@ WebInspector.NetworkDataGridNode.InitiatorComparator = function(a, b)
return 0;
}
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.RequestCookiesCountComparator = function(a, b)
{
var aScore = a._request.requestCookies ? a._request.requestCookies.length : 0;
@@ -2549,6 +2935,11 @@ WebInspector.NetworkDataGridNode.RequestCookiesCountComparator = function(a, b)
return aScore - bScore;
}
+/**
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator = function(a, b)
{
var aScore = a._request.responseCookies ? a._request.responseCookies.length : 0;
@@ -2556,6 +2947,13 @@ WebInspector.NetworkDataGridNode.ResponseCookiesCountComparator = function(a, b)
return aScore - bScore;
}
+/**
+ * @param {string} propertyName
+ * @param {boolean} revert
+ * @param {!WebInspector.NetworkDataGridNode} a
+ * @param {!WebInspector.NetworkDataGridNode} b
+ * @return {number}
+ */
WebInspector.NetworkDataGridNode.RequestPropertyComparator = function(propertyName, revert, a, b)
{
var aValue = a._request[propertyName];
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestCookiesView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestCookiesView.js
index 72cebb9a3d0..f733811f266 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestCookiesView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestCookiesView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestCookiesView = function(request)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("resource-cookies-view");
this._request = request;
@@ -90,5 +90,5 @@ WebInspector.RequestCookiesView.prototype = {
this._buildCookiesTable();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestHTMLView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js
index 6e7ef883600..5d05e9aa760 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestHTMLView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHTMLView.js
@@ -42,6 +42,9 @@ WebInspector.RequestHTMLView = function(request, dataURL)
}
WebInspector.RequestHTMLView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestHeadersView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHeadersView.js
index cafef5d3910..8ad05d96783 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestHeadersView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestHeadersView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestHeadersView = function(request)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("resourceView.css");
this.element.classList.add("resource-headers-view");
@@ -48,6 +48,11 @@ WebInspector.RequestHeadersView = function(request)
this._headersTreeOutline = new TreeOutline(this._headersListElement);
this._headersTreeOutline.expandTreeElementsWhenArrowing = true;
+ this._remoteAddressTreeElement = new TreeElement("", null, false);
+ this._remoteAddressTreeElement.selectable = false;
+ this._remoteAddressTreeElement.hidden = true;
+ this._headersTreeOutline.appendChild(this._remoteAddressTreeElement);
+
this._urlTreeElement = new TreeElement("", null, false);
this._urlTreeElement.selectable = false;
this._headersTreeOutline.appendChild(this._urlTreeElement);
@@ -98,6 +103,7 @@ WebInspector.RequestHeadersView.prototype = {
wasShown: function()
{
+ this._request.addEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
@@ -107,10 +113,12 @@ WebInspector.RequestHeadersView.prototype = {
this._refreshRequestHeaders();
this._refreshResponseHeaders();
this._refreshHTTPInformation();
+ this._refreshRemoteAddress();
},
willHide: function()
{
+ this._request.removeEventListener(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
@@ -337,12 +345,7 @@ WebInspector.RequestHeadersView.prototype = {
if (this._showRequestHeadersText && headersText)
this._refreshHeadersText(WebInspector.UIString("Request Headers"), headers.length, headersText, treeElement);
else
- this._refreshHeaders(WebInspector.UIString("Request Headers"), headers, treeElement);
-
- if (headersText === undefined) {
- var caution = WebInspector.UIString(" CAUTION: Provisional headers are shown.");
- treeElement.listItemElement.createChild("span", "caution").textContent = caution;
- }
+ this._refreshHeaders(WebInspector.UIString("Request Headers"), headers, treeElement, headersText === undefined);
if (headersText) {
var toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
@@ -394,10 +397,13 @@ WebInspector.RequestHeadersView.prototype = {
requestMethodElement.title = this._formatHeader(WebInspector.UIString("Request Method"), this._request.requestMethod);
- var value = statusCodeFragment.createChild("div", "header-value source-code");
- value.textContent = this._request.statusCode + " " + this._request.statusText;
- if (this._request.cached)
- value.createChild("span", "status-from-cache").textContent = " " + WebInspector.UIString("(from cache)");
+ var statusTextElement = statusCodeFragment.createChild("div", "header-value source-code");
+ var statusText = this._request.statusCode + " " + this._request.statusText;
+ if (this._request.cached) {
+ statusText += " " + WebInspector.UIString("(from cache)");
+ statusTextElement.classList.add("status-from-cache");
+ }
+ statusTextElement.textContent = statusText;
statusCodeElement.title = statusCodeFragment;
}
@@ -421,14 +427,26 @@ WebInspector.RequestHeadersView.prototype = {
* @param {string} title
* @param {!Array.<!WebInspector.NetworkRequest.NameValue>} headers
* @param {!TreeElement} headersTreeElement
+ * @param {boolean=} provisionalHeaders
*/
- _refreshHeaders: function(title, headers, headersTreeElement)
+ _refreshHeaders: function(title, headers, headersTreeElement, provisionalHeaders)
{
headersTreeElement.removeChildren();
var length = headers.length;
this._refreshHeadersTitle(title, headersTreeElement, length);
- headersTreeElement.hidden = !length;
+
+ if (provisionalHeaders) {
+ var cautionText = WebInspector.UIString("Provisional headers are shown");
+ var cautionFragment = document.createDocumentFragment();
+ cautionFragment.createChild("div", "warning-icon-small");
+ cautionFragment.createChild("div", "caution").textContent = cautionText;
+ var cautionTreeElement = new TreeElement(cautionFragment);
+ cautionTreeElement.selectable = false;
+ headersTreeElement.appendChild(cautionTreeElement);
+ }
+
+ headersTreeElement.hidden = !length && !provisionalHeaders;
for (var i = 0; i < length; ++i) {
var headerTreeElement = new TreeElement(this._formatHeader(headers[i].name, headers[i].value));
headerTreeElement.selectable = false;
@@ -448,6 +466,15 @@ WebInspector.RequestHeadersView.prototype = {
this._refreshHeadersTitle(title, headersTreeElement, count);
},
+ _refreshRemoteAddress: function()
+ {
+ var remoteAddress = this._request.remoteAddress();
+ var treeElement = this._remoteAddressTreeElement;
+ treeElement.hidden = !remoteAddress;
+ if (remoteAddress)
+ treeElement.title = this._formatHeader(WebInspector.UIString("Remote Address"), remoteAddress);
+ },
+
/**
* @param {?Event} event
*/
@@ -488,5 +515,5 @@ WebInspector.RequestHeadersView.prototype = {
return this._createToggleButton(toggleTitle);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestJSONView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestJSONView.js
index 153d3318cab..02abb036aa9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestJSONView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestJSONView.js
@@ -32,6 +32,7 @@
* @constructor
* @extends {WebInspector.RequestView}
* @param {!WebInspector.NetworkRequest} request
+ * @param {!WebInspector.ParsedJSON} parsedJSON
*/
WebInspector.RequestJSONView = function(request, parsedJSON)
{
@@ -40,6 +41,10 @@ WebInspector.RequestJSONView = function(request, parsedJSON)
this.element.classList.add("json");
}
+/**
+ * @param {string} text
+ * @return {?WebInspector.ParsedJSON}
+ */
WebInspector.RequestJSONView.parseJSON = function(text)
{
var prefix = "";
@@ -54,17 +59,21 @@ WebInspector.RequestJSONView.parseJSON = function(text)
try {
return new WebInspector.ParsedJSON(JSON.parse(text), prefix, "");
} catch (e) {
- return;
+ return null;
}
}
+/**
+ * @param {string} text
+ * @return {?WebInspector.ParsedJSON}
+ */
WebInspector.RequestJSONView.parseJSONP = function(text)
{
// Taking everything between first and last parentheses
var start = text.indexOf("(");
var end = text.lastIndexOf(")");
if (start == -1 || end == -1 || end < start)
- return;
+ return null;
var prefix = text.substring(0, start + 1);
var suffix = text.substring(end);
@@ -73,11 +82,14 @@ WebInspector.RequestJSONView.parseJSONP = function(text)
try {
return new WebInspector.ParsedJSON(JSON.parse(text), prefix, suffix);
} catch (e) {
- return;
+ return null;
}
}
WebInspector.RequestJSONView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestPreviewView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js
index d5237e05bf1..e429b532205 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestPreviewView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestPreviewView.js
@@ -32,6 +32,7 @@
* @constructor
* @extends {WebInspector.RequestContentView}
* @param {!WebInspector.NetworkRequest} request
+ * @param {!WebInspector.View} responseView
*/
WebInspector.RequestPreviewView = function(request, responseView)
{
@@ -42,7 +43,7 @@ WebInspector.RequestPreviewView = function(request, responseView)
WebInspector.RequestPreviewView.prototype = {
contentLoaded: function()
{
- if (!this.request.content) {
+ if (!this.request.content && !this.request.contentError()) {
if (!this._emptyView) {
this._emptyView = this._createEmptyView();
this._emptyView.show(this.element);
@@ -63,7 +64,16 @@ WebInspector.RequestPreviewView.prototype = {
_createEmptyView: function()
{
- return new WebInspector.EmptyView(WebInspector.UIString("This request has no preview available."));
+ return this._createMessageView(WebInspector.UIString("This request has no preview available."));
+ },
+
+ /**
+ * @param {string} message
+ * @return {!WebInspector.EmptyView}
+ */
+ _createMessageView: function(message)
+ {
+ return new WebInspector.EmptyView(message);
},
_jsonView: function()
@@ -73,39 +83,47 @@ WebInspector.RequestPreviewView.prototype = {
return new WebInspector.RequestJSONView(this.request, parsedJSON);
},
- _htmlView: function()
+ /**
+ * @return {?WebInspector.RequestHTMLView}
+ */
+ _htmlErrorPreview: function()
{
+ var whitelist = ["text/html", "text/plain", "application/xhtml+xml"];
+ if (whitelist.indexOf(this.request.mimeType) === -1)
+ return null;
+
var dataURL = this.request.asDataURL();
- if (dataURL !== null)
- return new WebInspector.RequestHTMLView(this.request, dataURL);
+ if (dataURL === null)
+ return null;
+
+ return new WebInspector.RequestHTMLView(this.request, dataURL);
},
_createPreviewView: function()
{
- if (this.request.content) {
- if (this.request.mimeType === "application/json") {
- var jsonView = this._jsonView();
- if (jsonView)
- return jsonView;
- }
+ if (this.request.contentError())
+ return this._createMessageView(WebInspector.UIString("Failed to load response data"));
- if (this.request.hasErrorStatusCode()) {
- var htmlView = this._htmlView();
- if (htmlView)
- return htmlView;
- }
+ var mimeType = this.request.mimeType || "";
+ if (mimeType === "application/json" || mimeType.endsWith("+json")) {
+ var jsonView = this._jsonView();
+ if (jsonView)
+ return jsonView;
+ }
- if (this.request.type === WebInspector.resourceTypes.XHR) {
- var jsonView = this._jsonView();
- if (jsonView)
- return jsonView;
- }
+ if (this.request.hasErrorStatusCode()) {
+ var htmlErrorPreview = this._htmlErrorPreview();
+ if (htmlErrorPreview)
+ return htmlErrorPreview;
+ }
- if (this.request.type === WebInspector.resourceTypes.XHR && this.request.mimeType === "text/html") {
- var htmlView = this._htmlView();
- if (htmlView)
- return htmlView;
- }
+ if (this.request.type === WebInspector.resourceTypes.XHR) {
+ var jsonView = this._jsonView();
+ if (jsonView)
+ return jsonView;
+ var htmlErrorPreview = this._htmlErrorPreview();
+ if (htmlErrorPreview)
+ return htmlErrorPreview;
}
if (this._responseView.sourceView)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestResponseView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js
index fa42fdaf530..af7a3384b58 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestResponseView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestResponseView.js
@@ -57,11 +57,20 @@ WebInspector.RequestResponseView.prototype = {
return this._sourceView;
},
+ /**
+ * @param {string} message
+ * @return {!WebInspector.EmptyView}
+ */
+ _createMessageView: function(message)
+ {
+ return new WebInspector.EmptyView(message);
+ },
+
contentLoaded: function()
{
- if (!this.request.content || !this.sourceView) {
+ if ((!this.request.content || !this.sourceView) && !this.request.contentError()) {
if (!this._emptyView) {
- this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This request has no response data available."));
+ this._emptyView = this._createMessageView(WebInspector.UIString("This request has no response data available."));
this._emptyView.show(this.element);
this.innerView = this._emptyView;
}
@@ -71,8 +80,15 @@ WebInspector.RequestResponseView.prototype = {
delete this._emptyView;
}
- this.sourceView.show(this.element);
- this.innerView = this.sourceView;
+ if (this.request.content && this.sourceView) {
+ this.sourceView.show(this.element);
+ this.innerView = this.sourceView;
+ } else {
+ if (!this._errorView)
+ this._errorView = this._createMessageView(WebInspector.UIString("Failed to load response data"));
+ this._errorView.show(this.element);
+ this.innerView = this._errorView;
+ }
}
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestTimingView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
index 566259686dd..b2b491ed6f0 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestTimingView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestTimingView = function(request)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("resource-timing-view");
this._request = request;
@@ -45,6 +45,7 @@ WebInspector.RequestTimingView.prototype = {
wasShown: function()
{
this._request.addEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this);
+ this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this);
if (!this._request.timing) {
if (!this._emptyView) {
@@ -66,6 +67,7 @@ WebInspector.RequestTimingView.prototype = {
willHide: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.TimingChanged, this._refresh, this);
+ this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._refresh, this);
},
_refresh: function()
@@ -77,10 +79,14 @@ WebInspector.RequestTimingView.prototype = {
this.element.appendChild(this._tableElement);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
+/**
+ * @param {!WebInspector.NetworkRequest} request
+ * @return {!Element}
+ */
WebInspector.RequestTimingView.createTimingTable = function(request)
{
var tableElement = document.createElement("table");
@@ -97,8 +103,20 @@ WebInspector.RequestTimingView.createTimingTable = function(request)
rows.push(row);
}
+ function firstPositive(numbers)
+ {
+ for (var i = 0; i < numbers.length; ++i) {
+ if (numbers[i] > 0)
+ return numbers[i];
+ }
+ return undefined;
+ }
+
var timing = request.timing;
- var blocking = timing.dnsStart > 0 ? timing.dnsStart : timing.connectStart > 0 ? timing.connectStart : timing.sendStart;
+ var blocking = firstPositive([timing.dnsStart, timing.connectStart, timing.sendStart]);
+ var endTime = firstPositive([request.endTime, request.responseReceivedTime, timing.requestTime]);
+ var total = (endTime - timing.requestTime) * 1000;
+
if (blocking > 0)
addRow(WebInspector.UIString("Blocking"), "blocking", 0, blocking);
@@ -116,10 +134,11 @@ WebInspector.RequestTimingView.createTimingTable = function(request)
addRow(WebInspector.UIString("Sending"), "sending", timing.sendStart, timing.sendEnd);
addRow(WebInspector.UIString("Waiting"), "waiting", timing.sendEnd, timing.receiveHeadersEnd);
- addRow(WebInspector.UIString("Receiving"), "receiving", (request.responseReceivedTime - timing.requestTime) * 1000, (request.endTime - timing.requestTime) * 1000);
+
+ if (request.endTime !== -1)
+ addRow(WebInspector.UIString("Receiving"), "receiving", (request.responseReceivedTime - timing.requestTime) * 1000, total);
const chartWidth = 200;
- var total = (request.endTime - timing.requestTime) * 1000;
var scale = chartWidth / total;
for (var i = 0; i < rows.length; ++i) {
@@ -156,5 +175,12 @@ WebInspector.RequestTimingView.createTimingTable = function(request)
tr.appendChild(td);
}
+
+ if (!request.finished) {
+ var cell = tableElement.createChild("tr").createChild("td", "caution");
+ cell.colSpan = 2;
+ cell.createTextChild(WebInspector.UIString("CAUTION: request is not finished yet!"));
+ }
+
return tableElement;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RequestView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestView.js
index da132942507..398931640f6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RequestView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/RequestView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.NetworkRequest} request
*/
WebInspector.RequestView = function(request)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("resourceView.css");
this.element.classList.add("resource-view");
@@ -43,28 +43,33 @@ WebInspector.RequestView = function(request)
}
WebInspector.RequestView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return false;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
* @param {!WebInspector.NetworkRequest} request
+ * @return {boolean}
*/
WebInspector.RequestView.hasTextContent = function(request)
{
if (request.type.isTextType())
- return true;
+ return true;
if (request.type === WebInspector.resourceTypes.Other || request.hasErrorStatusCode())
- return request.content && !request.contentEncoded;
+ return !!request.content && !request.contentEncoded;
return false;
}
/**
* @param {!WebInspector.NetworkRequest} request
+ * @return {!WebInspector.View}
*/
WebInspector.RequestView.nonSourceViewForRequest = function(request)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceWebSocketFrameView.js b/chromium/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
index 231a88b2a1d..7ec940bbcd4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceWebSocketFrameView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/ResourceWebSocketFrameView.js
@@ -18,11 +18,11 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.ResourceWebSocketFrameView = function(resource)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("resource-websocket");
this.resource = resource;
this.element.removeChildren();
@@ -130,5 +130,5 @@ WebInspector.ResourceWebSocketFrameView.prototype = {
InspectorFrontendHost.copyText(row.data);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/network/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/network/module.json
new file mode 100644
index 00000000000..2820a5debb1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/network/module.json
@@ -0,0 +1,23 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "network",
+ "title": "Network",
+ "order": 1,
+ "className": "WebInspector.NetworkPanel"
+ },
+ {
+ "type": "@WebInspector.ContextMenu.Provider",
+ "contextTypes": ["WebInspector.NetworkRequest", "WebInspector.Resource", "WebInspector.UISourceCode"],
+ "className": "WebInspector.NetworkPanel.ContextMenuProvider"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.NetworkRequest"],
+ "className": "WebInspector.NetworkPanel.RequestRevealer"
+ }
+ ],
+ "dependencies": [ "source_frame" ],
+ "scripts": [ "NetworkPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/networkLogView.css b/chromium/third_party/WebKit/Source/devtools/front_end/networkLogView.css
index c34afbc812f..d9f2784dd6e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/networkLogView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/networkLogView.css
@@ -49,12 +49,12 @@
}
.network-log-grid.data-grid table.data {
- background-size: 1px 82px;
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0)), color-stop(0.5, rgba(0, 0, 0, 0.05)), to(rgba(0, 0, 0, 0.05)));
+ background-size: 128px 82px;
+ background-image: linear-gradient(to bottom, white, white 50%, #eee 50%, #eee);
}
.network-log-grid.data-grid.small table.data {
- background-size: 1px 42px;
+ background-size: 128px 42px;
}
.network-log-grid.data-grid td {
@@ -100,14 +100,6 @@
color: inherit;
}
-.network-log-grid.data-grid.small tr.offscreen {
- height: 21px;
-}
-
-.network-log-grid.data-grid tr.offscreen {
- height: 41px;
-}
-
.network-log-grid.data-grid tr.offscreen > td > div {
display: none;
}
@@ -202,6 +194,21 @@
content: url(Images/resourceDocumentIconSmall.png);
}
+.network-log-grid.data-grid .network-type-media .icon {
+ content: url(Images/resourcePlainIcon.png); // FIXME: media icon
+}
+
+.network-log-grid.data-grid.small .network-type-media .icon {
+ content: url(Images/resourcePlainIconSmall.png); // FIXME: media icon
+}
+.network-log-grid.data-grid .network-type-texttrack .icon {
+ content: url(Images/resourcePlainIcon.png); // FIXME: vtt icon
+}
+
+.network-log-grid.data-grid.small .network-type-texttrack .icon {
+ content: url(Images/resourcePlainIconSmall.png); // FIXME: vtt icon
+}
+
.network-log-grid.data-grid .network-type-image .icon {
position: relative;
background-image: url(Images/resourcePlainIcon.png);
@@ -222,10 +229,6 @@
margin-right: 3px;
}
-.network-log-grid.data-grid th {
- border-bottom: 1px solid rgb(205,205,205) !important;
-}
-
.network-log-grid.data-grid.small .icon {
width: 16px;
height: 16px;
@@ -292,12 +295,11 @@
z-index: 150;
overflow: hidden;
text-align: center;
- opacity: 0;
- -webkit-transition: opacity 250ms ease-in-out;
+ visibility: hidden;
}
.network-graph-side:hover .network-graph-label {
- opacity: 1;
+ visibility: visible;
}
.network-graph-label:empty {
@@ -343,11 +345,16 @@
top: 0;
bottom: 0;
margin: auto -7px;
- border-width: 6px 7px;
- height: 0;
+ height: 12px;
min-width: 14px;
opacity: 0.65;
- -webkit-border-image: url(Images/timelinePillGray.png) 7 7 7 7;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 7px / 6px;
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8);
+
+ border-color: hsl(0, 0%, 65%);
+ background: linear-gradient(0deg, hsl(0, 0%, 73%), hsl(0, 0%, 78%));
}
.network-graph-bar.waiting,
@@ -359,63 +366,118 @@
.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillGray.png) 7 7 7 7;
+ background: hsl(0, 0%, 90%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(0, 0%, 73%),
+ inset 0 1px 0 2px hsla(0, 0%, 76%, 0.85);
}
.network-type-document .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillBlue.png) 7 7 7 7;
+ border-color: hsl(215, 49%, 52%);
+ background: linear-gradient(0deg, hsl(215, 72%, 61%), hsl(215, 100%, 69%));
}
.network-type-document.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillBlue.png) 7 7 7 7;
+ background: hsl(215, 99%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(215, 71%, 61%),
+ inset 0 1px 0 2px hsla(215, 58%, 65%, 0.85);
}
.network-type-stylesheet .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillGreen.png) 7 7 7 7;
+ border-color: hsl(99, 34%, 52%);
+ background: linear-gradient(0deg, hsl(100, 50%, 61%), hsl(90, 50%, 64%));
}
.network-type-stylesheet.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillGreen.png) 7 7 7 7;
+ background: hsl(99, 100%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(99, 72%, 61%),
+ inset 0 1px 0 2px hsla(99, 59%, 65%, 0.85);
}
.network-type-image .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillPurple.png) 6 7 6 7;
+ border-color: hsl(272, 31%, 52%);
+ background: linear-gradient(0deg, hsl(272, 46%, 61%), hsl(272, 64%, 69%));
}
.network-type-image.resource-cached .network-graph-bar {
- border-image: url(Images/timelineHollowPillPurple.png) 7 7 7 7;
+ background: hsl(272, 65%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(272, 47%, 61%),
+ inset 0 1px 0 2px hsla(273, 38%, 65%, 0.85);
+}
+
+.network-type-media .network-graph-bar {
+ border-color: hsl(272, 31%, 52%);
+ background: linear-gradient(0deg, hsl(272, 46%, 61%), hsl(272, 64%, 69%));
+}
+
+.network-type-media.resource-cached .network-graph-bar {
+ background: hsl(272, 65%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(272, 47%, 61%),
+ inset 0 1px 0 2px hsla(273, 38%, 65%, 0.85);
}
.network-type-font .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillRed.png) 7 7 7 7;
+ border-color: hsl(8, 49%, 52%);
+ background: linear-gradient(0deg, hsl(8, 72%, 61%), hsl(8, 100%, 69%));
}
.network-type-font.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillRed.png) 7 7 7 7;
+ background: hsl(8, 100%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(8, 72%, 61%),
+ inset 0 1px 0 2px hsla(8, 59%, 65%, 0.85);
+}
+
+.network-type-texttrack .network-graph-bar {
+ border-color: hsl(8, 49%, 52%);
+ background: linear-gradient(0deg, hsl(8, 72%, 61%), hsl(8, 100%, 69%));
+}
+
+.network-type-texttrack.resource-cached .network-graph-bar {
+ background: hsl(8, 100%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(8, 72%, 61%),
+ inset 0 1px 0 2px hsla(8, 59%, 65%, 0.85);
}
.network-type-script .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillOrange.png) 7 7 7 7;
+ border-color: hsl(31, 49%, 52%);
+ background: linear-gradient(0deg, hsl(31, 72%, 61%), hsl(31, 100%, 69%));
}
.network-type-script.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillOrange.png) 7 7 7 7;
+ background: hsl(31, 100%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(31, 78%, 61%),
+ inset 0 1px 0 2px hsla(31, 64%, 65%, 0.85);
}
.network-type-xhr .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillYellow.png) 7 7 7 7;
+ border-color: hsl(53, 49%, 52%);
+ background: linear-gradient(0deg, hsl(53, 72%, 61%), hsl(53, 100%, 69%));
}
.network-type-xhr.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillYellow.png) 7 7 7 7;
+ background: hsl(53, 100%, 86%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(53, 72%, 61%),
+ inset 0 1px 0 2px hsla(54, 59%, 65%, 0.85);
}
.network-type-websocket .network-graph-bar {
- -webkit-border-image: url(Images/timelinePillGray.png) 7 7 7 7;
+ border-color: hsl(0, 0%, 65%);
+ background: linear-gradient(0deg, hsl(0, 0%, 73%), hsl(0, 0%, 78%));
}
.network-type-websocket.resource-cached .network-graph-bar {
- -webkit-border-image: url(Images/timelineHollowPillGray.png) 7 7 7 7;
+ background: hsl(0, 0%, 90%);
+ box-shadow: inset 0 1px 1px 0px rgba(255, 255, 255, 0.8),
+ inset 0 0 0 2px hsl(0, 0%, 73%),
+ inset 0 1px 0 2px hsla(0, 0%, 76%, 0.85);
}
.network-dim-cell {
@@ -504,16 +566,10 @@
/* Filters */
-.network-log-grid.data-grid table.data tr.revealed.network-item.filtered-out {
+.network-log-grid.data-grid table.data tr.revealed.filtered-out {
display: none;
}
-/* Summary */
-
-.network-log-grid.data-grid tr.filler td {
- padding-bottom: 20px !important;
-}
-
#network-container {
overflow-y: auto;
overflow-x: hidden;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/networkPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/networkPanel.css
index e52a63b8dc0..00fbdf1cea1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/networkPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/networkPanel.css
@@ -47,7 +47,7 @@
top: 4px;
}
-.network.panel.viewing-resource #network-close-button {
+.network.panel.viewing-resource #network-close-button {
display: block;
}
@@ -85,12 +85,7 @@
.network-item-view {
display: none;
- position: absolute;
background: white;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
}
.network-item-view.visible {
@@ -130,12 +125,10 @@
white-space: nowrap;
}
-.resource-headers-view .outline-disclosure li.expanded .caution {
- color: rgb(255, 128, 0);
-}
-
-.resource-headers-view .outline-disclosure li:not(.expanded) .caution {
- display: none;
+.resource-headers-view .outline-disclosure .caution {
+ margin-left: 4px;
+ display: inline-block;
+ font-weight: bold;
}
.resource-headers-view .outline-disclosure li.expanded .header-count {
@@ -173,7 +166,7 @@
.resource-headers-view .outline-disclosure .header-value {
display: inline;
- margin-right: 100px;
+ margin-right: 1em;
white-space: pre-wrap;
word-break: break-all;
margin-top: 1px;
@@ -192,10 +185,11 @@
}
.resource-cookies-view.visible {
- display: block;
+ display: flex;
}
.resource-cookies-view .data-grid {
+ flex: auto;
height: 100%;
}
@@ -227,33 +221,33 @@
.resource-timing-view .network-timing-bar.blocking,
.resource-timing-view .network-timing-bar.proxy {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(242, 242, 194)), to(rgb(204, 204, 102)));
+ background-image: linear-gradient(to bottom, rgb(242, 242, 194), rgb(204, 204, 102));
border-left: 1px solid rgb(204, 204, 102);
}
.resource-timing-view .network-timing-bar.dns {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 242, 194)), to(rgb(102, 204, 102)));
+ background-image: linear-gradient(to bottom, rgb(194, 242, 194), rgb(102, 204, 102));
border-left: 1px solid rgb(102, 204, 102);
}
.resource-timing-view .network-timing-bar.connecting,
.resource-timing-view .network-timing-bar.ssl {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 242, 242)), to(rgb(102, 204, 204)));
+ background-image: linear-gradient(to bottom, rgb(194, 242, 242), rgb(102, 204, 204));
border-left: 1px solid rgb(102, 204, 204);
}
.resource-timing-view .network-timing-bar.sending {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 242)), to(rgb(102, 102, 204)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 242), rgb(102, 102, 204));
border-left: 1px solid rgb(102, 102, 204);
}
.resource-timing-view .network-timing-bar.waiting {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(242, 194, 242)), to(rgb(204, 102, 204)));
+ background-image: linear-gradient(to bottom, rgb(242, 194, 242), rgb(204, 102, 204));
border-left: 1px solid rgb(204, 102, 204);
}
.resource-timing-view .network-timing-bar.receiving {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(242, 194, 194)), to(rgb(204, 102, 102)));
+ background-image: linear-gradient(to bottom, rgb(242, 194, 194), rgb(204, 102, 102));
border-left: 1px solid rgb(204, 102, 102);
}
@@ -285,12 +279,6 @@
border-top: 1px solid rgb(240, 240, 240);
}
-.resource-websocket .data-column div {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
.resource-websocket-row-outcoming {
background-color: rgb(226, 247, 218);
}
@@ -328,4 +316,5 @@
.network-filters-header {
flex: 0 0 23px;
+ padding-right: 4px;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/overrides.css b/chromium/third_party/WebKit/Source/devtools/front_end/overrides.css
index 993ad439ae2..8432accdd3b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/overrides.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/overrides.css
@@ -30,7 +30,7 @@
.overrides-view .tabbed-pane {
- flex-direction: row;
+ flex-direction: row !important;
}
.overrides-view .tabbed-pane-header {
@@ -66,7 +66,7 @@
height: 22px;
padding-left: 0;
padding-left: 10px;
- border-left: 4px solid transparent;
+ border-left: 8px solid transparent;
}
.overrides-view .tabbed-pane-header-tab:not(.selected) {
@@ -76,7 +76,7 @@
.overrides-view .tabbed-pane-header-tab.selected {
color: inherit;
border: none transparent;
- border-left: 4px solid #666;
+ border-left: 8px solid #666;
}
.overrides-view fieldset {
@@ -84,18 +84,70 @@
padding: 0 0 5px 15px;
}
-.overrides-user-agent fieldset {
+.overrides-view fieldset p {
+ display: inline-block;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+.overrides-view fieldset p label {
+ display: inline-block;
+}
+
+.overrides-view .field-error-message {
+ display: none;
+}
+
+.overrides-view input[type='text']:focus::-webkit-input-placeholder {
+ color: transparent !important;
+}
+
+/* Network tab */
+
+.overrides-network fieldset {
padding-top: 5px;
}
+.overrides-network fieldset p {
+ width: 100%;
+ margin-left: 2px;
+}
+
+.overrides-network fieldset select {
+ margin-bottom: 5px;
+}
+
+.overrides-network fieldset p label {
+ cursor: default;
+ margin-right: 5px;
+}
+
+.overrides-network fieldset input[type='text'] {
+ width: 100%;
+ max-width: 400px;
+ min-width: 120px;
+ margin-left: 2px;
+}
+
+/* Device tab */
+
+.overrides-device {
+ width: 100%;
+}
+
.overrides-device > select {
margin-bottom: 10px;
width: 400px;
max-width: 90%;
}
-.overrides-device button {
- margin-right: 10px;
+.overrides-device input {
+ text-align: right;
+}
+
+.overrides-device input[type=range] {
+ width: 100%;
}
.overrides-device > label {
@@ -113,73 +165,83 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
- padding-top: 3px;
-}
-
-.overrides-viewport {
- width: 100%;
-}
-
-.overrides-viewport input {
- text-align: right;
-}
-
-.overrides-viewport input[type=range] {
- width: 100%;
+ margin-top: 10px;
}
button.overrides-swap {
height: 20px;
}
-.overrides-viewport label {
- display: block;
- margin-bottom: 5px;
+.overrides-device label {
+ margin-bottom: 10px;
}
-.overrides-viewport table {
+.overrides-device table {
margin-bottom: 5px;
}
-.overrides-viewport > label {
- margin-bottom: 8px;
+.overrides-device > label {
+ margin-bottom: 4px;
}
-.overrides-viewport .help-footnote {
+.overrides-device .help-footnote {
border-top: 1px solid #EEEEEE;
margin: 0;
padding: 12px;
}
-.overrides-user-agent input[type=text] {
- width: 400px;
- max-width: 90%;
+.overrides-view label {
+ display: flex;
+ height: auto;
+}
+
+#metrics-override-section > span {
+ padding: 0 10px 0 3px;
}
-.overrides-user-agent select {
- margin: 7px 0;
+#metrics-override-section > select {
+ width: 244px;
}
+/* Media tab */
+
+.overrides-media > label {
+ margin-bottom: 4px;
+}
+
+/* Sensors tab */
+
.overrides-sensors > label {
- display: block;
margin-bottom: 10px;
}
+.overrides-device, .overrides-media, .overrides-network, .overrides-sensors {
+ flex: none !important;
+}
+
.overrides-sensors input {
text-align: right;
}
.overrides-activate-device #tab-device,
-.overrides-activate-viewport #tab-viewport,
-.overrides-activate-user-agent #tab-user-agent,
+.overrides-activate-media #tab-media,
+.overrides-activate-network #tab-network,
.overrides-activate-sensors #tab-sensors {
- color: rgb(25, 100, 228);
opacity: 0.8;
}
+.overrides-activate-device #tab-device .tabbed-pane-header-tab-title::after,
+.overrides-activate-media #tab-media .tabbed-pane-header-tab-title::after,
+.overrides-activate-network #tab-network .tabbed-pane-header-tab-title::after,
+.overrides-activate-sensors #tab-sensors .tabbed-pane-header-tab-title::after {
+ padding-left: 3px;
+ content: "\2713";
+ color: rgb(25, 100, 228);
+}
+
.overrides-activate-device #tab-device.selected,
-.overrides-activate-viewport #tab-viewport.selected,
-.overrides-activate-user-agent #tab-user-agent.selected,
+.overrides-activate-media #tab-media.selected,
+.overrides-activate-network #tab-network.selected,
.overrides-activate-sensors #tab-sensors.selected {
opacity: 1;
}
@@ -207,6 +269,10 @@ button.overrides-swap {
padding: 3px;
}
+.overrides-view input[readonly] {
+ background-color: rgb(235, 235, 228);
+}
+
.overrides-view .overrides-footer {
flex: none;
padding: 0 0 1px 3px;
@@ -216,7 +282,7 @@ button.overrides-swap {
.overrides-view .overrides-footer::before {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
width: 10px;
height: 10px;
content: "";
@@ -227,6 +293,25 @@ button.overrides-swap {
margin-right: 4px;
}
+@media (-webkit-min-device-pixel-ratio: 1.5) {
+.overrides-view .overrides-footer::before {
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
+}
+} /* media */
+
.overrides-view .overrides-footer .warning-icon-small {
margin-right: 3px;
}
+
+.overrides-splash-screen {
+ display: block;
+ padding: 10px 10px;
+}
+
+.overrides-splash-screen > button {
+ margin: -4px 0;
+}
+
+.overrides-reset-button {
+ margin: 9px 0 0 17px;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/panelEnablerView.css b/chromium/third_party/WebKit/Source/devtools/front_end/panelEnablerView.css
index 72743835982..2290ab9c4b5 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/panelEnablerView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/panelEnablerView.css
@@ -90,7 +90,7 @@
color: rgb(6, 6, 6);
border: 1px solid rgb(165, 165, 165);
background-color: rgb(237, 237, 237);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
border-radius: 12px;
-webkit-appearance: none;
}
@@ -100,19 +100,20 @@ body.inactive .panel-enabler-view button:not(.status-bar-item),
color: rgb(130, 130, 130);
border-color: rgb(212, 212, 212);
background-color: rgb(239, 239, 239);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(250, 250, 250)), to(rgb(235, 235, 235)));
+ background-image: linear-gradient(to bottom, rgb(250, 250, 250), rgb(235, 235, 235));
}
.panel-enabler-view button:active:not(.status-bar-item) {
background-color: rgb(215, 215, 215);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
.panel-enabler-view input[type="radio"] {
height: 17px;
width: 17px;
+ min-width: 17px;
border: 1px solid rgb(165, 165, 165);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ background-image: linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
border-radius: 8px;
-webkit-appearance: none;
vertical-align: middle;
@@ -120,15 +121,15 @@ body.inactive .panel-enabler-view button:not(.status-bar-item),
}
.panel-enabler-view input[type="radio"]:active:not(:disabled) {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ background-image: linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
.panel-enabler-view input[type="radio"]:checked {
background: url(Images/radioDot.png) center no-repeat,
- -webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)));
+ linear-gradient(to bottom, rgb(252, 252, 252), rgb(223, 223, 223));
}
.panel-enabler-view input[type="radio"]:checked:active {
background: url(Images/radioDot.png) center no-repeat,
- -webkit-gradient(linear, left top, left bottom, from(rgb(194, 194, 194)), to(rgb(239, 239, 239)));
+ linear-gradient(to bottom, rgb(194, 194, 194), rgb(239, 239, 239));
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/popover.css b/chromium/third_party/WebKit/Source/devtools/front_end/popover.css
index d0518fca93d..2162d72125a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/popover.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/popover.css
@@ -2,7 +2,7 @@
position: absolute;
-webkit-border-image: url(Images/popoverBackground.png) 25 25 25 25;
border-width: 25px;
- z-index: 100;
+ z-index: 600;
pointer-events: none;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/BottomUpProfileDataGridTree.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileBottomUpDataGrid.js
index 8ee342446c9..5994476145a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/BottomUpProfileDataGridTree.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileBottomUpDataGrid.js
@@ -144,6 +144,9 @@ WebInspector.BottomUpProfileDataGridNode.prototype = {
}
}
+ for (var i = 0; i < this.children.length; ++i)
+ this.children[i].buildData();
+
delete this._remainingNodeInfos;
},
@@ -185,7 +188,7 @@ WebInspector.BottomUpProfileDataGridTree = function(profileView, rootProfileNode
if (!profileNode.UID)
profileNode.UID = ++profileNodeUIDs;
- if (profileNode.head && profileNode !== profileNode.head) {
+ if (profileNode.parent) {
// The total time of this ancestor is accounted for if we're in any form of recursive cycle.
var visitedNodes = visitedProfileNodesForCallUID[profileNode.callUID];
var totalTimeAccountedFor = false;
@@ -283,6 +286,10 @@ WebInspector.BottomUpProfileDataGridTree.prototype = {
this.sort(this.lastComparator, true);
},
+ buildData: function()
+ {
+ },
+
_sharedPopulate: WebInspector.BottomUpProfileDataGridNode.prototype._sharedPopulate,
__proto__: WebInspector.ProfileDataGridTree.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ProfileDataGridTree.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileDataGrid.js
index 4711b8fe374..9fd11dc9135 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ProfileDataGridTree.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileDataGrid.js
@@ -32,6 +32,7 @@
*/
WebInspector.ProfileDataGridNode = function(profileNode, owningTree, hasChildren)
{
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
this.profileNode = profileNode;
WebInspector.DataGridNode.call(this, null, hasChildren);
@@ -50,39 +51,6 @@ WebInspector.ProfileDataGridNode = function(profileNode, owningTree, hasChildren
}
WebInspector.ProfileDataGridNode.prototype = {
- get data()
- {
- function formatMilliseconds(time)
- {
- return WebInspector.UIString("%.1f\u2009ms", time);
- }
-
- var data = {};
-
- if (this._deoptReason) {
- var div = document.createElement("div");
- var marker = div.createChild("span");
- marker.className = "profile-warn-marker";
- marker.title = WebInspector.UIString("Not optimized: %s", this._deoptReason);
- var functionName = div.createChild("span");
- functionName.textContent = this.functionName;
- data["function"] = div;
- } else
- data["function"] = this.functionName;
-
- if (this.tree.profileView.showSelfTimeAsPercent.get())
- data["self"] = WebInspector.UIString("%.2f%", this.selfPercent);
- else
- data["self"] = formatMilliseconds(this.selfTime);
-
- if (this.tree.profileView.showTotalTimeAsPercent.get())
- data["total"] = WebInspector.UIString("%.2f%", this.totalPercent);
- else
- data["total"] = formatMilliseconds(this.totalTime);
-
- return data;
- },
-
/**
* @override
* @param {string} columnIdentifier
@@ -90,7 +58,7 @@ WebInspector.ProfileDataGridNode.prototype = {
*/
createCell: function(columnIdentifier)
{
- var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
+ var cell = this._createValueCell(columnIdentifier) || WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
if (columnIdentifier === "self" && this._searchMatchedSelfColumn)
cell.classList.add("highlight");
@@ -109,10 +77,10 @@ WebInspector.ProfileDataGridNode.prototype = {
if (this.profileNode.scriptId !== "0") {
var lineNumber = this.profileNode.lineNumber ? this.profileNode.lineNumber - 1 : 0;
var columnNumber = this.profileNode.columnNumber ? this.profileNode.columnNumber - 1 : 0;
- var location = new WebInspector.DebuggerModel.Location(this.profileNode.scriptId, lineNumber, columnNumber);
+ var location = new WebInspector.DebuggerModel.Location(/** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget()), this.profileNode.scriptId, lineNumber, columnNumber);
var urlElement = this.tree.profileView._linkifier.linkifyRawLocation(location, "profile-node-file");
if (!urlElement)
- urlElement = this.tree.profileView._linkifier.linkifyLocation(this.profileNode.url, lineNumber, columnNumber, "profile-node-file");
+ urlElement = this.tree.profileView._linkifier.linkifyLocation(this._target, this.profileNode.url, lineNumber, columnNumber, "profile-node-file");
urlElement.style.maxWidth = "75%";
cell.insertBefore(urlElement, cell.firstChild);
}
@@ -120,6 +88,64 @@ WebInspector.ProfileDataGridNode.prototype = {
return cell;
},
+ /**
+ * @param {string} columnIdentifier
+ * @return {?Element}
+ */
+ _createValueCell: function(columnIdentifier)
+ {
+ if (columnIdentifier !== "self" && columnIdentifier !== "total")
+ return null;
+
+ var cell = document.createElement("td");
+ cell.className = "numeric-column";
+ var div = document.createElement("div");
+ var valueSpan = document.createElement("span");
+ valueSpan.textContent = this.data[columnIdentifier];
+ div.appendChild(valueSpan);
+ var percentColumn = columnIdentifier + "-percent";
+ if (percentColumn in this.data) {
+ var percentSpan = document.createElement("span");
+ percentSpan.className = "percent-column";
+ percentSpan.textContent = this.data[percentColumn];
+ div.appendChild(percentSpan);
+ div.classList.add("profile-multiple-values");
+ }
+ cell.appendChild(div);
+ return cell;
+ },
+
+ buildData: function()
+ {
+ function formatMilliseconds(time)
+ {
+ return WebInspector.UIString("%.1f\u2009ms", time);
+ }
+ function formatPercent(value)
+ {
+ return WebInspector.UIString("%.2f\u2009%", value);
+ }
+
+ var functionName;
+ if (this._deoptReason) {
+ var content = document.createDocumentFragment();
+ var marker = content.createChild("span", "profile-warn-marker");
+ marker.title = WebInspector.UIString("Not optimized: %s", this._deoptReason);
+ content.createTextChild(this.functionName);
+ functionName = content;
+ } else {
+ functionName = this.functionName;
+ }
+
+ this.data = {
+ "function": functionName,
+ "self-percent": formatPercent(this.selfPercent),
+ "self": formatMilliseconds(this.selfTime),
+ "total-percent": formatPercent(this.totalPercent),
+ "total": formatMilliseconds(this.totalTime),
+ };
+ },
+
select: function(supressSelectedEvent)
{
WebInspector.DataGridNode.prototype.select.call(this, supressSelectedEvent);
@@ -203,6 +229,7 @@ WebInspector.ProfileDataGridNode.prototype = {
/**
* @param {!WebInspector.ProfileDataGridNode} node
+ * @return {?WebInspector.ProfileDataGridNode}
*/
findChild: function(node)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
new file mode 100644
index 00000000000..7ad221b89ae
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
@@ -0,0 +1,650 @@
+/**
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.FlameChartDataProvider}
+ * @param {!WebInspector.CPUProfileDataModel} cpuProfile
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.CPUFlameChartDataProvider = function(cpuProfile, target)
+{
+ WebInspector.FlameChartDataProvider.call(this);
+ this._cpuProfile = cpuProfile;
+ this._target = target;
+ this._colorGenerator = WebInspector.CPUFlameChartDataProvider.colorGenerator();
+}
+
+WebInspector.CPUFlameChartDataProvider.prototype = {
+ /**
+ * @return {number}
+ */
+ barHeight: function()
+ {
+ return 15;
+ },
+
+ /**
+ * @return {number}
+ */
+ textBaseline: function()
+ {
+ return 4;
+ },
+
+ /**
+ * @return {number}
+ */
+ textPadding: function()
+ {
+ return 2;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {?Array.<number>}
+ */
+ dividerOffsets: function(startTime, endTime)
+ {
+ return null;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._cpuProfile.profileStartTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ totalTime: function()
+ {
+ return this._cpuProfile.profileHead.totalTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function()
+ {
+ return this._maxStackDepth;
+ },
+
+ /**
+ * @return {?WebInspector.FlameChart.TimelineData}
+ */
+ timelineData: function()
+ {
+ return this._timelineData || this._calculateTimelineData();
+ },
+
+ /**
+ * @return {?WebInspector.FlameChart.TimelineData}
+ */
+ _calculateTimelineData: function()
+ {
+ /**
+ * @constructor
+ * @param {number} depth
+ * @param {number} duration
+ * @param {number} startTime
+ * @param {number} selfTime
+ * @param {!ProfilerAgent.CPUProfileNode} node
+ */
+ function ChartEntry(depth, duration, startTime, selfTime, node)
+ {
+ this.depth = depth;
+ this.duration = duration;
+ this.startTime = startTime;
+ this.selfTime = selfTime;
+ this.node = node;
+ }
+
+ /** @type {!Array.<?ChartEntry>} */
+ var entries = [];
+ /** @type {!Array.<number>} */
+ var stack = [];
+ var maxDepth = 5;
+
+ function onOpenFrame()
+ {
+ stack.push(entries.length);
+ // Reserve space for the entry, as they have to be ordered by startTime.
+ // The entry itself will be put there in onCloseFrame.
+ entries.push(null);
+ }
+ function onCloseFrame(depth, node, startTime, totalTime, selfTime)
+ {
+ var index = stack.pop();
+ entries[index] = new ChartEntry(depth, totalTime, startTime, selfTime, node);
+ maxDepth = Math.max(maxDepth, depth);
+ }
+ this._cpuProfile.forEachFrame(onOpenFrame, onCloseFrame);
+
+ /** @type {!Array.<!ProfilerAgent.CPUProfileNode>} */
+ var entryNodes = new Array(entries.length);
+ var entryLevels = new Uint8Array(entries.length);
+ var entryTotalTimes = new Float32Array(entries.length);
+ var entrySelfTimes = new Float32Array(entries.length);
+ var entryStartTimes = new Float64Array(entries.length);
+ var minimumBoundary = this.minimumBoundary();
+
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ entryNodes[i] = entry.node;
+ entryLevels[i] = entry.depth;
+ entryTotalTimes[i] = entry.duration;
+ entryStartTimes[i] = entry.startTime;
+ entrySelfTimes[i] = entry.selfTime;
+ }
+
+ this._maxStackDepth = maxDepth;
+
+ /** @type {!WebInspector.FlameChart.TimelineData} */
+ this._timelineData = {
+ entryLevels: entryLevels,
+ entryTotalTimes: entryTotalTimes,
+ entryStartTimes: entryStartTimes,
+ };
+
+ /** @type {!Array.<!ProfilerAgent.CPUProfileNode>} */
+ this._entryNodes = entryNodes;
+ this._entrySelfTimes = entrySelfTimes;
+
+ return this._timelineData;
+ },
+
+ /**
+ * @param {number} ms
+ * @return {string}
+ */
+ _millisecondsToString: function(ms)
+ {
+ if (ms === 0)
+ return "0";
+ if (ms < 1000)
+ return WebInspector.UIString("%.1f\u2009ms", ms);
+ return Number.secondsToString(ms / 1000, true);
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?Array.<!{title: string, text: string}>}
+ */
+ prepareHighlightedEntryInfo: function(entryIndex)
+ {
+ var timelineData = this._timelineData;
+ var node = this._entryNodes[entryIndex];
+ if (!node)
+ return null;
+
+ var entryInfo = [];
+ function pushEntryInfoRow(title, text)
+ {
+ var row = {};
+ row.title = title;
+ row.text = text;
+ entryInfo.push(row);
+ }
+
+ pushEntryInfoRow(WebInspector.UIString("Name"), node.functionName);
+ var selfTime = this._millisecondsToString(this._entrySelfTimes[entryIndex]);
+ var totalTime = this._millisecondsToString(timelineData.entryTotalTimes[entryIndex]);
+ pushEntryInfoRow(WebInspector.UIString("Self time"), selfTime);
+ pushEntryInfoRow(WebInspector.UIString("Total time"), totalTime);
+ var target = this._target;
+ var text = WebInspector.Linkifier.liveLocationText(target, node.scriptId, node.lineNumber, node.columnNumber);
+ pushEntryInfoRow(WebInspector.UIString("URL"), text);
+ pushEntryInfoRow(WebInspector.UIString("Aggregated self time"), Number.secondsToString(node.selfTime / 1000, true));
+ pushEntryInfoRow(WebInspector.UIString("Aggregated total time"), Number.secondsToString(node.totalTime / 1000, true));
+ if (node.deoptReason && node.deoptReason !== "no reason")
+ pushEntryInfoRow(WebInspector.UIString("Not optimized"), node.deoptReason);
+
+ return entryInfo;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ canJumpToEntry: function(entryIndex)
+ {
+ return this._entryNodes[entryIndex].scriptId !== "0";
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryTitle: function(entryIndex)
+ {
+ var node = this._entryNodes[entryIndex];
+ return node.functionName;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryFont: function(entryIndex)
+ {
+ if (!this._font) {
+ this._font = (this.barHeight() - 4) + "px " + WebInspector.fontFamily();
+ this._boldFont = "bold " + this._font;
+ }
+ var node = this._entryNodes[entryIndex];
+ var reason = node.deoptReason;
+ return (reason && reason !== "no reason") ? this._boldFont : this._font;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryColor: function(entryIndex)
+ {
+ var node = this._entryNodes[entryIndex];
+ return this._colorGenerator.colorForID(node.functionName + ":" + node.url);
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @param {!CanvasRenderingContext2D} context
+ * @param {?string} text
+ * @param {number} barX
+ * @param {number} barY
+ * @param {number} barWidth
+ * @param {number} barHeight
+ * @param {function(number):number} timeToPosition
+ * @return {boolean}
+ */
+ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, timeToPosition)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ forceDecoration: function(entryIndex)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {!{startTime: number, endTime: number}}
+ */
+ highlightTimeRange: function(entryIndex)
+ {
+ var startTime = this._timelineData.entryStartTimes[entryIndex];
+ return {
+ startTime: startTime,
+ endTime: startTime + this._timelineData.entryTotalTimes[entryIndex]
+ };
+ },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 15;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ textColor: function(entryIndex)
+ {
+ return "#333";
+ }
+}
+
+
+/**
+ * @return {!WebInspector.FlameChart.ColorGenerator}
+ */
+WebInspector.CPUFlameChartDataProvider.colorGenerator = function()
+{
+ if (!WebInspector.CPUFlameChartDataProvider._colorGenerator) {
+ var colorGenerator = new WebInspector.FlameChart.ColorGenerator(
+ { min: 180, max: 310, count: 7 },
+ { min: 50, max: 80, count: 5 },
+ { min: 80, max: 90, count: 3 });
+ colorGenerator.setColorForID("(idle):", "hsl(0, 0%, 94%)");
+ colorGenerator.setColorForID("(program):", "hsl(0, 0%, 80%)");
+ colorGenerator.setColorForID("(garbage collector):", "hsl(0, 0%, 80%)");
+ WebInspector.CPUFlameChartDataProvider._colorGenerator = colorGenerator;
+ }
+ return WebInspector.CPUFlameChartDataProvider._colorGenerator;
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.FlameChartDataProvider} dataProvider
+ */
+WebInspector.CPUProfileFlameChart = function(dataProvider)
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("flameChart.css");
+ this.element.id = "cpu-flame-chart";
+
+ this._overviewPane = new WebInspector.CPUProfileFlameChart.OverviewPane(dataProvider);
+ this._overviewPane.show(this.element);
+
+ this._mainPane = new WebInspector.FlameChart(dataProvider, this._overviewPane, true);
+ this._mainPane.show(this.element);
+ this._mainPane.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
+ this._overviewPane.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
+}
+
+WebInspector.CPUProfileFlameChart.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onWindowChanged: function(event)
+ {
+ var windowLeft = event.data.windowTimeLeft;
+ var windowRight = event.data.windowTimeRight;
+ this._mainPane.setWindowTimes(windowLeft, windowRight);
+ },
+
+ /**
+ * @param {!number} timeLeft
+ * @param {!number} timeRight
+ */
+ selectRange: function(timeLeft, timeRight)
+ {
+ this._overviewPane._selectRange(timeLeft, timeRight);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onEntrySelected: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, event.data);
+ },
+
+ update: function()
+ {
+ this._overviewPane.update();
+ this._mainPane.update();
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineGrid.Calculator}
+ */
+WebInspector.CPUProfileFlameChart.OverviewCalculator = function()
+{
+}
+
+WebInspector.CPUProfileFlameChart.OverviewCalculator.prototype = {
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @param {!WebInspector.CPUProfileFlameChart.OverviewPane} overviewPane
+ */
+ _updateBoundaries: function(overviewPane)
+ {
+ this._minimumBoundaries = overviewPane._dataProvider.minimumBoundary();
+ var totalTime = overviewPane._dataProvider.totalTime();
+ this._maximumBoundaries = this._minimumBoundaries + totalTime;
+ this._xScaleFactor = overviewPane._overviewContainer.clientWidth / totalTime;
+ },
+
+ /**
+ * @param {number} time
+ * @return {number}
+ */
+ computePosition: function(time)
+ {
+ return (time - this._minimumBoundaries) * this._xScaleFactor;
+ },
+
+ /**
+ * @param {number} value
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatTime: function(value, precision)
+ {
+ return Number.secondsToString((value - this._minimumBoundaries) / 1000);
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumBoundary: function()
+ {
+ return this._maximumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ zeroTime: function()
+ {
+ return this._minimumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ boundarySpan: function()
+ {
+ return this._maximumBoundaries - this._minimumBoundaries;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @implements {WebInspector.FlameChartDelegate}
+ * @param {!WebInspector.FlameChartDataProvider} dataProvider
+ */
+WebInspector.CPUProfileFlameChart.OverviewPane = function(dataProvider)
+{
+ WebInspector.VBox.call(this);
+ this.element.classList.add("flame-chart-overview-pane");
+ this._overviewContainer = this.element.createChild("div", "overview-container");
+ this._overviewGrid = new WebInspector.OverviewGrid("flame-chart");
+ this._overviewGrid.element.classList.add("fill");
+ this._overviewCanvas = this._overviewContainer.createChild("canvas", "flame-chart-overview-canvas");
+ this._overviewContainer.appendChild(this._overviewGrid.element);
+ this._overviewCalculator = new WebInspector.CPUProfileFlameChart.OverviewCalculator();
+ this._dataProvider = dataProvider;
+ this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
+}
+
+WebInspector.CPUProfileFlameChart.OverviewPane.prototype = {
+ /**
+ * @param {number} windowStartTime
+ * @param {number} windowEndTime
+ */
+ requestWindowTimes: function(windowStartTime, windowEndTime)
+ {
+ this._selectRange(windowStartTime, windowEndTime);
+ },
+
+ /**
+ * @param {!number} timeLeft
+ * @param {!number} timeRight
+ */
+ _selectRange: function(timeLeft, timeRight)
+ {
+ var startTime = this._dataProvider.minimumBoundary();
+ var totalTime = this._dataProvider.totalTime();
+ this._overviewGrid.setWindow((timeLeft - startTime) / totalTime, (timeRight - startTime) / totalTime);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onWindowChanged: function(event)
+ {
+ var startTime = this._dataProvider.minimumBoundary();
+ var totalTime = this._dataProvider.totalTime();
+ var data = {
+ windowTimeLeft: startTime + this._overviewGrid.windowLeft() * totalTime,
+ windowTimeRight: startTime + this._overviewGrid.windowRight() * totalTime
+ };
+ this.dispatchEventToListeners(WebInspector.OverviewGrid.Events.WindowChanged, data);
+ },
+
+ /**
+ * @return {?WebInspector.FlameChart.TimelineData}
+ */
+ _timelineData: function()
+ {
+ return this._dataProvider.timelineData();
+ },
+
+ onResize: function()
+ {
+ this._scheduleUpdate();
+ },
+
+ _scheduleUpdate: function()
+ {
+ if (this._updateTimerId)
+ return;
+ this._updateTimerId = requestAnimationFrame(this.update.bind(this));
+ },
+
+ update: function()
+ {
+ this._updateTimerId = 0;
+ var timelineData = this._timelineData();
+ if (!timelineData)
+ return;
+ this._resetCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - WebInspector.FlameChart.DividersBarHeight);
+ this._overviewCalculator._updateBoundaries(this);
+ this._overviewGrid.updateDividers(this._overviewCalculator);
+ this._drawOverviewCanvas();
+ },
+
+ _drawOverviewCanvas: function()
+ {
+ var canvasWidth = this._overviewCanvas.width;
+ var canvasHeight = this._overviewCanvas.height;
+ var drawData = this._calculateDrawData(canvasWidth);
+ var context = this._overviewCanvas.getContext("2d");
+ var ratio = window.devicePixelRatio;
+ var offsetFromBottom = ratio;
+ var lineWidth = 1;
+ var yScaleFactor = canvasHeight / (this._dataProvider.maxStackDepth() * 1.1);
+ context.lineWidth = lineWidth;
+ context.translate(0.5, 0.5);
+ context.strokeStyle = "rgba(20,0,0,0.4)";
+ context.fillStyle = "rgba(214,225,254,0.8)";
+ context.moveTo(-lineWidth, canvasHeight + lineWidth);
+ context.lineTo(-lineWidth, Math.round(canvasHeight - drawData[0] * yScaleFactor - offsetFromBottom));
+ var value;
+ for (var x = 0; x < canvasWidth; ++x) {
+ value = Math.round(canvasHeight - drawData[x] * yScaleFactor - offsetFromBottom);
+ context.lineTo(x, value);
+ }
+ context.lineTo(canvasWidth + lineWidth, value);
+ context.lineTo(canvasWidth + lineWidth, canvasHeight + lineWidth);
+ context.fill();
+ context.stroke();
+ context.closePath();
+ },
+
+ /**
+ * @param {number} width
+ * @return {!Uint8Array}
+ */
+ _calculateDrawData: function(width)
+ {
+ var dataProvider = this._dataProvider;
+ var timelineData = this._timelineData();
+ var entryStartTimes = timelineData.entryStartTimes;
+ var entryTotalTimes = timelineData.entryTotalTimes;
+ var entryLevels = timelineData.entryLevels;
+ var length = entryStartTimes.length;
+ var minimumBoundary = this._dataProvider.minimumBoundary();
+
+ var drawData = new Uint8Array(width);
+ var scaleFactor = width / dataProvider.totalTime();
+
+ for (var entryIndex = 0; entryIndex < length; ++entryIndex) {
+ var start = Math.floor((entryStartTimes[entryIndex] - minimumBoundary) * scaleFactor);
+ var finish = Math.floor((entryStartTimes[entryIndex] - minimumBoundary + entryTotalTimes[entryIndex]) * scaleFactor);
+ for (var x = start; x <= finish; ++x)
+ drawData[x] = Math.max(drawData[x], entryLevels[entryIndex] + 1);
+ }
+ return drawData;
+ },
+
+ /**
+ * @param {!number} width
+ * @param {!number} height
+ */
+ _resetCanvas: function(width, height)
+ {
+ var ratio = window.devicePixelRatio;
+ this._overviewCanvas.width = width * ratio;
+ this._overviewCanvas.height = height * ratio;
+ this._overviewCanvas.style.width = width + "px";
+ this._overviewCanvas.style.height = height + "px";
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TopDownProfileDataGridTree.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileTopDownDataGrid.js
index a2d3edbd54c..f1f7a7a5fe7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TopDownProfileDataGridTree.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileTopDownDataGrid.js
@@ -36,6 +36,7 @@ WebInspector.TopDownProfileDataGridNode = function(profileNode, owningTree)
WebInspector.ProfileDataGridNode.call(this, profileNode, owningTree, hasChildren);
this._remainingChildren = profileNode.children;
+ this.buildData();
}
WebInspector.TopDownProfileDataGridNode.prototype = {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CPUProfileView.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
index 9244e40d33d..c448cc921b1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CPUProfileView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
@@ -23,36 +23,32 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.CPUProfileHeader} profileHeader
*/
WebInspector.CPUProfileView = function(profileHeader)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
+ this.element.classList.add("cpu-profile-view");
- this.element.classList.add("profile-view");
-
- this.showSelfTimeAsPercent = WebInspector.settings.createSetting("cpuProfilerShowSelfTimeAsPercent", true);
- this.showTotalTimeAsPercent = WebInspector.settings.createSetting("cpuProfilerShowTotalTimeAsPercent", true);
- this.showAverageTimeAsPercent = WebInspector.settings.createSetting("cpuProfilerShowAverageTimeAsPercent", true);
this._viewType = WebInspector.settings.createSetting("cpuProfilerView", WebInspector.CPUProfileView._TypeHeavy);
var columns = [];
- columns.push({id: "self", title: WebInspector.UIString("Self"), width: "72px", sort: WebInspector.DataGrid.Order.Descending, sortable: true});
- columns.push({id: "total", title: WebInspector.UIString("Total"), width: "72px", sortable: true});
+ columns.push({id: "self", title: WebInspector.UIString("Self"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true});
+ columns.push({id: "total", title: WebInspector.UIString("Total"), width: "120px", sortable: true});
columns.push({id: "function", title: WebInspector.UIString("Function"), disclosure: true, sortable: true});
this.dataGrid = new WebInspector.DataGrid(columns);
this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortProfile, this);
- this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
this.dataGrid.show(this.element);
this.viewSelectComboBox = new WebInspector.StatusBarComboBox(this._changeView.bind(this));
var options = {};
- options[WebInspector.CPUProfileView._TypeFlame] = this.viewSelectComboBox.createOption(WebInspector.UIString("Flame Chart"), "", WebInspector.CPUProfileView._TypeFlame);
+ options[WebInspector.CPUProfileView._TypeFlame] = this.viewSelectComboBox.createOption(WebInspector.UIString("Chart"), "", WebInspector.CPUProfileView._TypeFlame);
options[WebInspector.CPUProfileView._TypeHeavy] = this.viewSelectComboBox.createOption(WebInspector.UIString("Heavy (Bottom Up)"), "", WebInspector.CPUProfileView._TypeHeavy);
options[WebInspector.CPUProfileView._TypeTree] = this.viewSelectComboBox.createOption(WebInspector.UIString("Tree (Top Down)"), "", WebInspector.CPUProfileView._TypeTree);
@@ -62,10 +58,6 @@ WebInspector.CPUProfileView = function(profileHeader)
this._statusBarButtonsElement = document.createElement("span");
- this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item");
- this.percentButton.addEventListener("click", this._percentClicked, this);
- this._statusBarButtonsElement.appendChild(this.percentButton.element);
-
this.focusButton = new WebInspector.StatusBarButton(WebInspector.UIString("Focus selected function."), "focus-profile-node-status-bar-item");
this.focusButton.setEnabled(false);
this.focusButton.addEventListener("click", this._focusClicked, this);
@@ -81,15 +73,14 @@ WebInspector.CPUProfileView = function(profileHeader)
this.resetButton.addEventListener("click", this._resetClicked, this);
this._statusBarButtonsElement.appendChild(this.resetButton.element);
- this.profileHead = /** @type {?ProfilerAgent.CPUProfileNode} */ (null);
- this.profile = profileHeader;
-
+ this._profileHeader = profileHeader;
this._linkifier = new WebInspector.Linkifier(new WebInspector.Linkifier.DefaultFormatter(30));
- if (this.profile._profile) // If the profile has been loaded from file then use it.
- this._processProfileData(this.profile._profile);
- else
- this._processProfileData(this.profile.protocolProfile());
+ this.profile = new WebInspector.CPUProfileDataModel(profileHeader._profile || profileHeader.protocolProfile());
+
+ this._changeView();
+ if (this._flameChart)
+ this._flameChart.update();
}
WebInspector.CPUProfileView._TypeFlame = "Flame";
@@ -108,36 +99,6 @@ WebInspector.CPUProfileView.prototype = {
this._flameChart.selectRange(timeLeft, timeRight);
},
- _revealProfilerNode: function(event)
- {
- var current = this.profileDataGridTree.children[0];
-
- while (current && current.profileNode !== event.data)
- current = current.traverseNextNode(false, null, false);
-
- if (current)
- current.revealAndSelect();
- },
-
- /**
- * @param {?ProfilerAgent.CPUProfile} profile
- */
- _processProfileData: function(profile)
- {
- this.profileHead = profile.head;
- this.samples = profile.samples;
-
- this._calculateTimes(profile);
-
- this._assignParentsInProfile();
- if (this.samples)
- this._buildIdToNodeMap();
- this._changeView();
- this._updatePercentButton();
- if (this._flameChart)
- this._flameChart.update();
- },
-
get statusBarItems()
{
return [this.viewSelectComboBox.element, this._statusBarButtonsElement];
@@ -149,7 +110,7 @@ WebInspector.CPUProfileView.prototype = {
_getBottomUpProfileDataGridTree: function()
{
if (!this._bottomUpProfileDataGridTree)
- this._bottomUpProfileDataGridTree = new WebInspector.BottomUpProfileDataGridTree(this, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profileHead));
+ this._bottomUpProfileDataGridTree = new WebInspector.BottomUpProfileDataGridTree(this, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profile.profileHead));
return this._bottomUpProfileDataGridTree;
},
@@ -159,7 +120,7 @@ WebInspector.CPUProfileView.prototype = {
_getTopDownProfileDataGridTree: function()
{
if (!this._topDownProfileDataGridTree)
- this._topDownProfileDataGridTree = new WebInspector.TopDownProfileDataGridTree(this, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profileHead));
+ this._topDownProfileDataGridTree = new WebInspector.TopDownProfileDataGridTree(this, /** @type {!ProfilerAgent.CPUProfileNode} */ (this.profile.profileHead));
return this._topDownProfileDataGridTree;
},
@@ -193,12 +154,6 @@ WebInspector.CPUProfileView.prototype = {
}
},
- refreshShowAsPercents: function()
- {
- this._updatePercentButton();
- this.refreshVisibleData();
- },
-
searchCanceled: function()
{
if (this._searchResults) {
@@ -360,16 +315,25 @@ WebInspector.CPUProfileView.prototype = {
this._jumpToSearchResult(this._currentSearchResultIndex);
},
+ /**
+ * @return {boolean}
+ */
showingFirstSearchResult: function()
{
return (this._currentSearchResultIndex === 0);
},
+ /**
+ * @return {boolean}
+ */
showingLastSearchResult: function()
{
return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
},
+ /**
+ * @return {number}
+ */
currentSearchResultIndex: function() {
return this._currentSearchResultIndex;
},
@@ -388,8 +352,8 @@ WebInspector.CPUProfileView.prototype = {
{
if (this._flameChart)
return;
- var dataProvider = new WebInspector.CPUFlameChartDataProvider(this);
- this._flameChart = new WebInspector.FlameChart(dataProvider);
+ this._dataProvider = new WebInspector.CPUFlameChartDataProvider(this.profile, this._profileHeader.target());
+ this._flameChart = new WebInspector.CPUProfileFlameChart(this._dataProvider);
this._flameChart.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected.bind(this));
},
@@ -398,16 +362,14 @@ WebInspector.CPUProfileView.prototype = {
*/
_onEntrySelected: function(event)
{
- var node = event.data;
+ var entryIndex = event.data;
+ var node = this._dataProvider._entryNodes[entryIndex];
if (!node || !node.scriptId)
return;
var script = WebInspector.debuggerModel.scriptForId(node.scriptId)
if (!script)
return;
- var uiLocation = script.rawLocationToUILocation(node.lineNumber);
- if (!uiLocation)
- return;
- WebInspector.panel("sources").showUILocation(uiLocation);
+ WebInspector.Revealer.reveal(script.rawLocationToUILocation(node.lineNumber));
},
_changeView: function()
@@ -421,7 +383,7 @@ WebInspector.CPUProfileView.prototype = {
this.dataGrid.detach();
this._flameChart.show(this.element);
this._viewType.set(WebInspector.CPUProfileView._TypeFlame);
- this._statusBarButtonsElement.enableStyleClass("hidden", true);
+ this._statusBarButtonsElement.classList.toggle("hidden", true);
return;
case WebInspector.CPUProfileView._TypeTree:
this.profileDataGridTree = this._getTopDownProfileDataGridTree();
@@ -435,7 +397,7 @@ WebInspector.CPUProfileView.prototype = {
break;
}
- this._statusBarButtonsElement.enableStyleClass("hidden", false);
+ this._statusBarButtonsElement.classList.toggle("hidden", false);
if (this._flameChart)
this._flameChart.detach();
@@ -451,26 +413,6 @@ WebInspector.CPUProfileView.prototype = {
this.performSearch(this.currentQuery, this._searchFinishedCallback);
},
- _percentClicked: function(event)
- {
- var currentState = this.showSelfTimeAsPercent.get() && this.showTotalTimeAsPercent.get() && this.showAverageTimeAsPercent.get();
- this.showSelfTimeAsPercent.set(!currentState);
- this.showTotalTimeAsPercent.set(!currentState);
- this.showAverageTimeAsPercent.set(!currentState);
- this.refreshShowAsPercents();
- },
-
- _updatePercentButton: function()
- {
- if (this.showSelfTimeAsPercent.get() && this.showTotalTimeAsPercent.get() && this.showAverageTimeAsPercent.get()) {
- this.percentButton.title = WebInspector.UIString("Show absolute total and self times.");
- this.percentButton.toggled = true;
- } else {
- this.percentButton.title = WebInspector.UIString("Show total and self times as percentages.");
- this.percentButton.toggled = false;
- }
- },
-
_focusClicked: function(event)
{
if (!this.dataGrid.selectedNode)
@@ -533,106 +475,18 @@ WebInspector.CPUProfileView.prototype = {
this.refresh();
},
- _mouseDownInDataGrid: function(event)
- {
- if (event.detail < 2)
- return;
-
- var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
- if (!cell || (!cell.classList.contains("total-column") && !cell.classList.contains("self-column") && !cell.classList.contains("average-column")))
- return;
-
- if (cell.classList.contains("total-column"))
- this.showTotalTimeAsPercent.set(!this.showTotalTimeAsPercent.get());
- else if (cell.classList.contains("self-column"))
- this.showSelfTimeAsPercent.set(!this.showSelfTimeAsPercent.get());
- else if (cell.classList.contains("average-column"))
- this.showAverageTimeAsPercent.set(!this.showAverageTimeAsPercent.get());
-
- this.refreshShowAsPercents();
-
- event.consume(true);
- },
-
- _calculateTimes: function(profile)
- {
- function totalHitCount(node) {
- var result = node.hitCount;
- for (var i = 0; i < node.children.length; i++)
- result += totalHitCount(node.children[i]);
- return result;
- }
- profile.totalHitCount = totalHitCount(profile.head);
-
- var durationMs = 1000 * (profile.endTime - profile.startTime);
- var samplingInterval = durationMs / profile.totalHitCount;
- this.samplingIntervalMs = samplingInterval;
-
- function calculateTimesForNode(node) {
- node.selfTime = node.hitCount * samplingInterval;
- var totalHitCount = node.hitCount;
- for (var i = 0; i < node.children.length; i++)
- totalHitCount += calculateTimesForNode(node.children[i]);
- node.totalTime = totalHitCount * samplingInterval;
- return totalHitCount;
- }
- calculateTimesForNode(profile.head);
- },
-
- _assignParentsInProfile: function()
- {
- var head = this.profileHead;
- head.parent = null;
- head.head = null;
- var nodesToTraverse = [ { parent: head, children: head.children } ];
- while (nodesToTraverse.length > 0) {
- var pair = nodesToTraverse.pop();
- var parent = pair.parent;
- var children = pair.children;
- var length = children.length;
- for (var i = 0; i < length; ++i) {
- children[i].head = head;
- children[i].parent = parent;
- if (children[i].children.length > 0)
- nodesToTraverse.push({ parent: children[i], children: children[i].children });
- }
- }
- },
-
- _buildIdToNodeMap: function()
- {
- var idToNode = this._idToNode = {};
- var stack = [this.profileHead];
- while (stack.length) {
- var node = stack.pop();
- idToNode[node.id] = node;
- for (var i = 0; i < node.children.length; i++)
- stack.push(node.children[i]);
- }
-
- var topLevelNodes = this.profileHead.children;
- for (var i = 0; i < topLevelNodes.length; i++) {
- var node = topLevelNodes[i];
- if (node.functionName == "(garbage collector)") {
- this._gcNode = node;
- break;
- }
- }
- },
-
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
* @constructor
* @extends {WebInspector.ProfileType}
- * @implements {WebInspector.CPUProfilerModelDelegate}
+ * @implements {WebInspector.CPUProfilerModel.Delegate}
*/
WebInspector.CPUProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.CPUProfileType.TypeId, WebInspector.UIString("Collect JavaScript CPU Profile"));
this._recording = false;
- this._nextProfileId = 1;
this._nextAnonymousConsoleProfileNumber = 1;
this._anonymousConsoleProfileIdToTitle = {};
@@ -685,78 +539,73 @@ WebInspector.CPUProfileType.prototype = {
/**
* @param {string} id
- * @param {!DebuggerAgent.Location} scriptLocation
+ * @param {!WebInspector.DebuggerModel.Location} scriptLocation
* @param {string=} title
*/
- consoleProfile: function(id, scriptLocation, title)
+ consoleProfileStarted: function(id, scriptLocation, title)
{
var resolvedTitle = title;
if (!resolvedTitle) {
resolvedTitle = WebInspector.UIString("Profile %s", this._nextAnonymousConsoleProfileNumber++);
this._anonymousConsoleProfileIdToTitle[id] = resolvedTitle;
}
- this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profile, scriptLocation, resolvedTitle);
+ this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.Profile, scriptLocation, WebInspector.UIString("Profile '%s' started.", resolvedTitle));
},
/**
* @param {string} protocolId
- * @param {!DebuggerAgent.Location} scriptLocation
+ * @param {!WebInspector.DebuggerModel.Location} scriptLocation
* @param {!ProfilerAgent.CPUProfile} cpuProfile
* @param {string=} title
*/
- consoleProfileEnd: function(protocolId, scriptLocation, cpuProfile, title)
+ consoleProfileFinished: function(protocolId, scriptLocation, cpuProfile, title)
{
- // Make sure ProfilesPanel is initialized and CPUProfileType is created.
var resolvedTitle = title;
if (typeof title === "undefined") {
resolvedTitle = this._anonymousConsoleProfileIdToTitle[protocolId];
delete this._anonymousConsoleProfileIdToTitle[protocolId];
}
- var id = this._nextProfileId++;
- var profile = new WebInspector.CPUProfileHeader(this, resolvedTitle, id);
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ var profile = new WebInspector.CPUProfileHeader(target, this, resolvedTitle);
profile.setProtocolProfile(cpuProfile);
this.addProfile(profile);
-
- resolvedTitle += "#" + id;
- this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.ProfileEnd, scriptLocation, resolvedTitle);
+ this._addMessageToConsole(WebInspector.ConsoleMessage.MessageType.ProfileEnd, scriptLocation, WebInspector.UIString("Profile '%s' finished.", resolvedTitle));
},
/**
* @param {string} type
- * @param {!DebuggerAgent.Location} scriptLocation
- * @param {string} title
+ * @param {!WebInspector.DebuggerModel.Location} scriptLocation
+ * @param {string} messageText
*/
- _addMessageToConsole: function(type, scriptLocation, title)
+ _addMessageToConsole: function(type, scriptLocation, messageText)
{
- var rawLocation = new WebInspector.DebuggerModel.Location(scriptLocation.scriptId, scriptLocation.lineNumber, scriptLocation.columnNumber || 0);
- var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(rawLocation);
- var url;
- if (uiLocation)
- url = uiLocation.url();
- var message = WebInspector.ConsoleMessage.create(
+ var script = scriptLocation.script();
+ var message = new WebInspector.ConsoleMessage(
+ WebInspector.console.target(),
WebInspector.ConsoleMessage.MessageSource.ConsoleAPI,
WebInspector.ConsoleMessage.MessageLevel.Debug,
- title,
+ messageText,
type,
- url || undefined,
- scriptLocation.lineNumber,
- scriptLocation.columnNumber);
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ undefined,
+ [{
+ functionName: "",
+ scriptId: scriptLocation.scriptId,
+ url: script ? script.contentURL() : "",
+ lineNumber: scriptLocation.lineNumber,
+ columnNumber: scriptLocation.columnNumber || 0
+ }]);
+
WebInspector.console.addMessage(message);
},
/**
- * @param {!ProfilerAgent.CPUProfile} cpuProfile
- * @param {string} title
+ * @return {boolean}
*/
- _addProfileHeader: function(cpuProfile, title)
- {
- var id = this._nextProfileId++;
- var profile = new WebInspector.CPUProfileHeader(this, title, id);
- profile.setProtocolProfile(cpuProfile);
- this.addProfile(profile);
- },
-
isRecordingProfile: function()
{
return this._recording;
@@ -766,10 +615,11 @@ WebInspector.CPUProfileType.prototype = {
{
if (this._profileBeingRecorded)
return;
- var id = this._nextProfileId++;
- this._profileBeingRecorded = new WebInspector.CPUProfileHeader(this, WebInspector.UIString("Recording\u2026"), id);
- this.addProfile(this._profileBeingRecorded);
-
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ var profile = new WebInspector.CPUProfileHeader(target, this);
+ this.setProfileBeingRecorded(profile);
+ this.addProfile(profile);
+ profile.updateStatus(WebInspector.UIString("Recording\u2026"));
this._recording = true;
WebInspector.cpuProfilerModel.setRecording(true);
WebInspector.userMetrics.ProfilesCPUProfileTaken.record();
@@ -791,13 +641,10 @@ WebInspector.CPUProfileType.prototype = {
if (!this._profileBeingRecorded)
return;
this._profileBeingRecorded.setProtocolProfile(profile);
-
- var title = WebInspector.UIString("Profile %d", this._profileBeingRecorded.uid);
- this._profileBeingRecorded.title = title;
- this._profileBeingRecorded.sidebarElement.mainTitle = title;
+ this._profileBeingRecorded.updateStatus("");
var recordedProfile = this._profileBeingRecorded;
- this._profileBeingRecorded = null;
- WebInspector.panels.profiles._showProfile(recordedProfile);
+ this.setProfileBeingRecorded(null);
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, recordedProfile);
}
ProfilerAgent.stop(didStopProfiling.bind(this));
},
@@ -809,27 +656,16 @@ WebInspector.CPUProfileType.prototype = {
*/
createProfileLoadedFromFile: function(title)
{
- return new WebInspector.CPUProfileHeader(this, title);
- },
-
- /**
- * @override
- */
- removeProfile: function(profile)
- {
- if (this._profileBeingRecorded === profile) {
- this.stopRecordingProfile();
- this._profileBeingRecorded = null;
- }
- WebInspector.ProfileType.prototype.removeProfile.call(this, profile);
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ return new WebInspector.CPUProfileHeader(target, this, title);
},
/**
* @override
*/
- resetProfiles: function()
+ profileBeingRecordedRemoved: function()
{
- this._reset();
+ this.stopRecordingProfile();
},
__proto__: WebInspector.ProfileType.prototype
@@ -840,13 +676,13 @@ WebInspector.CPUProfileType.prototype = {
* @extends {WebInspector.ProfileHeader}
* @implements {WebInspector.OutputStream}
* @implements {WebInspector.OutputStreamDelegate}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.CPUProfileType} type
- * @param {string} title
- * @param {number=} uid
+ * @param {string=} title
*/
-WebInspector.CPUProfileHeader = function(type, title, uid)
+WebInspector.CPUProfileHeader = function(target, type, title)
{
- WebInspector.ProfileHeader.call(this, type, title, uid);
+ WebInspector.ProfileHeader.call(this, target, type, title || WebInspector.UIString("Profile %d", type._nextProfileUid));
this._tempFile = null;
}
@@ -854,7 +690,7 @@ WebInspector.CPUProfileHeader.prototype = {
onTransferStarted: function()
{
this._jsonifiedProfile = "";
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026 %s", Number.bytesToString(this._jsonifiedProfile.length));
+ this.updateStatus(WebInspector.UIString("Loading\u2026 %s", Number.bytesToString(this._jsonifiedProfile.length)), true);
},
/**
@@ -862,37 +698,40 @@ WebInspector.CPUProfileHeader.prototype = {
*/
onChunkTransferred: function(reader)
{
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026 %d\%", Number.bytesToString(this._jsonifiedProfile.length));
+ this.updateStatus(WebInspector.UIString("Loading\u2026 %d\%", Number.bytesToString(this._jsonifiedProfile.length)));
},
onTransferFinished: function()
{
- this.sidebarElement.subtitle = WebInspector.UIString("Parsing\u2026");
+ this.updateStatus(WebInspector.UIString("Parsing\u2026"), true);
this._profile = JSON.parse(this._jsonifiedProfile);
this._jsonifiedProfile = null;
- this.sidebarElement.subtitle = WebInspector.UIString("Loaded");
+ this.updateStatus(WebInspector.UIString("Loaded"), false);
- if (this._profileType._profileBeingRecorded === this)
- this._profileType._profileBeingRecorded = null;
+ if (this._profileType.profileBeingRecorded() === this)
+ this._profileType.setProfileBeingRecorded(null);
},
/**
* @param {!WebInspector.ChunkedReader} reader
+ * @param {?Event} e
*/
onError: function(reader, e)
{
+ var subtitle;
switch(e.target.error.code) {
case e.target.error.NOT_FOUND_ERR:
- this.sidebarElement.subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
- break;
+ subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
+ break;
case e.target.error.NOT_READABLE_ERR:
- this.sidebarElement.subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
- break;
- case e.target.error.ABORT_ERR:
+ subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
break;
+ case e.target.error.ABORT_ERR:
+ return;
default:
- this.sidebarElement.subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
+ subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
}
+ this.updateStatus(subtitle);
},
/**
@@ -908,16 +747,26 @@ WebInspector.CPUProfileHeader.prototype = {
/**
* @override
*/
- createSidebarTreeElement: function()
+ dispose: function()
{
- return new WebInspector.ProfileSidebarTreeElement(this, "profile-sidebar-tree-item");
+ this.removeTempFile();
},
/**
* @override
- * @param {!WebInspector.ProfilesPanel} profilesPanel
+ * @param {!WebInspector.ProfilesPanel} panel
+ * @return {!WebInspector.ProfileSidebarTreeElement}
*/
- createView: function(profilesPanel)
+ createSidebarTreeElement: function(panel)
+ {
+ return new WebInspector.ProfileSidebarTreeElement(panel, this, "profile-sidebar-tree-item");
+ },
+
+ /**
+ * @override
+ * @return {!WebInspector.CPUProfileView}
+ */
+ createView: function()
{
return new WebInspector.CPUProfileView(this);
},
@@ -928,7 +777,7 @@ WebInspector.CPUProfileHeader.prototype = {
*/
canSaveToFile: function()
{
- return !!this._tempFile;
+ return !this.fromFile() && this._protocolProfile;
},
saveToFile: function()
@@ -950,7 +799,14 @@ WebInspector.CPUProfileHeader.prototype = {
else
fileOutputStream.close();
}
- this._tempFile.read(didRead.bind(this));
+ if (this._failedToCreateTempFile) {
+ WebInspector.messageSink.addErrorMessage("Failed to open temp file with heap snapshot");
+ fileOutputStream.close();
+ } else if (this._tempFile) {
+ this._tempFile.read(didRead);
+ } else {
+ this._onTempFileReady = onOpenForSave.bind(this, accepted);
+ }
}
this._fileName = this._fileName || "CPU-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
fileOutputStream.open(this._fileName, onOpenForSave.bind(this));
@@ -961,9 +817,7 @@ WebInspector.CPUProfileHeader.prototype = {
*/
loadFromFile: function(file)
{
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
- this.sidebarElement.wait = true;
-
+ this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
var fileReader = new WebInspector.ChunkedFileReader(file, 10000000, this);
fileReader.start(this);
},
@@ -984,6 +838,8 @@ WebInspector.CPUProfileHeader.prototype = {
{
this._protocolProfile = cpuProfile;
this._saveProfileDataToTempFile(cpuProfile);
+ if (this.canSaveToFile())
+ this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);
},
/**
@@ -1010,237 +866,32 @@ WebInspector.CPUProfileHeader.prototype = {
_writeToTempFile: function(tempFile, serializedData)
{
this._tempFile = tempFile;
- if (tempFile)
- tempFile.write(serializedData);
- },
-
- __proto__: WebInspector.ProfileHeader.prototype
-}
-
-/**
- * @constructor
- * @implements {WebInspector.FlameChartDataProvider}
- */
-WebInspector.CPUFlameChartDataProvider = function(cpuProfileView)
-{
- WebInspector.FlameChartDataProvider.call(this);
- this._cpuProfileView = cpuProfileView;
-}
-
-WebInspector.CPUFlameChartDataProvider.prototype = {
- /**
- * @param {!WebInspector.FlameChart.ColorGenerator} colorGenerator
- * @return {!Object}
- */
- timelineData: function(colorGenerator)
- {
- return this._timelineData || this._calculateTimelineData(colorGenerator);
- },
-
- /**
- * @param {!WebInspector.FlameChart.ColorGenerator} colorGenerator
- * @return {?Object}
- */
- _calculateTimelineData: function(colorGenerator)
- {
- if (!this._cpuProfileView.profileHead)
- return null;
-
- var samples = this._cpuProfileView.samples;
- var idToNode = this._cpuProfileView._idToNode;
- var gcNode = this._cpuProfileView._gcNode;
- var samplesCount = samples.length;
- var samplingInterval = this._cpuProfileView.samplingIntervalMs;
-
- var index = 0;
-
- var openIntervals = [];
- var stackTrace = [];
- var colorEntryIndexes = [];
- var maxDepth = 5; // minimum stack depth for the case when we see no activity.
- var depth = 0;
-
+ if (!tempFile) {
+ this._failedToCreateTempFile = true;
+ this._notifyTempFileReady();
+ return;
+ }
/**
- * @constructor
- * @param {!Object} colorPair
- * @param {!number} depth
- * @param {!number} duration
- * @param {!number} startTime
- * @param {!Object} node
+ * @param {boolean} success
+ * @this {WebInspector.CPUProfileHeader}
*/
- function ChartEntry(colorPair, depth, duration, startTime, node)
+ function didWriteToTempFile(success)
{
- this.colorPair = colorPair;
- this.depth = depth;
- this.duration = duration;
- this.startTime = startTime;
- this.node = node;
- this.selfTime = 0;
+ if (!success)
+ this._failedToCreateTempFile = true;
+ tempFile.finishWriting();
+ this._notifyTempFileReady();
}
- var entries = /** @type {!Array.<!ChartEntry>} */ ([]);
-
- for (var sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++) {
- var node = idToNode[samples[sampleIndex]];
- stackTrace.length = 0;
- while (node) {
- stackTrace.push(node);
- node = node.parent;
- }
- stackTrace.pop(); // Remove (root) node
-
- maxDepth = Math.max(maxDepth, depth);
- depth = 0;
- node = stackTrace.pop();
- var intervalIndex;
-
- // GC samples have no stack, so we just put GC node on top of the last recoreded sample.
- if (node === gcNode) {
- while (depth < openIntervals.length) {
- intervalIndex = openIntervals[depth].index;
- entries[intervalIndex].duration += samplingInterval;
- ++depth;
- }
- // If previous stack is also GC then just continue.
- if (openIntervals.length > 0 && openIntervals.peekLast().node === node) {
- entries[intervalIndex].selfTime += samplingInterval;
- continue;
- }
- }
-
- while (node && depth < openIntervals.length && node === openIntervals[depth].node) {
- intervalIndex = openIntervals[depth].index;
- entries[intervalIndex].duration += samplingInterval;
- node = stackTrace.pop();
- ++depth;
- }
- if (depth < openIntervals.length)
- openIntervals.length = depth;
- if (!node) {
- entries[intervalIndex].selfTime += samplingInterval;
- continue;
- }
-
- while (node) {
- var colorPair = colorGenerator._colorPairForID(node.functionName + ":" + node.url + ":" + node.lineNumber);
- var indexesForColor = colorEntryIndexes[colorPair.index];
- if (!indexesForColor)
- indexesForColor = colorEntryIndexes[colorPair.index] = [];
-
- var entry = new ChartEntry(colorPair, depth, samplingInterval, sampleIndex * samplingInterval, node);
- indexesForColor.push(entries.length);
- entries.push(entry);
- openIntervals.push({node: node, index: index});
- ++index;
-
- node = stackTrace.pop();
- ++depth;
- }
- entries[entries.length - 1].selfTime += samplingInterval;
- }
-
- var entryNodes = new Array(entries.length);
- var entryColorIndexes = new Uint16Array(entries.length);
- var entryLevels = new Uint8Array(entries.length);
- var entryTotalTimes = new Float32Array(entries.length);
- var entrySelfTimes = new Float32Array(entries.length);
- var entryOffsets = new Float32Array(entries.length);
- var entryTitles = new Array(entries.length);
- var entryDeoptFlags = new Uint8Array(entries.length);
-
- for (var i = 0; i < entries.length; ++i) {
- var entry = entries[i];
- entryNodes[i] = entry.node;
- entryColorIndexes[i] = colorPair.index;
- entryLevels[i] = entry.depth;
- entryTotalTimes[i] = entry.duration;
- entrySelfTimes[i] = entry.selfTime;
- entryOffsets[i] = entry.startTime;
- entryTitles[i] = entry.node.functionName;
- var reason = entry.node.deoptReason;
- entryDeoptFlags[i] = (reason && reason !== "no reason");
- }
-
- this._timelineData = {
- maxStackDepth: Math.max(maxDepth, depth),
- totalTime: this._cpuProfileView.profileHead.totalTime,
- entryNodes: entryNodes,
- entryColorIndexes: entryColorIndexes,
- entryLevels: entryLevels,
- entryTotalTimes: entryTotalTimes,
- entrySelfTimes: entrySelfTimes,
- entryOffsets: entryOffsets,
- colorEntryIndexes: colorEntryIndexes,
- entryTitles: entryTitles,
- entryDeoptFlags: entryDeoptFlags
- };
-
- return this._timelineData;
+ tempFile.write(serializedData, didWriteToTempFile.bind(this));
},
- /**
- * @param {number} ms
- */
- _millisecondsToString: function(ms)
+ _notifyTempFileReady: function()
{
- if (ms === 0)
- return "0";
- if (ms < 1000)
- return WebInspector.UIString("%.1f\u2009ms", ms);
- return Number.secondsToString(ms / 1000, true);
- },
-
- /**
- * @param {number} entryIndex
- */
- prepareHighlightedEntryInfo: function(entryIndex)
- {
- var timelineData = this._timelineData;
- var node = timelineData.entryNodes[entryIndex];
- if (!node)
- return null;
-
- var entryInfo = [];
- function pushEntryInfoRow(title, text)
- {
- var row = {};
- row.title = title;
- row.text = text;
- entryInfo.push(row);
+ if (this._onTempFileReady) {
+ this._onTempFileReady();
+ this._onTempFileReady = null;
}
-
- pushEntryInfoRow(WebInspector.UIString("Name"), timelineData.entryTitles[entryIndex]);
- var selfTime = this._millisecondsToString(timelineData.entrySelfTimes[entryIndex]);
- var totalTime = this._millisecondsToString(timelineData.entryTotalTimes[entryIndex]);
- pushEntryInfoRow(WebInspector.UIString("Self time"), selfTime);
- pushEntryInfoRow(WebInspector.UIString("Total time"), totalTime);
- if (node.url)
- pushEntryInfoRow(WebInspector.UIString("URL"), node.url + ":" + node.lineNumber);
- pushEntryInfoRow(WebInspector.UIString("Aggregated self time"), Number.secondsToString(node.selfTime / 1000, true));
- pushEntryInfoRow(WebInspector.UIString("Aggregated total time"), Number.secondsToString(node.totalTime / 1000, true));
- if (node.deoptReason && node.deoptReason !== "no reason")
- pushEntryInfoRow(WebInspector.UIString("Not optimized"), node.deoptReason);
-
- return entryInfo;
- },
-
- /**
- * @param {number} entryIndex
- * @return {boolean}
- */
- canJumpToEntry: function(entryIndex)
- {
- return this._timelineData.entryNodes[entryIndex].scriptId !== "0";
- },
-
- /**
- * @param {number} entryIndex
- * @return {!Object}
- */
- entryData: function(entryIndex)
- {
- return this._timelineData.entryNodes[entryIndex];
},
- __proto__: WebInspector.FlameChartDataProvider
+ __proto__: WebInspector.ProfileHeader.prototype
}
-
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CanvasProfileView.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasProfileView.js
index 3cd79298d26..edaeedb3cde 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CanvasProfileView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasProfileView.js
@@ -30,34 +30,42 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.CanvasProfileHeader} profile
*/
WebInspector.CanvasProfileView = function(profile)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("canvasProfiler.css");
this.element.classList.add("canvas-profile-view");
+
this._profile = profile;
this._traceLogId = profile.traceLogId();
this._traceLogPlayer = /** @type {!WebInspector.CanvasTraceLogPlayerProxy} */ (profile.traceLogPlayer());
this._linkifier = new WebInspector.Linkifier();
- const defaultReplayLogWidthPercent = 0.34;
- this._replayInfoSplitView = new WebInspector.SplitView(true, "canvasProfileViewReplaySplitLocation", defaultReplayLogWidthPercent);
- this._replayInfoSplitView.setMainElementConstraints(defaultReplayLogWidthPercent, defaultReplayLogWidthPercent);
+ this._replayInfoSplitView = new WebInspector.SplitView(true, true, "canvasProfileViewReplaySplitViewState", 0.34);
this._replayInfoSplitView.show(this.element);
- this._imageSplitView = new WebInspector.SplitView(false, "canvasProfileViewSplitLocation", 300);
- this._imageSplitView.show(this._replayInfoSplitView.firstElement());
+ this._imageSplitView = new WebInspector.SplitView(false, true, "canvasProfileViewSplitViewState", 300);
+ this._imageSplitView.show(this._replayInfoSplitView.mainElement());
+
+ var replayImageContainerView = new WebInspector.VBox();
+ replayImageContainerView.setMinimumSize(50, 28);
+ replayImageContainerView.show(this._imageSplitView.mainElement());
- var replayImageContainer = this._imageSplitView.firstElement().createChild("div");
+ // NOTE: The replayImageContainer can NOT be a flex div (e.g. VBox or SplitView elements)!
+ var replayImageContainer = replayImageContainerView.element.createChild("div");
replayImageContainer.id = "canvas-replay-image-container";
this._replayImageElement = replayImageContainer.createChild("img", "canvas-replay-image");
this._debugInfoElement = replayImageContainer.createChild("div", "canvas-debug-info hidden");
- this._spinnerIcon = replayImageContainer.createChild("img", "canvas-spinner-icon hidden");
+ this._spinnerIcon = replayImageContainer.createChild("div", "spinner-icon small hidden");
+
+ var replayLogContainerView = new WebInspector.VBox();
+ replayLogContainerView.setMinimumSize(22, 22);
+ replayLogContainerView.show(this._imageSplitView.sidebarElement());
- var replayLogContainer = this._imageSplitView.secondElement();
+ var replayLogContainer = replayLogContainerView.element;
var controlsContainer = replayLogContainer.createChild("div", "status-bar");
var logGridContainer = replayLogContainer.createChild("div", "canvas-replay-log");
@@ -75,7 +83,7 @@ WebInspector.CanvasProfileView = function(profile)
this._installReplayInfoSidebarWidgets(controlsContainer);
this._replayStateView = new WebInspector.CanvasReplayStateView(this._traceLogPlayer);
- this._replayStateView.show(this._replayInfoSplitView.secondElement());
+ this._replayStateView.show(this._replayInfoSplitView.sidebarElement());
/** @type {!Object.<string, boolean>} */
this._replayContexts = {};
@@ -136,37 +144,19 @@ WebInspector.CanvasProfileView.prototype = {
_installReplayInfoSidebarWidgets: function(controlsContainer)
{
this._replayInfoResizeWidgetElement = controlsContainer.createChild("div", "resizer-widget");
+ this._replayInfoSplitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._updateReplayInfoResizeWidget, this);
+ this._updateReplayInfoResizeWidget();
this._replayInfoSplitView.installResizer(this._replayInfoResizeWidgetElement);
- this._toggleReplayStateSidebarButton = new WebInspector.StatusBarButton("", "right-sidebar-show-hide-button canvas-sidebar-show-hide-button", 3);
- this._toggleReplayStateSidebarButton.addEventListener("click", clickHandler, this);
- controlsContainer.appendChild(this._toggleReplayStateSidebarButton.element);
- this._enableReplayInfoSidebar(false);
+ this._toggleReplayStateSidebarButton = this._replayInfoSplitView.createShowHideSidebarButton("sidebar", "canvas-sidebar-show-hide-button");
- /**
- * @this {WebInspector.CanvasProfileView}
- */
- function clickHandler()
- {
- this._enableReplayInfoSidebar(this._toggleReplayStateSidebarButton.state === "left");
- }
+ controlsContainer.appendChild(this._toggleReplayStateSidebarButton.element);
+ this._replayInfoSplitView.hideSidebar();
},
- /**
- * @param {boolean} show
- */
- _enableReplayInfoSidebar: function(show)
+ _updateReplayInfoResizeWidget: function()
{
- if (show) {
- this._toggleReplayStateSidebarButton.state = "right";
- this._toggleReplayStateSidebarButton.title = WebInspector.UIString("Hide sidebar.");
- this._replayInfoSplitView.showBoth();
- } else {
- this._toggleReplayStateSidebarButton.state = "left";
- this._toggleReplayStateSidebarButton.title = WebInspector.UIString("Show sidebar.");
- this._replayInfoSplitView.showOnlyFirst();
- }
- this._replayInfoResizeWidgetElement.enableStyleClass("hidden", !show);
+ this._replayInfoResizeWidgetElement.classList.toggle("hidden", this._replayInfoSplitView.showMode() !== WebInspector.SplitView.ShowMode.Both);
},
/**
@@ -176,7 +166,7 @@ WebInspector.CanvasProfileView.prototype = {
{
var resourceLinkElement = event.target.enclosingNodeOrSelfWithClass("canvas-formatted-resource");
if (resourceLinkElement) {
- this._enableReplayInfoSidebar(true);
+ this._replayInfoSplitView.showBoth();
this._replayStateView.selectResource(resourceLinkElement.__resourceId);
event.consume(true);
return;
@@ -292,8 +282,8 @@ WebInspector.CanvasProfileView.prototype = {
*/
_enableWaitIcon: function(enable)
{
- this._spinnerIcon.enableStyleClass("hidden", !enable);
- this._debugInfoElement.enableStyleClass("hidden", enable);
+ this._spinnerIcon.classList.toggle("hidden", !enable);
+ this._debugInfoElement.classList.toggle("hidden", enable);
},
_replayTraceLog: function()
@@ -316,7 +306,7 @@ WebInspector.CanvasProfileView.prototype = {
delete this._pendingReplayTraceLogEvent;
this._enableWaitIcon(false);
- this._debugInfoElement.textContent = "Replay time: " + Number.secondsToString(replayTime / 1000, true);
+ this._debugInfoElement.textContent = WebInspector.UIString("Replay time: %s", Number.secondsToString(replayTime / 1000, true));
this._onReplayContextChanged();
if (index !== this._selectedCallIndex())
@@ -401,7 +391,7 @@ WebInspector.CanvasProfileView.prototype = {
var index = rootNode.children.length;
var data = {};
data[0] = "";
- data[1] = "Frame #" + (index + 1);
+ data[1] = WebInspector.UIString("Frame #%d", index + 1);
data[2] = "";
frameNode = new WebInspector.DataGridNode(data);
frameNode.selectable = true;
@@ -430,7 +420,7 @@ WebInspector.CanvasProfileView.prototype = {
var index = self._drawCallGroupsCount || 0;
var data = {};
data[0] = "";
- data[1] = "Draw call group #" + (index + 1);
+ data[1] = WebInspector.UIString("Draw call group #%d", index + 1);
data[2] = "";
var node = new WebInspector.DataGridNode(data);
node.selectable = true;
@@ -496,7 +486,7 @@ WebInspector.CanvasProfileView.prototype = {
// FIXME(62725): stack trace line/column numbers are one-based.
var lineNumber = Math.max(0, call.lineNumber - 1) || 0;
var columnNumber = Math.max(0, call.columnNumber - 1) || 0;
- data[2] = this._linkifier.linkifyLocation(call.sourceURL, lineNumber, columnNumber);
+ data[2] = this._linkifier.linkifyLocation(this.profile.target(), call.sourceURL, lineNumber, columnNumber);
}
callViewElement.createChild("span", "canvas-function-name").textContent = call.functionName || "context." + call.property;
@@ -562,7 +552,7 @@ WebInspector.CanvasProfileView.prototype = {
var diffLeft = this._popoverAnchorElement.boxInWindow().x - argumentElement.boxInWindow().x;
this._popoverAnchorElement.style.left = this._popoverAnchorElement.offsetLeft - diffLeft + "px";
- showCallback(WebInspector.RemoteObject.fromPayload(result), false, this._popoverAnchorElement);
+ showCallback(WebInspector.runtimeModel.createRemoteObject(result), false, this._popoverAnchorElement);
}
var evalResult = argumentElement.__evalResult;
@@ -616,7 +606,7 @@ WebInspector.CanvasProfileView.prototype = {
rootNode.removeChild(frameNode);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
@@ -626,7 +616,6 @@ WebInspector.CanvasProfileView.prototype = {
WebInspector.CanvasProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.CanvasProfileType.TypeId, WebInspector.UIString("Capture Canvas Frame"));
- this._nextProfileUid = 1;
this._recording = false;
this._lastProfileHeader = null;
@@ -644,9 +633,11 @@ WebInspector.CanvasProfileType = function()
this._frameSelector = new WebInspector.StatusBarComboBox(this._dispatchViewUpdatedEvent.bind(this));
this._frameSelector.element.title = WebInspector.UIString("Frame containing the canvases to capture.");
this._frameSelector.element.classList.add("hidden");
- WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
- WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
+
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._target.resourceTreeModel.frames().forEach(this._addFrame, this);
+ this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
+ this._target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameRemoved, this);
this._dispatcher = new WebInspector.CanvasDispatcher(this);
this._canvasAgentEnabled = false;
@@ -696,19 +687,24 @@ WebInspector.CanvasProfileType.prototype = {
_runSingleFrameCapturing: function()
{
var frameId = this._selectedFrameId();
+ this._target.profilingLock.acquire();
CanvasAgent.captureFrame(frameId, this._didStartCapturingFrame.bind(this, frameId));
+ this._target.profilingLock.release();
},
_startFrameCapturing: function()
{
var frameId = this._selectedFrameId();
+ this._target.profilingLock.acquire();
CanvasAgent.startCapturing(frameId, this._didStartCapturingFrame.bind(this, frameId));
},
_stopFrameCapturing: function()
{
- if (!this._lastProfileHeader)
+ if (!this._lastProfileHeader) {
+ this._target.profilingLock.release();
return;
+ }
var profileHeader = this._lastProfileHeader;
var traceLogId = profileHeader.traceLogId();
this._lastProfileHeader = null;
@@ -716,7 +712,8 @@ WebInspector.CanvasProfileType.prototype = {
{
profileHeader._updateCapturingStatus();
}
- CanvasAgent.stopCapturing(traceLogId, didStopCapturing.bind(this));
+ CanvasAgent.stopCapturing(traceLogId, didStopCapturing);
+ this._target.profilingLock.release();
},
/**
@@ -728,8 +725,7 @@ WebInspector.CanvasProfileType.prototype = {
{
if (error || this._lastProfileHeader && this._lastProfileHeader.traceLogId() === traceLogId)
return;
- var profileHeader = new WebInspector.CanvasProfileHeader(this, WebInspector.UIString("Trace Log %d", this._nextProfileUid), this._nextProfileUid, traceLogId, frameId);
- ++this._nextProfileUid;
+ var profileHeader = new WebInspector.CanvasProfileHeader(this._target, this, traceLogId, frameId);
this._lastProfileHeader = profileHeader;
this.addProfile(profileHeader);
profileHeader._updateCapturingStatus();
@@ -756,15 +752,6 @@ WebInspector.CanvasProfileType.prototype = {
/**
* @override
- */
- _reset: function()
- {
- WebInspector.ProfileType.prototype._reset.call(this);
- this._nextProfileUid = 1;
- },
-
- /**
- * @override
* @param {!WebInspector.ProfileHeader} profile
*/
removeProfile: function(profile)
@@ -787,6 +774,7 @@ WebInspector.CanvasProfileType.prototype = {
button.textContent = this._canvasAgentEnabled ? WebInspector.UIString("Disable") : WebInspector.UIString("Enable");
button.addEventListener("click", this._onProfilerEnableButtonClick.bind(this, !this._canvasAgentEnabled), false);
+ var target = this._target;
/**
* @param {?Protocol.Error} error
* @param {boolean} result
@@ -794,16 +782,16 @@ WebInspector.CanvasProfileType.prototype = {
function hasUninstrumentedCanvasesCallback(error, result)
{
if (error || result)
- WebInspector.resourceTreeModel.reloadPage();
+ target.resourceTreeModel.reloadPage();
}
if (forcePageReload) {
if (this._canvasAgentEnabled) {
- CanvasAgent.hasUninstrumentedCanvases(hasUninstrumentedCanvasesCallback.bind(this));
+ CanvasAgent.hasUninstrumentedCanvases(hasUninstrumentedCanvasesCallback);
} else {
for (var frameId in this._framesWithCanvases) {
if (this._framesWithCanvases.hasOwnProperty(frameId)) {
- WebInspector.resourceTreeModel.reloadPage();
+ target.resourceTreeModel.reloadPage();
break;
}
}
@@ -850,19 +838,19 @@ WebInspector.CanvasProfileType.prototype = {
*/
_frameAdded: function(event)
{
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- this._addFrame(contextList);
+ var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
+ this._addFrame(frame);
},
/**
- * @param {!WebInspector.FrameExecutionContextList} contextList
+ * @param {!WebInspector.ResourceTreeFrame} frame
*/
- _addFrame: function(contextList)
+ _addFrame: function(frame)
{
- var frameId = contextList.frameId;
+ var frameId = frame.id;
var option = document.createElement("option");
- option.text = contextList.displayName;
- option.title = contextList.url;
+ option.text = frame.displayName();
+ option.title = frame.url;
option.value = frameId;
this._frameOptions[frameId] = option;
@@ -878,8 +866,8 @@ WebInspector.CanvasProfileType.prototype = {
*/
_frameRemoved: function(event)
{
- var contextList = /** @type {!WebInspector.FrameExecutionContextList} */ (event.data);
- var frameId = contextList.frameId;
+ var frame = /** @type {!WebInspector.ResourceTreeFrame} */ (event.data);
+ var frameId = frame.id;
var option = this._frameOptions[frameId];
if (option && this._framesWithCanvases[frameId]) {
this._frameSelector.removeOption(option);
@@ -937,7 +925,7 @@ WebInspector.CanvasProfileType.prototype = {
_dispatchViewUpdatedEvent: function()
{
- this._frameSelector.element.enableStyleClass("hidden", this._frameSelector.size() <= 1);
+ this._frameSelector.element.classList.toggle("hidden", this._frameSelector.size() <= 1);
this.dispatchEventToListeners(WebInspector.ProfileType.Events.ViewUpdated);
},
@@ -995,15 +983,14 @@ WebInspector.CanvasDispatcher.prototype = {
/**
* @constructor
* @extends {WebInspector.ProfileHeader}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.CanvasProfileType} type
- * @param {string} title
- * @param {number=} uid
* @param {!CanvasAgent.TraceLogId=} traceLogId
* @param {!PageAgent.FrameId=} frameId
*/
-WebInspector.CanvasProfileHeader = function(type, title, uid, traceLogId, frameId)
+WebInspector.CanvasProfileHeader = function(target, type, traceLogId, frameId)
{
- WebInspector.ProfileHeader.call(this, type, title, uid);
+ WebInspector.ProfileHeader.call(this, target, type, WebInspector.UIString("Trace Log %d", type._nextProfileUid));
/** @type {!CanvasAgent.TraceLogId} */
this._traceLogId = traceLogId || "";
this._frameId = frameId;
@@ -1039,18 +1026,19 @@ WebInspector.CanvasProfileHeader.prototype = {
/**
* @override
+ * @param {!WebInspector.ProfilesPanel} panel
* @return {!WebInspector.ProfileSidebarTreeElement}
*/
- createSidebarTreeElement: function()
+ createSidebarTreeElement: function(panel)
{
- return new WebInspector.ProfileSidebarTreeElement(this, "profile-sidebar-tree-item");
+ return new WebInspector.ProfileSidebarTreeElement(panel, this, "profile-sidebar-tree-item");
},
/**
* @override
- * @param {!WebInspector.ProfilesPanel} profilesPanel
+ * @return {!WebInspector.CanvasProfileView}
*/
- createView: function(profilesPanel)
+ createView: function()
{
return new WebInspector.CanvasProfileView(this);
},
@@ -1071,7 +1059,7 @@ WebInspector.CanvasProfileHeader.prototype = {
*/
_updateCapturingStatus: function(traceLog)
{
- if (!this.sidebarElement || !this._traceLogId)
+ if (!this._traceLogId)
return;
if (traceLog) {
@@ -1079,8 +1067,8 @@ WebInspector.CanvasProfileHeader.prototype = {
this._traceLogSize = traceLog.totalAvailableCalls;
}
- this.sidebarElement.subtitle = this._alive ? WebInspector.UIString("Capturing\u2026 %d calls", this._traceLogSize) : WebInspector.UIString("Captured %d calls", this._traceLogSize);
- this.sidebarElement.wait = this._alive;
+ var subtitle = this._alive ? WebInspector.UIString("Capturing\u2026 %d calls", this._traceLogSize) : WebInspector.UIString("Captured %d calls", this._traceLogSize);
+ this.updateStatus(subtitle, this._alive);
if (this._alive) {
clearTimeout(this._requestStatusTimer);
@@ -1127,7 +1115,7 @@ WebInspector.CanvasProfileDataGridHelper = {
element.createTextChild("\"");
element.__suppressPopover = (description.length <= maxStringLength && !/[\r\n]/.test(description));
if (!element.__suppressPopover)
- element.__evalResult = WebInspector.RemoteObject.fromPrimitiveValue(description);
+ element.__evalResult = WebInspector.runtimeModel.createRemoteObjectFromPrimitiveValue(description);
} else {
var type = callArgument.subtype || callArgument.type;
if (type) {
@@ -1137,7 +1125,7 @@ WebInspector.CanvasProfileDataGridHelper = {
}
element.textContent = description;
if (callArgument.remoteObject)
- element.__evalResult = WebInspector.RemoteObject.fromPayload(callArgument.remoteObject);
+ element.__evalResult = WebInspector.runtimeModel.createRemoteObject(callArgument.remoteObject);
}
if (callArgument.resourceId) {
element.classList.add("canvas-formatted-resource");
@@ -1156,7 +1144,7 @@ WebInspector.CanvasProfileDataGridHelper = {
var element = document.createElement("span");
element.className = "canvas-call-argument canvas-formatted-number";
element.textContent = enumName;
- element.__evalResult = WebInspector.RemoteObject.fromPrimitiveValue(enumValue);
+ element.__evalResult = WebInspector.runtimeModel.createRemoteObjectFromPrimitiveValue(enumValue);
return element;
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CanvasReplayStateView.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasReplayStateView.js
index 8ca9b75c07b..dedb14c2b4b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CanvasReplayStateView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/CanvasReplayStateView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.CanvasTraceLogPlayerProxy} traceLogPlayer
*/
WebInspector.CanvasReplayStateView = function(traceLogPlayer)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("canvasProfiler.css");
this.element.classList.add("canvas-replay-state-view");
this._traceLogPlayer = traceLogPlayer;
@@ -54,7 +54,7 @@ WebInspector.CanvasReplayStateView = function(traceLogPlayer)
/** @type {!Object.<string, !Object.<string, boolean>>} */
this._gridNodesExpandedState = {};
- /** @type {!Object.<string, {scrollTop:number, scrollLeft:number}>} */
+ /** @type {!Object.<string, !{scrollTop: number, scrollLeft: number}>} */
this._gridScrollPositions = {};
/** @type {?CanvasAgent.ResourceId} */
@@ -384,16 +384,14 @@ WebInspector.CanvasReplayStateView.prototype = {
*/
_updateDataGridHighlights: function(nodes)
{
- for (var i = 0, n = this._highlightedGridNodes.length; i < n; ++i) {
- var node = this._highlightedGridNodes[i];
- node.element.classList.remove("canvas-grid-node-highlighted");
- }
+ for (var i = 0, n = this._highlightedGridNodes.length; i < n; ++i)
+ this._highlightedGridNodes[i].element.classList.remove("canvas-grid-node-highlighted");
this._highlightedGridNodes = nodes;
for (var i = 0, n = this._highlightedGridNodes.length; i < n; ++i) {
var node = this._highlightedGridNodes[i];
- node.element.classList.add("canvas-grid-node-highlighted");
+ WebInspector.runCSSAnimationOnce(node.element, "canvas-grid-node-highlighted");
node.reveal();
}
},
@@ -527,5 +525,5 @@ WebInspector.CanvasReplayStateView.prototype = {
return node;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotCommon.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotCommon.js
new file mode 100644
index 00000000000..1effb8aa78b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotCommon.js
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.HeapSnapshotProgressEvent = {
+ Update: "ProgressUpdate"
+};
+
+WebInspector.HeapSnapshotCommon = {
+}
+
+WebInspector.HeapSnapshotCommon.baseSystemDistance = 100000000;
+
+/**
+ * @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} nodesWithSingleCaller
+ * @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} branchingCallers
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.AllocationNodeCallers = function(nodesWithSingleCaller, branchingCallers)
+{
+ /** @type {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */
+ this.nodesWithSingleCaller = nodesWithSingleCaller;
+ /** @type {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} */
+ this.branchingCallers = branchingCallers;
+}
+
+/**
+ * @param {number} nodeId
+ * @param {string} functionName
+ * @param {string} scriptName
+ * @param {number} scriptId
+ * @param {number} line
+ * @param {number} column
+ * @param {number} count
+ * @param {number} size
+ * @param {number} liveCount
+ * @param {number} liveSize
+ * @param {boolean} hasChildren
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.SerializedAllocationNode = function(nodeId, functionName, scriptName, scriptId, line, column, count, size, liveCount, liveSize, hasChildren)
+{
+ /** @type {number} */
+ this.id = nodeId;
+ /** @type {string} */
+ this.name = functionName;
+ /** @type {string} */
+ this.scriptName = scriptName;
+ /** @type {number} */
+ this.scriptId = scriptId;
+ /** @type {number} */
+ this.line = line;
+ /** @type {number} */
+ this.column = column;
+ /** @type {number} */
+ this.count = count;
+ /** @type {number} */
+ this.size = size;
+ /** @type {number} */
+ this.liveCount = liveCount;
+ /** @type {number} */
+ this.liveSize = liveSize;
+ /** @type {boolean} */
+ this.hasChildren = hasChildren;
+}
+
+/**
+ * @param {string} functionName
+ * @param {string} scriptName
+ * @param {number} scriptId
+ * @param {number} line
+ * @param {number} column
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.AllocationStackFrame = function(functionName, scriptName, scriptId, line, column)
+{
+ /** @type {string} */
+ this.functionName = functionName;
+ /** @type {string} */
+ this.scriptName = scriptName;
+ /** @type {number} */
+ this.scriptId = scriptId;
+ /** @type {number} */
+ this.line = line;
+ /** @type {number} */
+ this.column = column;
+}
+
+/**
+ * @constructor
+ * @param {number} id
+ * @param {string} name
+ * @param {number} distance
+ * @param {number} nodeIndex
+ * @param {number} retainedSize
+ * @param {number} selfSize
+ * @param {string} type
+ */
+WebInspector.HeapSnapshotCommon.Node = function(id, name, distance, nodeIndex, retainedSize, selfSize, type)
+{
+ this.id = id;
+ this.name = name;
+ this.distance = distance;
+ this.nodeIndex = nodeIndex;
+ this.retainedSize = retainedSize;
+ this.selfSize = selfSize;
+ this.type = type;
+
+ this.canBeQueried = false;
+ this.detachedDOMTreeNode = false;
+}
+
+/**
+ * @constructor
+ * @param {string} name
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
+ * @param {string} type
+ * @param {number} edgeIndex
+ */
+WebInspector.HeapSnapshotCommon.Edge = function(name, node, type, edgeIndex)
+{
+ this.name = name;
+ this.node = node;
+ this.type = type;
+ this.edgeIndex = edgeIndex;
+};
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.Aggregate = function()
+{
+ /** @type {number} */
+ this.count;
+ /** @type {number} */
+ this.distance;
+ /** @type {number} */
+ this.self;
+ /** @type {number} */
+ this.maxRet;
+ /** @type {number} */
+ this.type;
+ /** @type {string} */
+ this.name;
+ /** @type {!Array.<number>} */
+ this.idxs;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.AggregateForDiff = function() {
+ /** @type {!Array.<number>} */
+ this.indexes = [];
+ /** @type {!Array.<string>} */
+ this.ids = [];
+ /** @type {!Array.<number>} */
+ this.selfSizes = [];
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.Diff = function()
+{
+ /** @type {number} */
+ this.addedCount = 0;
+ /** @type {number} */
+ this.removedCount = 0;
+ /** @type {number} */
+ this.addedSize = 0;
+ /** @type {number} */
+ this.removedSize = 0;
+ /** @type {!Array.<number>} */
+ this.deletedIndexes = [];
+ /** @type {!Array.<number>} */
+ this.addedIndexes = [];
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.DiffForClass = function()
+{
+ /** @type {number} */
+ this.addedCount;
+ /** @type {number} */
+ this.removedCount;
+ /** @type {number} */
+ this.addedSize;
+ /** @type {number} */
+ this.removedSize;
+ /** @type {!Array.<number>} */
+ this.deletedIndexes;
+ /** @type {!Array.<number>} */
+ this.addedIndexes;
+
+ /** @type {number} */
+ this.countDelta;
+ /** @type {number} */
+ this.sizeDelta;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.ComparatorConfig = function()
+{
+ /** @type {string} */
+ this.fieldName1;
+ /** @type {boolean} */
+ this.ascending1;
+ /** @type {string} */
+ this.fieldName2;
+ /** @type {boolean} */
+ this.ascending2;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.WorkerCommand = function()
+{
+ /** @type {number} */
+ this.callId;
+ /** @type {string} */
+ this.disposition;
+ /** @type {number} */
+ this.objectId;
+ /** @type {number} */
+ this.newObjectId;
+ /** @type {string} */
+ this.methodName;
+ /** @type {!Array.<*>} */
+ this.methodArguments;
+ /** @type {string} */
+ this.source;
+}
+
+/**
+ * @constructor
+ * @param {number} startPosition
+ * @param {number} endPosition
+ * @param {number} totalLength
+ * @param {!Array.<*>} items
+ */
+WebInspector.HeapSnapshotCommon.ItemsRange = function(startPosition, endPosition, totalLength, items)
+{
+ /** @type {number} */
+ this.startPosition = startPosition;
+ /** @type {number} */
+ this.endPosition = endPosition;
+ /** @type {number} */
+ this.totalLength = totalLength;
+ /** @type {!Array.<*>} */
+ this.items = items;
+}
+
+/**
+ * @param {number} nodeCount
+ * @param {number} rootNodeIndex
+ * @param {number} totalSize
+ * @param {number} maxJSObjectId
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.StaticData = function(nodeCount, rootNodeIndex, totalSize, maxJSObjectId)
+{
+ /** @type {number} */
+ this.nodeCount = nodeCount;
+ /** @type {number} */
+ this.rootNodeIndex = rootNodeIndex;
+ /** @type {number} */
+ this.totalSize = totalSize;
+ /** @type {number} */
+ this.maxJSObjectId = maxJSObjectId;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.Statistics = function()
+{
+ /** @type {number} */
+ this.total;
+ /** @type {number} */
+ this.v8heap;
+ /** @type {number} */
+ this.native;
+ /** @type {number} */
+ this.code;
+ /** @type {number} */
+ this.jsArrays;
+ /** @type {number} */
+ this.strings;
+}
+
+
+/**
+ * @param {number=} minNodeId
+ * @param {number=} maxNodeId
+ * @constructor
+ */
+WebInspector.HeapSnapshotCommon.NodeFilter = function(minNodeId, maxNodeId)
+{
+ /** @type {number|undefined} */
+ this.minNodeId = minNodeId;
+ /** @type {number|undefined} */
+ this.maxNodeId = maxNodeId;
+ /** @type {number|undefined} */
+ this.allocationNodeId;
+}
+
+WebInspector.HeapSnapshotCommon.NodeFilter.prototype =
+{
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} o
+ * @return {boolean}
+ */
+ equals: function(o)
+ {
+ return this.minNodeId === o.minNodeId && this.maxNodeId === o.maxNodeId && this.allocationNodeId === o.allocationNodeId;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotDataGrids.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotDataGrids.js
index 44346406462..6b7ee735104 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotDataGrids.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotDataGrids.js
@@ -31,10 +31,13 @@
/**
* @constructor
* @extends {WebInspector.DataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
-WebInspector.HeapSnapshotSortableDataGrid = function(columns)
+WebInspector.HeapSnapshotSortableDataGrid = function(dataDisplayDelegate, columns)
{
WebInspector.DataGrid.call(this, columns);
+ this._dataDisplayDelegate = dataDisplayDelegate;
/**
* @type {number}
@@ -48,16 +51,29 @@ WebInspector.HeapSnapshotSortableDataGrid = function(columns)
* @type {boolean}
*/
this._populatedAndSorted = false;
- this.addEventListener("sorting complete", this._sortingComplete, this);
+ /**
+ * @type {?WebInspector.StatusBarInput}
+ */
+ this._nameFilter = null;
+ this.addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
this.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this.sortingChanged, this);
}
WebInspector.HeapSnapshotSortableDataGrid.Events = {
- ContentShown: "ContentShown"
+ ContentShown: "ContentShown",
+ SortingComplete: "SortingComplete"
}
WebInspector.HeapSnapshotSortableDataGrid.prototype = {
/**
+ * @param {!WebInspector.StatusBarInput} nameFilter
+ */
+ setNameFilter: function(nameFilter)
+ {
+ this._nameFilter = nameFilter;
+ },
+
+ /**
* @return {number}
*/
defaultPopulateCount: function()
@@ -65,7 +81,7 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
return 100;
},
- dispose: function()
+ _disposeAllNodes: function()
{
var children = this.topLevelNodes();
for (var i = 0, l = children.length; i < l; ++i)
@@ -77,13 +93,17 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
*/
wasShown: function()
{
+ if (this._nameFilter) {
+ this._nameFilter.addEventListener(WebInspector.StatusBarInput.Event.TextChanged, this._onNameFilterChanged, this);
+ this.updateVisibleNodes(true);
+ }
if (this._populatedAndSorted)
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
},
_sortingComplete: function()
{
- this.removeEventListener("sorting complete", this._sortingComplete, this);
+ this.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete, this._sortingComplete, this);
this._populatedAndSorted = true;
this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, this);
},
@@ -93,33 +113,42 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
*/
willHide: function()
{
+ if (this._nameFilter)
+ this._nameFilter.removeEventListener(WebInspector.StatusBarInput.Event.TextChanged, this._onNameFilterChanged, this);
this._clearCurrentHighlight();
},
/**
- * @param {!WebInspector.ProfilesPanel} profilesPanel
* @param {!WebInspector.ContextMenu} contextMenu
* @param {?Event} event
*/
- populateContextMenu: function(profilesPanel, contextMenu, event)
+ populateContextMenu: function(contextMenu, event)
{
var td = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!td)
return;
var node = td.heapSnapshotNode;
+
+ /**
+ * @this {WebInspector.HeapSnapshotSortableDataGrid}
+ */
function revealInDominatorsView()
{
- profilesPanel.showObject(node.snapshotNodeId, "Dominators");
+ this._dataDisplayDelegate.showObject(node.snapshotNodeId, "Dominators");
}
+
+ /**
+ * @this {WebInspector.HeapSnapshotSortableDataGrid}
+ */
function revealInSummaryView()
{
- profilesPanel.showObject(node.snapshotNodeId, "Summary");
+ this._dataDisplayDelegate.showObject(node.snapshotNodeId, "Summary");
}
- if(node && node.showRetainingEdges) {
+
+ if (node instanceof WebInspector.HeapSnapshotRetainingObjectNode) {
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Summary view" : "Reveal in Summary View"), revealInSummaryView.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Dominators view" : "Reveal in Dominators View"), revealInDominatorsView.bind(this));
- }
- else if (node instanceof WebInspector.HeapSnapshotInstanceNode || node instanceof WebInspector.HeapSnapshotObjectNode) {
+ } else if (node instanceof WebInspector.HeapSnapshotInstanceNode || node instanceof WebInspector.HeapSnapshotObjectNode) {
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Dominators view" : "Reveal in Dominators View"), revealInDominatorsView.bind(this));
} else if (node instanceof WebInspector.HeapSnapshotDominatorObjectNode) {
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Summary view" : "Reveal in Summary View"), revealInSummaryView.bind(this));
@@ -132,6 +161,9 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
delete this._lastSortAscending;
},
+ /**
+ * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
+ */
topLevelNodes: function()
{
return this.rootNode().children;
@@ -153,15 +185,7 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
var prevNode = this._highlightedNode;
this._clearCurrentHighlight();
this._highlightedNode = node;
- this._highlightedNode.element.classList.add("highlighted-row");
- // If highlighted node hasn't changed reinsert it to make the highlight animation restart.
- if (node === prevNode) {
- var element = node.element;
- var parent = element.parentElement;
- var nextSibling = element.nextSibling;
- parent.removeChild(element);
- parent.insertBefore(element, nextSibling);
- }
+ WebInspector.runCSSAnimationOnce(this._highlightedNode.element, "highlighted-row");
},
nodeWasDetached: function(node)
@@ -178,16 +202,15 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
this._highlightedNode = null;
},
- changeNameFilter: function(filter)
+ resetNameFilter: function()
{
- filter = filter.toLowerCase();
- var children = this.topLevelNodes();
- for (var i = 0, l = children.length; i < l; ++i) {
- var node = children[i];
- if (node.depth === 0)
- node.revealed = node._name.toLowerCase().indexOf(filter) !== -1;
- }
- this.updateVisibleNodes();
+ this._nameFilter.setValue("");
+ this._onNameFilterChanged();
+ },
+
+ _onNameFilterChanged: function()
+ {
+ this.updateVisibleNodes(true);
},
sortingChanged: function()
@@ -222,7 +245,7 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
_performSorting: function(sortFunction)
{
this.recursiveSortingEnter();
- var children = this._topLevelNodes;
+ var children = this.allChildren(this.rootNode());
this.rootNode().removeChildren();
children.sort(sortFunction);
for (var i = 0, l = children.length; i < l; ++i) {
@@ -231,7 +254,6 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
if (child.expanded)
child.sort();
}
- this.updateVisibleNodes();
this.recursiveSortingLeave();
},
@@ -242,10 +264,6 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
child.revealed = revealed;
},
- updateVisibleNodes: function()
- {
- },
-
recursiveSortingEnter: function()
{
++this._recursiveSortingDepth;
@@ -255,36 +273,88 @@ WebInspector.HeapSnapshotSortableDataGrid.prototype = {
{
if (!this._recursiveSortingDepth)
return;
- if (!--this._recursiveSortingDepth)
- this.dispatchEventToListeners("sorting complete");
+ if (--this._recursiveSortingDepth)
+ return;
+ this.updateVisibleNodes(true);
+ this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);
+ },
+
+ /**
+ * @param {boolean} force
+ */
+ updateVisibleNodes: function(force)
+ {
+ },
+
+ /**
+ * @param {!WebInspector.DataGridNode} parent
+ * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
+ */
+ allChildren: function(parent)
+ {
+ return parent.children;
+ },
+
+ /**
+ * @param {!WebInspector.DataGridNode} parent
+ * @param {!WebInspector.DataGridNode} node
+ * @param {number} index
+ */
+ insertChild: function(parent, node, index)
+ {
+ parent.insertChild(node, index);
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotGridNode} parent
+ * @param {number} index
+ */
+ removeChildByIndex: function(parent, index)
+ {
+ parent.removeChild(parent.children[index]);
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotGridNode} parent
+ */
+ removeAllChildren: function(parent)
+ {
+ parent.removeChildren();
},
__proto__: WebInspector.DataGrid.prototype
}
-
/**
* @constructor
* @extends {WebInspector.HeapSnapshotSortableDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>} columns
*/
-WebInspector.HeapSnapshotViewportDataGrid = function(columns)
+WebInspector.HeapSnapshotViewportDataGrid = function(dataDisplayDelegate, columns)
{
- WebInspector.HeapSnapshotSortableDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotSortableDataGrid.call(this, dataDisplayDelegate, columns);
this.scrollContainer.addEventListener("scroll", this._onScroll.bind(this), true);
- this._topLevelNodes = [];
- this._topPadding = new WebInspector.HeapSnapshotPaddingNode();
- this._bottomPadding = new WebInspector.HeapSnapshotPaddingNode();
/**
* @type {?WebInspector.HeapSnapshotGridNode}
*/
this._nodeToHighlightAfterScroll = null;
+ this._topPadding = new WebInspector.HeapSnapshotPaddingNode();
+ this._topPaddingHeight = 0;
+ this.dataTableBody.insertBefore(this._topPadding.element, this.dataTableBody.firstChild);
+ this._bottomPadding = new WebInspector.HeapSnapshotPaddingNode();
+ this._bottomPaddingHeight = 0;
+ this.dataTableBody.insertBefore(this._bottomPadding.element, this.dataTableBody.lastChild);
}
WebInspector.HeapSnapshotViewportDataGrid.prototype = {
+ /**
+ * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
+ */
topLevelNodes: function()
{
- return this._topLevelNodes;
+ return this.allChildren(this.rootNode());
},
appendChildAfterSorting: function(child)
@@ -292,93 +362,187 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
// Do nothing here, it will be added in updateVisibleNodes.
},
- updateVisibleNodes: function()
+ /**
+ * @override
+ * @param {boolean} force
+ * @param {!Array.<!WebInspector.HeapSnapshotGridNode>=} pathToReveal
+ */
+ updateVisibleNodes: function(force, pathToReveal)
{
+ // Guard zone is used to ensure there are always some extra items
+ // above and below the viewport to support keyboard navigation.
+ var guardZoneHeight = 40;
+ var scrollHeight = this.scrollContainer.scrollHeight;
var scrollTop = this.scrollContainer.scrollTop;
- var children = this._topLevelNodes;
-
- var i = 0;
- var topPadding = 0;
- while (i < children.length) {
- if (children[i].revealed) {
- var newTop = topPadding + children[i].nodeHeight();
- if (newTop > scrollTop)
- break;
- topPadding = newTop;
- }
- ++i;
+ var scrollBottom = scrollHeight - scrollTop - this.scrollContainer.offsetHeight;
+ scrollTop = Math.max(0, scrollTop - guardZoneHeight);
+ scrollBottom = Math.max(0, scrollBottom - guardZoneHeight);
+ var viewPortHeight = scrollHeight - scrollTop - scrollBottom;
+ if (!pathToReveal) {
+ // Do nothing if populated nodes still fit the viewport.
+ if (!force && scrollTop >= this._topPaddingHeight && scrollBottom >= this._bottomPaddingHeight)
+ return;
+ var hysteresisHeight = 500;
+ scrollTop -= hysteresisHeight;
+ viewPortHeight += 2 * hysteresisHeight;
}
-
- this._addVisibleNodes(i, scrollTop - topPadding, topPadding);
- },
-
- _addVisibleNodes: function(firstVisibleNodeIndex, firstNodeHiddenHeight, topPadding)
- {
- var viewPortHeight = this.scrollContainer.offsetHeight;
- this._removePaddingRows();
-
- var children = this._topLevelNodes;
var selectedNode = this.selectedNode;
-
this.rootNode().removeChildren();
- // The height of the view port + invisible top part.
- var heightToFill = viewPortHeight + firstNodeHiddenHeight;
- var filledHeight = 0;
- var i = firstVisibleNodeIndex;
- while (i < children.length && filledHeight < heightToFill) {
- if (children[i].revealed) {
- this.rootNode().appendChild(children[i]);
- filledHeight += children[i].nodeHeight();
- }
- ++i;
- }
- var bottomPadding = 0;
- while (i < children.length) {
- bottomPadding += children[i].nodeHeight();
- ++i;
- }
+ this._topPaddingHeight = 0;
+ this._bottomPaddingHeight = 0;
- this._addPaddingRows(topPadding, bottomPadding);
+ this._addVisibleNodes(this.rootNode(), scrollTop, scrollTop + viewPortHeight, pathToReveal || null);
+
+ this._topPadding.setHeight(this._topPaddingHeight);
+ this._bottomPadding.setHeight(this._bottomPaddingHeight);
if (selectedNode) {
- if (selectedNode.parent) {
+ // Keep selection even if the node is not in the current viewport.
+ if (selectedNode.parent)
selectedNode.select(true);
- } else {
- // Keep selection even if the node is not in the current viewport.
+ else
this.selectedNode = selectedNode;
- }
}
},
- _revealTopLevelNode: function(nodeToReveal)
+ /**
+ * @param {!WebInspector.DataGridNode} parentNode
+ * @param {number} topBound
+ * @param {number} bottomBound
+ * @param {?Array.<!WebInspector.HeapSnapshotGridNode>} pathToReveal
+ * @return {number}
+ */
+ _addVisibleNodes: function(parentNode, topBound, bottomBound, pathToReveal)
{
- var children = this._topLevelNodes;
+ if (!parentNode.expanded)
+ return 0;
- var i = 0;
+ var nodeToReveal = pathToReveal ? pathToReveal[0] : null;
+ var restPathToReveal = pathToReveal && pathToReveal.length > 1 ? pathToReveal.slice(1) : null;
+ var children = this.allChildren(parentNode);
var topPadding = 0;
- while (i < children.length) {
- if (children[i] === nodeToReveal)
+ var nameFilterValue = this._nameFilter ? this._nameFilter.value().toLowerCase() : "";
+ // Iterate over invisible nodes beyond the upper bound of viewport.
+ // Do not insert them into the grid, but count their total height.
+ for (var i = 0; i < children.length; ++i) {
+ var child = children[i];
+ if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
+ continue;
+ var newTop = topPadding + this._nodeHeight(child);
+ if (nodeToReveal === child || (!nodeToReveal && newTop > topBound))
break;
- if (children[i].revealed) {
- var newTop = topPadding + children[i].nodeHeight();
- topPadding = newTop;
- }
- ++i;
+ topPadding = newTop;
+ }
+
+ // Put visible nodes into the data grid.
+ var position = topPadding;
+ for (; i < children.length && (nodeToReveal || position < bottomBound); ++i) {
+ var child = children[i];
+ if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
+ continue;
+ var hasChildren = child.hasChildren;
+ child.removeChildren();
+ child.hasChildren = hasChildren;
+ child.revealed = true;
+ parentNode.appendChild(child);
+ position += child.nodeSelfHeight();
+ position += this._addVisibleNodes(child, topBound - position, bottomBound - position, restPathToReveal);
+ if (nodeToReveal === child)
+ break;
+ }
+
+ // Count the invisible nodes beyond the bottom bound of the viewport.
+ var bottomPadding = 0;
+ for (; i < children.length; ++i) {
+ var child = children[i];
+ if (nameFilterValue && child.filteredOut && child.filteredOut(nameFilterValue))
+ continue;
+ bottomPadding += this._nodeHeight(child);
}
- this._addVisibleNodes(i, 0, topPadding);
+ this._topPaddingHeight += topPadding;
+ this._bottomPaddingHeight += bottomPadding;
+ return position + bottomPadding;
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotGridNode} node
+ * @return {number}
+ */
+ _nodeHeight: function(node)
+ {
+ if (!node.revealed)
+ return 0;
+ var result = node.nodeSelfHeight();
+ if (!node.expanded)
+ return result;
+ var children = this.allChildren(node);
+ for (var i = 0; i < children.length; i++)
+ result += this._nodeHeight(children[i]);
+ return result;
+ },
+
+ /**
+ * @override
+ * @return {?Element}
+ */
+ defaultAttachLocation: function()
+ {
+ return this._bottomPadding.element;
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.HeapSnapshotGridNode>} pathToReveal
+ */
+ revealTreeNode: function(pathToReveal)
+ {
+ this.updateVisibleNodes(true, pathToReveal);
+ },
+
+ /**
+ * @param {!WebInspector.DataGridNode} parent
+ * @return {!Array.<!WebInspector.HeapSnapshotGridNode>}
+ */
+ allChildren: function(parent)
+ {
+ return parent._allChildren || (parent._allChildren = []);
+ },
+
+ /**
+ * @param {!WebInspector.DataGridNode} parent
+ * @param {!WebInspector.DataGridNode} node
+ */
+ appendNode: function(parent, node)
+ {
+ this.allChildren(parent).push(node);
+ },
+
+ /**
+ * @param {!WebInspector.DataGridNode} parent
+ * @param {!WebInspector.DataGridNode} node
+ * @param {number} index
+ */
+ insertChild: function(parent, node, index)
+ {
+ this.allChildren(parent).splice(index, 0, node);
},
- appendTopLevelNode: function(node)
+ removeChildByIndex: function(parent, index)
{
- this._topLevelNodes.push(node);
+ this.allChildren(parent).splice(index, 1);
+ },
+
+ removeAllChildren: function(parent)
+ {
+ parent._allChildren = [];
},
removeTopLevelNodes: function()
{
+ this._disposeAllNodes();
this.rootNode().removeChildren();
- this._topLevelNodes = [];
+ this.rootNode()._allChildren = [];
},
/**
@@ -387,14 +551,19 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
*/
highlightNode: function(node)
{
- if (this._isScrolledIntoView(node.element))
+ if (this._isScrolledIntoView(node.element)) {
+ this.updateVisibleNodes(true);
WebInspector.HeapSnapshotSortableDataGrid.prototype.highlightNode.call(this, node);
- else {
+ } else {
node.element.scrollIntoViewIfNeeded(true);
this._nodeToHighlightAfterScroll = node;
}
},
+ /**
+ * @param {!Element} element
+ * @return {boolean}
+ */
_isScrolledIntoView: function(element)
{
var viewportTop = this.scrollContainer.scrollTop;
@@ -404,31 +573,15 @@ WebInspector.HeapSnapshotViewportDataGrid.prototype = {
return elemBottom <= viewportBottom && elemTop >= viewportTop;
},
- _addPaddingRows: function(top, bottom)
- {
- if (this._topPadding.element.parentNode !== this.dataTableBody)
- this.dataTableBody.insertBefore(this._topPadding.element, this.dataTableBody.firstChild);
- if (this._bottomPadding.element.parentNode !== this.dataTableBody)
- this.dataTableBody.insertBefore(this._bottomPadding.element, this.dataTableBody.lastChild);
- this._topPadding.setHeight(top);
- this._bottomPadding.setHeight(bottom);
- },
-
- _removePaddingRows: function()
- {
- this._bottomPadding.removeFromTable();
- this._topPadding.removeFromTable();
- },
-
onResize: function()
{
WebInspector.HeapSnapshotSortableDataGrid.prototype.onResize.call(this);
- this.updateVisibleNodes();
+ this.updateVisibleNodes(false);
},
_onScroll: function(event)
{
- this.updateVisibleNodes();
+ this.updateVisibleNodes(false);
if (this._nodeToHighlightAfterScroll) {
WebInspector.HeapSnapshotSortableDataGrid.prototype.highlightNode.call(this, this._nodeToHighlightAfterScroll);
@@ -446,6 +599,7 @@ WebInspector.HeapSnapshotPaddingNode = function()
{
this.element = document.createElement("tr");
this.element.classList.add("revealed");
+ this.setHeight(0);
}
WebInspector.HeapSnapshotPaddingNode.prototype = {
@@ -465,9 +619,10 @@ WebInspector.HeapSnapshotPaddingNode.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotSortableDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!Array.<!WebInspector.DataGrid.ColumnDescriptor>=} columns
*/
-WebInspector.HeapSnapshotContainmentDataGrid = function(columns)
+WebInspector.HeapSnapshotContainmentDataGrid = function(dataDisplayDelegate, columns)
{
columns = columns || [
{id: "object", title: WebInspector.UIString("Object"), disclosure: true, sortable: true},
@@ -475,22 +630,33 @@ WebInspector.HeapSnapshotContainmentDataGrid = function(columns)
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sortable: true, sort: WebInspector.DataGrid.Order.Descending}
];
- WebInspector.HeapSnapshotSortableDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotSortableDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotContainmentDataGrid.prototype = {
+ /**
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot
+ * @param {number} nodeIndex
+ */
setDataSource: function(snapshot, nodeIndex)
{
this.snapshot = snapshot;
- var node = new WebInspector.HeapSnapshotNode(snapshot, nodeIndex || snapshot.rootNodeIndex);
+ var node = { nodeIndex: nodeIndex || snapshot.rootNodeIndex };
var fakeEdge = { node: node };
- this.setRootNode(new WebInspector.HeapSnapshotObjectNode(this, false, fakeEdge, null));
+ this.setRootNode(this._createRootNode(snapshot, fakeEdge));
this.rootNode().sort();
},
+ _createRootNode: function(snapshot, fakeEdge)
+ {
+ return new WebInspector.HeapSnapshotObjectNode(this, snapshot, fakeEdge, null);
+ },
+
sortingChanged: function()
{
- this.rootNode().sort();
+ var rootNode = this.rootNode();
+ if (rootNode.hasChildren)
+ rootNode.sort();
},
__proto__: WebInspector.HeapSnapshotSortableDataGrid.prototype
@@ -500,17 +666,17 @@ WebInspector.HeapSnapshotContainmentDataGrid.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotContainmentDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
-WebInspector.HeapSnapshotRetainmentDataGrid = function()
+WebInspector.HeapSnapshotRetainmentDataGrid = function(dataDisplayDelegate)
{
- this.showRetainingEdges = true;
var columns = [
{id: "object", title: WebInspector.UIString("Object"), disclosure: true, sortable: true},
{id: "distance", title: WebInspector.UIString("Distance"), width: "80px", sortable: true, sort: WebInspector.DataGrid.Order.Ascending},
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sortable: true}
];
- WebInspector.HeapSnapshotContainmentDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotContainmentDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotRetainmentDataGrid.Events = {
@@ -518,6 +684,11 @@ WebInspector.HeapSnapshotRetainmentDataGrid.Events = {
}
WebInspector.HeapSnapshotRetainmentDataGrid.prototype = {
+ _createRootNode: function(snapshot, fakeEdge)
+ {
+ return new WebInspector.HeapSnapshotRetainingObjectNode(this, snapshot, fakeEdge, null);
+ },
+
_sortFields: function(sortColumn, sortAscending)
{
return {
@@ -542,27 +713,7 @@ WebInspector.HeapSnapshotRetainmentDataGrid.prototype = {
setDataSource: function(snapshot, nodeIndex)
{
WebInspector.HeapSnapshotContainmentDataGrid.prototype.setDataSource.call(this, snapshot, nodeIndex);
-
- var dataGrid = this;
- var maxExpandLevels = 20;
- /**
- * @this {!WebInspector.HeapSnapshotObjectNode}
- */
- function populateComplete()
- {
- this.removeEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
- this.expand();
- if (--maxExpandLevels > 0 && this.children.length > 0) {
- var retainer = this.children[0];
- if (retainer._distance > 1) {
- retainer.addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, retainer);
- retainer.populate();
- return;
- }
- }
- dataGrid.dispatchEventToListeners(WebInspector.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);
- }
- this.rootNode().addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this.rootNode());
+ this.rootNode().expand();
},
__proto__: WebInspector.HeapSnapshotContainmentDataGrid.prototype
@@ -571,8 +722,9 @@ WebInspector.HeapSnapshotRetainmentDataGrid.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotViewportDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
-WebInspector.HeapSnapshotConstructorsDataGrid = function()
+WebInspector.HeapSnapshotConstructorsDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true},
@@ -581,29 +733,12 @@ WebInspector.HeapSnapshotConstructorsDataGrid = function()
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true}
];
- WebInspector.HeapSnapshotViewportDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
this._profileIndex = -1;
- this._topLevelNodes = [];
this._objectIdToSelect = null;
}
-/**
- * @constructor
- * @param {number=} minNodeId
- * @param {number=} maxNodeId
- */
-WebInspector.HeapSnapshotConstructorsDataGrid.Request = function(minNodeId, maxNodeId)
-{
- if (typeof minNodeId === "number") {
- this.key = minNodeId + ".." + maxNodeId;
- this.filter = "function(node) { var id = node.id(); return id > " + minNodeId + " && id <= " + maxNodeId + "; }";
- } else {
- this.key = "allObjects";
- this.filter = null;
- }
-}
-
WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
_sortFields: function(sortColumn, sortAscending)
{
@@ -642,11 +777,6 @@ WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
for (var i = 0; i < constructorNodes.length; i++) {
var parent = constructorNodes[i];
if (parent._name === className) {
- if (!parent.dataGrid) {
- // Make sure Constructor node is within the view port and added
- // to the data grid
- this._revealTopLevelNode(parent);
- }
parent.revealNodeBySnapshotObjectId(parseInt(id, 10), callback);
return;
}
@@ -655,6 +785,13 @@ WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
this.snapshot.nodeClassName(parseInt(id, 10), didGetClassName.bind(this));
},
+ clear: function()
+ {
+ this._nextRequestedFilter = null;
+ this._lastFilter = null;
+ this.removeTopLevelNodes();
+ },
+
setDataSource: function(snapshot)
{
this.snapshot = snapshot;
@@ -673,55 +810,68 @@ WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
*/
setSelectionRange: function(minNodeId, maxNodeId)
{
- this._populateChildren(new WebInspector.HeapSnapshotConstructorsDataGrid.Request(minNodeId, maxNodeId));
+ this._populateChildren(new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId, maxNodeId));
},
- _aggregatesReceived: function(key, aggregates)
+ /**
+ * @param {number} allocationNodeId
+ */
+ setAllocationNodeId: function(allocationNodeId)
+ {
+ var filter = new WebInspector.HeapSnapshotCommon.NodeFilter();
+ filter.allocationNodeId = allocationNodeId;
+ this._populateChildren(filter);
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
+ * @param {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>} aggregates
+ */
+ _aggregatesReceived: function(nodeFilter, aggregates)
{
- this._requestInProgress = null;
- if (this._nextRequest) {
- this.snapshot.aggregates(false, this._nextRequest.key, this._nextRequest.filter, this._aggregatesReceived.bind(this, this._nextRequest.key));
- this._requestInProgress = this._nextRequest;
- this._nextRequest = null;
+ this._filterInProgress = null;
+ if (this._nextRequestedFilter) {
+ this.snapshot.aggregatesWithFilter(this._nextRequestedFilter, this._aggregatesReceived.bind(this, this._nextRequestedFilter));
+ this._filterInProgress = this._nextRequestedFilter;
+ this._nextRequestedFilter = null;
}
- this.dispose();
this.removeTopLevelNodes();
this.resetSortingCache();
for (var constructor in aggregates)
- this.appendTopLevelNode(new WebInspector.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor], key));
+ this.appendNode(this.rootNode(), new WebInspector.HeapSnapshotConstructorNode(this, constructor, aggregates[constructor], nodeFilter));
this.sortingChanged();
- this._lastKey = key;
+ this._lastFilter = nodeFilter;
},
/**
- * @param {?WebInspector.HeapSnapshotConstructorsDataGrid.Request=} request
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter=} nodeFilter
*/
- _populateChildren: function(request)
+ _populateChildren: function(nodeFilter)
{
- request = request || new WebInspector.HeapSnapshotConstructorsDataGrid.Request();
+ nodeFilter = nodeFilter || new WebInspector.HeapSnapshotCommon.NodeFilter();
- if (this._requestInProgress) {
- this._nextRequest = this._requestInProgress.key === request.key ? null : request;
+ if (this._filterInProgress) {
+ this._nextRequestedFilter = this._filterInProgress.equals(nodeFilter) ? null : nodeFilter;
return;
}
- if (this._lastKey === request.key)
+ if (this._lastFilter && this._lastFilter.equals(nodeFilter))
return;
- this._requestInProgress = request;
- this.snapshot.aggregates(false, request.key, request.filter, this._aggregatesReceived.bind(this, request.key));
+ this._filterInProgress = nodeFilter;
+ this.snapshot.aggregatesWithFilter(nodeFilter, this._aggregatesReceived.bind(this, nodeFilter));
},
filterSelectIndexChanged: function(profiles, profileIndex)
{
this._profileIndex = profileIndex;
- var request = null;
+ var nodeFilter;
if (profileIndex !== -1) {
var minNodeId = profileIndex > 0 ? profiles[profileIndex - 1].maxJSObjectId : 0;
var maxNodeId = profiles[profileIndex].maxJSObjectId;
- request = new WebInspector.HeapSnapshotConstructorsDataGrid.Request(minNodeId, maxNodeId)
+ nodeFilter = new WebInspector.HeapSnapshotCommon.NodeFilter(minNodeId, maxNodeId)
}
- this._populateChildren(request);
+ this._populateChildren(nodeFilter);
},
__proto__: WebInspector.HeapSnapshotViewportDataGrid.prototype
@@ -731,19 +881,20 @@ WebInspector.HeapSnapshotConstructorsDataGrid.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotViewportDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
-WebInspector.HeapSnapshotDiffDataGrid = function()
+WebInspector.HeapSnapshotDiffDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true},
{id: "addedCount", title: WebInspector.UIString("# New"), width: "72px", sortable: true},
{id: "removedCount", title: WebInspector.UIString("# Deleted"), width: "72px", sortable: true},
- {id: "countDelta", title: "# Delta", width: "64px", sortable: true},
+ {id: "countDelta", title: WebInspector.UIString("# Delta"), width: "64px", sortable: true},
{id: "addedSize", title: WebInspector.UIString("Alloc. Size"), width: "72px", sortable: true, sort: WebInspector.DataGrid.Order.Descending},
{id: "removedSize", title: WebInspector.UIString("Freed Size"), width: "72px", sortable: true},
- {id: "sizeDelta", title: "Size Delta", width: "72px", sortable: true}
+ {id: "sizeDelta", title: WebInspector.UIString("Size Delta"), width: "72px", sortable: true}
];
- WebInspector.HeapSnapshotViewportDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
}
WebInspector.HeapSnapshotDiffDataGrid.prototype = {
@@ -780,11 +931,10 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
setBaseDataSource: function(baseSnapshot)
{
this.baseSnapshot = baseSnapshot;
- this.dispose();
this.removeTopLevelNodes();
this.resetSortingCache();
if (this.baseSnapshot === this.snapshot) {
- this.dispatchEventToListeners("sorting complete");
+ this.dispatchEventToListeners(WebInspector.HeapSnapshotSortableDataGrid.Events.SortingComplete);
return;
}
this._populateChildren();
@@ -806,7 +956,7 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
{
for (var className in diffByClassName) {
var diff = diffByClassName[className];
- this.appendTopLevelNode(new WebInspector.HeapSnapshotDiffNode(this, className, diff));
+ this.appendNode(this.rootNode(), new WebInspector.HeapSnapshotDiffNode(this, className, diff));
}
this.sortingChanged();
}
@@ -824,15 +974,16 @@ WebInspector.HeapSnapshotDiffDataGrid.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotSortableDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
-WebInspector.HeapSnapshotDominatorsDataGrid = function()
+WebInspector.HeapSnapshotDominatorsDataGrid = function(dataDisplayDelegate)
{
var columns = [
{id: "object", title: WebInspector.UIString("Object"), disclosure: true, sortable: true},
{id: "shallowSize", title: WebInspector.UIString("Shallow Size"), width: "120px", sortable: true},
{id: "retainedSize", title: WebInspector.UIString("Retained Size"), width: "120px", sort: WebInspector.DataGrid.Order.Descending, sortable: true}
];
- WebInspector.HeapSnapshotSortableDataGrid.call(this, columns);
+ WebInspector.HeapSnapshotSortableDataGrid.call(this, dataDisplayDelegate, columns);
this._objectIdToSelect = null;
}
@@ -850,7 +1001,7 @@ WebInspector.HeapSnapshotDominatorsDataGrid.prototype = {
{
this.snapshot = snapshot;
- var fakeNode = { nodeIndex: this.snapshot.rootNodeIndex };
+ var fakeNode = new WebInspector.HeapSnapshotCommon.Node(-1, "", 0, this.snapshot.rootNodeIndex, 0, 0, "");
this.setRootNode(new WebInspector.HeapSnapshotDominatorObjectNode(this, fakeNode));
this.rootNode().sort();
@@ -884,7 +1035,7 @@ WebInspector.HeapSnapshotDominatorsDataGrid.prototype = {
function didGetDominators(dominatorIds)
{
if (!dominatorIds) {
- WebInspector.log(WebInspector.UIString("Cannot find corresponding heap snapshot node"));
+ console.error("Cannot find corresponding heap snapshot node");
callback(false);
return;
}
@@ -921,115 +1072,84 @@ WebInspector.HeapSnapshotDominatorsDataGrid.prototype = {
/**
* @constructor
- * @extends {WebInspector.DataGrid}
+ * @extends {WebInspector.HeapSnapshotViewportDataGrid}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
*/
-WebInspector.AllocationDataGrid = function()
+WebInspector.AllocationDataGrid = function(dataDisplayDelegate)
{
var columns = [
+ {id: "liveCount", title: WebInspector.UIString("Live Count"), width: "72px", sortable: true},
{id: "count", title: WebInspector.UIString("Count"), width: "72px", sortable: true},
+ {id: "liveSize", title: WebInspector.UIString("Live Size"), width: "72px", sortable: true},
{id: "size", title: WebInspector.UIString("Size"), width: "72px", sortable: true, sort: WebInspector.DataGrid.Order.Descending},
{id: "name", title: WebInspector.UIString("Function"), disclosure: true, sortable: true},
];
- WebInspector.DataGrid.call(this, columns);
+ WebInspector.HeapSnapshotViewportDataGrid.call(this, dataDisplayDelegate, columns);
this._linkifier = new WebInspector.Linkifier();
}
WebInspector.AllocationDataGrid.prototype = {
+ dispose: function()
+ {
+ this._linkifier.reset();
+ },
+
setDataSource: function(snapshot)
{
- this._snapshot = snapshot;
- this._snapshot.allocationTracesTops(didReceiveAllocationTracesTops.bind(this));
+ this.snapshot = snapshot;
+ this.snapshot.allocationTracesTops(didReceiveAllocationTracesTops.bind(this));
/**
- * @param {!Array.<!WebInspector.DataGrid>} tops
+ * @param {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>} tops
* @this {WebInspector.AllocationDataGrid}
*/
function didReceiveAllocationTracesTops(tops)
{
- var root = this.rootNode();
- for (var i = 0; i < tops.length; i++)
- root.appendChild(new WebInspector.AllocationGridNode(this, tops[i]));
+ this._topNodes = tops;
+ this._populateChildren();
}
},
- __proto__: WebInspector.DataGrid.prototype
-}
-
-
-/**
- * @constructor
- * @extends {WebInspector.DataGridNode}
- * @param {!WebInspector.DataGrid} dataGrid
- */
-WebInspector.AllocationGridNode = function(dataGrid, data)
-{
- WebInspector.DataGridNode.call(this, data, data.hasChildren);
- this._dataGrid = dataGrid;
- this._populated = false;
-}
-
-WebInspector.AllocationGridNode.prototype = {
- populate: function()
+ _populateChildren: function()
{
- if (this._populated)
- return;
- this._populated = true;
- this._dataGrid._snapshot.allocationNodeCallers(this.data.id, didReceiveCallers.bind(this));
-
- /**
- * @this {WebInspector.AllocationGridNode}
- */
- function didReceiveCallers(callers)
- {
- var callersChain = callers.nodesWithSingleCaller;
- var parentNode = this;
- for (var i = 0; i < callersChain.length; i++) {
- var child = new WebInspector.AllocationGridNode(this._dataGrid, callersChain[i]);
- parentNode.appendChild(child);
- parentNode = child;
- parentNode._populated = true;
- if (this.expanded)
- parentNode.expand();
- }
-
- var callersBranch = callers.branchingCallers;
- for (var i = 0; i < callersBranch.length; i++)
- parentNode.appendChild(new WebInspector.AllocationGridNode(this._dataGrid, callersBranch[i]));
- }
+ this.removeTopLevelNodes();
+ var root = this.rootNode();
+ var tops = this._topNodes;
+ for (var i = 0; i < tops.length; i++)
+ this.appendNode(root, new WebInspector.AllocationGridNode(this, tops[i]));
+ this.updateVisibleNodes(true);
},
- /**
- * @override
- */
- expand: function()
+ sortingChanged: function()
{
- WebInspector.DataGridNode.prototype.expand.call(this);
- if (this.children.length === 1)
- this.children[0].expand();
+ this._topNodes.sort(this._createComparator());
+ this.rootNode().removeChildren();
+ this._populateChildren();
},
+
/**
- * @override
- * @param {string} columnIdentifier
- * @return {!Element}
+ * @return {function(!Object, !Object):number}
*/
- createCell: function(columnIdentifier)
- {
- var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
-
- if (columnIdentifier !== "name")
- return cell;
-
- var functionInfo = this.data;
- if (functionInfo.scriptName) {
- var urlElement = this._dataGrid._linkifier.linkifyLocation(functionInfo.scriptName, functionInfo.line - 1, functionInfo.column - 1, "profile-node-file");
- urlElement.style.maxWidth = "75%";
- cell.insertBefore(urlElement, cell.firstChild);
+ _createComparator: function()
+ {
+ var fieldName = this.sortColumnIdentifier();
+ var compareResult = (this.sortOrder() === WebInspector.DataGrid.Order.Ascending) ? +1 : -1;
+ /**
+ * @param {!Object} a
+ * @param {!Object} b
+ * @return {number}
+ */
+ function compare(a, b)
+ {
+ if (a[fieldName] > b[fieldName])
+ return compareResult;
+ if (a[fieldName] < b[fieldName])
+ return -compareResult;
+ return 0;
}
+ return compare;
+ },
- return cell;
- },
-
- __proto__: WebInspector.DataGridNode.prototype
+ __proto__: WebInspector.HeapSnapshotViewportDataGrid.prototype
}
-
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotGridNodes.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotGridNodes.js
index 7b7a9a40a73..3a2223f1fbd 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotGridNodes.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotGridNodes.js
@@ -46,23 +46,80 @@ WebInspector.HeapSnapshotGridNode = function(tree, hasChildren)
* Position is an item position in the provider.
*/
this._retrievedChildrenRanges = [];
+
+ /**
+ * @type {?WebInspector.HeapSnapshotGridNode.ChildrenProvider}
+ */
+ this._providerObject = null;
}
WebInspector.HeapSnapshotGridNode.Events = {
PopulateComplete: "PopulateComplete"
}
+/**
+ * @param {!Array.<string>} fieldNames
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
+WebInspector.HeapSnapshotGridNode.createComparator = function(fieldNames)
+{
+ return /** @type {!WebInspector.HeapSnapshotCommon.ComparatorConfig} */ ({fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]});
+}
+
+
+/**
+ * @interface
+ */
+WebInspector.HeapSnapshotGridNode.ChildrenProvider = function() { }
+
+WebInspector.HeapSnapshotGridNode.ChildrenProvider.prototype = {
+ dispose: function() { },
+
+ /**
+ * @param {number} snapshotObjectId
+ * @param {function(number)} callback
+ */
+ nodePosition: function(snapshotObjectId, callback) { },
+
+ /**
+ * @param {function(boolean)} callback
+ */
+ isEmpty: function(callback) { },
+
+ /**
+ * @param {number} startPosition
+ * @param {number} endPosition
+ * @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
+ */
+ serializeItemsRange: function(startPosition, endPosition, callback) { },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
+ * @param {function()} callback
+ */
+ sortAndRewind: function(comparator, callback) { }
+}
+
+
WebInspector.HeapSnapshotGridNode.prototype = {
/**
- * @return {!WebInspector.HeapSnapshotProviderProxy}
+ * @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
*/
createProvider: function()
{
- throw new Error("Needs implemented.");
+ throw new Error("Not implemented.");
},
/**
- * @return {!WebInspector.HeapSnapshotProviderProxy}
+ * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
+ */
+ retainersDataSource: function()
+ {
+ return null;
+ },
+
+ /**
+ * @return {!WebInspector.HeapSnapshotGridNode.ChildrenProvider}
*/
_provider: function()
{
@@ -71,6 +128,10 @@ WebInspector.HeapSnapshotGridNode.prototype = {
return this._providerObject;
},
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
createCell: function(columnIdentifier)
{
var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
@@ -79,16 +140,31 @@ WebInspector.HeapSnapshotGridNode.prototype = {
return cell;
},
+ /**
+ * @override
+ */
collapse: function()
{
WebInspector.DataGridNode.prototype.collapse.call(this);
- this._dataGrid.updateVisibleNodes();
+ this._dataGrid.updateVisibleNodes(true);
},
+ /**
+ * @override
+ */
+ expand: function()
+ {
+ WebInspector.DataGridNode.prototype.expand.call(this);
+ this._dataGrid.updateVisibleNodes(true);
+ },
+
+ /**
+ * @override
+ */
dispose: function()
{
- if (this._provider())
- this._provider().dispose();
+ if (this._providerObject)
+ this._providerObject.dispose();
for (var node = this.children[0]; node; node = node.traverseNextNode(true, this, true))
if (node.dispose)
node.dispose();
@@ -108,32 +184,67 @@ WebInspector.HeapSnapshotGridNode.prototype = {
this._dataGrid.nodeWasDetached(this);
},
+ /**
+ * @param {number} num
+ * @return {string}
+ */
_toPercentString: function(num)
{
return num.toFixed(0) + "\u2009%"; // \u2009 is a thin space.
},
/**
+ * @param {number} distance
+ * @return {string}
+ */
+ _toUIDistance: function(distance)
+ {
+ var baseSystemDistance = WebInspector.HeapSnapshotCommon.baseSystemDistance;
+ return distance >= 0 && distance < baseSystemDistance ? WebInspector.UIString("%d", distance) : WebInspector.UIString("\u2212");
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.DataGridNode>}
+ */
+ allChildren: function()
+ {
+ return this._dataGrid.allChildren(this);
+ },
+
+ /**
+ * @param {number} index
+ */
+ removeChildByIndex: function(index)
+ {
+ this._dataGrid.removeChildByIndex(this, index);
+ },
+
+ /**
* @param {number} nodePosition
+ * @return {?WebInspector.DataGridNode}
*/
childForPosition: function(nodePosition)
{
- var indexOfFirsChildInRange = 0;
+ var indexOfFirstChildInRange = 0;
for (var i = 0; i < this._retrievedChildrenRanges.length; i++) {
var range = this._retrievedChildrenRanges[i];
if (range.from <= nodePosition && nodePosition < range.to) {
- var childIndex = indexOfFirsChildInRange + nodePosition - range.from;
- return this.children[childIndex];
+ var childIndex = indexOfFirstChildInRange + nodePosition - range.from;
+ return this.allChildren()[childIndex];
}
- indexOfFirsChildInRange += range.to - range.from + 1;
+ indexOfFirstChildInRange += range.to - range.from + 1;
}
return null;
},
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
_createValueCell: function(columnIdentifier)
{
var cell = document.createElement("td");
- cell.className = columnIdentifier + "-column";
+ cell.className = "numeric-column";
if (this.dataGrid.snapshot.totalSize !== 0) {
var div = document.createElement("div");
var valueSpan = document.createElement("span");
@@ -145,7 +256,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
percentSpan.className = "percent-column";
percentSpan.textContent = this.data[percentColumn];
div.appendChild(percentSpan);
- div.classList.add("heap-snapshot-multiple-values");
+ div.classList.add("profile-multiple-values");
}
cell.appendChild(div);
}
@@ -207,11 +318,11 @@ WebInspector.HeapSnapshotGridNode.prototype = {
if (this._savedChildren) {
var hash = this._childHashForEntity(item);
if (hash in this._savedChildren) {
- this.insertChild(this._savedChildren[hash], insertionIndex);
+ this._dataGrid.insertChild(this, this._savedChildren[hash], insertionIndex);
return;
}
}
- this.insertChild(this._createChildNode(item), insertionIndex);
+ this._dataGrid.insertChild(this, this._createChildNode(item), insertionIndex);
}
/**
@@ -220,28 +331,30 @@ WebInspector.HeapSnapshotGridNode.prototype = {
function insertShowMoreButton(from, to, insertionIndex)
{
var button = new WebInspector.ShowMoreDataGridNode(this._populateChildren.bind(this), from, to, this._dataGrid.defaultPopulateCount());
- this.insertChild(button, insertionIndex);
+ this._dataGrid.insertChild(this, button, insertionIndex);
}
/**
+ * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotGridNode}
*/
- function childrenRetrieved(items)
+ function childrenRetrieved(itemsRange)
{
var itemIndex = 0;
- var itemPosition = items.startPosition;
+ var itemPosition = itemsRange.startPosition;
+ var items = itemsRange.items;
var insertionIndex = 0;
if (!this._retrievedChildrenRanges.length) {
- if (items.startPosition > 0) {
+ if (itemsRange.startPosition > 0) {
this._retrievedChildrenRanges.push({from: 0, to: 0});
- insertShowMoreButton.call(this, 0, items.startPosition, insertionIndex++);
+ insertShowMoreButton.call(this, 0, itemsRange.startPosition, insertionIndex++);
}
- this._retrievedChildrenRanges.push({from: items.startPosition, to: items.endPosition});
+ this._retrievedChildrenRanges.push({from: itemsRange.startPosition, to: itemsRange.endPosition});
for (var i = 0, l = items.length; i < l; ++i)
insertRetrievedChild.call(this, items[i], insertionIndex++);
- if (items.endPosition < items.totalLength)
- insertShowMoreButton.call(this, items.endPosition, items.totalLength, insertionIndex++);
+ if (itemsRange.endPosition < itemsRange.totalLength)
+ insertShowMoreButton.call(this, itemsRange.endPosition, itemsRange.totalLength, insertionIndex++);
} else {
var rangeIndex = 0;
var found = false;
@@ -254,16 +367,16 @@ WebInspector.HeapSnapshotGridNode.prototype = {
}
insertionIndex += range.to - range.from;
// Skip the button if there is one.
- if (range.to < items.totalLength)
+ if (range.to < itemsRange.totalLength)
insertionIndex += 1;
++rangeIndex;
}
- if (!found || items.startPosition < range.from) {
+ if (!found || itemsRange.startPosition < range.from) {
// Update previous button.
- this.children[insertionIndex - 1].setEndPosition(items.startPosition);
- insertShowMoreButton.call(this, items.startPosition, found ? range.from : items.totalLength, insertionIndex);
- range = {from: items.startPosition, to: items.startPosition};
+ this.allChildren()[insertionIndex - 1].setEndPosition(itemsRange.startPosition);
+ insertShowMoreButton.call(this, itemsRange.startPosition, found ? range.from : itemsRange.totalLength, insertionIndex);
+ range = {from: itemsRange.startPosition, to: itemsRange.startPosition};
if (!found)
rangeIndex = this._retrievedChildrenRanges.length;
this._retrievedChildrenRanges.splice(rangeIndex, 0, range);
@@ -274,7 +387,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
// Also it is always true here that range.from <= itemPosition <= range.to
// Stretch the range right bound to include all new items.
- while (range.to < items.endPosition) {
+ while (range.to < itemsRange.endPosition) {
// Skip already added nodes.
var skipCount = range.to - itemPosition;
insertionIndex += skipCount;
@@ -283,9 +396,9 @@ WebInspector.HeapSnapshotGridNode.prototype = {
// We're at the position before button: ...<?node>x<button>
var nextRange = this._retrievedChildrenRanges[rangeIndex + 1];
- var newEndOfRange = nextRange ? nextRange.from : items.totalLength;
- if (newEndOfRange > items.endPosition)
- newEndOfRange = items.endPosition;
+ var newEndOfRange = nextRange ? nextRange.from : itemsRange.totalLength;
+ if (newEndOfRange > itemsRange.endPosition)
+ newEndOfRange = itemsRange.endPosition;
while (itemPosition < newEndOfRange) {
insertRetrievedChild.call(this, items[itemIndex++], insertionIndex++);
++itemPosition;
@@ -294,15 +407,15 @@ WebInspector.HeapSnapshotGridNode.prototype = {
if (nextRange && newEndOfRange === nextRange.from) {
range.to = nextRange.to;
// Remove "show next" button if there is one.
- this.removeChild(this.children[insertionIndex]);
+ this.removeChildByIndex(insertionIndex);
this._retrievedChildrenRanges.splice(rangeIndex + 1, 1);
} else {
range.to = newEndOfRange;
// Remove or update next button.
- if (newEndOfRange === items.totalLength)
- this.removeChild(this.children[insertionIndex]);
+ if (newEndOfRange === itemsRange.totalLength)
+ this.removeChildByIndex(insertionIndex);
else
- this.children[insertionIndex].setStartPosition(items.endPosition);
+ this.allChildren()[insertionIndex].setStartPosition(itemsRange.endPosition);
}
}
}
@@ -314,6 +427,8 @@ WebInspector.HeapSnapshotGridNode.prototype = {
return;
}
+ if (this.expanded)
+ this._dataGrid.updateVisibleNodes(true);
if (afterPopulate)
afterPopulate();
this.dispatchEventToListeners(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete);
@@ -324,8 +439,9 @@ WebInspector.HeapSnapshotGridNode.prototype = {
_saveChildren: function()
{
this._savedChildren = null;
- for (var i = 0, childrenCount = this.children.length; i < childrenCount; ++i) {
- var child = this.children[i];
+ var children = this.allChildren();
+ for (var i = 0, l = children.length; i < l; ++i) {
+ var child = children[i];
if (!child.expanded)
continue;
if (!this._savedChildren)
@@ -344,7 +460,7 @@ WebInspector.HeapSnapshotGridNode.prototype = {
function afterSort()
{
this._saveChildren();
- this.removeChildren();
+ this._dataGrid.removeAllChildren(this);
this._retrievedChildrenRanges = [];
/**
@@ -352,8 +468,9 @@ WebInspector.HeapSnapshotGridNode.prototype = {
*/
function afterPopulate()
{
- for (var i = 0, l = this.children.length; i < l; ++i) {
- var child = this.children[i];
+ var children = this.allChildren();
+ for (var i = 0, l = children.length; i < l; ++i) {
+ var child = children[i];
if (child.expanded)
child.sort();
}
@@ -374,12 +491,12 @@ WebInspector.HeapSnapshotGridNode.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGridNode}
- * @param {!WebInspector.HeapSnapshotSortableDataGrid} tree
+ * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
*/
-WebInspector.HeapSnapshotGenericObjectNode = function(tree, node)
+WebInspector.HeapSnapshotGenericObjectNode = function(dataGrid, node)
{
- this.snapshotNodeIndex = 0;
- WebInspector.HeapSnapshotGridNode.call(this, tree, false);
+ WebInspector.HeapSnapshotGridNode.call(this, dataGrid, false);
// node is null for DataGrid root nodes.
if (!node)
return;
@@ -399,9 +516,32 @@ WebInspector.HeapSnapshotGenericObjectNode = function(tree, node)
this._reachableFromWindow = true;
if (node.detachedDOMTreeNode)
this.detachedDOMTreeNode = true;
+
+ var snapshot = dataGrid.snapshot;
+ var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
+ var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
+ this.data = {
+ "distance": this._toUIDistance(this._distance),
+ "shallowSize": Number.withThousandsSeparator(this._shallowSize),
+ "retainedSize": Number.withThousandsSeparator(this._retainedSize),
+ "shallowSize-percent": this._toPercentString(shallowSizePercent),
+ "retainedSize-percent": this._toPercentString(retainedSizePercent)
+ };
};
WebInspector.HeapSnapshotGenericObjectNode.prototype = {
+ /**
+ * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
+ */
+ retainersDataSource: function()
+ {
+ return {snapshot: this._dataGrid.snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
+ },
+
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
createCell: function(columnIdentifier)
{
var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : this._createObjectCell();
@@ -410,43 +550,11 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
return cell;
},
+ /**
+ * @return {!Element}
+ */
_createObjectCell: function()
{
- var cell = document.createElement("td");
- cell.className = "object-column";
- var div = document.createElement("div");
- div.className = "source-code event-properties";
- div.style.overflow = "visible";
-
- var data = this.data["object"];
- if (this._prefixObjectCell)
- this._prefixObjectCell(div, data);
-
- var valueSpan = document.createElement("span");
- valueSpan.className = "value console-formatted-" + data.valueStyle;
- valueSpan.textContent = data.value;
- div.appendChild(valueSpan);
-
- var idSpan = document.createElement("span");
- idSpan.className = "console-formatted-id";
- idSpan.textContent = " @" + data["nodeId"];
- div.appendChild(idSpan);
-
- if (this._postfixObjectCell)
- this._postfixObjectCell(div, data);
-
- cell.appendChild(div);
- cell.classList.add("disclosure");
- if (this.depth)
- cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
- cell.heapSnapshotNode = this;
- return cell;
- },
-
- get data()
- {
- var data = this._emptyData();
-
var value = this._name;
var valueStyle = "object";
switch (this._type) {
@@ -482,15 +590,39 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
value = "";
if (this.detachedDOMTreeNode)
valueStyle += " detached-dom-tree-node";
- data["object"] = { valueStyle: valueStyle, value: value, nodeId: this.snapshotNodeId };
+ return this._createObjectCellWithValue(valueStyle, value);
+ },
- data["distance"] = this._distance;
- data["shallowSize"] = Number.withThousandsSeparator(this._shallowSize);
- data["retainedSize"] = Number.withThousandsSeparator(this._retainedSize);
- data["shallowSize-percent"] = this._toPercentString(this._shallowSizePercent);
- data["retainedSize-percent"] = this._toPercentString(this._retainedSizePercent);
+ _createObjectCellWithValue: function(valueStyle, value)
+ {
+ var cell = document.createElement("td");
+ cell.className = "object-column";
+ var div = document.createElement("div");
+ div.className = "source-code event-properties";
+ div.style.overflow = "visible";
- return this._enhanceData ? this._enhanceData(data) : data;
+ this._prefixObjectCell(div);
+
+ var valueSpan = document.createElement("span");
+ valueSpan.className = "value console-formatted-" + valueStyle;
+ valueSpan.textContent = value;
+ div.appendChild(valueSpan);
+
+ var idSpan = document.createElement("span");
+ idSpan.className = "console-formatted-id";
+ idSpan.textContent = " @" + this.snapshotNodeId;
+ div.appendChild(idSpan);
+
+ cell.appendChild(div);
+ cell.classList.add("disclosure");
+ if (this.depth)
+ cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
+ cell.heapSnapshotNode = this;
+ return cell;
+ },
+
+ _prefixObjectCell: function(div)
+ {
},
queryObjectContent: function(callback, objectGroupName)
@@ -502,27 +634,17 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
function formatResult(error, object)
{
if (!error && object.type)
- callback(WebInspector.RemoteObject.fromPayload(object), !!error);
+ callback(WebInspector.runtimeModel.createRemoteObject(object), !!error);
else
- callback(WebInspector.RemoteObject.fromPrimitiveValue(WebInspector.UIString("Preview is not available")));
+ callback(WebInspector.runtimeModel.createRemoteObjectFromPrimitiveValue(WebInspector.UIString("Preview is not available")));
}
if (this._type === "string")
- callback(WebInspector.RemoteObject.fromPrimitiveValue(this._name));
+ callback(WebInspector.runtimeModel.createRemoteObjectFromPrimitiveValue(this._name));
else
HeapProfilerAgent.getObjectByHeapObjectId(String(this.snapshotNodeId), objectGroupName, formatResult);
},
- get _retainedSizePercent()
- {
- return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0;
- },
-
- get _shallowSizePercent()
- {
- return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0;
- },
-
updateHasChildren: function()
{
/**
@@ -535,6 +657,11 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
this._provider().isEmpty(isEmptyCallback.bind(this));
},
+ /**
+ * @param {string} fullName
+ * @param {boolean} hasObjectId
+ * @return {string}
+ */
shortenWindowURL: function(fullName, hasObjectId)
{
var startPos = fullName.indexOf("/");
@@ -555,67 +682,92 @@ WebInspector.HeapSnapshotGenericObjectNode.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGenericObjectNode}
- * @param {!WebInspector.HeapSnapshotSortableDataGrid} tree
- * @param {boolean} isFromBaseSnapshot
+ * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
+ * @param {?WebInspector.HeapSnapshotObjectNode} parentObjectNode
*/
-WebInspector.HeapSnapshotObjectNode = function(tree, isFromBaseSnapshot, edge, parentGridNode)
+WebInspector.HeapSnapshotObjectNode = function(dataGrid, snapshot, edge, parentObjectNode)
{
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, edge.node);
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, edge.node);
this._referenceName = edge.name;
this._referenceType = edge.type;
- this._distance = edge.distance;
- this.showRetainingEdges = tree.showRetainingEdges;
- this._isFromBaseSnapshot = isFromBaseSnapshot;
+ this._edgeIndex = edge.edgeIndex;
+ this._snapshot = snapshot;
- this._parentGridNode = parentGridNode;
+ this._parentObjectNode = parentObjectNode;
this._cycledWithAncestorGridNode = this._findAncestorWithSameSnapshotNodeId();
if (!this._cycledWithAncestorGridNode)
this.updateHasChildren();
+
+ var data = this.data;
+ data["count"] = "";
+ data["addedCount"] = "";
+ data["removedCount"] = "";
+ data["countDelta"] = "";
+ data["addedSize"] = "";
+ data["removedSize"] = "";
+ data["sizeDelta"] = "";
}
WebInspector.HeapSnapshotObjectNode.prototype = {
/**
+ * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
+ */
+ retainersDataSource: function()
+ {
+ return {snapshot: this._snapshot, snapshotNodeIndex: this.snapshotNodeIndex};
+ },
+
+ /**
* @return {!WebInspector.HeapSnapshotProviderProxy}
*/
createProvider: function()
{
- var tree = this._dataGrid;
- var showHiddenData = WebInspector.settings.showAdvancedHeapSnapshotProperties.get();
- var snapshot = this._isFromBaseSnapshot ? tree.baseSnapshot : tree.snapshot;
- if (this.showRetainingEdges)
- return snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex, showHiddenData);
- else
- return snapshot.createEdgesProvider(this.snapshotNodeIndex, showHiddenData);
+ return this._snapshot.createEdgesProvider(this.snapshotNodeIndex);
},
_findAncestorWithSameSnapshotNodeId: function()
{
- var ancestor = this._parentGridNode;
+ var ancestor = this._parentObjectNode;
while (ancestor) {
if (ancestor.snapshotNodeId === this.snapshotNodeId)
return ancestor;
- ancestor = ancestor._parentGridNode;
+ ancestor = ancestor._parentObjectNode;
}
return null;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} item
+ * @return {!WebInspector.HeapSnapshotObjectNode}
+ */
_createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._isFromBaseSnapshot, item, this);
+ return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._snapshot, item, this);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
+ * @return {number}
+ */
_childHashForEntity: function(edge)
{
- var prefix = this.showRetainingEdges ? edge.node.id + "#" : "";
- return prefix + edge.type + "#" + edge.name;
+ return edge.edgeIndex;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotObjectNode} childNode
+ * @return {number}
+ */
_childHashForNode: function(childNode)
{
- var prefix = this.showRetainingEdges ? childNode.snapshotNodeId + "#" : "";
- return prefix + childNode._referenceType + "#" + childNode._referenceName;
+ return childNode._edgeIndex;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
@@ -627,15 +779,10 @@ WebInspector.HeapSnapshotObjectNode.prototype = {
retainedSize: ["retainedSize", sortAscending, "!edgeName", true],
distance: ["distance", sortAscending, "_name", true]
}[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
- return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
+ return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
- _emptyData: function()
- {
- return { count: "", addedCount: "", removedCount: "", countDelta: "", addedSize: "", removedSize: "", sizeDelta: "" };
- },
-
- _enhanceData: function(data)
+ _prefixObjectCell: function(div)
{
var name = this._referenceName;
if (name === "") name = "(empty)";
@@ -646,73 +793,195 @@ WebInspector.HeapSnapshotObjectNode.prototype = {
break;
case "internal":
case "hidden":
+ case "weak":
nameClass = "console-formatted-null";
break;
case "element":
name = "[" + name + "]";
break;
}
- data["object"].nameClass = nameClass;
- data["object"].name = name;
- data["distance"] = this._distance;
- return data;
- },
- _prefixObjectCell: function(div, data)
- {
if (this._cycledWithAncestorGridNode)
div.className += " cycled-ancessor-node";
var nameSpan = document.createElement("span");
- nameSpan.className = data.nameClass;
- nameSpan.textContent = data.name;
+ nameSpan.className = nameClass;
+ nameSpan.textContent = name;
div.appendChild(nameSpan);
var separatorSpan = document.createElement("span");
separatorSpan.className = "grayed";
- separatorSpan.textContent = this.showRetainingEdges ? " in " : " :: ";
+ separatorSpan.textContent = this._edgeNodeSeparator();
div.appendChild(separatorSpan);
},
+ /**
+ * @return {string}
+ */
+ _edgeNodeSeparator: function()
+ {
+ return " :: ";
+ },
+
__proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
}
/**
* @constructor
+ * @extends {WebInspector.HeapSnapshotObjectNode}
+ * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
+ * @param {?WebInspector.HeapSnapshotRetainingObjectNode} parentRetainingObjectNode
+ */
+WebInspector.HeapSnapshotRetainingObjectNode = function(dataGrid, snapshot, edge, parentRetainingObjectNode)
+{
+ WebInspector.HeapSnapshotObjectNode.call(this, dataGrid, snapshot, edge, parentRetainingObjectNode);
+}
+
+WebInspector.HeapSnapshotRetainingObjectNode.prototype = {
+ /**
+ * @return {!WebInspector.HeapSnapshotProviderProxy}
+ */
+ createProvider: function()
+ {
+ return this._snapshot.createRetainingEdgesProvider(this.snapshotNodeIndex);
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} item
+ * @return {!WebInspector.HeapSnapshotRetainingObjectNode}
+ */
+ _createChildNode: function(item)
+ {
+ return new WebInspector.HeapSnapshotRetainingObjectNode(this._dataGrid, this._snapshot, item, this);
+ },
+
+ /**
+ * @return {string}
+ */
+ _edgeNodeSeparator: function()
+ {
+ return " in ";
+ },
+
+ expand: function()
+ {
+ this._expandRetainersChain(20);
+ },
+
+ /**
+ * @param {number} maxExpandLevels
+ */
+ _expandRetainersChain: function(maxExpandLevels)
+ {
+ /**
+ * @this {!WebInspector.HeapSnapshotRetainingObjectNode}
+ */
+ function populateComplete()
+ {
+ this.removeEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
+ this._expandRetainersChain(maxExpandLevels);
+ }
+
+ if (!this._populated) {
+ this.addEventListener(WebInspector.HeapSnapshotGridNode.Events.PopulateComplete, populateComplete, this);
+ this.populate();
+ return;
+ }
+ WebInspector.HeapSnapshotGenericObjectNode.prototype.expand.call(this);
+ if (--maxExpandLevels > 0 && this.children.length > 0) {
+ var retainer = this.children[0];
+ if (retainer._distance > 1) {
+ retainer._expandRetainersChain(maxExpandLevels);
+ return;
+ }
+ }
+ this._dataGrid.dispatchEventToListeners(WebInspector.HeapSnapshotRetainmentDataGrid.Events.ExpandRetainersComplete);
+ },
+
+ __proto__: WebInspector.HeapSnapshotObjectNode.prototype
+}
+
+/**
+ * @constructor
* @extends {WebInspector.HeapSnapshotGenericObjectNode}
+ * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
+ * @param {boolean} isDeletedNode
*/
-WebInspector.HeapSnapshotInstanceNode = function(tree, baseSnapshot, snapshot, node)
+WebInspector.HeapSnapshotInstanceNode = function(dataGrid, snapshot, node, isDeletedNode)
{
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
- this._baseSnapshotOrSnapshot = baseSnapshot || snapshot;
- this._isDeletedNode = !!baseSnapshot;
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, node);
+ this._baseSnapshotOrSnapshot = snapshot;
+ this._isDeletedNode = isDeletedNode;
this.updateHasChildren();
+
+ var data = this.data;
+ data["count"] = "";
+ data["countDelta"] = "";
+ data["sizeDelta"] = "";
+ if (this._isDeletedNode) {
+ data["addedCount"] = "";
+ data["addedSize"] = "";
+ data["removedCount"] = "\u2022";
+ data["removedSize"] = Number.withThousandsSeparator(this._shallowSize);
+ } else {
+ data["addedCount"] = "\u2022";
+ data["addedSize"] = Number.withThousandsSeparator(this._shallowSize);
+ data["removedCount"] = "";
+ data["removedSize"] = "";
+ }
};
WebInspector.HeapSnapshotInstanceNode.prototype = {
+ /**
+ * @return {?{snapshot:!WebInspector.HeapSnapshotProxy, snapshotNodeIndex:number}}
+ */
+ retainersDataSource: function()
+ {
+ return {snapshot: this._baseSnapshotOrSnapshot, snapshotNodeIndex: this.snapshotNodeIndex};
+ },
+
+ /**
+ * @return {!WebInspector.HeapSnapshotProviderProxy}
+ */
createProvider: function()
{
- var showHiddenData = WebInspector.settings.showAdvancedHeapSnapshotProperties.get();
- return this._baseSnapshotOrSnapshot.createEdgesProvider(
- this.snapshotNodeIndex,
- showHiddenData);
+ return this._baseSnapshotOrSnapshot.createEdgesProvider(this.snapshotNodeIndex);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} item
+ * @return {!WebInspector.HeapSnapshotObjectNode}
+ */
_createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._isDeletedNode, item, null);
+ return new WebInspector.HeapSnapshotObjectNode(this._dataGrid, this._baseSnapshotOrSnapshot, item, null);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Edge} edge
+ * @return {number}
+ */
_childHashForEntity: function(edge)
{
- return edge.type + "#" + edge.name;
+ return edge.edgeIndex;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotObjectNode} childNode
+ * @return {number}
+ */
_childHashForNode: function(childNode)
{
- return childNode._referenceType + "#" + childNode._referenceName;
+ return childNode._edgeIndex;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
@@ -726,33 +995,7 @@ WebInspector.HeapSnapshotInstanceNode.prototype = {
shallowSize: ["selfSize", sortAscending, "!edgeName", true],
retainedSize: ["retainedSize", sortAscending, "!edgeName", true]
}[sortColumnIdentifier] || ["!edgeName", true, "retainedSize", false];
- return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
- },
-
- _emptyData: function()
- {
- return {count: "", countDelta: "", sizeDelta: ""};
- },
-
- _enhanceData: function(data)
- {
- if (this._isDeletedNode) {
- data["addedCount"] = "";
- data["addedSize"] = "";
- data["removedCount"] = "\u2022";
- data["removedSize"] = Number.withThousandsSeparator(this._shallowSize);
- } else {
- data["addedCount"] = "\u2022";
- data["addedSize"] = Number.withThousandsSeparator(this._shallowSize);
- data["removedCount"] = "";
- data["removedSize"] = "";
- }
- return data;
- },
-
- get isDeletedNode()
- {
- return this._isDeletedNode;
+ return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
__proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
@@ -760,17 +1003,37 @@ WebInspector.HeapSnapshotInstanceNode.prototype = {
/**
* @constructor
+ * @param {!WebInspector.HeapSnapshotConstructorsDataGrid} dataGrid
+ * @param {string} className
+ * @param {!WebInspector.HeapSnapshotCommon.Aggregate} aggregate
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
* @extends {WebInspector.HeapSnapshotGridNode}
*/
-WebInspector.HeapSnapshotConstructorNode = function(tree, className, aggregate, aggregatesKey)
+WebInspector.HeapSnapshotConstructorNode = function(dataGrid, className, aggregate, nodeFilter)
{
- WebInspector.HeapSnapshotGridNode.call(this, tree, aggregate.count > 0);
+ WebInspector.HeapSnapshotGridNode.call(this, dataGrid, aggregate.count > 0);
this._name = className;
- this._aggregatesKey = aggregatesKey;
+ this._nodeFilter = nodeFilter;
this._distance = aggregate.distance;
this._count = aggregate.count;
this._shallowSize = aggregate.self;
this._retainedSize = aggregate.maxRet;
+
+ var snapshot = dataGrid.snapshot;
+ var countPercent = this._count / snapshot.nodeCount * 100.0;
+ var retainedSizePercent = this._retainedSize / snapshot.totalSize * 100.0;
+ var shallowSizePercent = this._shallowSize / snapshot.totalSize * 100.0;
+
+ this.data = {
+ "object": className,
+ "count": Number.withThousandsSeparator(this._count),
+ "distance": this._toUIDistance(this._distance),
+ "shallowSize": Number.withThousandsSeparator(this._shallowSize),
+ "retainedSize": Number.withThousandsSeparator(this._retainedSize),
+ "count-percent": this._toPercentString(countPercent),
+ "shallowSize-percent": this._toPercentString(shallowSizePercent),
+ "retainedSize-percent": this._toPercentString(retainedSizePercent)
+ };
}
WebInspector.HeapSnapshotConstructorNode.prototype = {
@@ -780,7 +1043,7 @@ WebInspector.HeapSnapshotConstructorNode.prototype = {
*/
createProvider: function()
{
- return this._dataGrid.snapshot.createNodesProviderForClass(this._name, this._aggregatesKey)
+ return this._dataGrid.snapshot.createNodesProviderForClass(this._name, this._nodeFilter)
},
/**
@@ -799,6 +1062,7 @@ WebInspector.HeapSnapshotConstructorNode.prototype = {
/**
* @this {WebInspector.HeapSnapshotConstructorNode}
+ * @param {number} nodePosition
*/
function didGetNodePosition(nodePosition)
{
@@ -812,27 +1076,35 @@ WebInspector.HeapSnapshotConstructorNode.prototype = {
/**
* @this {WebInspector.HeapSnapshotConstructorNode}
+ * @param {number} nodePosition
*/
function didPopulateChildren(nodePosition)
{
- var indexOfFirsChildInRange = 0;
- for (var i = 0; i < this._retrievedChildrenRanges.length; i++) {
- var range = this._retrievedChildrenRanges[i];
- if (range.from <= nodePosition && nodePosition < range.to) {
- var childIndex = indexOfFirsChildInRange + nodePosition - range.from;
- var instanceNode = this.children[childIndex];
- this._dataGrid.highlightNode(/** @type {!WebInspector.HeapSnapshotGridNode} */ (instanceNode));
- callback(true);
- return;
- }
- indexOfFirsChildInRange += range.to - range.from + 1;
+ var child = this.childForPosition(nodePosition);
+ if (child) {
+ this._dataGrid.revealTreeNode([this, child]);
+ this._dataGrid.highlightNode(/** @type {!WebInspector.HeapSnapshotGridNode} */ (child));
}
- callback(false);
+ callback(!!child);
}
+ this._dataGrid.resetNameFilter();
this.expandWithoutPopulate(didExpand.bind(this));
},
+ /**
+ * @param {string} filterValue
+ * @return {boolean}
+ */
+ filteredOut: function(filterValue)
+ {
+ return this._name.toLowerCase().indexOf(filterValue) === -1;
+ },
+
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
createCell: function(columnIdentifier)
{
var cell = columnIdentifier !== "object" ? this._createValueCell(columnIdentifier) : WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
@@ -841,11 +1113,18 @@ WebInspector.HeapSnapshotConstructorNode.prototype = {
return cell;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Node} item
+ * @return {!WebInspector.HeapSnapshotInstanceNode}
+ */
_createChildNode: function(item)
{
- return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, null, this._dataGrid.snapshot, item);
+ return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
@@ -857,56 +1136,38 @@ WebInspector.HeapSnapshotConstructorNode.prototype = {
shallowSize: ["selfSize", sortAscending, "id", true],
retainedSize: ["retainedSize", sortAscending, "id", true]
}[sortColumnIdentifier];
- return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
+ return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
+ * @return {number}
+ */
_childHashForEntity: function(node)
{
return node.id;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotInstanceNode} childNode
+ * @return {number}
+ */
_childHashForNode: function(childNode)
{
return childNode.snapshotNodeId;
},
- get data()
- {
- var data = { object: this._name };
- data["count"] = Number.withThousandsSeparator(this._count);
- data["distance"] = this._distance;
- data["shallowSize"] = Number.withThousandsSeparator(this._shallowSize);
- data["retainedSize"] = Number.withThousandsSeparator(this._retainedSize);
- data["count-percent"] = this._toPercentString(this._countPercent);
- data["shallowSize-percent"] = this._toPercentString(this._shallowSizePercent);
- data["retainedSize-percent"] = this._toPercentString(this._retainedSizePercent);
- return data;
- },
-
- get _countPercent()
- {
- return this._count / this.dataGrid.snapshot.nodeCount * 100.0;
- },
-
- get _retainedSizePercent()
- {
- return this._retainedSize / this.dataGrid.snapshot.totalSize * 100.0;
- },
-
- get _shallowSizePercent()
- {
- return this._shallowSize / this.dataGrid.snapshot.totalSize * 100.0;
- },
-
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
/**
* @constructor
- * @extends {WebInspector.HeapSnapshotProviderProxy}
+ * @implements {WebInspector.HeapSnapshotGridNode.ChildrenProvider}
* @param {!WebInspector.HeapSnapshotProviderProxy} addedNodesProvider
* @param {!WebInspector.HeapSnapshotProviderProxy} deletedNodesProvider
+ * @param {number} addedCount
+ * @param {number} removedCount
*/
WebInspector.HeapSnapshotDiffNodesProvider = function(addedNodesProvider, deletedNodesProvider, addedCount, removedCount)
{
@@ -923,14 +1184,33 @@ WebInspector.HeapSnapshotDiffNodesProvider.prototype = {
this._deletedNodesProvider.dispose();
},
+ /**
+ * @override
+ * @param {number} snapshotObjectId
+ * @param {function(number)} callback
+ */
+ nodePosition: function(snapshotObjectId, callback)
+ {
+ throw new Error("Unreachable");
+ },
+
+ /**
+ * @param {function(boolean)} callback
+ */
isEmpty: function(callback)
{
callback(false);
},
+ /**
+ * @param {number} beginPosition
+ * @param {number} endPosition
+ * @param {!function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
+ */
serializeItemsRange: function(beginPosition, endPosition, callback)
{
/**
+ * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} items
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
function didReceiveAllItems(items)
@@ -940,40 +1220,51 @@ WebInspector.HeapSnapshotDiffNodesProvider.prototype = {
}
/**
+ * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} addedItems
+ * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
- function didReceiveDeletedItems(addedItems, items)
+ function didReceiveDeletedItems(addedItems, itemsRange)
{
- if (!addedItems.length)
- addedItems.startPosition = this._addedCount + items.startPosition;
+ var items = itemsRange.items;
+ if (!addedItems.items.length)
+ addedItems.startPosition = this._addedCount + itemsRange.startPosition;
for (var i = 0; i < items.length; i++) {
items[i].isAddedNotRemoved = false;
- addedItems.push(items[i]);
+ addedItems.items.push(items[i]);
}
- addedItems.endPosition = this._addedCount + items.endPosition;
+ addedItems.endPosition = this._addedCount + itemsRange.endPosition;
didReceiveAllItems.call(this, addedItems);
}
/**
+ * @param {!WebInspector.HeapSnapshotCommon.ItemsRange} itemsRange
* @this {WebInspector.HeapSnapshotDiffNodesProvider}
*/
- function didReceiveAddedItems(items)
+ function didReceiveAddedItems(itemsRange)
{
+ var items = itemsRange.items;
for (var i = 0; i < items.length; i++)
items[i].isAddedNotRemoved = true;
- if (items.endPosition < endPosition)
- return this._deletedNodesProvider.serializeItemsRange(0, endPosition - items.endPosition, didReceiveDeletedItems.bind(this, items));
+ if (itemsRange.endPosition < endPosition)
+ return this._deletedNodesProvider.serializeItemsRange(0, endPosition - itemsRange.endPosition, didReceiveDeletedItems.bind(this, itemsRange));
- items.totalLength = this._addedCount + this._removedCount;
- didReceiveAllItems.call(this, items);
+ itemsRange.totalLength = this._addedCount + this._removedCount;
+ didReceiveAllItems.call(this, itemsRange);
}
- if (beginPosition < this._addedCount)
+ if (beginPosition < this._addedCount) {
this._addedNodesProvider.serializeItemsRange(beginPosition, endPosition, didReceiveAddedItems.bind(this));
- else
- this._deletedNodesProvider.serializeItemsRange(beginPosition - this._addedCount, endPosition - this._addedCount, didReceiveDeletedItems.bind(this, []));
+ } else {
+ var emptyRange = new WebInspector.HeapSnapshotCommon.ItemsRange(0, 0, 0, []);
+ this._deletedNodesProvider.serializeItemsRange(beginPosition - this._addedCount, endPosition - this._addedCount, didReceiveDeletedItems.bind(this, emptyRange));
+ }
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
+ * @param {function()} callback
+ */
sortAndRewind: function(comparator, callback)
{
/**
@@ -989,13 +1280,15 @@ WebInspector.HeapSnapshotDiffNodesProvider.prototype = {
/**
* @constructor
+ * @param {!WebInspector.HeapSnapshotDiffDataGrid} dataGrid
+ * @param {string} className
+ * @param {!WebInspector.HeapSnapshotCommon.DiffForClass} diffForClass
* @extends {WebInspector.HeapSnapshotGridNode}
*/
-WebInspector.HeapSnapshotDiffNode = function(tree, className, diffForClass)
+WebInspector.HeapSnapshotDiffNode = function(dataGrid, className, diffForClass)
{
- WebInspector.HeapSnapshotGridNode.call(this, tree, true);
+ WebInspector.HeapSnapshotGridNode.call(this, dataGrid, true);
this._name = className;
-
this._addedCount = diffForClass.addedCount;
this._removedCount = diffForClass.removedCount;
this._countDelta = diffForClass.countDelta;
@@ -1003,6 +1296,15 @@ WebInspector.HeapSnapshotDiffNode = function(tree, className, diffForClass)
this._removedSize = diffForClass.removedSize;
this._sizeDelta = diffForClass.sizeDelta;
this._deletedIndexes = diffForClass.deletedIndexes;
+ this.data = {
+ "object": className,
+ "addedCount": Number.withThousandsSeparator(this._addedCount),
+ "removedCount": Number.withThousandsSeparator(this._removedCount),
+ "countDelta": this._signForDelta(this._countDelta) + Number.withThousandsSeparator(Math.abs(this._countDelta)),
+ "addedSize": Number.withThousandsSeparator(this._addedSize),
+ "removedSize": Number.withThousandsSeparator(this._removedSize),
+ "sizeDelta": this._signForDelta(this._sizeDelta) + Number.withThousandsSeparator(Math.abs(this._sizeDelta))
+ };
}
WebInspector.HeapSnapshotDiffNode.prototype = {
@@ -1020,24 +1322,51 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
this._removedCount);
},
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
+ createCell: function(columnIdentifier)
+ {
+ var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
+ if (columnIdentifier !== "object")
+ cell.classList.add("numeric-column");
+ return cell;
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Node} item
+ * @return {!WebInspector.HeapSnapshotInstanceNode}
+ */
_createChildNode: function(item)
{
if (item.isAddedNotRemoved)
- return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, null, this._dataGrid.snapshot, item);
+ return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.snapshot, item, false);
else
- return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.baseSnapshot, null, item);
+ return new WebInspector.HeapSnapshotInstanceNode(this._dataGrid, this._dataGrid.baseSnapshot, item, true);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
+ * @return {number}
+ */
_childHashForEntity: function(node)
{
return node.id;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotInstanceNode} childNode
+ * @return {number}
+ */
_childHashForNode: function(childNode)
{
return childNode.snapshotNodeId;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
@@ -1051,7 +1380,16 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
removedSize: ["selfSize", sortAscending, "id", true],
sizeDelta: ["selfSize", sortAscending, "id", true]
}[sortColumnIdentifier];
- return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
+ return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
+ },
+
+ /**
+ * @param {string} filterValue
+ * @return {boolean}
+ */
+ filteredOut: function(filterValue)
+ {
+ return this._name.toLowerCase().indexOf(filterValue) === -1;
},
_signForDelta: function(delta)
@@ -1064,20 +1402,6 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
return "\u2212"; // Math minus sign, same width as plus.
},
- get data()
- {
- var data = {object: this._name};
-
- data["addedCount"] = Number.withThousandsSeparator(this._addedCount);
- data["removedCount"] = Number.withThousandsSeparator(this._removedCount);
- data["countDelta"] = this._signForDelta(this._countDelta) + Number.withThousandsSeparator(Math.abs(this._countDelta));
- data["addedSize"] = Number.withThousandsSeparator(this._addedSize);
- data["removedSize"] = Number.withThousandsSeparator(this._removedSize);
- data["sizeDelta"] = this._signForDelta(this._sizeDelta) + Number.withThousandsSeparator(Math.abs(this._sizeDelta));
-
- return data;
- },
-
__proto__: WebInspector.HeapSnapshotGridNode.prototype
}
@@ -1085,10 +1409,12 @@ WebInspector.HeapSnapshotDiffNode.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotGenericObjectNode}
+ * @param {!WebInspector.HeapSnapshotSortableDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
*/
-WebInspector.HeapSnapshotDominatorObjectNode = function(tree, node)
+WebInspector.HeapSnapshotDominatorObjectNode = function(dataGrid, node)
{
- WebInspector.HeapSnapshotGenericObjectNode.call(this, tree, node);
+ WebInspector.HeapSnapshotGenericObjectNode.call(this, dataGrid, node);
this.updateHasChildren();
};
@@ -1104,7 +1430,7 @@ WebInspector.HeapSnapshotDominatorObjectNode.prototype = {
/**
* @param {number} snapshotObjectId
- * @param {function(?WebInspector.HeapSnapshotDominatorObjectNode)} callback
+ * @param {function(?WebInspector.DataGridNode)} callback
*/
retrieveChildBySnapshotObjectId: function(snapshotObjectId, callback)
{
@@ -1148,16 +1474,27 @@ WebInspector.HeapSnapshotDominatorObjectNode.prototype = {
return new WebInspector.HeapSnapshotDominatorObjectNode(this._dataGrid, item);
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Node} node
+ * @return {number}
+ */
_childHashForEntity: function(node)
{
return node.id;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotDominatorObjectNode} childNode
+ * @return {number}
+ */
_childHashForNode: function(childNode)
{
return childNode.snapshotNodeId;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.ComparatorConfig}
+ */
comparator: function()
{
var sortAscending = this._dataGrid.isSortOrderAscending();
@@ -1167,14 +1504,113 @@ WebInspector.HeapSnapshotDominatorObjectNode.prototype = {
shallowSize: ["selfSize", sortAscending, "id", true],
retainedSize: ["retainedSize", sortAscending, "id", true]
}[sortColumnIdentifier];
- return WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator(sortFields);
+ return WebInspector.HeapSnapshotGridNode.createComparator(sortFields);
+ },
+
+ __proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotGridNode}
+ * @param {!WebInspector.AllocationDataGrid} dataGrid
+ * @param {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode} data
+ */
+WebInspector.AllocationGridNode = function(dataGrid, data)
+{
+ WebInspector.HeapSnapshotGridNode.call(this, dataGrid, data.hasChildren);
+ this._populated = false;
+ this._allocationNode = data;
+ this.data = {
+ "liveCount": Number.withThousandsSeparator(data.liveCount),
+ "count": Number.withThousandsSeparator(data.count),
+ "liveSize": Number.withThousandsSeparator(data.liveSize),
+ "size": Number.withThousandsSeparator(data.size),
+ "name": data.name
+ };
+}
+
+WebInspector.AllocationGridNode.prototype = {
+ populate: function()
+ {
+ if (this._populated)
+ return;
+ this._populated = true;
+ this._dataGrid.snapshot.allocationNodeCallers(this._allocationNode.id, didReceiveCallers.bind(this));
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} callers
+ * @this {WebInspector.AllocationGridNode}
+ */
+ function didReceiveCallers(callers)
+ {
+ var callersChain = callers.nodesWithSingleCaller;
+ var parentNode = this;
+ var dataGrid = /** @type {!WebInspector.AllocationDataGrid} */ (this._dataGrid);
+ for (var i = 0; i < callersChain.length; i++) {
+ var child = new WebInspector.AllocationGridNode(dataGrid, callersChain[i]);
+ dataGrid.appendNode(parentNode, child);
+ parentNode = child;
+ parentNode._populated = true;
+ if (this.expanded)
+ parentNode.expand();
+ }
+
+ var callersBranch = callers.branchingCallers;
+ callersBranch.sort(this._dataGrid._createComparator());
+ for (var i = 0; i < callersBranch.length; i++)
+ dataGrid.appendNode(parentNode, new WebInspector.AllocationGridNode(dataGrid, callersBranch[i]));
+ dataGrid.updateVisibleNodes(true);
+ }
},
- _emptyData: function()
+ /**
+ * @override
+ */
+ expand: function()
{
- return {};
+ WebInspector.HeapSnapshotGridNode.prototype.expand.call(this);
+ if (this.children.length === 1)
+ this.children[0].expand();
},
- __proto__: WebInspector.HeapSnapshotGenericObjectNode.prototype
-}
+ /**
+ * @override
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
+ createCell: function(columnIdentifier)
+ {
+ if (columnIdentifier !== "name")
+ return this._createValueCell(columnIdentifier);
+
+ var cell = WebInspector.HeapSnapshotGridNode.prototype.createCell.call(this, columnIdentifier);
+ var allocationNode = this._allocationNode;
+ if (allocationNode.scriptId) {
+ var urlElement;
+ var linkifier = this._dataGrid._linkifier;
+ var script = WebInspector.debuggerModel.scriptForId(String(allocationNode.scriptId));
+ if (script) {
+ var rawLocation = WebInspector.debuggerModel.createRawLocation(script, allocationNode.line - 1, allocationNode.column - 1);
+ urlElement = linkifier.linkifyRawLocation(rawLocation, "profile-node-file");
+ } else {
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ urlElement = linkifier.linkifyLocation(target, allocationNode.scriptName, allocationNode.line - 1, allocationNode.column - 1, "profile-node-file");
+ }
+ urlElement.style.maxWidth = "75%";
+ cell.insertBefore(urlElement, cell.firstChild);
+ }
+ return cell;
+ },
+ /**
+ * @return {number}
+ */
+ allocationNodeId: function()
+ {
+ return this._allocationNode.id;
+ },
+
+ __proto__: WebInspector.HeapSnapshotGridNode.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotProxy.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js
index f88feb2d668..109398a15a0 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotProxy.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js
@@ -30,144 +30,6 @@
/**
* @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.HeapSnapshotWorkerWrapper = function()
-{
-}
-
-WebInspector.HeapSnapshotWorkerWrapper.prototype = {
- postMessage: function(message)
- {
- },
- terminate: function()
- {
- },
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @extends {WebInspector.HeapSnapshotWorkerWrapper}
- */
-WebInspector.HeapSnapshotRealWorker = function()
-{
- this._worker = new Worker("HeapSnapshotWorker.js");
- this._worker.addEventListener("message", this._messageReceived.bind(this), false);
-}
-
-WebInspector.HeapSnapshotRealWorker.prototype = {
- _messageReceived: function(event)
- {
- var message = event.data;
- this.dispatchEventToListeners("message", message);
- },
-
- postMessage: function(message)
- {
- this._worker.postMessage(message);
- },
-
- terminate: function()
- {
- this._worker.terminate();
- },
-
- __proto__: WebInspector.HeapSnapshotWorkerWrapper.prototype
-}
-
-
-/**
- * @constructor
- */
-WebInspector.AsyncTaskQueue = function()
-{
- this._queue = [];
- this._isTimerSheduled = false;
-}
-
-WebInspector.AsyncTaskQueue.prototype = {
- /**
- * @param {function()} task
- */
- addTask: function(task)
- {
- this._queue.push(task);
- this._scheduleTimer();
- },
-
- _onTimeout: function()
- {
- this._isTimerSheduled = false;
- var queue = this._queue;
- this._queue = [];
- for (var i = 0; i < queue.length; i++) {
- try {
- queue[i]();
- } catch (e) {
- console.error("Exception while running task: " + e.stack);
- }
- }
- this._scheduleTimer();
- },
-
- _scheduleTimer: function()
- {
- if (this._queue.length && !this._isTimerSheduled) {
- setTimeout(this._onTimeout.bind(this), 0);
- this._isTimerSheduled = true;
- }
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.HeapSnapshotWorkerWrapper}
- */
-WebInspector.HeapSnapshotFakeWorker = function()
-{
- this._dispatcher = new WebInspector.HeapSnapshotWorkerDispatcher(window, this._postMessageFromWorker.bind(this));
- this._asyncTaskQueue = new WebInspector.AsyncTaskQueue();
-}
-
-WebInspector.HeapSnapshotFakeWorker.prototype = {
- postMessage: function(message)
- {
- /**
- * @this {WebInspector.HeapSnapshotFakeWorker}
- */
- function dispatch()
- {
- if (this._dispatcher)
- this._dispatcher.dispatchMessage({data: message});
- }
- this._asyncTaskQueue.addTask(dispatch.bind(this));
- },
-
- terminate: function()
- {
- this._dispatcher = null;
- },
-
- _postMessageFromWorker: function(message)
- {
- /**
- * @this {WebInspector.HeapSnapshotFakeWorker}
- */
- function send()
- {
- this.dispatchEventToListeners("message", message);
- }
- this._asyncTaskQueue.addTask(send.bind(this));
- },
-
- __proto__: WebInspector.HeapSnapshotWorkerWrapper.prototype
-}
-
-
-/**
- * @constructor
* @param {function(string, *)} eventHandler
* @extends {WebInspector.Object}
*/
@@ -178,19 +40,20 @@ WebInspector.HeapSnapshotWorkerProxy = function(eventHandler)
this._nextCallId = 1;
this._callbacks = [];
this._previousCallbacks = [];
- // There is no support for workers in Chromium DRT.
- this._worker = typeof InspectorTest === "undefined" ? new WebInspector.HeapSnapshotRealWorker() : new WebInspector.HeapSnapshotFakeWorker();
- this._worker.addEventListener("message", this._messageReceived, this);
+ this._worker = new Worker("profiler/heap_snapshot_worker/HeapSnapshotWorker.js");
+ this._worker.onmessage = this._messageReceived.bind(this);
}
WebInspector.HeapSnapshotWorkerProxy.prototype = {
/**
+ * @param {number} profileUid
+ * @param {function(!WebInspector.HeapSnapshotProxy)} snapshotReceivedCallback
* @return {!WebInspector.HeapSnapshotLoaderProxy}
*/
- createLoader: function(snapshotConstructorName, proxyConstructor)
+ createLoader: function(profileUid, snapshotReceivedCallback)
{
var objectId = this._nextObjectId++;
- var proxy = new WebInspector.HeapSnapshotLoaderProxy(this, objectId, snapshotConstructorName, proxyConstructor);
+ var proxy = new WebInspector.HeapSnapshotLoaderProxy(this, objectId, profileUid, snapshotReceivedCallback);
this._postMessage({callId: this._nextCallId++, disposition: "create", objectId: objectId, methodName: "WebInspector.HeapSnapshotLoader"});
return proxy;
},
@@ -207,13 +70,21 @@ WebInspector.HeapSnapshotWorkerProxy.prototype = {
this._postMessage({callId: this._nextCallId++, disposition: "dispose", objectId: objectId});
},
- callGetter: function(callback, objectId, getterName)
+ evaluateForTest: function(script, callback)
{
var callId = this._nextCallId++;
this._callbacks[callId] = callback;
- this._postMessage({callId: callId, disposition: "getter", objectId: objectId, methodName: getterName});
+ this._postMessage({callId: callId, disposition: "evaluateForTest", source: script});
},
+ /**
+ * @param {?function(...[?])} callback
+ * @param {string} objectId
+ * @param {string} methodName
+ * @param {function(new:T, ...[?])} proxyConstructor
+ * @return {?Object}
+ * @template T
+ */
callFactoryMethod: function(callback, objectId, methodName, proxyConstructor)
{
var callId = this._nextCallId++;
@@ -238,6 +109,11 @@ WebInspector.HeapSnapshotWorkerProxy.prototype = {
}
},
+ /**
+ * @param {function(*)} callback
+ * @param {string} objectId
+ * @param {string} methodName
+ */
callMethod: function(callback, objectId, methodName)
{
var callId = this._nextCallId++;
@@ -270,15 +146,9 @@ WebInspector.HeapSnapshotWorkerProxy.prototype = {
this._previousCallbacks[callId] = true;
},
- _findFunction: function(name)
- {
- var path = name.split(".");
- var result = window;
- for (var i = 0; i < path.length; ++i)
- result = result[path[i]];
- return result;
- },
-
+ /**
+ * @param {!MessageEvent} event
+ */
_messageReceived: function(event)
{
var data = event.data;
@@ -289,8 +159,8 @@ WebInspector.HeapSnapshotWorkerProxy.prototype = {
}
if (data.error) {
if (data.errorMethodName)
- WebInspector.log(WebInspector.UIString("An error happened when a call for method '%s' was requested", data.errorMethodName));
- WebInspector.log(data.errorCallStack);
+ WebInspector.messageSink.addMessage(WebInspector.UIString("An error occurred when a call to method '%s' was requested", data.errorMethodName));
+ WebInspector.messageSink.addMessage(data["errorCallStack"]);
delete this._callbacks[data.callId];
return;
}
@@ -312,6 +182,8 @@ WebInspector.HeapSnapshotWorkerProxy.prototype = {
/**
* @constructor
+ * @param {!WebInspector.HeapSnapshotWorkerProxy} worker
+ * @param {number} objectId
*/
WebInspector.HeapSnapshotProxyObject = function(worker, objectId)
{
@@ -320,6 +192,10 @@ WebInspector.HeapSnapshotProxyObject = function(worker, objectId)
}
WebInspector.HeapSnapshotProxyObject.prototype = {
+ /**
+ * @param {string} workerMethodName
+ * @param {!Array.<*>} args
+ */
_callWorker: function(workerMethodName, args)
{
args.splice(1, 0, this._objectId);
@@ -337,28 +213,28 @@ WebInspector.HeapSnapshotProxyObject.prototype = {
},
/**
+ * @param {?function(...[?])} callback
+ * @param {string} methodName
+ * @param {function (new:T, ...[?])} proxyConstructor
* @param {...*} var_args
+ * @return {!T}
+ * @template T
*/
callFactoryMethod: function(callback, methodName, proxyConstructor, var_args)
{
return this._callWorker("callFactoryMethod", Array.prototype.slice.call(arguments, 0));
},
- callGetter: function(callback, getterName)
- {
- return this._callWorker("callGetter", Array.prototype.slice.call(arguments, 0));
- },
-
/**
+ * @param {function(T)|undefined} callback
+ * @param {string} methodName
* @param {...*} var_args
+ * @return {*}
+ * @template T
*/
callMethod: function(callback, methodName, var_args)
{
return this._callWorker("callMethod", Array.prototype.slice.call(arguments, 0));
- },
-
- get worker() {
- return this._worker;
}
};
@@ -366,25 +242,20 @@ WebInspector.HeapSnapshotProxyObject.prototype = {
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
* @implements {WebInspector.OutputStream}
+ * @param {!WebInspector.HeapSnapshotWorkerProxy} worker
+ * @param {number} objectId
+ * @param {number} profileUid
+ * @param {function(!WebInspector.HeapSnapshotProxy)} snapshotReceivedCallback
*/
-WebInspector.HeapSnapshotLoaderProxy = function(worker, objectId, snapshotConstructorName, proxyConstructor)
+WebInspector.HeapSnapshotLoaderProxy = function(worker, objectId, profileUid, snapshotReceivedCallback)
{
WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId);
- this._snapshotConstructorName = snapshotConstructorName;
- this._proxyConstructor = proxyConstructor;
- this._pendingSnapshotConsumers = [];
+ this._profileUid = profileUid;
+ this._snapshotReceivedCallback = snapshotReceivedCallback;
}
WebInspector.HeapSnapshotLoaderProxy.prototype = {
/**
- * @param {function(!WebInspector.HeapSnapshotProxy)} callback
- */
- addConsumer: function(callback)
- {
- this._pendingSnapshotConsumers.push(callback);
- },
-
- /**
* @param {string} chunk
* @param {function(!WebInspector.OutputStream)=} callback
*/
@@ -405,26 +276,19 @@ WebInspector.HeapSnapshotLoaderProxy.prototype = {
{
if (callback)
callback();
- this.callFactoryMethod(updateStaticData.bind(this), "buildSnapshot", this._proxyConstructor, this._snapshotConstructorName);
+ var showHiddenData = WebInspector.settings.showAdvancedHeapSnapshotProperties.get();
+ this.callFactoryMethod(updateStaticData.bind(this), "buildSnapshot", WebInspector.HeapSnapshotProxy, showHiddenData);
}
/**
+ * @param {!WebInspector.HeapSnapshotProxy} snapshotProxy
* @this {WebInspector.HeapSnapshotLoaderProxy}
*/
function updateStaticData(snapshotProxy)
{
this.dispose();
- snapshotProxy.updateStaticData(notifyPendingConsumers.bind(this));
- }
-
- /**
- * @this {WebInspector.HeapSnapshotLoaderProxy}
- */
- function notifyPendingConsumers(snapshotProxy)
- {
- for (var i = 0; i < this._pendingSnapshotConsumers.length; ++i)
- this._pendingSnapshotConsumers[i](snapshotProxy);
- this._pendingSnapshotConsumers = [];
+ snapshotProxy.setProfileUid(this._profileUid);
+ snapshotProxy.updateStaticData(this._snapshotReceivedCallback.bind(this));
}
this.callMethod(buildSnapshot.bind(this), "close");
@@ -437,16 +301,24 @@ WebInspector.HeapSnapshotLoaderProxy.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
+ * @param {!WebInspector.HeapSnapshotWorkerProxy} worker
+ * @param {number} objectId
*/
WebInspector.HeapSnapshotProxy = function(worker, objectId)
{
WebInspector.HeapSnapshotProxyObject.call(this, worker, objectId);
+ /** @type {?WebInspector.HeapSnapshotCommon.StaticData} */
+ this._staticData = null;
}
WebInspector.HeapSnapshotProxy.prototype = {
- aggregates: function(sortedIndexes, key, filter, callback)
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} filter
+ * @param {function(!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>)} callback
+ */
+ aggregatesWithFilter: function(filter, callback)
{
- this.callMethod(callback, "aggregates", sortedIndexes, key, filter);
+ this.callMethod(callback, "aggregatesWithFilter", filter);
},
aggregatesForDiff: function(callback)
@@ -469,59 +341,97 @@ WebInspector.HeapSnapshotProxy.prototype = {
this.callMethod(callback, "dominatorIdsForNode", nodeIndex);
},
- createEdgesProvider: function(nodeIndex, showHiddenData)
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.HeapSnapshotProviderProxy}
+ */
+ createEdgesProvider: function(nodeIndex)
{
- return this.callFactoryMethod(null, "createEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex, showHiddenData);
+ return this.callFactoryMethod(null, "createEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex);
},
- createRetainingEdgesProvider: function(nodeIndex, showHiddenData)
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.HeapSnapshotProviderProxy}
+ */
+ createRetainingEdgesProvider: function(nodeIndex)
{
- return this.callFactoryMethod(null, "createRetainingEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex, showHiddenData);
+ return this.callFactoryMethod(null, "createRetainingEdgesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndex);
},
+ /**
+ * @param {string} baseSnapshotId
+ * @param {string} className
+ * @return {?WebInspector.HeapSnapshotProviderProxy}
+ */
createAddedNodesProvider: function(baseSnapshotId, className)
{
return this.callFactoryMethod(null, "createAddedNodesProvider", WebInspector.HeapSnapshotProviderProxy, baseSnapshotId, className);
},
+ /**
+ * @param {!Array.<number>} nodeIndexes
+ * @return {?WebInspector.HeapSnapshotProviderProxy}
+ */
createDeletedNodesProvider: function(nodeIndexes)
{
return this.callFactoryMethod(null, "createDeletedNodesProvider", WebInspector.HeapSnapshotProviderProxy, nodeIndexes);
},
+ /**
+ * @param {function(*):boolean} filter
+ * @return {?WebInspector.HeapSnapshotProviderProxy}
+ */
createNodesProvider: function(filter)
{
return this.callFactoryMethod(null, "createNodesProvider", WebInspector.HeapSnapshotProviderProxy, filter);
},
- createNodesProviderForClass: function(className, aggregatesKey)
+ /**
+ * @param {string} className
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
+ * @return {?WebInspector.HeapSnapshotProviderProxy}
+ */
+ createNodesProviderForClass: function(className, nodeFilter)
{
- return this.callFactoryMethod(null, "createNodesProviderForClass", WebInspector.HeapSnapshotProviderProxy, className, aggregatesKey);
+ return this.callFactoryMethod(null, "createNodesProviderForClass", WebInspector.HeapSnapshotProviderProxy, className, nodeFilter);
},
+ /**
+ * @param {number} nodeIndex
+ * @return {?WebInspector.HeapSnapshotProviderProxy}
+ */
createNodesProviderForDominator: function(nodeIndex)
{
return this.callFactoryMethod(null, "createNodesProviderForDominator", WebInspector.HeapSnapshotProviderProxy, nodeIndex);
},
- maxJsNodeId: function(callback)
- {
- this.callMethod(callback, "maxJsNodeId");
- },
-
allocationTracesTops: function(callback)
{
this.callMethod(callback, "allocationTracesTops");
},
+ /**
+ * @param {number} nodeId
+ * @param {function(!WebInspector.HeapSnapshotCommon.AllocationNodeCallers)} callback
+ */
allocationNodeCallers: function(nodeId, callback)
{
this.callMethod(callback, "allocationNodeCallers", nodeId);
},
+ /**
+ * @param {number} nodeIndex
+ * @param {function(?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>)} callback
+ */
+ allocationStack: function(nodeIndex, callback)
+ {
+ this.callMethod(callback, "allocationStack", nodeIndex);
+ },
+
dispose: function()
{
- this.disposeWorker();
+ throw new Error("Should never be called");
},
get nodeCount()
@@ -537,6 +447,7 @@ WebInspector.HeapSnapshotProxy.prototype = {
updateStaticData: function(callback)
{
/**
+ * @param {!WebInspector.HeapSnapshotCommon.StaticData} staticData
* @this {WebInspector.HeapSnapshotProxy}
*/
function dataReceived(staticData)
@@ -547,6 +458,14 @@ WebInspector.HeapSnapshotProxy.prototype = {
this.callMethod(dataReceived.bind(this), "updateStaticData");
},
+ /**
+ * @param {!function(!WebInspector.HeapSnapshotCommon.Statistics):void} callback
+ */
+ getStatistics: function(callback)
+ {
+ this.callMethod(callback, "getStatistics");
+ },
+
get totalSize()
{
return this._staticData.totalSize;
@@ -554,7 +473,20 @@ WebInspector.HeapSnapshotProxy.prototype = {
get uid()
{
- return this._staticData.uid;
+ return this._profileUid;
+ },
+
+ setProfileUid: function(profileUid)
+ {
+ this._profileUid = profileUid;
+ },
+
+ /**
+ * @return {number}
+ */
+ maxJSObjectId: function()
+ {
+ return this._staticData.maxJSObjectId;
},
__proto__: WebInspector.HeapSnapshotProxyObject.prototype
@@ -564,6 +496,9 @@ WebInspector.HeapSnapshotProxy.prototype = {
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProxyObject}
+ * @implements {WebInspector.HeapSnapshotGridNode.ChildrenProvider}
+ * @param {!WebInspector.HeapSnapshotWorkerProxy} worker
+ * @param {number} objectId
*/
WebInspector.HeapSnapshotProviderProxy = function(worker, objectId)
{
@@ -571,21 +506,41 @@ WebInspector.HeapSnapshotProviderProxy = function(worker, objectId)
}
WebInspector.HeapSnapshotProviderProxy.prototype = {
+ /**
+ * @override
+ * @param {number} snapshotObjectId
+ * @param {function(number)} callback
+ */
nodePosition: function(snapshotObjectId, callback)
{
this.callMethod(callback, "nodePosition", snapshotObjectId);
},
+ /**
+ * @override
+ * @param {function(boolean)} callback
+ */
isEmpty: function(callback)
{
this.callMethod(callback, "isEmpty");
},
+ /**
+ * @override
+ * @param {number} startPosition
+ * @param {number} endPosition
+ * @param {function(!WebInspector.HeapSnapshotCommon.ItemsRange)} callback
+ */
serializeItemsRange: function(startPosition, endPosition, callback)
{
this.callMethod(callback, "serializeItemsRange", startPosition, endPosition);
},
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
+ * @param {function()} callback
+ */
sortAndRewind: function(comparator, callback)
{
this.callMethod(callback, "sortAndRewind", comparator);
@@ -593,4 +548,3 @@ WebInspector.HeapSnapshotProviderProxy.prototype = {
__proto__: WebInspector.HeapSnapshotProxyObject.prototype
}
-
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
new file mode 100644
index 00000000000..33148fcd4b1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
@@ -0,0 +1,2285 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * FIXME: ES5 strict mode check is suppressed due to multiple uses of arguments.callee.
+ * @fileoverview
+ * @suppress {es5Strict}
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @param {!WebInspector.HeapProfileHeader} profile
+ */
+WebInspector.HeapSnapshotView = function(dataDisplayDelegate, profile)
+{
+ WebInspector.VBox.call(this);
+
+ this.element.classList.add("heap-snapshot-view");
+
+ profile.profileType().addEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
+ profile.profileType().addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
+
+ if (profile._profileType.id === WebInspector.TrackingHeapSnapshotProfileType.TypeId) {
+ this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile);
+ this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
+ }
+
+ this._splitView = new WebInspector.SplitView(false, true, "heapSnapshotSplitViewState", 200, 200);
+ this._splitView.show(this.element);
+
+ this._containmentView = new WebInspector.VBox();
+ this._containmentView.setMinimumSize(50, 25);
+ this._containmentDataGrid = new WebInspector.HeapSnapshotContainmentDataGrid(dataDisplayDelegate);
+ this._containmentDataGrid.show(this._containmentView.element);
+ this._containmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
+
+ this._statisticsView = new WebInspector.HeapSnapshotStatisticsView();
+
+ this._constructorsView = new WebInspector.VBox();
+ this._constructorsView.setMinimumSize(50, 25);
+
+ this._constructorsDataGrid = new WebInspector.HeapSnapshotConstructorsDataGrid(dataDisplayDelegate);
+ this._constructorsDataGrid.show(this._constructorsView.element);
+ this._constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
+
+ this._diffView = new WebInspector.VBox();
+ this._diffView.setMinimumSize(50, 25);
+
+ this._diffDataGrid = new WebInspector.HeapSnapshotDiffDataGrid(dataDisplayDelegate);
+ this._diffDataGrid.show(this._diffView.element);
+ this._diffDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
+
+ this._dominatorView = new WebInspector.VBox();
+ this._dominatorView.setMinimumSize(50, 25);
+ this._dominatorDataGrid = new WebInspector.HeapSnapshotDominatorsDataGrid(dataDisplayDelegate);
+ this._dominatorDataGrid.show(this._dominatorView.element);
+ this._dominatorDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
+
+ if (WebInspector.experimentsSettings.heapAllocationProfiler.isEnabled() && profile.profileType() === WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) {
+ this._allocationView = new WebInspector.VBox();
+ this._allocationView.setMinimumSize(50, 25);
+ this._allocationDataGrid = new WebInspector.AllocationDataGrid(dataDisplayDelegate);
+ this._allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._onSelectAllocationNode, this);
+ this._allocationDataGrid.show(this._allocationView.element);
+
+ this._allocationStackView = new WebInspector.HeapAllocationStackView();
+ this._allocationStackView.setMinimumSize(50, 25);
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.closeableTabs = false;
+ this._tabbedPane.headerElement().classList.add("heap-object-details-header");
+ }
+
+ this._retainmentView = new WebInspector.VBox();
+ this._retainmentView.setMinimumSize(50, 21);
+ this._retainmentView.element.classList.add("retaining-paths-view");
+
+ var splitViewResizer;
+ if (this._allocationStackView) {
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.closeableTabs = false;
+ this._tabbedPane.headerElement().classList.add("heap-object-details-header");
+
+ this._tabbedPane.appendTab("retainers", WebInspector.UIString("Retainers"), this._retainmentView);
+ this._tabbedPane.appendTab("allocation-stack", WebInspector.UIString("Allocation stack"), this._allocationStackView);
+
+ splitViewResizer = this._tabbedPane.headerElement();
+ this._objectDetailsView = this._tabbedPane;
+ } else {
+ var retainmentViewHeader = document.createElementWithClass("div", "heap-snapshot-view-resizer");
+ var retainingPathsTitleDiv = retainmentViewHeader.createChild("div", "title");
+ var retainingPathsTitle = retainingPathsTitleDiv.createChild("span");
+ retainingPathsTitle.textContent = WebInspector.UIString("Retainers");
+ this._retainmentView.element.appendChild(retainmentViewHeader);
+
+ splitViewResizer = retainmentViewHeader;
+ this._objectDetailsView = this._retainmentView;
+ }
+ this._splitView.hideDefaultResizer();
+ this._splitView.installResizer(splitViewResizer);
+
+ this._retainmentDataGrid = new WebInspector.HeapSnapshotRetainmentDataGrid(dataDisplayDelegate);
+ this._retainmentDataGrid.show(this._retainmentView.element);
+ this._retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
+ this._retainmentDataGrid.reset();
+
+ this._perspectives = [];
+ this._perspectives.push(new WebInspector.HeapSnapshotView.SummaryPerspective());
+ if (profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
+ this._perspectives.push(new WebInspector.HeapSnapshotView.ComparisonPerspective());
+ this._perspectives.push(new WebInspector.HeapSnapshotView.ContainmentPerspective());
+ if (WebInspector.settings.showAdvancedHeapSnapshotProperties.get())
+ this._perspectives.push(new WebInspector.HeapSnapshotView.DominatorPerspective());
+ if (this._allocationView)
+ this._perspectives.push(new WebInspector.HeapSnapshotView.AllocationPerspective());
+ if (WebInspector.experimentsSettings.heapSnapshotStatistics.isEnabled())
+ this._perspectives.push(new WebInspector.HeapSnapshotView.StatisticsPerspective());
+
+ this._perspectiveSelect = new WebInspector.StatusBarComboBox(this._onSelectedPerspectiveChanged.bind(this));
+ for (var i = 0; i < this._perspectives.length; ++i)
+ this._perspectiveSelect.createOption(this._perspectives[i].title());
+
+ this._profile = profile;
+
+ this._baseSelect = new WebInspector.StatusBarComboBox(this._changeBase.bind(this));
+ this._baseSelect.visible = false;
+ this._updateBaseOptions();
+
+ this._filterSelect = new WebInspector.StatusBarComboBox(this._changeFilter.bind(this));
+ this._filterSelect.visible = false;
+ this._updateFilterOptions();
+
+ this._classNameFilter = new WebInspector.StatusBarInput("Class filter");
+ this._classNameFilter.visible = false;
+ this._constructorsDataGrid.setNameFilter(this._classNameFilter);
+ this._diffDataGrid.setNameFilter(this._classNameFilter);
+
+ this._selectedSizeText = new WebInspector.StatusBarText("");
+
+ this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true);
+
+ this._currentPerspectiveIndex = 0;
+ this._currentPerspective = this._perspectives[0];
+ this._currentPerspective.activate(this);
+ this._dataGrid = this._currentPerspective.masterGrid(this);
+
+ this._refreshView();
+}
+
+/**
+ * @constructor
+ * @param {string} title
+ */
+WebInspector.HeapSnapshotView.Perspective = function(title)
+{
+ this._title = title;
+}
+
+WebInspector.HeapSnapshotView.Perspective.prototype = {
+ /**
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView) { },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ deactivate: function(heapSnapshotView)
+ {
+ heapSnapshotView._baseSelect.visible = false;
+ heapSnapshotView._filterSelect.visible = false;
+ heapSnapshotView._classNameFilter.visible = false;
+ if (heapSnapshotView._trackingOverviewGrid)
+ heapSnapshotView._trackingOverviewGrid.detach();
+ if (heapSnapshotView._allocationView)
+ heapSnapshotView._allocationView.detach();
+ if (heapSnapshotView._statisticsView)
+ heapSnapshotView._statisticsView.detach();
+
+ heapSnapshotView._splitView.detach();
+ heapSnapshotView._splitView.detachChildViews();
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return null;
+ },
+
+ /**
+ * @return {string}
+ */
+ title: function()
+ {
+ return this._title;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ supportsSearch: function()
+ {
+ return false;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.SummaryPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Summary"));
+}
+
+WebInspector.HeapSnapshotView.SummaryPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._constructorsView.show(heapSnapshotView._splitView.mainElement());
+ heapSnapshotView._objectDetailsView.show(heapSnapshotView._splitView.sidebarElement());
+ heapSnapshotView._splitView.show(heapSnapshotView.element);
+ heapSnapshotView._filterSelect.visible = true;
+ heapSnapshotView._classNameFilter.visible = true;
+ if (heapSnapshotView._trackingOverviewGrid) {
+ heapSnapshotView._trackingOverviewGrid.show(heapSnapshotView.element, heapSnapshotView._splitView.element);
+ heapSnapshotView._trackingOverviewGrid.update();
+ heapSnapshotView._trackingOverviewGrid._updateGrid();
+ }
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return heapSnapshotView._constructorsDataGrid;
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsSearch: function()
+ {
+ return true;
+ },
+
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.ComparisonPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Comparison"));
+}
+
+WebInspector.HeapSnapshotView.ComparisonPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._diffView.show(heapSnapshotView._splitView.mainElement());
+ heapSnapshotView._objectDetailsView.show(heapSnapshotView._splitView.sidebarElement());
+ heapSnapshotView._splitView.show(heapSnapshotView.element);
+ heapSnapshotView._baseSelect.visible = true;
+ heapSnapshotView._classNameFilter.visible = true;
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return heapSnapshotView._diffDataGrid;
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ supportsSearch: function()
+ {
+ return true;
+ },
+
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.ContainmentPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Containment"));
+}
+
+WebInspector.HeapSnapshotView.ContainmentPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._containmentView.show(heapSnapshotView._splitView.mainElement());
+ heapSnapshotView._objectDetailsView.show(heapSnapshotView._splitView.sidebarElement());
+ heapSnapshotView._splitView.show(heapSnapshotView.element);
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return heapSnapshotView._containmentDataGrid;
+ },
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.DominatorPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Dominators"));
+}
+
+WebInspector.HeapSnapshotView.DominatorPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._dominatorView.show(heapSnapshotView._splitView.mainElement());
+ heapSnapshotView._objectDetailsView.show(heapSnapshotView._splitView.sidebarElement());
+ heapSnapshotView._splitView.show(heapSnapshotView.element);
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return heapSnapshotView._dominatorDataGrid;
+ },
+
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.AllocationPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Allocation"));
+ this._allocationSplitView = new WebInspector.SplitView(false, true, "heapSnapshotAllocationSplitViewState", 200, 200);
+
+ var resizer = document.createElementWithClass("div", "heap-snapshot-view-resizer");
+ var title = resizer.createChild("div", "title").createChild("span");
+ title.textContent = WebInspector.UIString("Live objects");
+ this._allocationSplitView.hideDefaultResizer();
+ this._allocationSplitView.installResizer(resizer);
+
+ this._allocationSplitView.sidebarElement().appendChild(resizer);
+}
+
+WebInspector.HeapSnapshotView.AllocationPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._allocationView.show(this._allocationSplitView.mainElement());
+ heapSnapshotView._constructorsView.show(heapSnapshotView._splitView.mainElement());
+ heapSnapshotView._objectDetailsView.show(heapSnapshotView._splitView.sidebarElement());
+ heapSnapshotView._splitView.show(this._allocationSplitView.sidebarElement());
+ this._allocationSplitView.show(heapSnapshotView.element);
+
+ heapSnapshotView._constructorsDataGrid.clear();
+ var selectedNode = heapSnapshotView._allocationDataGrid.selectedNode;
+ if (selectedNode)
+ heapSnapshotView._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ deactivate: function(heapSnapshotView)
+ {
+ this._allocationSplitView.detach();
+ WebInspector.HeapSnapshotView.Perspective.prototype.deactivate.call(this, heapSnapshotView);
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return heapSnapshotView._allocationDataGrid;
+ },
+
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotView.Perspective}
+ */
+WebInspector.HeapSnapshotView.StatisticsPerspective = function()
+{
+ WebInspector.HeapSnapshotView.Perspective.call(this, WebInspector.UIString("Statistics"));
+}
+
+WebInspector.HeapSnapshotView.StatisticsPerspective.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ */
+ activate: function(heapSnapshotView)
+ {
+ heapSnapshotView._statisticsView.show(heapSnapshotView.element);
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.HeapSnapshotView} heapSnapshotView
+ * @return {?WebInspector.DataGrid}
+ */
+ masterGrid: function(heapSnapshotView)
+ {
+ return null;
+ },
+
+ __proto__: WebInspector.HeapSnapshotView.Perspective.prototype
+}
+
+
+WebInspector.HeapSnapshotView.prototype = {
+ _refreshView: function()
+ {
+ this._profile.load(profileCallback.bind(this));
+
+ /**
+ * @param {!WebInspector.HeapSnapshotProxy} heapSnapshotProxy
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function profileCallback(heapSnapshotProxy)
+ {
+ heapSnapshotProxy.getStatistics(this._gotStatistics.bind(this));
+ var list = this._profiles();
+ var profileIndex = list.indexOf(this._profile);
+ this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
+ this._dataGrid.setDataSource(heapSnapshotProxy);
+ if (this._trackingOverviewGrid)
+ this._trackingOverviewGrid._updateGrid();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.Statistics} statistics
+ */
+ _gotStatistics: function(statistics) {
+ this._statisticsView.setTotal(statistics.total);
+ this._statisticsView.addRecord(statistics.code, WebInspector.UIString("Code"), "#f77");
+ this._statisticsView.addRecord(statistics.strings, WebInspector.UIString("Strings"), "#5e5");
+ this._statisticsView.addRecord(statistics.jsArrays, WebInspector.UIString("JS Arrays"), "#7af");
+ this._statisticsView.addRecord(statistics.native, WebInspector.UIString("Typed Arrays"), "#fc5");
+ this._statisticsView.addRecord(statistics.total, WebInspector.UIString("Total"));
+ },
+
+ _onIdsRangeChanged: function(event)
+ {
+ var minId = event.data.minId;
+ var maxId = event.data.maxId;
+ this._selectedSizeText.setText(WebInspector.UIString("Selected size: %s", Number.bytesToString(event.data.size)));
+ if (this._constructorsDataGrid.snapshot)
+ this._constructorsDataGrid.setSelectionRange(minId, maxId);
+ },
+
+ get statusBarItems()
+ {
+ var result = [this._perspectiveSelect.element, this._classNameFilter.element];
+ if (this._profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
+ result.push(this._baseSelect.element, this._filterSelect.element);
+ result.push(this._selectedSizeText.element);
+ return result;
+ },
+
+ wasShown: function()
+ {
+ // FIXME: load base and current snapshots in parallel
+ this._profile.load(profileCallback.bind(this));
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function profileCallback() {
+ this._profile._wasShown();
+ if (this._baseProfile)
+ this._baseProfile.load(function() { });
+ }
+ },
+
+ willHide: function()
+ {
+ this._currentSearchResultIndex = -1;
+ this._popoverHelper.hidePopover();
+ if (this.helpPopover && this.helpPopover.isShowing())
+ this.helpPopover.hide();
+ },
+
+ searchCanceled: function()
+ {
+ if (this._searchResults) {
+ for (var i = 0; i < this._searchResults.length; ++i) {
+ var node = this._searchResults[i].node;
+ delete node._searchMatched;
+ node.refresh();
+ }
+ }
+
+ delete this._searchFinishedCallback;
+ this._currentSearchResultIndex = -1;
+ this._searchResults = [];
+ },
+
+ /**
+ * @param {string} query
+ * @param {function(!WebInspector.View, number)} finishedCallback
+ */
+ performSearch: function(query, finishedCallback)
+ {
+ // Call searchCanceled since it will reset everything we need before doing a new search.
+ this.searchCanceled();
+
+ query = query.trim();
+
+ if (!query)
+ return;
+ if (!this._currentPerspective.supportsSearch())
+ return;
+
+ /**
+ * @param {boolean} found
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function didHighlight(found)
+ {
+ finishedCallback(this, found ? 1 : 0);
+ }
+
+ if (query.charAt(0) === "@") {
+ var snapshotNodeId = parseInt(query.substring(1), 10);
+ if (!isNaN(snapshotNodeId))
+ this._dataGrid.highlightObjectByHeapSnapshotId(String(snapshotNodeId), didHighlight.bind(this));
+ else
+ finishedCallback(this, 0);
+ return;
+ }
+
+ this._searchFinishedCallback = finishedCallback;
+ var nameRegExp = createPlainTextSearchRegex(query, "i");
+
+ function matchesByName(gridNode) {
+ return ("_name" in gridNode) && nameRegExp.test(gridNode._name);
+ }
+
+ function matchesQuery(gridNode)
+ {
+ delete gridNode._searchMatched;
+ if (matchesByName(gridNode)) {
+ gridNode._searchMatched = true;
+ gridNode.refresh();
+ return true;
+ }
+ return false;
+ }
+
+ var current = this._dataGrid.rootNode().children[0];
+ var depth = 0;
+ var info = {};
+
+ // Restrict to type nodes and instances.
+ const maxDepth = 1;
+
+ while (current) {
+ if (matchesQuery(current))
+ this._searchResults.push({ node: current });
+ current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
+ depth += info.depthChange;
+ }
+
+ finishedCallback(this, this._searchResults.length);
+ },
+
+ jumpToFirstSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ this._currentSearchResultIndex = 0;
+ this._jumpToSearchResult(this._currentSearchResultIndex);
+ },
+
+ jumpToLastSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ this._currentSearchResultIndex = (this._searchResults.length - 1);
+ this._jumpToSearchResult(this._currentSearchResultIndex);
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ if (++this._currentSearchResultIndex >= this._searchResults.length)
+ this._currentSearchResultIndex = 0;
+ this._jumpToSearchResult(this._currentSearchResultIndex);
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ if (--this._currentSearchResultIndex < 0)
+ this._currentSearchResultIndex = (this._searchResults.length - 1);
+ this._jumpToSearchResult(this._currentSearchResultIndex);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ showingFirstSearchResult: function()
+ {
+ return (this._currentSearchResultIndex === 0);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ showingLastSearchResult: function()
+ {
+ return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
+ },
+
+ /**
+ * @return {number}
+ */
+ currentSearchResultIndex: function() {
+ return this._currentSearchResultIndex;
+ },
+
+ _jumpToSearchResult: function(index)
+ {
+ var searchResult = this._searchResults[index];
+ if (!searchResult)
+ return;
+
+ var node = searchResult.node;
+ node.revealAndSelect();
+ },
+
+ refreshVisibleData: function()
+ {
+ if (!this._dataGrid)
+ return;
+ var child = this._dataGrid.rootNode().children[0];
+ while (child) {
+ child.refresh();
+ child = child.traverseNextNode(false, null, true);
+ }
+ },
+
+ _changeBase: function()
+ {
+ if (this._baseProfile === this._profiles()[this._baseSelect.selectedIndex()])
+ return;
+
+ this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
+ var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this._dataGrid);
+ // Change set base data source only if main data source is already set.
+ if (dataGrid.snapshot)
+ this._baseProfile.load(dataGrid.setBaseDataSource.bind(dataGrid));
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again with the same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
+ },
+
+ _changeFilter: function()
+ {
+ var profileIndex = this._filterSelect.selectedIndex() - 1;
+ this._dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);
+
+ WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
+ action: WebInspector.UserMetrics.UserActionNames.HeapSnapshotFilterChanged,
+ label: this._filterSelect.selectedOption().label
+ });
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again with the same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.ProfileHeader>}
+ */
+ _profiles: function()
+ {
+ return this._profile.profileType().getProfiles();
+ },
+
+ /**
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {?Event} event
+ */
+ populateContextMenu: function(contextMenu, event)
+ {
+ if (this._dataGrid)
+ this._dataGrid.populateContextMenu(contextMenu, event);
+ },
+
+ _selectionChanged: function(event)
+ {
+ var selectedNode = event.target.selectedNode;
+ this._setSelectedNodeForDetailsView(selectedNode);
+ this._inspectedObjectChanged(event);
+ },
+
+ _onSelectAllocationNode: function(event)
+ {
+ var selectedNode = event.target.selectedNode;
+ this._constructorsDataGrid.setAllocationNodeId(selectedNode.allocationNodeId());
+ this._setSelectedNodeForDetailsView(null);
+ },
+
+ _inspectedObjectChanged: function(event)
+ {
+ var selectedNode = event.target.selectedNode;
+ if (!this._profile.fromFile() && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode)
+ ConsoleAgent.addInspectedHeapObject(selectedNode.snapshotNodeId);
+ },
+
+ /**
+ * @param {?WebInspector.HeapSnapshotGridNode} nodeItem
+ */
+ _setSelectedNodeForDetailsView: function(nodeItem)
+ {
+ var dataSource = nodeItem && nodeItem.retainersDataSource();
+ if (dataSource) {
+ this._retainmentDataGrid.setDataSource(dataSource.snapshot, dataSource.snapshotNodeIndex);
+ if (this._allocationStackView)
+ this._allocationStackView.setAllocatedObject(dataSource.snapshot, dataSource.snapshotNodeIndex)
+ } else {
+ if (this._allocationStackView)
+ this._allocationStackView.clear();
+ this._retainmentDataGrid.reset();
+ }
+ },
+
+ /**
+ * @param {string} perspectiveTitle
+ * @param {function()} callback
+ */
+ _changePerspectiveAndWait: function(perspectiveTitle, callback)
+ {
+ var perspectiveIndex = null;
+ for (var i = 0; i < this._perspectives.length; ++i) {
+ if (this._perspectives[i].title() === perspectiveTitle) {
+ perspectiveIndex = i;
+ break;
+ }
+ }
+ if (this._currentPerspectiveIndex === perspectiveIndex || perspectiveIndex === null) {
+ setTimeout(callback, 0);
+ return;
+ }
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function dataGridContentShown(event)
+ {
+ var dataGrid = event.data;
+ dataGrid.removeEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
+ if (dataGrid === this._dataGrid)
+ callback();
+ }
+ this._perspectives[perspectiveIndex].masterGrid(this).addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
+
+ this._perspectiveSelect.setSelectedIndex(perspectiveIndex);
+ this._changePerspective(perspectiveIndex);
+ },
+
+ _updateDataSourceAndView: function()
+ {
+ var dataGrid = this._dataGrid;
+ if (!dataGrid || dataGrid.snapshot)
+ return;
+
+ this._profile.load(didLoadSnapshot.bind(this));
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function didLoadSnapshot(snapshotProxy)
+ {
+ if (this._dataGrid !== dataGrid)
+ return;
+ if (dataGrid.snapshot !== snapshotProxy)
+ dataGrid.setDataSource(snapshotProxy);
+ if (dataGrid === this._diffDataGrid) {
+ if (!this._baseProfile)
+ this._baseProfile = this._profiles()[this._baseSelect.selectedIndex()];
+ this._baseProfile.load(didLoadBaseSnaphot.bind(this));
+ }
+ }
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function didLoadBaseSnaphot(baseSnapshotProxy)
+ {
+ if (this._diffDataGrid.baseSnapshot !== baseSnapshotProxy)
+ this._diffDataGrid.setBaseDataSource(baseSnapshotProxy);
+ }
+ },
+
+ _onSelectedPerspectiveChanged: function(event)
+ {
+ this._changePerspective(event.target.selectedIndex);
+ // FIXME: This is needed by CodeSchool extension.
+ this._onSelectedViewChanged(event);
+ },
+
+ _onSelectedViewChanged: function(event)
+ {
+ },
+
+ _changePerspective: function(selectedIndex)
+ {
+ if (selectedIndex === this._currentPerspectiveIndex)
+ return;
+
+ this._currentPerspectiveIndex = selectedIndex;
+
+ this._currentPerspective.deactivate(this);
+ var perspective = this._perspectives[selectedIndex];
+ this._currentPerspective = perspective;
+ this._dataGrid = perspective.masterGrid(this);
+ perspective.activate(this);
+
+ this.refreshVisibleData();
+ if (this._dataGrid)
+ this._dataGrid.updateWidths();
+
+ this._updateDataSourceAndView();
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again the with same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
+ },
+
+ /**
+ * @param {string} perspectiveName
+ * @param {number} snapshotObjectId
+ */
+ highlightLiveObject: function(perspectiveName, snapshotObjectId)
+ {
+ this._changePerspectiveAndWait(perspectiveName, didChangePerspective.bind(this));
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function didChangePerspective()
+ {
+ this._dataGrid.highlightObjectByHeapSnapshotId(snapshotObjectId, didHighlightObject);
+ }
+
+ function didHighlightObject(found)
+ {
+ if (!found)
+ WebInspector.messageSink.addErrorMessage("Cannot find corresponding heap snapshot node", true);
+ }
+ },
+
+ _getHoverAnchor: function(target)
+ {
+ var span = target.enclosingNodeOrSelfWithNodeName("span");
+ if (!span)
+ return;
+ var row = target.enclosingNodeOrSelfWithNodeName("tr");
+ if (!row)
+ return;
+ span.node = row._dataGridNode;
+ return span;
+ },
+
+ _resolveObjectForPopover: function(element, showCallback, objectGroupName)
+ {
+ if (this._profile.fromFile())
+ return;
+ element.node.queryObjectContent(showCallback, objectGroupName);
+ },
+
+ _updateBaseOptions: function()
+ {
+ var list = this._profiles();
+ // We're assuming that snapshots can only be added.
+ if (this._baseSelect.size() === list.length)
+ return;
+
+ for (var i = this._baseSelect.size(), n = list.length; i < n; ++i) {
+ var title = list[i].title;
+ this._baseSelect.createOption(title);
+ }
+ },
+
+ _updateFilterOptions: function()
+ {
+ var list = this._profiles();
+ // We're assuming that snapshots can only be added.
+ if (this._filterSelect.size() - 1 === list.length)
+ return;
+
+ if (!this._filterSelect.size())
+ this._filterSelect.createOption(WebInspector.UIString("All objects"));
+
+ for (var i = this._filterSelect.size() - 1, n = list.length; i < n; ++i) {
+ var title = list[i].title;
+ if (!i)
+ title = WebInspector.UIString("Objects allocated before %s", title);
+ else
+ title = WebInspector.UIString("Objects allocated between %s and %s", list[i - 1].title, title);
+ this._filterSelect.createOption(title);
+ }
+ },
+
+ _updateControls: function()
+ {
+ this._updateBaseOptions();
+ this._updateFilterOptions();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onReceiveSnapshot: function(event)
+ {
+ this._updateControls();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onProfileHeaderRemoved: function(event)
+ {
+ var profile = event.data;
+ if (this._profile === profile) {
+ this.detach();
+ this._profile.profileType().removeEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceiveSnapshot, this);
+ this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
+ this.dispose();
+ } else {
+ this._updateControls();
+ }
+ },
+
+ dispose: function()
+ {
+ if (this._allocationStackView) {
+ this._allocationStackView.clear();
+ this._allocationDataGrid.dispose();
+ }
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @implements {HeapProfilerAgent.Dispatcher}
+ */
+WebInspector.HeapProfilerDispatcher = function()
+{
+ this._dispatchers = [];
+ InspectorBackend.registerHeapProfilerDispatcher(this);
+}
+
+WebInspector.HeapProfilerDispatcher.prototype = {
+ /**
+ * @param {!HeapProfilerAgent.Dispatcher} dispatcher
+ */
+ register: function(dispatcher)
+ {
+ this._dispatchers.push(dispatcher);
+ },
+
+ _genericCaller: function(eventName)
+ {
+ var args = Array.prototype.slice.call(arguments.callee.caller.arguments);
+ for (var i = 0; i < this._dispatchers.length; ++i)
+ this._dispatchers[i][eventName].apply(this._dispatchers[i], args);
+ },
+
+ /**
+ * @override
+ * @param {!Array.<number>} samples
+ */
+ heapStatsUpdate: function(samples)
+ {
+ this._genericCaller("heapStatsUpdate");
+ },
+
+ /**
+ * @override
+ * @param {number} lastSeenObjectId
+ * @param {number} timestamp
+ */
+ lastSeenObjectId: function(lastSeenObjectId, timestamp)
+ {
+ this._genericCaller("lastSeenObjectId");
+ },
+
+ /**
+ * @override
+ * @param {string} chunk
+ */
+ addHeapSnapshotChunk: function(chunk)
+ {
+ this._genericCaller("addHeapSnapshotChunk");
+ },
+
+ /**
+ * @override
+ * @param {number} done
+ * @param {number} total
+ * @param {boolean=} finished
+ */
+ reportHeapSnapshotProgress: function(done, total, finished)
+ {
+ this._genericCaller("reportHeapSnapshotProgress");
+ },
+
+ /**
+ * @override
+ */
+ resetProfiles: function()
+ {
+ this._genericCaller("resetProfiles");
+ }
+}
+
+WebInspector.HeapProfilerDispatcher._dispatcher = new WebInspector.HeapProfilerDispatcher();
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfileType}
+ * @implements {HeapProfilerAgent.Dispatcher}
+ * @param {string=} id
+ * @param {string=} title
+ */
+WebInspector.HeapSnapshotProfileType = function(id, title)
+{
+ WebInspector.ProfileType.call(this, id || WebInspector.HeapSnapshotProfileType.TypeId, title || WebInspector.UIString("Take Heap Snapshot"));
+ WebInspector.HeapProfilerDispatcher._dispatcher.register(this);
+}
+
+WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
+WebInspector.HeapSnapshotProfileType.SnapshotReceived = "SnapshotReceived";
+
+WebInspector.HeapSnapshotProfileType.prototype = {
+ /**
+ * @override
+ * @return {string}
+ */
+ fileExtension: function()
+ {
+ return ".heapsnapshot";
+ },
+
+ get buttonTooltip()
+ {
+ return WebInspector.UIString("Take heap snapshot.");
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ isInstantProfile: function()
+ {
+ return true;
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ buttonClicked: function()
+ {
+ this._takeHeapSnapshot(function() {});
+ WebInspector.userMetrics.ProfilesHeapProfileTaken.record();
+ return false;
+ },
+
+ /**
+ * @override
+ * @param {!Array.<number>} samples
+ */
+ heapStatsUpdate: function(samples)
+ {
+ },
+
+ /**
+ * @override
+ * @param {number} lastSeenObjectId
+ * @param {number} timestamp
+ */
+ lastSeenObjectId: function(lastSeenObjectId, timestamp)
+ {
+ },
+
+ get treeItemTitle()
+ {
+ return WebInspector.UIString("HEAP SNAPSHOTS");
+ },
+
+ get description()
+ {
+ return WebInspector.UIString("Heap snapshot profiles show memory distribution among your page's JavaScript objects and related DOM nodes.");
+ },
+
+ /**
+ * @override
+ * @param {string} title
+ * @return {!WebInspector.ProfileHeader}
+ */
+ createProfileLoadedFromFile: function(title)
+ {
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ return new WebInspector.HeapProfileHeader(target, this, title);
+ },
+
+ _takeHeapSnapshot: function(callback)
+ {
+ if (this.profileBeingRecorded())
+ return;
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ var profile = new WebInspector.HeapProfileHeader(target, this);
+ this.setProfileBeingRecorded(profile);
+ this.addProfile(profile);
+ profile.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
+
+ /**
+ * @param {?string} error
+ * @this {WebInspector.HeapSnapshotProfileType}
+ */
+ function didTakeHeapSnapshot(error)
+ {
+ var profile = this._profileBeingRecorded;
+ profile.title = WebInspector.UIString("Snapshot %d", profile.uid);
+ profile._finishLoad();
+ this.setProfileBeingRecorded(null);
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile);
+ callback();
+ }
+ HeapProfilerAgent.takeHeapSnapshot(true, didTakeHeapSnapshot.bind(this));
+ },
+
+ /**
+ * @override
+ * @param {string} chunk
+ */
+ addHeapSnapshotChunk: function(chunk)
+ {
+ if (!this.profileBeingRecorded())
+ return;
+ this.profileBeingRecorded().transferChunk(chunk);
+ },
+
+ /**
+ * @override
+ * @param {number} done
+ * @param {number} total
+ * @param {boolean=} finished
+ */
+ reportHeapSnapshotProgress: function(done, total, finished)
+ {
+ var profile = this.profileBeingRecorded();
+ if (!profile)
+ return;
+ profile.updateStatus(WebInspector.UIString("%.0f%", (done / total) * 100), true);
+ if (finished)
+ profile._prepareToLoad();
+ },
+
+ /**
+ * @override
+ */
+ resetProfiles: function()
+ {
+ this._reset();
+ },
+
+ _snapshotReceived: function(profile)
+ {
+ if (this._profileBeingRecorded === profile)
+ this.setProfileBeingRecorded(null);
+ this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile);
+ },
+
+ __proto__: WebInspector.ProfileType.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.HeapSnapshotProfileType}
+ */
+WebInspector.TrackingHeapSnapshotProfileType = function()
+{
+ WebInspector.HeapSnapshotProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Heap Allocations"));
+}
+
+WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
+
+WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate = "HeapStatsUpdate";
+WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted = "TrackingStarted";
+WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped = "TrackingStopped";
+
+WebInspector.TrackingHeapSnapshotProfileType.prototype = {
+
+ /**
+ * @override
+ * @param {!Array.<number>} samples
+ */
+ heapStatsUpdate: function(samples)
+ {
+ if (!this._profileSamples)
+ return;
+ var index;
+ for (var i = 0; i < samples.length; i += 3) {
+ index = samples[i];
+ var count = samples[i+1];
+ var size = samples[i+2];
+ this._profileSamples.sizes[index] = size;
+ if (!this._profileSamples.max[index])
+ this._profileSamples.max[index] = size;
+ }
+ },
+
+ /**
+ * @override
+ * @param {number} lastSeenObjectId
+ * @param {number} timestamp
+ */
+ lastSeenObjectId: function(lastSeenObjectId, timestamp)
+ {
+ var profileSamples = this._profileSamples;
+ if (!profileSamples)
+ return;
+ var currentIndex = Math.max(profileSamples.ids.length, profileSamples.max.length - 1);
+ profileSamples.ids[currentIndex] = lastSeenObjectId;
+ if (!profileSamples.max[currentIndex]) {
+ profileSamples.max[currentIndex] = 0;
+ profileSamples.sizes[currentIndex] = 0;
+ }
+ profileSamples.timestamps[currentIndex] = timestamp;
+ if (profileSamples.totalTime < timestamp - profileSamples.timestamps[0])
+ profileSamples.totalTime *= 2;
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
+ this._profileBeingRecorded.updateStatus(null, true);
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ hasTemporaryView: function()
+ {
+ return true;
+ },
+
+ get buttonTooltip()
+ {
+ return this._recording ? WebInspector.UIString("Stop recording heap profile.") : WebInspector.UIString("Start recording heap profile.");
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ isInstantProfile: function()
+ {
+ return false;
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ buttonClicked: function()
+ {
+ return this._toggleRecording();
+ },
+
+ _startRecordingProfile: function()
+ {
+ if (this.profileBeingRecorded())
+ return;
+ this._addNewProfile();
+ HeapProfilerAgent.startTrackingHeapObjects(WebInspector.experimentsSettings.heapAllocationProfiler.isEnabled());
+ },
+
+ _addNewProfile: function()
+ {
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this.setProfileBeingRecorded(new WebInspector.HeapProfileHeader(target, this));
+ this._lastSeenIndex = -1;
+ this._profileSamples = {
+ 'sizes': [],
+ 'ids': [],
+ 'timestamps': [],
+ 'max': [],
+ 'totalTime': 30000
+ };
+ this._profileBeingRecorded._profileSamples = this._profileSamples;
+ this._recording = true;
+ this.addProfile(this._profileBeingRecorded);
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString("Recording\u2026"));
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted);
+ },
+
+ _stopRecordingProfile: function()
+ {
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
+ /**
+ * @param {?string} error
+ * @this {WebInspector.HeapSnapshotProfileType}
+ */
+ function didTakeHeapSnapshot(error)
+ {
+ var profile = this._profileBeingRecorded;
+ if (!profile)
+ return;
+ profile._finishLoad();
+ this._profileSamples = null;
+ this.setProfileBeingRecorded(null);
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProfileComplete, profile);
+ }
+
+ HeapProfilerAgent.stopTrackingHeapObjects(true, didTakeHeapSnapshot.bind(this));
+ this._recording = false;
+ this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped);
+ },
+
+ _toggleRecording: function()
+ {
+ if (this._recording)
+ this._stopRecordingProfile();
+ else
+ this._startRecordingProfile();
+ return this._recording;
+ },
+
+ get treeItemTitle()
+ {
+ return WebInspector.UIString("HEAP TIMELINES");
+ },
+
+ get description()
+ {
+ return WebInspector.UIString("Record JavaScript object allocations over time. Use this profile type to isolate memory leaks.");
+ },
+
+ /**
+ * @override
+ */
+ resetProfiles: function()
+ {
+ var wasRecording = this._recording;
+ // Clear current profile to avoid stopping backend.
+ this.setProfileBeingRecorded(null);
+ WebInspector.HeapSnapshotProfileType.prototype.resetProfiles.call(this);
+ this._profileSamples = null;
+ this._lastSeenIndex = -1;
+ if (wasRecording)
+ this._addNewProfile();
+ },
+
+ /**
+ * @override
+ */
+ profileBeingRecordedRemoved: function()
+ {
+ this._stopRecordingProfile();
+ this._profileSamples = null;
+ },
+
+ __proto__: WebInspector.HeapSnapshotProfileType.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfileHeader}
+ * @param {!WebInspector.Target} target
+ * @param {!WebInspector.HeapSnapshotProfileType} type
+ * @param {string=} title
+ */
+WebInspector.HeapProfileHeader = function(target, type, title)
+{
+ WebInspector.ProfileHeader.call(this, target, type, title || WebInspector.UIString("Snapshot %d", type._nextProfileUid));
+ this.maxJSObjectId = -1;
+ /**
+ * @type {?WebInspector.HeapSnapshotWorkerProxy}
+ */
+ this._workerProxy = null;
+ /**
+ * @type {?WebInspector.OutputStream}
+ */
+ this._receiver = null;
+ /**
+ * @type {?WebInspector.HeapSnapshotProxy}
+ */
+ this._snapshotProxy = null;
+ /**
+ * @type {?Array.<function(!WebInspector.HeapSnapshotProxy)>}
+ */
+ this._loadCallbacks = [];
+ this._totalNumberOfChunks = 0;
+ this._bufferedWriter = null;
+}
+
+WebInspector.HeapProfileHeader.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @return {!WebInspector.ProfileSidebarTreeElement}
+ */
+ createSidebarTreeElement: function(dataDisplayDelegate)
+ {
+ return new WebInspector.ProfileSidebarTreeElement(dataDisplayDelegate, this, "heap-snapshot-sidebar-tree-item");
+ },
+
+ /**
+ * @override
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @return {!WebInspector.HeapSnapshotView}
+ */
+ createView: function(dataDisplayDelegate)
+ {
+ return new WebInspector.HeapSnapshotView(dataDisplayDelegate, this);
+ },
+
+ /**
+ * @override
+ * @param {function(!WebInspector.HeapSnapshotProxy):void} callback
+ */
+ load: function(callback)
+ {
+ if (this.uid === -1)
+ return;
+ if (this._snapshotProxy) {
+ callback(this._snapshotProxy);
+ return;
+ }
+ this._loadCallbacks.push(callback);
+ },
+
+ _prepareToLoad: function()
+ {
+ console.assert(!this._receiver, "Already loading");
+ this._setupWorker();
+ this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
+ },
+
+ _finishLoad: function()
+ {
+ if (!this._wasDisposed)
+ this._receiver.close(function() {});
+ if (this._bufferedWriter) {
+ this._bufferedWriter.close(this._didWriteToTempFile.bind(this));
+ this._bufferedWriter = null;
+ }
+ },
+
+ _didWriteToTempFile: function(tempFile)
+ {
+ if (this._wasDisposed) {
+ if (tempFile)
+ tempFile.remove();
+ return;
+ }
+ this._tempFile = tempFile;
+ if (!tempFile)
+ this._failedToCreateTempFile = true;
+ if (this._onTempFileReady) {
+ this._onTempFileReady();
+ this._onTempFileReady = null;
+ }
+ },
+
+ _setupWorker: function()
+ {
+ /**
+ * @this {WebInspector.HeapProfileHeader}
+ */
+ function setProfileWait(event)
+ {
+ this.updateStatus(null, event.data);
+ }
+ console.assert(!this._workerProxy, "HeapSnapshotWorkerProxy already exists");
+ this._workerProxy = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
+ this._workerProxy.addEventListener("wait", setProfileWait, this);
+ this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
+ },
+
+ /**
+ * @param {string} eventName
+ * @param {*} data
+ */
+ _handleWorkerEvent: function(eventName, data)
+ {
+ if (WebInspector.HeapSnapshotProgressEvent.Update !== eventName)
+ return;
+ var subtitle = /** @type {string} */ (data);
+ this.updateStatus(subtitle);
+ },
+
+ /**
+ * @override
+ */
+ dispose: function()
+ {
+ if (this._workerProxy)
+ this._workerProxy.dispose();
+ this.removeTempFile();
+ this._wasDisposed = true;
+ },
+
+ _didCompleteSnapshotTransfer: function()
+ {
+ if (!this._snapshotProxy)
+ return;
+ this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false);
+ },
+
+ /**
+ * @param {string} chunk
+ */
+ transferChunk: function(chunk)
+ {
+ if (!this._bufferedWriter)
+ this._bufferedWriter = new WebInspector.BufferedTempFileWriter("heap-profiler", this.uid);
+ this._bufferedWriter.write(chunk);
+
+ ++this._totalNumberOfChunks;
+ this._receiver.write(chunk, function() {});
+ },
+
+ _snapshotReceived: function(snapshotProxy)
+ {
+ if (this._wasDisposed)
+ return;
+ this._receiver = null;
+ this._snapshotProxy = snapshotProxy;
+ this.maxJSObjectId = snapshotProxy.maxJSObjectId();
+ this._didCompleteSnapshotTransfer();
+ this._workerProxy.startCheckingForLongRunningCalls();
+ this.notifySnapshotReceived();
+ },
+
+ notifySnapshotReceived: function()
+ {
+ for (var i = 0; i < this._loadCallbacks.length; i++)
+ this._loadCallbacks[i](this._snapshotProxy);
+ this._loadCallbacks = null;
+ this._profileType._snapshotReceived(this);
+ if (this.canSaveToFile())
+ this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);
+ },
+
+ // Hook point for tests.
+ _wasShown: function()
+ {
+ },
+
+ /**
+ * @override
+ * @return {boolean}
+ */
+ canSaveToFile: function()
+ {
+ return !this.fromFile() && this._snapshotProxy;
+ },
+
+ /**
+ * @override
+ */
+ saveToFile: function()
+ {
+ var fileOutputStream = new WebInspector.FileOutputStream();
+
+ /**
+ * @param {boolean} accepted
+ * @this {WebInspector.HeapProfileHeader}
+ */
+ function onOpen(accepted)
+ {
+ if (!accepted)
+ return;
+ if (this._failedToCreateTempFile) {
+ WebInspector.messageSink.addErrorMessage("Failed to open temp file with heap snapshot");
+ fileOutputStream.close();
+ } else if (this._tempFile) {
+ var delegate = new WebInspector.SaveSnapshotOutputStreamDelegate(this);
+ this._tempFile.writeToOutputSteam(fileOutputStream, delegate);
+ } else {
+ this._onTempFileReady = onOpen.bind(this, accepted);
+ this._updateSaveProgress(0, 1);
+ }
+ }
+ this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
+ fileOutputStream.open(this._fileName, onOpen.bind(this));
+ },
+
+ _updateSaveProgress: function(value, total)
+ {
+ var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
+ this.updateStatus(WebInspector.UIString("Saving\u2026 %d\%", percentValue));
+ },
+
+ /**
+ * @override
+ * @param {!File} file
+ */
+ loadFromFile: function(file)
+ {
+ this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
+ this._setupWorker();
+ var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this);
+ var fileReader = this._createFileReader(file, delegate);
+ fileReader.start(this._receiver);
+ },
+
+ _createFileReader: function(file, delegate)
+ {
+ return new WebInspector.ChunkedFileReader(file, 10000000, delegate);
+ },
+
+ __proto__: WebInspector.ProfileHeader.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.OutputStreamDelegate}
+ */
+WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader)
+{
+ this._snapshotHeader = snapshotHeader;
+}
+
+WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = {
+ onTransferStarted: function()
+ {
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ */
+ onChunkTransferred: function(reader)
+ {
+ },
+
+ onTransferFinished: function()
+ {
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ * @param {?Event} e
+ */
+ onError: function (reader, e)
+ {
+ var subtitle;
+ switch(e.target.error.code) {
+ case e.target.error.NOT_FOUND_ERR:
+ subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
+ break;
+ case e.target.error.NOT_READABLE_ERR:
+ subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
+ break;
+ case e.target.error.ABORT_ERR:
+ return;
+ default:
+ subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
+ }
+ this._snapshotHeader.updateStatus(subtitle);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.OutputStreamDelegate}
+ * @param {!WebInspector.HeapProfileHeader} profileHeader
+ */
+WebInspector.SaveSnapshotOutputStreamDelegate = function(profileHeader)
+{
+ this._profileHeader = profileHeader;
+}
+
+WebInspector.SaveSnapshotOutputStreamDelegate.prototype = {
+ onTransferStarted: function()
+ {
+ this._profileHeader._updateSaveProgress(0, 1);
+ },
+
+ onTransferFinished: function()
+ {
+ this._profileHeader._didCompleteSnapshotTransfer();
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ */
+ onChunkTransferred: function(reader)
+ {
+ this._profileHeader._updateSaveProgress(reader.loadedSize(), reader.fileSize());
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ * @param {?Event} event
+ */
+ onError: function(reader, event)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to read heap snapshot from temp file: " + /** @type {!ErrorEvent} */ (event).message);
+ this.onTransferFinished();
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.HeapProfileHeader} heapProfileHeader
+ */
+WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader)
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("flameChart.css");
+ this.element.id = "heap-recording-view";
+ this.element.classList.add("heap-tracking-overview");
+
+ this._overviewContainer = this.element.createChild("div", "overview-container");
+ this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
+ this._overviewGrid.element.classList.add("fill");
+
+ this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-recording-overview-canvas");
+ this._overviewContainer.appendChild(this._overviewGrid.element);
+ this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator();
+ this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
+
+ this._profileSamples = heapProfileHeader._profileSamples;
+ if (heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) {
+ this._profileType = heapProfileHeader._profileType;
+ this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
+ this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
+ }
+ var timestamps = this._profileSamples.timestamps;
+ var totalTime = this._profileSamples.totalTime;
+ this._windowLeft = 0.0;
+ this._windowRight = totalTime && timestamps.length ? (timestamps[timestamps.length - 1] - timestamps[0]) / totalTime : 1.0;
+ this._overviewGrid.setWindow(this._windowLeft, this._windowRight);
+ this._yScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
+ this._xScale = new WebInspector.HeapTrackingOverviewGrid.SmoothScale();
+}
+
+WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged";
+
+WebInspector.HeapTrackingOverviewGrid.prototype = {
+ _onStopTracking: function(event)
+ {
+ this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
+ this._profileType.removeEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
+ },
+
+ _onHeapStatsUpdate: function(event)
+ {
+ this._profileSamples = event.data;
+ this._scheduleUpdate();
+ },
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ */
+ _drawOverviewCanvas: function(width, height)
+ {
+ if (!this._profileSamples)
+ return;
+ var profileSamples = this._profileSamples;
+ var sizes = profileSamples.sizes;
+ var topSizes = profileSamples.max;
+ var timestamps = profileSamples.timestamps;
+ var startTime = timestamps[0];
+ var endTime = timestamps[timestamps.length - 1];
+
+ var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
+ var maxSize = 0;
+ /**
+ * @param {!Array.<number>} sizes
+ * @param {function(number, number):void} callback
+ */
+ function aggregateAndCall(sizes, callback)
+ {
+ var size = 0;
+ var currentX = 0;
+ for (var i = 1; i < timestamps.length; ++i) {
+ var x = Math.floor((timestamps[i] - startTime) * scaleFactor);
+ if (x !== currentX) {
+ if (size)
+ callback(currentX, size);
+ size = 0;
+ currentX = x;
+ }
+ size += sizes[i];
+ }
+ callback(currentX, size);
+ }
+
+ /**
+ * @param {number} x
+ * @param {number} size
+ */
+ function maxSizeCallback(x, size)
+ {
+ maxSize = Math.max(maxSize, size);
+ }
+
+ aggregateAndCall(sizes, maxSizeCallback);
+
+ var yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0);
+
+ this._overviewCanvas.width = width * window.devicePixelRatio;
+ this._overviewCanvas.height = height * window.devicePixelRatio;
+ this._overviewCanvas.style.width = width + "px";
+ this._overviewCanvas.style.height = height + "px";
+
+ var context = this._overviewCanvas.getContext("2d");
+ context.scale(window.devicePixelRatio, window.devicePixelRatio);
+
+ context.beginPath();
+ context.lineWidth = 2;
+ context.strokeStyle = "rgba(192, 192, 192, 0.6)";
+ var currentX = (endTime - startTime) * scaleFactor;
+ context.moveTo(currentX, height - 1);
+ context.lineTo(currentX, 0);
+ context.stroke();
+ context.closePath();
+
+ var gridY;
+ var gridValue;
+ var gridLabelHeight = 14;
+ if (yScaleFactor) {
+ const maxGridValue = (height - gridLabelHeight) / yScaleFactor;
+ // The round value calculation is a bit tricky, because
+ // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer,
+ // e.g. a round value 10KB is 10240 bytes.
+ gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024)));
+ gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10));
+ if (gridValue * 5 <= maxGridValue)
+ gridValue *= 5;
+ gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5;
+ context.beginPath();
+ context.lineWidth = 1;
+ context.strokeStyle = "rgba(0, 0, 0, 0.2)";
+ context.moveTo(0, gridY);
+ context.lineTo(width, gridY);
+ context.stroke();
+ context.closePath();
+ }
+
+ /**
+ * @param {number} x
+ * @param {number} size
+ */
+ function drawBarCallback(x, size)
+ {
+ context.moveTo(x, height - 1);
+ context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
+ }
+
+ context.beginPath();
+ context.lineWidth = 2;
+ context.strokeStyle = "rgba(192, 192, 192, 0.6)";
+ aggregateAndCall(topSizes, drawBarCallback);
+ context.stroke();
+ context.closePath();
+
+ context.beginPath();
+ context.lineWidth = 2;
+ context.strokeStyle = "rgba(0, 0, 192, 0.8)";
+ aggregateAndCall(sizes, drawBarCallback);
+ context.stroke();
+ context.closePath();
+
+ if (gridValue) {
+ var label = Number.bytesToString(gridValue);
+ var labelPadding = 4;
+ var labelX = 0;
+ var labelY = gridY - 0.5;
+ var labelWidth = 2 * labelPadding + context.measureText(label).width;
+ context.beginPath();
+ context.textBaseline = "bottom";
+ context.font = "10px " + window.getComputedStyle(this.element, null).getPropertyValue("font-family");
+ context.fillStyle = "rgba(255, 255, 255, 0.75)";
+ context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight);
+ context.fillStyle = "rgb(64, 64, 64)";
+ context.fillText(label, labelX + labelPadding, labelY);
+ context.fill();
+ context.closePath();
+ }
+ },
+
+ onResize: function()
+ {
+ this._updateOverviewCanvas = true;
+ this._scheduleUpdate();
+ },
+
+ _onWindowChanged: function()
+ {
+ if (!this._updateGridTimerId)
+ this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10);
+ },
+
+ _scheduleUpdate: function()
+ {
+ if (this._updateTimerId)
+ return;
+ this._updateTimerId = setTimeout(this.update.bind(this), 10);
+ },
+
+ _updateBoundaries: function()
+ {
+ this._windowLeft = this._overviewGrid.windowLeft();
+ this._windowRight = this._overviewGrid.windowRight();
+ this._windowWidth = this._windowRight - this._windowLeft;
+ },
+
+ update: function()
+ {
+ this._updateTimerId = null;
+ if (!this.isShowing())
+ return;
+ this._updateBoundaries();
+ this._overviewCalculator._updateBoundaries(this);
+ this._overviewGrid.updateDividers(this._overviewCalculator);
+ this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
+ },
+
+ _updateGrid: function()
+ {
+ this._updateGridTimerId = 0;
+ this._updateBoundaries();
+ var ids = this._profileSamples.ids;
+ var timestamps = this._profileSamples.timestamps;
+ var sizes = this._profileSamples.sizes;
+ var startTime = timestamps[0];
+ var totalTime = this._profileSamples.totalTime;
+ var timeLeft = startTime + totalTime * this._windowLeft;
+ var timeRight = startTime + totalTime * this._windowRight;
+ var minId = 0;
+ var maxId = ids[ids.length - 1] + 1;
+ var size = 0;
+ for (var i = 0; i < timestamps.length; ++i) {
+ if (!timestamps[i])
+ continue;
+ if (timestamps[i] > timeRight)
+ break;
+ maxId = ids[i];
+ if (timestamps[i] < timeLeft) {
+ minId = ids[i];
+ continue;
+ }
+ size += sizes[i];
+ }
+
+ this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+
+/**
+ * @constructor
+ */
+WebInspector.HeapTrackingOverviewGrid.SmoothScale = function()
+{
+ this._lastUpdate = 0;
+ this._currentScale = 0.0;
+}
+
+WebInspector.HeapTrackingOverviewGrid.SmoothScale.prototype = {
+ /**
+ * @param {number} target
+ * @return {number}
+ */
+ nextScale: function(target) {
+ target = target || this._currentScale;
+ if (this._currentScale) {
+ var now = Date.now();
+ var timeDeltaMs = now - this._lastUpdate;
+ this._lastUpdate = now;
+ var maxChangePerSec = 20;
+ var maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000);
+ var scaleChange = target / this._currentScale;
+ this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta);
+ } else
+ this._currentScale = target;
+ return this._currentScale;
+ }
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineGrid.Calculator}
+ */
+WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = function()
+{
+}
+
+WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = {
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @param {!WebInspector.HeapTrackingOverviewGrid} chart
+ */
+ _updateBoundaries: function(chart)
+ {
+ this._minimumBoundaries = 0;
+ this._maximumBoundaries = chart._profileSamples.totalTime;
+ this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries;
+ },
+
+ /**
+ * @param {number} time
+ * @return {number}
+ */
+ computePosition: function(time)
+ {
+ return (time - this._minimumBoundaries) * this._xScaleFactor;
+ },
+
+ /**
+ * @param {number} value
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatTime: function(value, precision)
+ {
+ return Number.secondsToString(value / 1000, !!precision);
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumBoundary: function()
+ {
+ return this._maximumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ zeroTime: function()
+ {
+ return this._minimumBoundaries;
+ },
+
+ /**
+ * @return {number}
+ */
+ boundarySpan: function()
+ {
+ return this._maximumBoundaries - this._minimumBoundaries;
+ }
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.HeapSnapshotStatisticsView = function()
+{
+ WebInspector.VBox.call(this);
+ this.setMinimumSize(50, 25);
+ this._pieChart = new WebInspector.PieChart();
+ this._pieChart.setSize(150);
+ this.element.appendChild(this._pieChart.element);
+ this._labels = this.element.createChild("div", "heap-snapshot-stats-legend");
+}
+
+WebInspector.HeapSnapshotStatisticsView.prototype = {
+ /**
+ * @param {number} value
+ */
+ setTotal: function(value)
+ {
+ this._pieChart.setTotal(value);
+ },
+
+ /**
+ * @param {number} value
+ * @param {string} name
+ * @param {string=} color
+ */
+ addRecord: function(value, name, color)
+ {
+ if (color)
+ this._pieChart.addSlice(value, color);
+
+ var node = this._labels.createChild("div");
+ var swatchDiv = node.createChild("div", "heap-snapshot-stats-swatch");
+ var nameDiv = node.createChild("div", "heap-snapshot-stats-name");
+ var sizeDiv = node.createChild("div", "heap-snapshot-stats-size");
+ if (color)
+ swatchDiv.style.backgroundColor = color;
+ else
+ swatchDiv.classList.add("heap-snapshot-stats-empty-swatch");
+ nameDiv.textContent = name;
+ sizeDiv.textContent = WebInspector.UIString("%s KB", Number.withThousandsSeparator(Math.round(value / 1024)));
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ */
+WebInspector.HeapAllocationStackView = function()
+{
+ WebInspector.View.call(this);
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._linkifier = new WebInspector.Linkifier();
+}
+
+WebInspector.HeapAllocationStackView.prototype = {
+ /**
+ * @param {!WebInspector.HeapSnapshotProxy} snapshot
+ * @param {number} snapshotNodeIndex
+ */
+ setAllocatedObject: function(snapshot, snapshotNodeIndex)
+ {
+ this.clear();
+ snapshot.allocationStack(snapshotNodeIndex, this._didReceiveAllocationStack.bind(this));
+ },
+
+ clear: function()
+ {
+ this.element.removeChildren();
+ this._linkifier.reset();
+ },
+
+ /**
+ * @param {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>} frames
+ */
+ _didReceiveAllocationStack: function(frames)
+ {
+ if (!frames) {
+ var stackDiv = this.element.createChild("div", "no-heap-allocation-stack");
+ stackDiv.createTextChild(WebInspector.UIString("Stack was not recorded for this object because it had been allocated before this profile recording started."));
+ return;
+ }
+
+ var stackDiv = this.element.createChild("div", "heap-allocation-stack");
+ for (var i = 0; i < frames.length; i++) {
+ var frame = frames[i];
+ var frameDiv = stackDiv.createChild("div", "stack-frame");
+ var name = frameDiv.createChild("div");
+ name.textContent = frame.functionName;
+ if (frame.scriptId) {
+ var urlElement;
+ var rawLocation = new WebInspector.DebuggerModel.Location(this._target, String(frame.scriptId), frame.line - 1, frame.column - 1);
+ if (rawLocation)
+ urlElement = this._linkifier.linkifyRawLocation(rawLocation);
+ if (!urlElement)
+ urlElement = this._linkifier.linkifyLocation(this._target, frame.scriptName, frame.line - 1, frame.column - 1);
+ frameDiv.appendChild(urlElement);
+ }
+ }
+ },
+
+ __proto__: WebInspector.View.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ProfileLauncherView.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfileLauncherView.js
index 7f40ae5375b..a36592873db 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ProfileLauncherView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfileLauncherView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.ProfilesPanel} profilesPanel
*/
WebInspector.ProfileLauncherView = function(profilesPanel)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._panel = profilesPanel;
@@ -47,6 +47,11 @@ WebInspector.ProfileLauncherView = function(profilesPanel)
this._controlButton = this._contentElement.createChild("button", "control-profiling");
this._controlButton.addEventListener("click", this._controlButtonClicked.bind(this), false);
+ this._recordButtonEnabled = true;
+
+ this._loadButton = this._contentElement.createChild("button", "load-profile");
+ this._loadButton.textContent = WebInspector.UIString("Load");
+ this._loadButton.addEventListener("click", this._loadButtonClicked.bind(this), false);
}
WebInspector.ProfileLauncherView.prototype = {
@@ -70,12 +75,18 @@ WebInspector.ProfileLauncherView.prototype = {
this._panel.toggleRecordButton();
},
+ _loadButtonClicked: function()
+ {
+ this._panel.showLoadFromFileDialog();
+ },
+
_updateControls: function()
{
- if (this._isEnabled)
+ if (this._isEnabled && this._recordButtonEnabled)
this._controlButton.removeAttribute("disabled");
else
this._controlButton.setAttribute("disabled", "");
+ this._controlButton.title = this._recordButtonEnabled ? "" : WebInspector.UIString("Another profiler is already active");
if (this._isInstantProfile) {
this._controlButton.classList.remove("running");
this._controlButton.textContent = WebInspector.UIString("Take Snapshot");
@@ -102,16 +113,18 @@ WebInspector.ProfileLauncherView.prototype = {
/**
* @param {!WebInspector.ProfileType} profileType
+ * @param {boolean} recordButtonEnabled
*/
- updateProfileType: function(profileType)
+ updateProfileType: function(profileType, recordButtonEnabled)
{
this._isInstantProfile = profileType.isInstantProfile();
+ this._recordButtonEnabled = recordButtonEnabled;
this._isEnabled = profileType.isEnabled();
this._profileTypeId = profileType.id;
this._updateControls();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
@@ -152,6 +165,7 @@ WebInspector.MultiProfileLauncherView.prototype = {
var optionElement = document.createElement("input");
labelElement.insertBefore(optionElement, labelElement.firstChild);
this._typeIdToOptionElement[profileType.id] = optionElement;
+ optionElement._profileType = profileType;
optionElement.type = "radio";
optionElement.name = "profile-type";
optionElement.style.hidden = true;
@@ -165,13 +179,12 @@ WebInspector.MultiProfileLauncherView.prototype = {
restoreSelectedProfileType: function()
{
- var typeName = WebInspector.settings.selectedProfileType.get();
- if (!(typeName in this._typeIdToOptionElement))
- typeName = Object.keys(this._typeIdToOptionElement)[0];
- this._typeIdToOptionElement[typeName].checked = true;
- this.dispatchEventToListeners(
- WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected,
- this._panel.getProfileType(typeName));
+ var typeId = WebInspector.settings.selectedProfileType.get();
+ if (!(typeId in this._typeIdToOptionElement))
+ typeId = Object.keys(this._typeIdToOptionElement)[0];
+ this._typeIdToOptionElement[typeId].checked = true;
+ var type = this._typeIdToOptionElement[typeId]._profileType;
+ this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, type);
},
_controlButtonClicked: function()
@@ -192,7 +205,7 @@ WebInspector.MultiProfileLauncherView.prototype = {
/**
* @param {!WebInspector.ProfileType} profileType
*/
- _profileTypeChanged: function(profileType, event)
+ _profileTypeChanged: function(profileType)
{
this.dispatchEventToListeners(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, profileType);
this._isInstantProfile = profileType.isInstantProfile();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
index 6fa00bd631f..4e00a2ca50b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
@@ -31,18 +31,24 @@
*/
WebInspector.ProfileType = function(id, name)
{
+ WebInspector.Object.call(this);
this._id = id;
this._name = name;
/** @type {!Array.<!WebInspector.ProfileHeader>} */
this._profiles = [];
- /** @type {?WebInspector.SidebarSectionTreeElement} */
- this.treeElement = null;
/** @type {?WebInspector.ProfileHeader} */
this._profileBeingRecorded = null;
+ this._nextProfileUid = 1;
+
+ window.addEventListener("unload", this._clearTempStorage.bind(this), false);
}
+/**
+ * @enum {string}
+ */
WebInspector.ProfileType.Events = {
AddProfileHeader: "add-profile-header",
+ ProfileComplete: "profile-complete",
RemoveProfileHeader: "remove-profile-header",
ViewUpdated: "view-updated"
}
@@ -168,13 +174,13 @@ WebInspector.ProfileType.prototype = {
name = name.substr(0, name.length - this.fileExtension().length);
var profile = this.createProfileLoadedFromFile(name);
profile.setFromFile();
- this._profileBeingRecorded = profile;
+ this.setProfileBeingRecorded(profile);
this.addProfile(profile);
profile.loadFromFile(file);
},
/**
- * @param {!string} title
+ * @param {string} title
* @return {!WebInspector.ProfileHeader}
*/
createProfileLoadedFromFile: function(title)
@@ -196,14 +202,17 @@ WebInspector.ProfileType.prototype = {
*/
removeProfile: function(profile)
{
- if (this._profileBeingRecorded === profile)
- this._profileBeingRecorded = null;
- for (var i = 0; i < this._profiles.length; ++i) {
- if (this._profiles[i].uid === profile.uid) {
- this._profiles.splice(i, 1);
- break;
- }
- }
+ var index = this._profiles.indexOf(profile);
+ if (index === -1)
+ return;
+ this._profiles.splice(index, 1);
+ this._disposeProfile(profile);
+ },
+
+ _clearTempStorage: function()
+ {
+ for (var i = 0; i < this._profiles.length; ++i)
+ this._profiles[i].removeTempFile();
},
/**
@@ -215,41 +224,102 @@ WebInspector.ProfileType.prototype = {
return this._profileBeingRecorded;
},
+ /**
+ * @param {?WebInspector.ProfileHeader} profile
+ */
+ setProfileBeingRecorded: function(profile)
+ {
+ if (this._profileBeingRecorded)
+ this._profileBeingRecorded.target().profilingLock.release();
+ if (profile)
+ profile.target().profilingLock.acquire();
+ this._profileBeingRecorded = profile;
+ },
+
+ profileBeingRecordedRemoved: function()
+ {
+ },
+
_reset: function()
{
var profiles = this._profiles.slice(0);
- for (var i = 0; i < profiles.length; ++i) {
- var profile = profiles[i];
- var view = profile.existingView();
- if (view) {
- view.detach();
- if ("dispose" in view)
- view.dispose();
- }
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProfileHeader, profile);
- }
- this.treeElement.removeChildren();
+ for (var i = 0; i < profiles.length; ++i)
+ this._disposeProfile(profiles[i]);
this._profiles = [];
+
+ this._nextProfileUid = 1;
+ },
+
+ /**
+ * @param {!WebInspector.ProfileHeader} profile
+ */
+ _disposeProfile: function(profile)
+ {
+ this.dispatchEventToListeners(WebInspector.ProfileType.Events.RemoveProfileHeader, profile);
+ profile.dispose();
+ if (this._profileBeingRecorded === profile) {
+ this.profileBeingRecordedRemoved();
+ this.setProfileBeingRecorded(null);
+ }
},
__proto__: WebInspector.Object.prototype
}
/**
+ * @interface
+ */
+WebInspector.ProfileType.DataDisplayDelegate = function()
+{
+}
+
+WebInspector.ProfileType.DataDisplayDelegate.prototype = {
+ /**
+ * @param {?WebInspector.ProfileHeader} profile
+ * @return {?WebInspector.View}
+ */
+ showProfile: function(profile) { },
+
+ /**
+ * @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
+ * @param {string} perspectiveName
+ */
+ showObject: function(snapshotObjectId, perspectiveName) { }
+}
+
+/**
* @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.ProfileType} profileType
* @param {string} title
- * @param {number=} uid
*/
-WebInspector.ProfileHeader = function(profileType, title, uid)
+WebInspector.ProfileHeader = function(target, profileType, title)
{
+ WebInspector.TargetAwareObject.call(this, target);
this._profileType = profileType;
this.title = title;
- this.uid = (uid === undefined) ? -1 : uid;
+ this.uid = profileType._nextProfileUid++;
this._fromFile = false;
}
-WebInspector.ProfileHeader._nextProfileFromFileUid = 1;
+/**
+ * @constructor
+ * @param {?string} subtitle
+ * @param {boolean|undefined} wait
+ */
+WebInspector.ProfileHeader.StatusUpdate = function(subtitle, wait)
+{
+ /** @type {?string} */
+ this.subtitle = subtitle;
+ /** @type {boolean|undefined} */
+ this.wait = wait;
+}
+
+WebInspector.ProfileHeader.Events = {
+ UpdateStatus: "UpdateStatus",
+ ProfileReceived: "ProfileReceived"
+}
WebInspector.ProfileHeader.prototype = {
/**
@@ -261,40 +331,37 @@ WebInspector.ProfileHeader.prototype = {
},
/**
- * Must be implemented by subclasses.
- * @return {!WebInspector.ProfileSidebarTreeElement}
+ * @param {?string} subtitle
+ * @param {boolean=} wait
*/
- createSidebarTreeElement: function()
+ updateStatus: function(subtitle, wait)
{
- throw new Error("Needs implemented.");
+ this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.UpdateStatus, new WebInspector.ProfileHeader.StatusUpdate(subtitle, wait));
},
/**
- * @return {?WebInspector.View}
+ * Must be implemented by subclasses.
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @return {!WebInspector.ProfileSidebarTreeElement}
*/
- existingView: function()
+ createSidebarTreeElement: function(dataDisplayDelegate)
{
- return this._view;
+ throw new Error("Needs implemented.");
},
/**
- * @param {!WebInspector.ProfilesPanel} panel
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @return {!WebInspector.View}
*/
- view: function(panel)
+ createView: function(dataDisplayDelegate)
{
- if (!this._view)
- this._view = this.createView(panel);
- return this._view;
+ throw new Error("Not implemented.");
},
- /**
- * @param {!WebInspector.ProfilesPanel} panel
- * @return {!WebInspector.View}
- */
- createView: function(panel)
+ removeTempFile: function()
{
- throw new Error("Not implemented.");
+ if (this._tempFile)
+ this._tempFile.remove();
},
dispose: function()
@@ -340,53 +407,48 @@ WebInspector.ProfileHeader.prototype = {
setFromFile: function()
{
this._fromFile = true;
- this.uid = "From file #" + WebInspector.ProfileHeader._nextProfileFromFileUid++;
- }
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
* @constructor
* @implements {WebInspector.Searchable}
- * @implements {WebInspector.ContextMenu.Provider}
- * @extends {WebInspector.Panel}
- * @param {string=} name
- * @param {!WebInspector.ProfileType=} type
+ * @implements {WebInspector.ProfileType.DataDisplayDelegate}
+ * @extends {WebInspector.PanelWithSidebarTree}
*/
-WebInspector.ProfilesPanel = function(name, type)
+WebInspector.ProfilesPanel = function()
{
- // If the name is not specified the ProfilesPanel works in multi-profile mode.
- var singleProfileMode = typeof name !== "undefined";
- name = name || "profiles";
- WebInspector.Panel.call(this, name);
+ WebInspector.PanelWithSidebarTree.call(this, "profiles");
this.registerRequiredCSS("panelEnablerView.css");
this.registerRequiredCSS("heapProfiler.css");
this.registerRequiredCSS("profilesPanel.css");
- this.createSidebarViewWithTree();
-
- this.splitView.mainElement.classList.add("vbox");
- this.splitView.sidebarElement.classList.add("vbox");
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
+ this._target.profilingLock.addEventListener(WebInspector.Lock.Events.StateChanged, this._onProfilingStateChanged, this);
this._searchableView = new WebInspector.SearchableView(this);
- this._searchableView.show(this.splitView.mainElement);
+
+ var mainView = new WebInspector.VBox();
+ this._searchableView.show(mainView.element);
+ mainView.show(this.mainElement());
this.profilesItemTreeElement = new WebInspector.ProfilesSidebarTreeElement(this);
this.sidebarTree.appendChild(this.profilesItemTreeElement);
- this._singleProfileMode = singleProfileMode;
- this._profileTypesByIdMap = {};
-
this.profileViews = document.createElement("div");
this.profileViews.id = "profile-views";
this.profileViews.classList.add("vbox");
this._searchableView.element.appendChild(this.profileViews);
- var statusBarContainer = this.splitView.mainElement.createChild("div", "profiles-status-bar");
+ var statusBarContainer = document.createElementWithClass("div", "profiles-status-bar");
+ mainView.element.insertBefore(statusBarContainer, mainView.element.firstChild);
this._statusBarElement = statusBarContainer.createChild("div", "status-bar");
- var sidebarTreeBox = this.sidebarElement.createChild("div", "profiles-sidebar-tree-box");
- sidebarTreeBox.appendChild(this.sidebarTreeElement);
- var statusBarContainerLeft = this.sidebarElement.createChild("div", "profiles-status-bar");
+ this.sidebarElement().classList.add("profiles-sidebar-tree-box");
+ var statusBarContainerLeft = document.createElementWithClass("div", "profiles-status-bar");
+ this.sidebarElement().insertBefore(statusBarContainerLeft, this.sidebarElement().firstChild);
this._statusBarButtons = statusBarContainerLeft.createChild("div", "status-bar");
this.recordButton = new WebInspector.StatusBarButton("", "record-profile-status-bar-item");
@@ -394,41 +456,74 @@ WebInspector.ProfilesPanel = function(name, type)
this._statusBarButtons.appendChild(this.recordButton.element);
this.clearResultsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear all profiles."), "clear-status-bar-item");
- this.clearResultsButton.addEventListener("click", this._clearProfiles, this);
+ this.clearResultsButton.addEventListener("click", this._reset, this);
this._statusBarButtons.appendChild(this.clearResultsButton.element);
this._profileTypeStatusBarItemsContainer = this._statusBarElement.createChild("div");
this._profileViewStatusBarItemsContainer = this._statusBarElement.createChild("div");
- if (singleProfileMode) {
- this._launcherView = this._createLauncherView();
- this._registerProfileType(/** @type {!WebInspector.ProfileType} */ (type));
- this._selectedProfileType = type;
- this._updateProfileTypeSpecificUI();
- } else {
- this._launcherView = new WebInspector.MultiProfileLauncherView(this);
- this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, this._onProfileTypeSelected, this);
-
- this._registerProfileType(new WebInspector.CPUProfileType());
- this._registerProfileType(new WebInspector.HeapSnapshotProfileType());
- this._registerProfileType(new WebInspector.TrackingHeapSnapshotProfileType(this));
- if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.canvasInspection.isEnabled())
- this._registerProfileType(new WebInspector.CanvasProfileType());
- this._launcherView.restoreSelectedProfileType();
- }
+ this._profileGroups = {};
+ this._launcherView = new WebInspector.MultiProfileLauncherView(this);
+ this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, this._onProfileTypeSelected, this);
- this._reset();
+ this._profileToView = [];
+ this._typeIdToSidebarSection = {};
+ var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
+ for (var i = 0; i < types.length; i++)
+ this._registerProfileType(types[i]);
+ this._launcherView.restoreSelectedProfileType();
+ this.profilesItemTreeElement.select();
+ this._showLauncherView();
this._createFileSelectorElement();
this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
this._registerShortcuts();
- WebInspector.ContextMenu.registerProvider(this);
-
this._configureCpuProfilerSamplingInterval();
WebInspector.settings.highResolutionCpuProfiling.addChangeListener(this._configureCpuProfilerSamplingInterval, this);
}
+
+/**
+ * @constructor
+ */
+WebInspector.ProfileTypeRegistry = function() {
+ this._profileTypes = [];
+
+ this.cpuProfileType = new WebInspector.CPUProfileType();
+ this._addProfileType(this.cpuProfileType);
+ this.heapSnapshotProfileType = new WebInspector.HeapSnapshotProfileType();
+ this._addProfileType(this.heapSnapshotProfileType);
+ this.trackingHeapSnapshotProfileType = new WebInspector.TrackingHeapSnapshotProfileType();
+ this._addProfileType(this.trackingHeapSnapshotProfileType);
+ HeapProfilerAgent.enable();
+
+ if (Capabilities.isMainFrontend && WebInspector.experimentsSettings.canvasInspection.isEnabled()) {
+ this.canvasProfileType = new WebInspector.CanvasProfileType();
+ this._addProfileType(this.canvasProfileType);
+ }
+}
+
+WebInspector.ProfileTypeRegistry.prototype = {
+ /**
+ * @param {!WebInspector.ProfileType} profileType
+ */
+ _addProfileType: function(profileType)
+ {
+ this._profileTypes.push(profileType);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.ProfileType>}
+ */
+ profileTypes: function()
+ {
+ return this._profileTypes;
+ }
+}
+
+
+
WebInspector.ProfilesPanel.prototype = {
/**
* @return {!WebInspector.SearchableView}
@@ -446,18 +541,11 @@ WebInspector.ProfilesPanel.prototype = {
this.element.appendChild(this._fileSelectorElement);
},
- /**
- * @return {!WebInspector.ProfileLauncherView}
- */
- _createLauncherView: function()
- {
- return new WebInspector.ProfileLauncherView(this);
- },
-
_findProfileTypeByExtension: function(fileName)
{
- for (var id in this._profileTypesByIdMap) {
- var type = this._profileTypesByIdMap[id];
+ var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
+ for (var i = 0; i < types.length; i++) {
+ var type = types[i];
var extension = type.fileExtension();
if (!extension)
continue;
@@ -469,17 +557,17 @@ WebInspector.ProfilesPanel.prototype = {
_registerShortcuts: function()
{
- this.registerShortcuts(WebInspector.ProfilesPanelDescriptor.ShortcutKeys.StartStopRecording, this.toggleRecordButton.bind(this));
+ this.registerShortcuts(WebInspector.ShortcutsScreen.ProfilesPanelShortcuts.StartStopRecording, this.toggleRecordButton.bind(this));
},
_configureCpuProfilerSamplingInterval: function()
{
var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000;
- ProfilerAgent.setSamplingInterval(intervalUs, didChangeInterval.bind(this));
+ ProfilerAgent.setSamplingInterval(intervalUs, didChangeInterval);
function didChangeInterval(error)
{
if (error)
- WebInspector.showErrorMessage(error)
+ WebInspector.messageSink.addErrorMessage(error, true);
}
},
@@ -493,18 +581,19 @@ WebInspector.ProfilesPanel.prototype = {
var profileType = this._findProfileTypeByExtension(file.name);
if (!profileType) {
var extensions = [];
- for (var id in this._profileTypesByIdMap) {
- var extension = this._profileTypesByIdMap[id].fileExtension();
- if (!extension)
+ var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
+ for (var i = 0; i < types.length; i++) {
+ var extension = types[i].fileExtension();
+ if (!extension || extensions.indexOf(extension) !== -1)
continue;
extensions.push(extension);
}
- WebInspector.log(WebInspector.UIString("Can't load file. Only files with extensions '%s' can be loaded.", extensions.join("', '")));
+ WebInspector.messageSink.addMessage(WebInspector.UIString("Can't load file. Only files with extensions '%s' can be loaded.", extensions.join("', '")));
return;
}
if (!!profileType.profileBeingRecorded()) {
- WebInspector.log(WebInspector.UIString("Can't load profile when other profile is recording."));
+ WebInspector.messageSink.addMessage(WebInspector.UIString("Can't load profile while another profile is recording."));
return;
}
@@ -516,20 +605,48 @@ WebInspector.ProfilesPanel.prototype = {
*/
toggleRecordButton: function()
{
+ if (!this.recordButton.enabled())
+ return true;
var type = this._selectedProfileType;
var isProfiling = type.buttonClicked();
- this.recordButton.toggled = isProfiling;
- this.recordButton.title = type.buttonTooltip;
+ this._updateRecordButton(isProfiling);
if (isProfiling) {
this._launcherView.profileStarted();
if (type.hasTemporaryView())
- this._showProfile(type.profileBeingRecorded());
+ this.showProfile(type.profileBeingRecorded());
} else {
this._launcherView.profileFinished();
}
return true;
},
+ _onProfilingStateChanged: function()
+ {
+ this._updateRecordButton(this.recordButton.toggled);
+ },
+
+ /**
+ * @param {boolean} toggled
+ */
+ _updateRecordButton: function(toggled)
+ {
+ var enable = toggled || !this._target.profilingLock.isAcquired();
+ this.recordButton.setEnabled(enable);
+ this.recordButton.toggled = toggled;
+ if (enable)
+ this.recordButton.title = this._selectedProfileType ? this._selectedProfileType.buttonTooltip : "";
+ else
+ this.recordButton.title = WebInspector.UIString("Another profiler is already active");
+ if (this._selectedProfileType)
+ this._launcherView.updateProfileType(this._selectedProfileType, enable);
+ },
+
+ _profileBeingRecordedRemoved: function()
+ {
+ this._updateRecordButton(false);
+ this._launcherView.profileFinished();
+ },
+
/**
* @param {!WebInspector.Event} event
*/
@@ -541,8 +658,7 @@ WebInspector.ProfilesPanel.prototype = {
_updateProfileTypeSpecificUI: function()
{
- this.recordButton.title = this._selectedProfileType.buttonTooltip;
- this._launcherView.updateProfileType(this._selectedProfileType);
+ this._updateRecordButton(this.recordButton.toggled);
this._profileTypeStatusBarItemsContainer.removeChildren();
var statusBarItems = this._selectedProfileType.statusBarItems;
if (statusBarItems) {
@@ -555,20 +671,19 @@ WebInspector.ProfilesPanel.prototype = {
{
WebInspector.Panel.prototype.reset.call(this);
- for (var typeId in this._profileTypesByIdMap)
- this._profileTypesByIdMap[typeId]._reset();
+ var types = WebInspector.ProfileTypeRegistry.instance.profileTypes();
+ for (var i = 0; i < types.length; i++)
+ types[i]._reset();
delete this.visibleView;
delete this.currentQuery;
this.searchCanceled();
this._profileGroups = {};
- this.recordButton.toggled = false;
- if (this._selectedProfileType)
- this.recordButton.title = this._selectedProfileType.buttonTooltip;
+ this._updateRecordButton(false);
this._launcherView.profileFinished();
- this.sidebarTreeElement.classList.remove("some-expandable");
+ this.sidebarTree.element.classList.remove("some-expandable");
this._launcherView.detach();
this.profileViews.removeChildren();
@@ -591,12 +706,6 @@ WebInspector.ProfilesPanel.prototype = {
this.visibleView = this._launcherView;
},
- _clearProfiles: function()
- {
- HeapProfilerAgent.clearProfiles();
- this._reset();
- },
-
_garbageCollectButtonClicked: function()
{
HeapProfilerAgent.collectGarbage();
@@ -607,32 +716,47 @@ WebInspector.ProfilesPanel.prototype = {
*/
_registerProfileType: function(profileType)
{
- this._profileTypesByIdMap[profileType.id] = profileType;
this._launcherView.addProfileType(profileType);
- profileType.treeElement = new WebInspector.SidebarSectionTreeElement(profileType.treeItemTitle, null, true);
- profileType.treeElement.hidden = !this._singleProfileMode;
- this.sidebarTree.appendChild(profileType.treeElement);
- profileType.treeElement.childrenListElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
+ var profileTypeSection = new WebInspector.ProfileTypeSidebarSection(this, profileType);
+ this._typeIdToSidebarSection[profileType.id] = profileTypeSection
+ this.sidebarTree.appendChild(profileTypeSection);
+ profileTypeSection.childrenListElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
/**
+ * @param {!WebInspector.Event} event
* @this {WebInspector.ProfilesPanel}
*/
function onAddProfileHeader(event)
{
- this._addProfileHeader(event.data);
+ this._addProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.data));
}
/**
+ * @param {!WebInspector.Event} event
* @this {WebInspector.ProfilesPanel}
*/
function onRemoveProfileHeader(event)
{
- this._removeProfileHeader(event.data);
+ this._removeProfileHeader(/** @type {!WebInspector.ProfileHeader} */ (event.data));
+ }
+
+ /**
+ * @param {!WebInspector.Event} event
+ * @this {WebInspector.ProfilesPanel}
+ */
+ function profileComplete(event)
+ {
+ this.showProfile(/** @type {!WebInspector.ProfileHeader} */ (event.data));
}
profileType.addEventListener(WebInspector.ProfileType.Events.ViewUpdated, this._updateProfileTypeSpecificUI, this);
profileType.addEventListener(WebInspector.ProfileType.Events.AddProfileHeader, onAddProfileHeader, this);
profileType.addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, onRemoveProfileHeader, this);
+ profileType.addEventListener(WebInspector.ProfileType.Events.ProfileComplete, profileComplete, this);
+
+ var profiles = profileType.getProfiles();
+ for (var i = 0; i < profiles.length; i++)
+ this._addProfileHeader(profiles[i]);
},
/**
@@ -654,21 +778,15 @@ WebInspector.ProfilesPanel.prototype = {
if (this.visibleView instanceof WebInspector.HeapSnapshotView) {
this.visibleView.populateContextMenu(contextMenu, event);
}
- if (element !== this.element || event.srcElement === this.sidebarElement) {
+ if (element !== this.element || event.srcElement === this.sidebarElement()) {
contextMenu.appendItem(WebInspector.UIString("Load\u2026"), this._fileSelectorElement.click.bind(this._fileSelectorElement));
}
contextMenu.show();
},
- /**
- * @nosideeffects
- * @param {string} text
- * @param {string} profileTypeId
- * @return {string}
- */
- _makeTitleKey: function(text, profileTypeId)
+ showLoadFromFileDialog: function()
{
- return escape(text) + '/' + escape(profileTypeId);
+ this._fileSelectorElement.click();
},
/**
@@ -678,60 +796,9 @@ WebInspector.ProfilesPanel.prototype = {
{
var profileType = profile.profileType();
var typeId = profileType.id;
- var sidebarParent = profileType.treeElement;
- sidebarParent.hidden = false;
- var small = false;
- var alternateTitle;
-
- if (!profile.fromFile() && profile.profileType().profileBeingRecorded() !== profile) {
- var profileTitleKey = this._makeTitleKey(profile.title, typeId);
- if (!(profileTitleKey in this._profileGroups))
- this._profileGroups[profileTitleKey] = [];
-
- var group = this._profileGroups[profileTitleKey];
- group.push(profile);
- if (group.length === 2) {
- // Make a group TreeElement now that there are 2 profiles.
- group._profilesTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(this, profile.title);
-
- // Insert at the same index for the first profile of the group.
- var index = sidebarParent.children.indexOf(group[0]._profilesTreeElement);
- sidebarParent.insertChild(group._profilesTreeElement, index);
-
- // Move the first profile to the group.
- var selected = group[0]._profilesTreeElement.selected;
- sidebarParent.removeChild(group[0]._profilesTreeElement);
- group._profilesTreeElement.appendChild(group[0]._profilesTreeElement);
- if (selected)
- group[0]._profilesTreeElement.revealAndSelect();
-
- group[0]._profilesTreeElement.small = true;
- group[0]._profilesTreeElement.mainTitle = WebInspector.UIString("Run %d", 1);
-
- this.sidebarTreeElement.classList.add("some-expandable");
- }
-
- if (group.length >= 2) {
- sidebarParent = group._profilesTreeElement;
- alternateTitle = WebInspector.UIString("Run %d", group.length);
- small = true;
- }
- }
-
- var profileTreeElement = profile.createSidebarTreeElement();
- profile.sidebarElement = profileTreeElement;
- profileTreeElement.small = small;
- if (alternateTitle)
- profileTreeElement.mainTitle = alternateTitle;
- profile._profilesTreeElement = profileTreeElement;
-
- sidebarParent.appendChild(profileTreeElement);
+ this._typeIdToSidebarSection[typeId].addProfileHeader(profile);
if (!this.visibleView || this.visibleView === this._launcherView)
- this._showProfile(profile);
-
- this.dispatchEventToListeners("profile added", {
- type: typeId
- });
+ this.showProfile(profile);
},
/**
@@ -739,35 +806,22 @@ WebInspector.ProfilesPanel.prototype = {
*/
_removeProfileHeader: function(profile)
{
- profile.dispose();
- profile.profileType().removeProfile(profile);
+ if (profile.profileType()._profileBeingRecorded === profile)
+ this._profileBeingRecordedRemoved();
- var sidebarParent = profile.profileType().treeElement;
- var profileTitleKey = this._makeTitleKey(profile.title, profile.profileType().id);
- var group = this._profileGroups[profileTitleKey];
- if (group) {
- group.splice(group.indexOf(profile), 1);
- if (group.length === 1) {
- // Move the last profile out of its group and remove the group.
- var index = sidebarParent.children.indexOf(group._profilesTreeElement);
- sidebarParent.insertChild(group[0]._profilesTreeElement, index);
- group[0]._profilesTreeElement.small = false;
- group[0]._profilesTreeElement.mainTitle = group[0].title;
- sidebarParent.removeChild(group._profilesTreeElement);
- }
- if (group.length !== 0)
- sidebarParent = group._profilesTreeElement;
- else
- delete this._profileGroups[profileTitleKey];
- }
- sidebarParent.removeChild(profile._profilesTreeElement);
+ var i = this._indexOfViewForProfile(profile);
+ if (i !== -1)
+ this._profileToView.splice(i, 1);
+
+ var profileType = profile.profileType();
+ var typeId = profileType.id;
+ var sectionIsEmpty = this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);
// No other item will be selected if there aren't any other profiles, so
// make sure that view gets cleared when the last profile is removed.
- if (!sidebarParent.children.length) {
+ if (sectionIsEmpty) {
this.profilesItemTreeElement.select();
this._showLauncherView();
- sidebarParent.hidden = !this._singleProfileMode;
}
},
@@ -775,12 +829,12 @@ WebInspector.ProfilesPanel.prototype = {
* @param {?WebInspector.ProfileHeader} profile
* @return {?WebInspector.View}
*/
- _showProfile: function(profile)
+ showProfile: function(profile)
{
if (!profile || (profile.profileType().profileBeingRecorded() === profile) && !profile.profileType().hasTemporaryView())
return null;
- var view = profile.view(this);
+ var view = this._viewForProfile(profile);
if (view === this.visibleView)
return view;
@@ -788,12 +842,12 @@ WebInspector.ProfilesPanel.prototype = {
view.show(this.profileViews);
- profile._profilesTreeElement._suppressOnSelect = true;
- profile._profilesTreeElement.revealAndSelect();
- delete profile._profilesTreeElement._suppressOnSelect;
-
this.visibleView = view;
+ var profileTypeSection = this._typeIdToSidebarSection[profile.profileType().id];
+ var sidebarElement = profileTypeSection.sidebarElementForProfile(profile);
+ sidebarElement.revealAndSelect();
+
this._profileViewStatusBarItemsContainer.removeChildren();
var statusBarItems = view.statusBarItems;
@@ -806,62 +860,49 @@ WebInspector.ProfilesPanel.prototype = {
/**
* @param {!HeapProfilerAgent.HeapSnapshotObjectId} snapshotObjectId
- * @param {string} viewName
+ * @param {string} perspectiveName
*/
- showObject: function(snapshotObjectId, viewName)
+ showObject: function(snapshotObjectId, perspectiveName)
{
- var heapProfiles = this.getProfileType(WebInspector.HeapSnapshotProfileType.TypeId).getProfiles();
+ var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
for (var i = 0; i < heapProfiles.length; i++) {
var profile = heapProfiles[i];
// FIXME: allow to choose snapshot if there are several options.
if (profile.maxJSObjectId >= snapshotObjectId) {
- this._showProfile(profile);
- var view = profile.view(this);
- view.changeView(viewName, function() {
- function didHighlightObject(found) {
- if (!found)
- WebInspector.log("Cannot find corresponding heap snapshot node", WebInspector.ConsoleMessage.MessageLevel.Error, true);
- }
- view.dataGrid.highlightObjectByHeapSnapshotId(snapshotObjectId, didHighlightObject.bind(this));
- });
+ this.showProfile(profile);
+ var view = this._viewForProfile(profile);
+ view.highlightLiveObject(perspectiveName, snapshotObjectId);
break;
}
}
},
/**
- * @param {string} typeId
- * @param {number} uid
- */
- getProfile: function(typeId, uid)
- {
- return this.getProfileType(typeId).getProfile(uid);
- },
-
- /**
- * @param {!WebInspector.View} view
- */
- showView: function(view)
- {
- this._showProfile(view.profile);
- },
-
- /**
- * @param {string} typeId
+ * @param {!WebInspector.ProfileHeader} profile
+ * @return {!WebInspector.View}
*/
- getProfileType: function(typeId)
- {
- return this._profileTypesByIdMap[typeId];
+ _viewForProfile: function(profile)
+ {
+ var index = this._indexOfViewForProfile(profile);
+ if (index !== -1)
+ return this._profileToView[index].view;
+ var view = profile.createView(this);
+ view.element.classList.add("profile-view");
+ this._profileToView.push({ profile: profile, view: view});
+ return view;
},
/**
- * @param {string} typeId
- * @param {string} uid
- * @return {?WebInspector.View}
+ * @param {!WebInspector.ProfileHeader} profile
+ * @return {number}
*/
- showProfile: function(typeId, uid)
+ _indexOfViewForProfile: function(profile)
{
- return this._showProfile(this.getProfile(typeId, Number(uid)));
+ for (var i = 0; i < this._profileToView.length; i++) {
+ if (this._profileToView[i].profile === profile)
+ return i;
+ }
+ return -1;
},
closeVisibleView: function()
@@ -874,8 +915,9 @@ WebInspector.ProfilesPanel.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
*/
- performSearch: function(query, shouldJump)
+ performSearch: function(query, shouldJump, jumpBackwards)
{
this.searchCanceled();
@@ -893,7 +935,10 @@ WebInspector.ProfilesPanel.prototype = {
this._searchableView.updateSearchMatchesCount(searchMatches);
this._searchResultsView = view;
if (shouldJump) {
- view.jumpToFirstSearchResult();
+ if (jumpBackwards)
+ view.jumpToLastSearchResult();
+ else
+ view.jumpToFirstSearchResult();
this._searchableView.updateCurrentMatchIndex(view.currentSearchResultIndex());
}
}
@@ -922,17 +967,6 @@ WebInspector.ProfilesPanel.prototype = {
this._searchableView.updateCurrentMatchIndex(this._searchResultsView.currentSearchResultIndex());
},
- /**
- * @return {!Array.<!WebInspector.ProfileHeader>}
- */
- _getAllProfiles: function()
- {
- var profiles = [];
- for (var typeId in this._profileTypesByIdMap)
- profiles = profiles.concat(this._profileTypesByIdMap[typeId].getProfiles());
- return profiles;
- },
-
searchCanceled: function()
{
if (this._searchResultsView) {
@@ -945,22 +979,15 @@ WebInspector.ProfilesPanel.prototype = {
},
/**
- * @param {!WebInspector.ProfileHeader} profile
- * @param {number} done
- * @param {number} total
- */
- _reportProfileProgress: function(profile, done, total)
- {
- profile.sidebarElement.subtitle = WebInspector.UIString("%.0f%", (done / total) * 100);
- profile.sidebarElement.wait = true;
- },
-
- /**
+ * @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target)
{
+ if (!(target instanceof WebInspector.RemoteObject))
+ return;
+
if (WebInspector.inspectorView.currentPanel() !== this)
return;
@@ -969,7 +996,7 @@ WebInspector.ProfilesPanel.prototype = {
if (!objectId)
return;
- var heapProfiles = this.getProfileType(WebInspector.HeapSnapshotProfileType.TypeId).getProfiles();
+ var heapProfiles = WebInspector.ProfileTypeRegistry.instance.heapSnapshotProfileType.getProfiles();
if (!heapProfiles.length)
return;
@@ -992,50 +1019,242 @@ WebInspector.ProfilesPanel.prototype = {
this.showObject(result, viewName);
}
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Dominators view" : "Reveal in Dominators View"), revealInView.bind(this, "Dominators"));
+ if (WebInspector.settings.showAdvancedHeapSnapshotProperties.get())
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Dominators view" : "Reveal in Dominators View"), revealInView.bind(this, "Dominators"));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Summary view" : "Reveal in Summary View"), revealInView.bind(this, "Summary"));
},
- __proto__: WebInspector.Panel.prototype
+ __proto__: WebInspector.PanelWithSidebarTree.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.SidebarSectionTreeElement}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
+ * @param {!WebInspector.ProfileType} profileType
+ */
+WebInspector.ProfileTypeSidebarSection = function(dataDisplayDelegate, profileType)
+{
+ WebInspector.SidebarSectionTreeElement.call(this, profileType.treeItemTitle, null, true);
+ this._dataDisplayDelegate = dataDisplayDelegate;
+ this._profileTreeElements = [];
+ this._profileGroups = {};
+ this.hidden = true;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.ProfileTypeSidebarSection.ProfileGroup = function()
+{
+ this.profileSidebarTreeElements = [];
+ this.sidebarTreeElement = null;
+}
+
+WebInspector.ProfileTypeSidebarSection.prototype = {
+ /**
+ * @param {!WebInspector.ProfileHeader} profile
+ */
+ addProfileHeader: function(profile)
+ {
+ this.hidden = false;
+ var profileType = profile.profileType();
+ var sidebarParent = this;
+ var profileTreeElement = profile.createSidebarTreeElement(this._dataDisplayDelegate);
+ this._profileTreeElements.push(profileTreeElement);
+
+ if (!profile.fromFile() && profileType.profileBeingRecorded() !== profile) {
+ var profileTitle = profile.title;
+ var group = this._profileGroups[profileTitle];
+ if (!group) {
+ group = new WebInspector.ProfileTypeSidebarSection.ProfileGroup();
+ this._profileGroups[profileTitle] = group;
+ }
+ group.profileSidebarTreeElements.push(profileTreeElement);
+
+ var groupSize = group.profileSidebarTreeElements.length;
+ if (groupSize === 2) {
+ // Make a group TreeElement now that there are 2 profiles.
+ group.sidebarTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(this._dataDisplayDelegate, profile.title);
+
+ var firstProfileTreeElement = group.profileSidebarTreeElements[0];
+ // Insert at the same index for the first profile of the group.
+ var index = this.children.indexOf(firstProfileTreeElement);
+ this.insertChild(group.sidebarTreeElement, index);
+
+ // Move the first profile to the group.
+ var selected = firstProfileTreeElement.selected;
+ this.removeChild(firstProfileTreeElement);
+ group.sidebarTreeElement.appendChild(firstProfileTreeElement);
+ if (selected)
+ firstProfileTreeElement.revealAndSelect();
+
+ firstProfileTreeElement.small = true;
+ firstProfileTreeElement.mainTitle = WebInspector.UIString("Run %d", 1);
+
+ this.treeOutline.element.classList.add("some-expandable");
+ }
+
+ if (groupSize >= 2) {
+ sidebarParent = group.sidebarTreeElement;
+ profileTreeElement.small = true;
+ profileTreeElement.mainTitle = WebInspector.UIString("Run %d", groupSize);
+ }
+ }
+
+ sidebarParent.appendChild(profileTreeElement);
+ },
+
+ /**
+ * @param {!WebInspector.ProfileHeader} profile
+ * @return {boolean}
+ */
+ removeProfileHeader: function(profile)
+ {
+ var index = this._sidebarElementIndex(profile);
+ if (index === -1)
+ return false;
+ var profileTreeElement = this._profileTreeElements[index];
+ this._profileTreeElements.splice(index, 1);
+
+ var sidebarParent = this;
+ var group = this._profileGroups[profile.title];
+ if (group) {
+ var groupElements = group.profileSidebarTreeElements;
+ groupElements.splice(groupElements.indexOf(profileTreeElement), 1);
+ if (groupElements.length === 1) {
+ // Move the last profile out of its group and remove the group.
+ var pos = sidebarParent.children.indexOf(group.sidebarTreeElement);
+ this.insertChild(groupElements[0], pos);
+ groupElements[0].small = false;
+ groupElements[0].mainTitle = group.sidebarTreeElement.title;
+ this.removeChild(group.sidebarTreeElement);
+ }
+ if (groupElements.length !== 0)
+ sidebarParent = group.sidebarTreeElement;
+ }
+ sidebarParent.removeChild(profileTreeElement);
+ profileTreeElement.dispose();
+
+ if (this.children.length)
+ return false;
+ this.hidden = true;
+ return true;
+ },
+
+ /**
+ * @param {!WebInspector.ProfileHeader} profile
+ * @return {?WebInspector.ProfileSidebarTreeElement}
+ */
+ sidebarElementForProfile: function(profile)
+ {
+ var index = this._sidebarElementIndex(profile);
+ return index === -1 ? null : this._profileTreeElements[index];
+ },
+
+ /**
+ * @param {!WebInspector.ProfileHeader} profile
+ * @return {number}
+ */
+ _sidebarElementIndex: function(profile)
+ {
+ var elements = this._profileTreeElements;
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i].profile === profile)
+ return i;
+ }
+ return -1;
+ },
+
+ __proto__: WebInspector.SidebarSectionTreeElement.prototype
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ */
+WebInspector.ProfilesPanel.ContextMenuProvider = function()
+{
+}
+
+WebInspector.ProfilesPanel.ContextMenuProvider.prototype = {
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ WebInspector.inspectorView.panel("profiles").appendApplicableItems(event, contextMenu, target);
+ }
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {!WebInspector.ProfileHeader} profile
* @param {string} className
*/
-WebInspector.ProfileSidebarTreeElement = function(profile, className)
+WebInspector.ProfileSidebarTreeElement = function(dataDisplayDelegate, profile, className)
{
+ this._dataDisplayDelegate = dataDisplayDelegate;
this.profile = profile;
- WebInspector.SidebarTreeElement.call(this, className, "", "", profile, false);
+ WebInspector.SidebarTreeElement.call(this, className, profile.title, "", profile, false);
this.refreshTitles();
+ profile.addEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
+ if (profile.canSaveToFile())
+ this._createSaveLink();
+ else
+ profile.addEventListener(WebInspector.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
}
WebInspector.ProfileSidebarTreeElement.prototype = {
- onselect: function()
+ _createSaveLink: function()
{
- if (!this._suppressOnSelect)
- this.treeOutline.panel._showProfile(this.profile);
+ this._saveLinkElement = this.titleContainer.createChild("span", "save-link");
+ this._saveLinkElement.textContent = WebInspector.UIString("Save");
+ this._saveLinkElement.addEventListener("click", this._saveProfile.bind(this), false);
},
- ondelete: function()
+ _onProfileReceived: function(event)
{
- this.treeOutline.panel._removeProfileHeader(this.profile);
- return true;
+ this._createSaveLink();
},
- get mainTitle()
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _updateStatus: function(event)
{
- if (this._mainTitle)
- return this._mainTitle;
- return this.profile.title;
+ var statusUpdate = event.data;
+ if (statusUpdate.subtitle !== null)
+ this.subtitle = statusUpdate.subtitle;
+ if (typeof statusUpdate.wait === "boolean")
+ this.wait = statusUpdate.wait;
+ this.refreshTitles();
},
- set mainTitle(x)
+ dispose: function()
{
- this._mainTitle = x;
- this.refreshTitles();
+ this.profile.removeEventListener(WebInspector.ProfileHeader.Events.UpdateStatus, this._updateStatus, this);
+ this.profile.removeEventListener(WebInspector.ProfileHeader.Events.ProfileReceived, this._onProfileReceived, this);
+ },
+
+ onselect: function()
+ {
+ this._dataDisplayDelegate.showProfile(this.profile);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ ondelete: function()
+ {
+ this.profile.profileType().removeProfile(this.profile);
+ return true;
},
/**
@@ -1054,27 +1273,32 @@ WebInspector.ProfileSidebarTreeElement.prototype = {
contextMenu.show();
},
+ _saveProfile: function(event)
+ {
+ this.profile.saveToFile();
+ },
+
__proto__: WebInspector.SidebarTreeElement.prototype
}
/**
* @constructor
* @extends {WebInspector.SidebarTreeElement}
- * @param {!WebInspector.ProfilesPanel} panel
+ * @param {!WebInspector.ProfileType.DataDisplayDelegate} dataDisplayDelegate
* @param {string} title
* @param {string=} subtitle
*/
-WebInspector.ProfileGroupSidebarTreeElement = function(panel, title, subtitle)
+WebInspector.ProfileGroupSidebarTreeElement = function(dataDisplayDelegate, title, subtitle)
{
WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item", title, subtitle, null, true);
- this._panel = panel;
+ this._dataDisplayDelegate = dataDisplayDelegate;
}
WebInspector.ProfileGroupSidebarTreeElement.prototype = {
onselect: function()
{
if (this.children.length > 0)
- this._panel._showProfile(this.children[this.children.length - 1].profile);
+ this._dataDisplayDelegate.showProfile(this.children[this.children.length - 1].profile);
},
__proto__: WebInspector.SidebarTreeElement.prototype
@@ -1108,71 +1332,19 @@ WebInspector.ProfilesSidebarTreeElement.prototype = {
}
-/**
- * @constructor
- * @extends {WebInspector.ProfilesPanel}
- */
-WebInspector.CPUProfilerPanel = function()
-{
- WebInspector.ProfilesPanel.call(this, "cpu-profiler", new WebInspector.CPUProfileType());
-}
-
-WebInspector.CPUProfilerPanel.prototype = {
- __proto__: WebInspector.ProfilesPanel.prototype
-}
-
-
-/**
- * @constructor
- * @extends {WebInspector.ProfilesPanel}
- */
-WebInspector.HeapProfilerPanel = function()
-{
- var heapSnapshotProfileType = new WebInspector.HeapSnapshotProfileType();
- WebInspector.ProfilesPanel.call(this, "heap-profiler", heapSnapshotProfileType);
- this._singleProfileMode = false;
- this._registerProfileType(new WebInspector.TrackingHeapSnapshotProfileType(this));
- this._launcherView.addEventListener(WebInspector.MultiProfileLauncherView.EventTypes.ProfileTypeSelected, this._onProfileTypeSelected, this);
- this._launcherView._profileTypeChanged(heapSnapshotProfileType);
-}
-
-WebInspector.HeapProfilerPanel.prototype = {
- _createLauncherView: function()
- {
- return new WebInspector.MultiProfileLauncherView(this);
- },
-
- __proto__: WebInspector.ProfilesPanel.prototype
-}
-
-
-/**
- * @constructor
- * @extends {WebInspector.ProfilesPanel}
- */
-WebInspector.CanvasProfilerPanel = function()
-{
- WebInspector.ProfilesPanel.call(this, "canvas-profiler", new WebInspector.CanvasProfileType());
-}
-
-WebInspector.CanvasProfilerPanel.prototype = {
- __proto__: WebInspector.ProfilesPanel.prototype
-}
-
-
-importScript("ProfileDataGridTree.js");
-importScript("AllocationProfile.js");
-importScript("BottomUpProfileDataGridTree.js");
+importScript("../sdk/CPUProfileModel.js");
+importScript("CPUProfileDataGrid.js");
+importScript("CPUProfileBottomUpDataGrid.js");
+importScript("CPUProfileTopDownDataGrid.js");
+importScript("CPUProfileFlameChart.js");
importScript("CPUProfileView.js");
-importScript("HeapSnapshot.js");
+importScript("HeapSnapshotCommon.js");
+importScript("HeapSnapshotProxy.js");
importScript("HeapSnapshotDataGrids.js");
importScript("HeapSnapshotGridNodes.js");
-importScript("HeapSnapshotLoader.js");
-importScript("HeapSnapshotProxy.js");
importScript("HeapSnapshotView.js");
-importScript("HeapSnapshotWorkerDispatcher.js");
-importScript("JSHeapSnapshot.js");
importScript("ProfileLauncherView.js");
-importScript("TopDownProfileDataGridTree.js");
importScript("CanvasProfileView.js");
importScript("CanvasReplayStateView.js");
+
+WebInspector.ProfileTypeRegistry.instance = new WebInspector.ProfileTypeRegistry();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/AllocationProfile.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/AllocationProfile.js
index d33717800a9..c6eb7c7ac4a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/AllocationProfile.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/AllocationProfile.js
@@ -31,23 +31,25 @@
/**
* @constructor
*/
-WebInspector.AllocationProfile = function(profile)
+WebInspector.AllocationProfile = function(profile, liveObjectStats)
{
this._strings = profile.strings;
+ this._liveObjectStats = liveObjectStats;
this._nextNodeId = 1;
- this._idToFunctionInfo = {};
+ this._functionInfos = []
this._idToNode = {};
+ this._idToTopDownNode = {};
this._collapsedTopNodeIdToFunctionInfo = {};
this._traceTops = null;
- this._buildAllocationFunctionInfos(profile);
- this._traceTree = this._buildInvertedAllocationTree(profile);
+ this._buildFunctionAllocationInfos(profile);
+ this._traceTree = this._buildAllocationTree(profile, liveObjectStats);
}
WebInspector.AllocationProfile.prototype = {
- _buildAllocationFunctionInfos: function(profile)
+ _buildFunctionAllocationInfos: function(profile)
{
var strings = this._strings;
@@ -60,15 +62,12 @@ WebInspector.AllocationProfile.prototype = {
var columnOffset = functionInfoFields.indexOf("column");
var functionInfoFieldCount = functionInfoFields.length;
- var map = this._idToFunctionInfo;
-
- // Special case for the root node.
- map[0] = new WebInspector.FunctionAllocationInfo("(root)", "<unknown>", 0, -1, -1);
-
var rawInfos = profile.trace_function_infos;
var infoLength = rawInfos.length;
+ var functionInfos = this._functionInfos = new Array(infoLength / functionInfoFieldCount);
+ var index = 0;
for (var i = 0; i < infoLength; i += functionInfoFieldCount) {
- map[rawInfos[i + functionIdOffset]] = new WebInspector.FunctionAllocationInfo(
+ functionInfos[index++] = new WebInspector.FunctionAllocationInfo(
strings[rawInfos[i + functionNameOffset]],
strings[rawInfos[i + scriptNameOffset]],
rawInfos[i + scriptIdOffset],
@@ -77,14 +76,15 @@ WebInspector.AllocationProfile.prototype = {
}
},
- _buildInvertedAllocationTree: function(profile)
+ _buildAllocationTree: function(profile, liveObjectStats)
{
var traceTreeRaw = profile.trace_tree;
- var idToFunctionInfo = this._idToFunctionInfo;
+ var functionInfos = this._functionInfos;
+ var idToTopDownNode = this._idToTopDownNode;
var traceNodeFields = profile.snapshot.meta.trace_node_fields;
var nodeIdOffset = traceNodeFields.indexOf("id");
- var functionIdOffset = traceNodeFields.indexOf("function_id");
+ var functionInfoIndexOffset = traceNodeFields.indexOf("function_info_index");
var allocationCountOffset = traceNodeFields.indexOf("count");
var allocationSizeOffset = traceNodeFields.indexOf("size");
var childrenOffset = traceNodeFields.indexOf("children");
@@ -92,13 +92,20 @@ WebInspector.AllocationProfile.prototype = {
function traverseNode(rawNodeArray, nodeOffset, parent)
{
- var functionInfo = idToFunctionInfo[rawNodeArray[nodeOffset + functionIdOffset]];
- var result = new WebInspector.AllocationTraceNode(
- rawNodeArray[nodeOffset + nodeIdOffset],
+ var functionInfo = functionInfos[rawNodeArray[nodeOffset + functionInfoIndexOffset]];
+ var id = rawNodeArray[nodeOffset + nodeIdOffset];
+ var stats = liveObjectStats[id];
+ var liveCount = stats ? stats.count : 0;
+ var liveSize = stats ? stats.size : 0;
+ var result = new WebInspector.TopDownAllocationNode(
+ id,
functionInfo,
rawNodeArray[nodeOffset + allocationCountOffset],
rawNodeArray[nodeOffset + allocationSizeOffset],
+ liveCount,
+ liveSize,
parent);
+ idToTopDownNode[id] = result;
functionInfo.addTraceTopNode(result);
var rawChildren = rawNodeArray[nodeOffset + childrenOffset];
@@ -111,23 +118,29 @@ WebInspector.AllocationProfile.prototype = {
return traverseNode(traceTreeRaw, 0, null);
},
+ /**
+ * @return {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>}
+ */
serializeTraceTops: function()
{
if (this._traceTops)
return this._traceTops;
var result = this._traceTops = [];
- var idToFunctionInfo = this._idToFunctionInfo;
- for (var id in idToFunctionInfo) {
- var info = idToFunctionInfo[id];
+ var functionInfos = this._functionInfos;
+ for (var i = 0; i < functionInfos.length; i++) {
+ var info = functionInfos[i];
if (info.totalCount === 0)
continue;
var nodeId = this._nextNodeId++;
+ var isRoot = i == 0;
result.push(this._serializeNode(
nodeId,
info,
info.totalCount,
info.totalSize,
- true));
+ info.totalLiveCount,
+ info.totalLiveSize,
+ !isRoot));
this._collapsedTopNodeIdToFunctionInfo[nodeId] = info;
}
result.sort(function(a, b) {
@@ -136,16 +149,13 @@ WebInspector.AllocationProfile.prototype = {
return result;
},
+ /**
+ * @param {number} nodeId
+ * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers}
+ */
serializeCallers: function(nodeId)
{
- var node = this._idToNode[nodeId];
- if (!node) {
- var functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId];
- node = functionInfo.tracesWithThisTop();
- delete this._collapsedTopNodeIdToFunctionInfo[nodeId];
- this._idToNode[nodeId] = node;
- }
-
+ var node = this._ensureBottomUpNode(nodeId);
var nodesWithSingleCaller = [];
while (node.callers().length === 1) {
node = node.callers()[0];
@@ -157,12 +167,60 @@ WebInspector.AllocationProfile.prototype = {
for (var i = 0; i < callers.length; i++) {
branchingCallers.push(this._serializeCaller(callers[i]));
}
- return {
- nodesWithSingleCaller: nodesWithSingleCaller,
- branchingCallers: branchingCallers
- };
+ return new WebInspector.HeapSnapshotCommon.AllocationNodeCallers(nodesWithSingleCaller, branchingCallers);
+ },
+
+ /**
+ * @param {number} traceNodeId
+ * @return {!Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>}
+ */
+ serializeAllocationStack: function(traceNodeId)
+ {
+ var node = this._idToTopDownNode[traceNodeId];
+ var result = [];
+ while (node) {
+ var functionInfo = node.functionInfo;
+ result.push(new WebInspector.HeapSnapshotCommon.AllocationStackFrame(
+ functionInfo.functionName,
+ functionInfo.scriptName,
+ functionInfo.scriptId,
+ functionInfo.line,
+ functionInfo.column
+ ));
+ node = node.parent;
+ }
+ return result;
+ },
+
+ /**
+ * @param {number} allocationNodeId
+ * @return {!Array.<number>}
+ */
+ traceIds: function(allocationNodeId)
+ {
+ return this._ensureBottomUpNode(allocationNodeId).traceTopIds;
},
+ /**
+ * @param {number} nodeId
+ * @return {!WebInspector.BottomUpAllocationNode}
+ */
+ _ensureBottomUpNode: function(nodeId)
+ {
+ var node = this._idToNode[nodeId];
+ if (!node) {
+ var functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId];
+ node = functionInfo.bottomUpRoot();
+ delete this._collapsedTopNodeIdToFunctionInfo[nodeId];
+ this._idToNode[nodeId] = node;
+ }
+ return node;
+ },
+
+ /**
+ * @param {!WebInspector.BottomUpAllocationNode} node
+ * @return {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode}
+ */
_serializeCaller: function(node)
{
var callerId = this._nextNodeId++;
@@ -172,34 +230,58 @@ WebInspector.AllocationProfile.prototype = {
node.functionInfo,
node.allocationCount,
node.allocationSize,
+ node.liveCount,
+ node.liveSize,
node.hasCallers());
},
- _serializeNode: function(nodeId, functionInfo, count, size, hasChildren)
+ /**
+ * @param {number} nodeId
+ * @param {!WebInspector.FunctionAllocationInfo} functionInfo
+ * @param {number} count
+ * @param {number} size
+ * @param {number} liveCount
+ * @param {number} liveSize
+ * @param {boolean} hasChildren
+ * @return {!WebInspector.HeapSnapshotCommon.SerializedAllocationNode}
+ */
+ _serializeNode: function(nodeId, functionInfo, count, size, liveCount, liveSize, hasChildren)
{
- return {
- id: nodeId,
- name: functionInfo.functionName,
- scriptName: functionInfo.scriptName,
- line: functionInfo.line,
- column: functionInfo.column,
- count: count,
- size: size,
- hasChildren: hasChildren
- };
+ return new WebInspector.HeapSnapshotCommon.SerializedAllocationNode(
+ nodeId,
+ functionInfo.functionName,
+ functionInfo.scriptName,
+ functionInfo.scriptId,
+ functionInfo.line,
+ functionInfo.column,
+ count,
+ size,
+ liveCount,
+ liveSize,
+ hasChildren
+ );
}
}
/**
* @constructor
+ * @param {number} id
+ * @param {!WebInspector.FunctionAllocationInfo} functionInfo
+ * @param {number} count
+ * @param {number} size
+ * @param {number} liveCount
+ * @param {number} liveSize
+ * @param {?WebInspector.TopDownAllocationNode} parent
*/
-WebInspector.AllocationTraceNode = function(id, functionInfo, count, size, parent)
+WebInspector.TopDownAllocationNode = function(id, functionInfo, count, size, liveCount, liveSize, parent)
{
this.id = id;
this.functionInfo = functionInfo;
this.allocationCount = count;
this.allocationSize = size;
+ this.liveCount = liveCount;
+ this.liveSize = liveSize;
this.parent = parent;
this.children = [];
}
@@ -209,19 +291,22 @@ WebInspector.AllocationTraceNode = function(id, functionInfo, count, size, paren
* @constructor
* @param {!WebInspector.FunctionAllocationInfo} functionInfo
*/
-WebInspector.AllocationBackTraceNode = function(functionInfo)
+WebInspector.BottomUpAllocationNode = function(functionInfo)
{
this.functionInfo = functionInfo;
this.allocationCount = 0;
this.allocationSize = 0;
+ this.liveCount = 0;
+ this.liveSize = 0;
+ this.traceTopIds = [];
this._callers = [];
}
-WebInspector.AllocationBackTraceNode.prototype = {
+WebInspector.BottomUpAllocationNode.prototype = {
/**
- * @param {!WebInspector.AllocationTraceNode} traceNode
- * @return {!WebInspector.AllocationTraceNode}
+ * @param {!WebInspector.TopDownAllocationNode} traceNode
+ * @return {!WebInspector.BottomUpAllocationNode}
*/
addCaller: function(traceNode)
{
@@ -235,17 +320,23 @@ WebInspector.AllocationBackTraceNode.prototype = {
}
}
if (!result) {
- result = new WebInspector.AllocationBackTraceNode(functionInfo);
+ result = new WebInspector.BottomUpAllocationNode(functionInfo);
this._callers.push(result);
}
return result;
},
+ /**
+ * @return {!Array.<!WebInspector.BottomUpAllocationNode>}
+ */
callers: function()
{
return this._callers;
},
+ /**
+ * @return {boolean}
+ */
hasCallers: function()
{
return this._callers.length > 0;
@@ -255,6 +346,11 @@ WebInspector.AllocationBackTraceNode.prototype = {
/**
* @constructor
+ * @param {string} functionName
+ * @param {string} scriptName
+ * @param {number} scriptId
+ * @param {number} line
+ * @param {number} column
*/
WebInspector.FunctionAllocationInfo = function(functionName, scriptName, scriptId, line, column)
{
@@ -265,10 +361,15 @@ WebInspector.FunctionAllocationInfo = function(functionName, scriptName, scriptI
this.column = column;
this.totalCount = 0;
this.totalSize = 0;
+ this.totalLiveCount = 0;
+ this.totalLiveSize = 0;
this._traceTops = [];
}
WebInspector.FunctionAllocationInfo.prototype = {
+ /**
+ * @param {!WebInspector.TopDownAllocationNode} node
+ */
addTraceTopNode: function(node)
{
if (node.allocationCount === 0)
@@ -276,34 +377,45 @@ WebInspector.FunctionAllocationInfo.prototype = {
this._traceTops.push(node);
this.totalCount += node.allocationCount;
this.totalSize += node.allocationSize;
+ this.totalLiveCount += node.liveCount;
+ this.totalLiveSize += node.liveSize;
},
- tracesWithThisTop: function()
+ /**
+ * @return {?WebInspector.BottomUpAllocationNode}
+ */
+ bottomUpRoot: function()
{
if (!this._traceTops.length)
return null;
- if (!this._backTraceTree)
+ if (!this._bottomUpTree)
this._buildAllocationTraceTree();
- return this._backTraceTree;
+ return this._bottomUpTree;
},
_buildAllocationTraceTree: function()
{
- this._backTraceTree = new WebInspector.AllocationBackTraceNode(this._traceTops[0].functionInfo);
+ this._bottomUpTree = new WebInspector.BottomUpAllocationNode(this);
for (var i = 0; i < this._traceTops.length; i++) {
var node = this._traceTops[i];
- var backTraceNode = this._backTraceTree;
+ var bottomUpNode = this._bottomUpTree;
var count = node.allocationCount;
var size = node.allocationSize;
+ var liveCount = node.liveCount;
+ var liveSize = node.liveSize;
+ var traceId = node.id;
while (true) {
- backTraceNode.allocationCount += count;
- backTraceNode.allocationSize += size;
+ bottomUpNode.allocationCount += count;
+ bottomUpNode.allocationSize += size;
+ bottomUpNode.liveCount += liveCount;
+ bottomUpNode.liveSize += liveSize;
+ bottomUpNode.traceTopIds.push(traceId);
node = node.parent;
if (node === null) {
break;
}
- backTraceNode = backTraceNode.addCaller(node);
+ bottomUpNode = bottomUpNode.addCaller(node);
}
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshot.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshot.js
index dc18ce13175..910b5a33f34 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshot.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshot.js
@@ -29,128 +29,242 @@
*/
/**
- * @constructor
+ * @interface
*/
-WebInspector.HeapSnapshotArraySlice = function(array, start, end)
-{
- this._array = array;
- this._start = start;
- this.length = end - start;
-}
+WebInspector.HeapSnapshotItem = function() { }
-WebInspector.HeapSnapshotArraySlice.prototype = {
- item: function(index)
- {
- return this._array[this._start + index];
- },
+WebInspector.HeapSnapshotItem.prototype = {
+ /**
+ * @return {number}
+ */
+ itemIndex: function() { },
- slice: function(start, end)
- {
- if (typeof end === "undefined")
- end = this.length;
- return this._array.subarray(this._start + start, this._start + end);
- }
-}
+ /**
+ * @return {!Object}
+ */
+ serialize: function() { }
+};
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItem}
+ * @param {!WebInspector.HeapSnapshot} snapshot
* @param {number=} edgeIndex
*/
-WebInspector.HeapSnapshotEdge = function(snapshot, edges, edgeIndex)
+WebInspector.HeapSnapshotEdge = function(snapshot, edgeIndex)
{
this._snapshot = snapshot;
- this._edges = edges;
+ this._edges = snapshot._containmentEdges;
this.edgeIndex = edgeIndex || 0;
}
WebInspector.HeapSnapshotEdge.prototype = {
+ /**
+ * @return {!WebInspector.HeapSnapshotEdge}
+ */
clone: function()
{
- return new WebInspector.HeapSnapshotEdge(this._snapshot, this._edges, this.edgeIndex);
+ return new WebInspector.HeapSnapshotEdge(this._snapshot, this.edgeIndex);
},
+ /**
+ * @return {boolean}
+ */
hasStringName: function()
{
throw new Error("Not implemented");
},
+ /**
+ * @return {string}
+ */
name: function()
{
throw new Error("Not implemented");
},
+ /**
+ * @return {!WebInspector.HeapSnapshotNode}
+ */
node: function()
{
return this._snapshot.createNode(this.nodeIndex());
},
+ /**
+ * @return {number}
+ */
nodeIndex: function()
{
- return this._edges.item(this.edgeIndex + this._snapshot._edgeToNodeOffset);
- },
-
- rawEdges: function()
- {
- return this._edges;
+ return this._edges[this.edgeIndex + this._snapshot._edgeToNodeOffset];
},
+ /**
+ * @return {string}
+ */
toString: function()
{
return "HeapSnapshotEdge: " + this.name();
},
+ /**
+ * @return {string}
+ */
type: function()
{
return this._snapshot._edgeTypes[this._type()];
},
+ /**
+ * @override
+ * @return {number}
+ */
+ itemIndex: function()
+ {
+ return this.edgeIndex;
+ },
+
+ /**
+ * @override
+ * @return {!WebInspector.HeapSnapshotCommon.Edge}
+ */
serialize: function()
{
- var node = this.node();
- return {
- name: this.name(),
- node: node.serialize(),
- nodeIndex: this.nodeIndex(),
- type: this.type(),
- distance: node.distance()
- };
+ return new WebInspector.HeapSnapshotCommon.Edge(this.name(), this.node().serialize(), this.type(), this.edgeIndex);
},
_type: function()
{
- return this._edges.item(this.edgeIndex + this._snapshot._edgeTypeOffset);
+ return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset];
}
};
+
+/**
+ * @interface
+ */
+WebInspector.HeapSnapshotItemIterator = function() { }
+
+WebInspector.HeapSnapshotItemIterator.prototype = {
+ /**
+ * @return {boolean}
+ */
+ hasNext: function() { },
+
+ /**
+ * @return {!WebInspector.HeapSnapshotItem}
+ */
+ item: function() { },
+
+ next: function() { }
+};
+
+
+/**
+ * @interface
+ */
+WebInspector.HeapSnapshotItemIndexProvider = function() { }
+
+WebInspector.HeapSnapshotItemIndexProvider.prototype = {
+ /**
+ * @param {number} newIndex
+ * @return {!WebInspector.HeapSnapshotItem}
+ */
+ itemForIndex: function(newIndex) { },
+};
+
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItemIndexProvider}
+ * @param {!WebInspector.HeapSnapshot} snapshot
*/
-WebInspector.HeapSnapshotEdgeIterator = function(edge)
+WebInspector.HeapSnapshotNodeIndexProvider = function(snapshot)
{
- this.edge = edge;
+ this._node = snapshot.createNode();
}
-WebInspector.HeapSnapshotEdgeIterator.prototype = {
- rewind: function()
+WebInspector.HeapSnapshotNodeIndexProvider.prototype = {
+ /**
+ * @param {number} index
+ * @return {!WebInspector.HeapSnapshotNode}
+ */
+ itemForIndex: function(index)
{
- this.edge.edgeIndex = 0;
- },
+ this._node.nodeIndex = index;
+ return this._node;
+ }
+};
- hasNext: function()
+
+/**
+ * @constructor
+ * @implements {WebInspector.HeapSnapshotItemIndexProvider}
+ * @param {!WebInspector.HeapSnapshot} snapshot
+ */
+WebInspector.HeapSnapshotEdgeIndexProvider = function(snapshot)
+{
+ this._edge = snapshot.createEdge(0);
+}
+
+WebInspector.HeapSnapshotEdgeIndexProvider.prototype = {
+ /**
+ * @param {number} index
+ * @return {!WebInspector.HeapSnapshotEdge}
+ */
+ itemForIndex: function(index)
{
- return this.edge.edgeIndex < this.edge._edges.length;
- },
+ this._edge.edgeIndex = index;
+ return this._edge;
+ }
+};
+
- index: function()
+/**
+ * @constructor
+ * @implements {WebInspector.HeapSnapshotItemIndexProvider}
+ * @param {!WebInspector.HeapSnapshot} snapshot
+ */
+WebInspector.HeapSnapshotRetainerEdgeIndexProvider = function(snapshot)
+{
+ this._retainerEdge = snapshot.createRetainingEdge(0);
+}
+
+WebInspector.HeapSnapshotRetainerEdgeIndexProvider.prototype = {
+ /**
+ * @param {number} index
+ * @return {!WebInspector.HeapSnapshotRetainerEdge}
+ */
+ itemForIndex: function(index)
{
- return this.edge.edgeIndex;
- },
+ this._retainerEdge.setRetainerIndex(index);
+ return this._retainerEdge;
+ }
+};
+
- setIndex: function(newIndex)
+/**
+ * @constructor
+ * @implements {WebInspector.HeapSnapshotItemIterator}
+ * @param {!WebInspector.HeapSnapshotNode} node
+ */
+WebInspector.HeapSnapshotEdgeIterator = function(node)
+{
+ this._sourceNode = node;
+ this.edge = node._snapshot.createEdge(node._edgeIndexesStart());
+}
+
+WebInspector.HeapSnapshotEdgeIterator.prototype = {
+ /**
+ * @return {boolean}
+ */
+ hasNext: function()
{
- this.edge.edgeIndex = newIndex;
+ return this.edge.edgeIndex < this._sourceNode._edgeIndexesEnd();
},
+ /**
+ * @return {!WebInspector.HeapSnapshotEdge}
+ */
item: function()
{
return this.edge;
@@ -164,100 +278,130 @@ WebInspector.HeapSnapshotEdgeIterator.prototype = {
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItem}
+ * @param {!WebInspector.HeapSnapshot} snapshot
+ * @param {number} retainerIndex
*/
-WebInspector.HeapSnapshotRetainerEdge = function(snapshot, retainedNodeIndex, retainerIndex)
+WebInspector.HeapSnapshotRetainerEdge = function(snapshot, retainerIndex)
{
this._snapshot = snapshot;
- this._retainedNodeIndex = retainedNodeIndex;
-
- var retainedNodeOrdinal = retainedNodeIndex / snapshot._nodeFieldCount;
- this._firstRetainer = snapshot._firstRetainerIndex[retainedNodeOrdinal];
- this._retainersCount = snapshot._firstRetainerIndex[retainedNodeOrdinal + 1] - this._firstRetainer;
-
this.setRetainerIndex(retainerIndex);
}
WebInspector.HeapSnapshotRetainerEdge.prototype = {
+ /**
+ * @return {!WebInspector.HeapSnapshotRetainerEdge}
+ */
clone: function()
{
- return new WebInspector.HeapSnapshotRetainerEdge(this._snapshot, this._retainedNodeIndex, this.retainerIndex());
+ return new WebInspector.HeapSnapshotRetainerEdge(this._snapshot, this.retainerIndex());
},
+ /**
+ * @return {boolean}
+ */
hasStringName: function()
{
return this._edge().hasStringName();
},
+ /**
+ * @return {string}
+ */
name: function()
{
return this._edge().name();
},
+ /**
+ * @return {!WebInspector.HeapSnapshotNode}
+ */
node: function()
{
return this._node();
},
+ /**
+ * @return {number}
+ */
nodeIndex: function()
{
- return this._nodeIndex;
+ return this._retainingNodeIndex;
},
+ /**
+ * @return {number}
+ */
retainerIndex: function()
{
return this._retainerIndex;
},
- setRetainerIndex: function(newIndex)
+ /**
+ * @param {number} retainerIndex
+ */
+ setRetainerIndex: function(retainerIndex)
{
- if (newIndex !== this._retainerIndex) {
- this._retainerIndex = newIndex;
- this.edgeIndex = newIndex;
- }
+ if (retainerIndex === this._retainerIndex)
+ return;
+ this._retainerIndex = retainerIndex;
+ this._globalEdgeIndex = this._snapshot._retainingEdges[retainerIndex];
+ this._retainingNodeIndex = this._snapshot._retainingNodes[retainerIndex];
+ this._edgeInstance = null;
+ this._nodeInstance = null;
},
+ /**
+ * @param {number} edgeIndex
+ */
set edgeIndex(edgeIndex)
{
- var retainerIndex = this._firstRetainer + edgeIndex;
- this._globalEdgeIndex = this._snapshot._retainingEdges[retainerIndex];
- this._nodeIndex = this._snapshot._retainingNodes[retainerIndex];
- delete this._edgeInstance;
- delete this._nodeInstance;
+ this.setRetainerIndex(edgeIndex);
},
_node: function()
{
if (!this._nodeInstance)
- this._nodeInstance = this._snapshot.createNode(this._nodeIndex);
+ this._nodeInstance = this._snapshot.createNode(this._retainingNodeIndex);
return this._nodeInstance;
},
_edge: function()
{
- if (!this._edgeInstance) {
- var edgeIndex = this._globalEdgeIndex - this._node()._edgeIndexesStart();
- this._edgeInstance = this._snapshot.createEdge(this._node().rawEdges(), edgeIndex);
- }
+ if (!this._edgeInstance)
+ this._edgeInstance = this._snapshot.createEdge(this._globalEdgeIndex);
return this._edgeInstance;
},
+ /**
+ * @return {string}
+ */
toString: function()
{
return this._edge().toString();
},
+ /**
+ * @override
+ * @return {number}
+ */
+ itemIndex: function()
+ {
+ return this._retainerIndex;
+ },
+
+ /**
+ * @override
+ * @return {!WebInspector.HeapSnapshotCommon.Edge}
+ */
serialize: function()
{
- var node = this.node();
- return {
- name: this.name(),
- node: node.serialize(),
- nodeIndex: this.nodeIndex(),
- type: this.type(),
- distance: node.distance()
- };
+ return new WebInspector.HeapSnapshotCommon.Edge(this.name(), this.node().serialize(), this.type(), this._globalEdgeIndex);
},
+ /**
+ * @return {string}
+ */
type: function()
{
return this._edge().type();
@@ -266,33 +410,30 @@ WebInspector.HeapSnapshotRetainerEdge.prototype = {
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItemIterator}
+ * @param {!WebInspector.HeapSnapshotNode} retainedNode
*/
-WebInspector.HeapSnapshotRetainerEdgeIterator = function(retainer)
+WebInspector.HeapSnapshotRetainerEdgeIterator = function(retainedNode)
{
- this.retainer = retainer;
+ var snapshot = retainedNode._snapshot;
+ var retainedNodeOrdinal = retainedNode._ordinal();
+ var retainerIndex = snapshot._firstRetainerIndex[retainedNodeOrdinal];
+ this._retainersEnd = snapshot._firstRetainerIndex[retainedNodeOrdinal + 1];
+ this.retainer = snapshot.createRetainingEdge(retainerIndex);
}
WebInspector.HeapSnapshotRetainerEdgeIterator.prototype = {
- rewind: function()
- {
- this.retainer.setRetainerIndex(0);
- },
-
+ /**
+ * @return {boolean}
+ */
hasNext: function()
{
- return this.retainer.retainerIndex() < this.retainer._retainersCount;
- },
-
- index: function()
- {
- return this.retainer.retainerIndex();
- },
-
- setIndex: function(newIndex)
- {
- this.retainer.setRetainerIndex(newIndex);
+ return this.retainer.retainerIndex() < this._retainersEnd;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotRetainerEdge}
+ */
item: function()
{
return this.retainer;
@@ -306,128 +447,204 @@ WebInspector.HeapSnapshotRetainerEdgeIterator.prototype = {
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItem}
+ * @param {!WebInspector.HeapSnapshot} snapshot
* @param {number=} nodeIndex
*/
WebInspector.HeapSnapshotNode = function(snapshot, nodeIndex)
{
this._snapshot = snapshot;
- this._firstNodeIndex = nodeIndex;
- this.nodeIndex = nodeIndex;
+ this.nodeIndex = nodeIndex || 0;
}
WebInspector.HeapSnapshotNode.prototype = {
+ /**
+ * @return {number}
+ */
distance: function()
{
return this._snapshot._nodeDistances[this.nodeIndex / this._snapshot._nodeFieldCount];
},
+ /**
+ * @return {string}
+ */
className: function()
{
throw new Error("Not implemented");
},
+ /**
+ * @return {number}
+ */
classIndex: function()
{
throw new Error("Not implemented");
},
+ /**
+ * @return {number}
+ */
dominatorIndex: function()
{
var nodeFieldCount = this._snapshot._nodeFieldCount;
return this._snapshot._dominatorsTree[this.nodeIndex / this._snapshot._nodeFieldCount] * nodeFieldCount;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotEdgeIterator}
+ */
edges: function()
{
- return new WebInspector.HeapSnapshotEdgeIterator(this._snapshot.createEdge(this.rawEdges(), 0));
+ return new WebInspector.HeapSnapshotEdgeIterator(this);
},
+ /**
+ * @return {number}
+ */
edgesCount: function()
{
return (this._edgeIndexesEnd() - this._edgeIndexesStart()) / this._snapshot._edgeFieldsCount;
},
+ /**
+ * @return {number}
+ */
id: function()
{
throw new Error("Not implemented");
},
+ /**
+ * @return {boolean}
+ */
isRoot: function()
{
return this.nodeIndex === this._snapshot._rootNodeIndex;
},
+ /**
+ * @return {string}
+ */
name: function()
{
return this._snapshot._strings[this._name()];
},
- rawEdges: function()
+ /**
+ * @return {number}
+ */
+ retainedSize: function()
{
- return new WebInspector.HeapSnapshotArraySlice(this._snapshot._containmentEdges, this._edgeIndexesStart(), this._edgeIndexesEnd());
+ return this._snapshot._retainedSizes[this._ordinal()];
},
- retainedSize: function()
+ /**
+ * @return {!WebInspector.HeapSnapshotRetainerEdgeIterator}
+ */
+ retainers: function()
{
- var snapshot = this._snapshot;
- return snapshot._nodes[this.nodeIndex + snapshot._nodeRetainedSizeOffset];
+ return new WebInspector.HeapSnapshotRetainerEdgeIterator(this);
},
- retainers: function()
+ /**
+ * @return {number}
+ */
+ retainersCount: function()
{
- return new WebInspector.HeapSnapshotRetainerEdgeIterator(this._snapshot.createRetainingEdge(this.nodeIndex, 0));
+ var snapshot = this._snapshot;
+ var ordinal = this._ordinal();
+ return snapshot._firstRetainerIndex[ordinal + 1] - snapshot._firstRetainerIndex[ordinal];
},
+ /**
+ * @return {number}
+ */
selfSize: function()
{
var snapshot = this._snapshot;
return snapshot._nodes[this.nodeIndex + snapshot._nodeSelfSizeOffset];
},
+ /**
+ * @return {string}
+ */
type: function()
{
return this._snapshot._nodeTypes[this._type()];
},
+ /**
+ * @return {number}
+ */
+ traceNodeId: function()
+ {
+ var snapshot = this._snapshot;
+ return snapshot._nodes[this.nodeIndex + snapshot._nodeTraceNodeIdOffset];
+ },
+
+ /**
+ * @override
+ * @return {number}
+ */
+ itemIndex: function()
+ {
+ return this.nodeIndex;
+ },
+
+ /**
+ * @override
+ * @return {!WebInspector.HeapSnapshotCommon.Node}
+ */
serialize: function()
{
- return {
- id: this.id(),
- name: this.name(),
- distance: this.distance(),
- nodeIndex: this.nodeIndex,
- retainedSize: this.retainedSize(),
- selfSize: this.selfSize(),
- type: this.type(),
- };
+ return new WebInspector.HeapSnapshotCommon.Node(this.id(), this.name(), this.distance(), this.nodeIndex, this.retainedSize(), this.selfSize(), this.type());
},
+ /**
+ * @return {number}
+ */
_name: function()
{
var snapshot = this._snapshot;
return snapshot._nodes[this.nodeIndex + snapshot._nodeNameOffset];
},
+ /**
+ * @return {number}
+ */
_edgeIndexesStart: function()
{
return this._snapshot._firstEdgeIndexes[this._ordinal()];
},
+ /**
+ * @return {number}
+ */
_edgeIndexesEnd: function()
{
return this._snapshot._firstEdgeIndexes[this._ordinal() + 1];
},
+ /**
+ * @return {number}
+ */
_ordinal: function()
{
return this.nodeIndex / this._snapshot._nodeFieldCount;
},
+ /**
+ * @return {number}
+ */
_nextNodeIndex: function()
{
return this.nodeIndex + this._snapshot._nodeFieldCount;
},
+ /**
+ * @return {number}
+ */
_type: function()
{
var snapshot = this._snapshot;
@@ -437,6 +654,8 @@ WebInspector.HeapSnapshotNode.prototype = {
/**
* @constructor
+ * @implements {WebInspector.HeapSnapshotItemIterator}
+ * @param {!WebInspector.HeapSnapshotNode} node
*/
WebInspector.HeapSnapshotNodeIterator = function(node)
{
@@ -445,34 +664,108 @@ WebInspector.HeapSnapshotNodeIterator = function(node)
}
WebInspector.HeapSnapshotNodeIterator.prototype = {
- rewind: function()
+ /**
+ * @return {boolean}
+ */
+ hasNext: function()
{
- this.node.nodeIndex = this.node._firstNodeIndex;
+ return this.node.nodeIndex < this._nodesLength;
},
+ /**
+ * @return {!WebInspector.HeapSnapshotNode}
+ */
+ item: function()
+ {
+ return this.node;
+ },
+
+ next: function()
+ {
+ this.node.nodeIndex = this.node._nextNodeIndex();
+ }
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.HeapSnapshotItemIterator}
+ * @param {!WebInspector.HeapSnapshotItemIndexProvider} itemProvider
+ * @param {!Array.<number>|!Uint32Array} indexes
+ */
+WebInspector.HeapSnapshotIndexRangeIterator = function(itemProvider, indexes)
+{
+ this._itemProvider = itemProvider;
+ this._indexes = indexes;
+ this._position = 0;
+}
+
+WebInspector.HeapSnapshotIndexRangeIterator.prototype = {
+ /**
+ * @return {boolean}
+ */
hasNext: function()
{
- return this.node.nodeIndex < this._nodesLength;
+ return this._position < this._indexes.length
},
- index: function()
+ /**
+ * @return {!WebInspector.HeapSnapshotItem}
+ */
+ item: function()
{
- return this.node.nodeIndex;
+ var index = this._indexes[this._position];
+ return this._itemProvider.itemForIndex(index);
},
- setIndex: function(newIndex)
+ next: function()
{
- this.node.nodeIndex = newIndex;
+ ++this._position;
+ }
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.HeapSnapshotItemIterator}
+ * @param {!WebInspector.HeapSnapshotItemIterator} iterator
+ * @param {function(!WebInspector.HeapSnapshotItem):boolean=} filter
+ */
+WebInspector.HeapSnapshotFilteredIterator = function(iterator, filter)
+{
+ this._iterator = iterator;
+ this._filter = filter;
+ this._skipFilteredItems();
+}
+
+WebInspector.HeapSnapshotFilteredIterator.prototype = {
+ /**
+ * @return {boolean}
+ */
+ hasNext: function()
+ {
+ return this._iterator.hasNext();
},
+ /**
+ * @return {!WebInspector.HeapSnapshotItem}
+ */
item: function()
{
- return this.node;
+ return this._iterator.item();
},
next: function()
{
- this.node.nodeIndex = this.node._nextNodeIndex();
+ this._iterator.next();
+ this._skipFilteredItems();
+ },
+
+ _skipFilteredItems: function()
+ {
+ while (this._iterator.hasNext() && !this._filter(this._iterator.item())) {
+ this._iterator.next();
+ }
}
}
@@ -486,10 +779,6 @@ WebInspector.HeapSnapshotProgress = function(dispatcher)
this._dispatcher = dispatcher;
}
-WebInspector.HeapSnapshotProgress.Event = {
- Update: "ProgressUpdate"
-};
-
WebInspector.HeapSnapshotProgress.prototype = {
/**
* @param {string} status
@@ -517,18 +806,19 @@ WebInspector.HeapSnapshotProgress.prototype = {
{
// May be undefined in tests.
if (this._dispatcher)
- this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgress.Event.Update, text);
+ this._dispatcher.sendEvent(WebInspector.HeapSnapshotProgressEvent.Update, text);
}
}
/**
+ * @param {!Object} profile
* @param {!WebInspector.HeapSnapshotProgress} progress
+ * @param {boolean} showHiddenData
* @constructor
*/
-WebInspector.HeapSnapshot = function(profile, progress)
+WebInspector.HeapSnapshot = function(profile, progress, showHiddenData)
{
- this.uid = profile.snapshot.uid;
this._nodes = profile.nodes;
this._containmentEdges = profile.edges;
/** @type {!HeapSnapshotMetainfo} */
@@ -543,18 +833,35 @@ WebInspector.HeapSnapshot = function(profile, progress)
this._snapshotDiffs = {};
this._aggregatesForDiff = null;
+ this._aggregates = {};
+ this._aggregatesSortedFlags = {};
+ this._showHiddenData = showHiddenData;
this._init();
- if (WebInspector.HeapSnapshot.enableAllocationProfiler) {
+ if (profile.snapshot.trace_function_count) {
this._progress.updateStatus("Buiding allocation statistics\u2026");
- this._allocationProfile = new WebInspector.AllocationProfile(profile);
+ var nodes = this._nodes;
+ var nodesLength = nodes.length;
+ var nodeFieldCount = this._nodeFieldCount;
+ var node = this.rootNode();
+ var liveObjects = {};
+ for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
+ node.nodeIndex = nodeIndex;
+ var traceNodeId = node.traceNodeId();
+ var stats = liveObjects[traceNodeId];
+ if (!stats) {
+ liveObjects[traceNodeId] = stats = { count: 0, size: 0, ids: []};
+ }
+ stats.count++;
+ stats.size += node.selfSize();
+ stats.ids.push(node.id());
+ }
+ this._allocationProfile = new WebInspector.AllocationProfile(profile, liveObjects);
this._progress.updateStatus("Done");
}
}
-WebInspector.HeapSnapshot.enableAllocationProfiler = false;
-
/**
* @constructor
*/
@@ -577,7 +884,6 @@ function HeapSnapshotHeader()
{
// New format.
this.title = "";
- this.uid = 0;
this.meta = new HeapSnapshotMetainfo();
this.node_count = 0;
this.edge_count = 0;
@@ -593,6 +899,7 @@ WebInspector.HeapSnapshot.prototype = {
this._nodeIdOffset = meta.node_fields.indexOf("id");
this._nodeSelfSizeOffset = meta.node_fields.indexOf("self_size");
this._nodeEdgeCountOffset = meta.node_fields.indexOf("edge_count");
+ this._nodeTraceNodeIdOffset = meta.node_fields.indexOf("trace_node_id");
this._nodeFieldCount = meta.node_fields.length;
this._nodeTypes = meta.node_types[this._nodeTypeOffset];
@@ -623,8 +930,6 @@ WebInspector.HeapSnapshot.prototype = {
this._progress.updateStatus("Building edge indexes\u2026");
this._buildEdgeIndexes();
- this._progress.updateStatus("Marking invisible edges\u2026");
- this._markInvisibleEdges();
this._progress.updateStatus("Building retainers\u2026");
this._buildRetainers();
this._progress.updateStatus("Calculating node flags\u2026");
@@ -640,6 +945,8 @@ WebInspector.HeapSnapshot.prototype = {
this._calculateRetainedSizes(result.postOrderIndex2NodeOrdinal);
this._progress.updateStatus("Buiding dominated nodes\u2026");
this._buildDominatedNodes();
+ this._progress.updateStatus("Calculating statistics\u2026");
+ this._calculateStatistics();
this._progress.updateStatus("Finished processing.");
},
@@ -712,12 +1019,20 @@ WebInspector.HeapSnapshot.prototype = {
throw new Error("Not implemented");
},
- createEdge: function(edges, edgeIndex)
+ /**
+ * @param {number} edgeIndex
+ * @return {!WebInspector.JSHeapSnapshotEdge}
+ */
+ createEdge: function(edgeIndex)
{
throw new Error("Not implemented");
},
- createRetainingEdge: function(retainedNodeIndex, retainerIndex)
+ /**
+ * @param {number} retainerIndex
+ * @return {!WebInspector.JSHeapSnapshotRetainerEdge}
+ */
+ createRetainingEdge: function(retainerIndex)
{
throw new Error("Not implemented");
},
@@ -729,10 +1044,8 @@ WebInspector.HeapSnapshot.prototype = {
delete this._retainingEdges;
delete this._retainingNodes;
delete this._firstRetainerIndex;
- if (this._aggregates) {
- delete this._aggregates;
- delete this._aggregatesSortedFlags;
- }
+ delete this._aggregates;
+ delete this._aggregatesSortedFlags;
delete this._dominatedNodes;
delete this._firstDominatedNodeIndex;
delete this._nodeDistances;
@@ -744,6 +1057,9 @@ WebInspector.HeapSnapshot.prototype = {
return new WebInspector.HeapSnapshotNodeIterator(this.rootNode());
},
+ /**
+ * @return {!WebInspector.HeapSnapshotNode}
+ */
rootNode: function()
{
return this.createNode(this._rootNodeIndex);
@@ -766,61 +1082,139 @@ WebInspector.HeapSnapshot.prototype = {
return this._firstDominatedNodeIndex[nodeIndex / this._nodeFieldCount];
},
+ /**
+ * @param {!WebInspector.HeapSnapshotNode} node
+ * @return {!Uint32Array}
+ */
_dominatedNodesOfNode: function(node)
{
var dominatedIndexFrom = this._getDominatedIndex(node.nodeIndex);
var dominatedIndexTo = this._getDominatedIndex(node._nextNodeIndex());
- return new WebInspector.HeapSnapshotArraySlice(this._dominatedNodes, dominatedIndexFrom, dominatedIndexTo);
+ return this._dominatedNodes.subarray(dominatedIndexFrom, dominatedIndexTo);
},
/**
- * @param {boolean} sortedIndexes
- * @param {string} key
- * @param {string=} filterString
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
+ * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>}
*/
- aggregates: function(sortedIndexes, key, filterString)
+ aggregatesWithFilter: function(nodeFilter)
{
- if (!this._aggregates) {
- this._aggregates = {};
- this._aggregatesSortedFlags = {};
+ var minNodeId = nodeFilter.minNodeId;
+ var maxNodeId = nodeFilter.maxNodeId;
+ var allocationNodeId = nodeFilter.allocationNodeId;
+ var key;
+ var filter;
+ if (typeof allocationNodeId === "number") {
+ filter = this._createAllocationStackFilter(allocationNodeId);
+ } else if (typeof minNodeId === "number" && typeof maxNodeId === "number") {
+ key = minNodeId + ".." + maxNodeId;
+ filter = this._createNodeIdFilter(minNodeId, maxNodeId);
+ } else {
+ key = "allObjects";
}
+ return this.aggregates(false, key, filter);
+ },
- var aggregatesByClassName = this._aggregates[key];
- if (aggregatesByClassName) {
- if (sortedIndexes && !this._aggregatesSortedFlags[key]) {
- this._sortAggregateIndexes(aggregatesByClassName);
- this._aggregatesSortedFlags[key] = sortedIndexes;
- }
- return aggregatesByClassName;
+ /**
+ * @param {number} minNodeId
+ * @param {number} maxNodeId
+ * @return {function(!WebInspector.HeapSnapshotNode):boolean}
+ */
+ _createNodeIdFilter: function(minNodeId, maxNodeId)
+ {
+ /**
+ * @param {!WebInspector.HeapSnapshotNode} node
+ * @return {boolean}
+ */
+ function nodeIdFilter(node)
+ {
+ var id = node.id();
+ return id > minNodeId && id <= maxNodeId;
}
+ return nodeIdFilter;
+ },
- var filter;
- if (filterString)
- filter = this._parseFilter(filterString);
+ /**
+ * @param {number} bottomUpAllocationNodeId
+ * @return {function(!WebInspector.HeapSnapshotNode):boolean|undefined}
+ */
+ _createAllocationStackFilter: function(bottomUpAllocationNodeId)
+ {
+ var traceIds = this._allocationProfile.traceIds(bottomUpAllocationNodeId);
+ if (!traceIds.length)
+ return undefined;
+ var set = {};
+ for (var i = 0; i < traceIds.length; i++)
+ set[traceIds[i]] = true;
+ /**
+ * @param {!WebInspector.HeapSnapshotNode} node
+ * @return {boolean}
+ */
+ function traceIdFilter(node)
+ {
+ return !!set[node.traceNodeId()];
+ };
+ return traceIdFilter;
+ },
- var aggregates = this._buildAggregates(filter);
- this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex, filter);
- aggregatesByClassName = aggregates.aggregatesByClassName;
+ /**
+ * @param {boolean} sortedIndexes
+ * @param {string=} key
+ * @param {function(!WebInspector.HeapSnapshotNode):boolean=} filter
+ * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Aggregate>}
+ */
+ aggregates: function(sortedIndexes, key, filter)
+ {
+ var aggregatesByClassName = key && this._aggregates[key];
+ if (!aggregatesByClassName) {
+ var aggregates = this._buildAggregates(filter);
+ this._calculateClassesRetainedSize(aggregates.aggregatesByClassIndex, filter);
+ aggregatesByClassName = aggregates.aggregatesByClassName;
+ if (key)
+ this._aggregates[key] = aggregatesByClassName;
+ }
- if (sortedIndexes)
+ if (sortedIndexes && (!key || !this._aggregatesSortedFlags[key])) {
this._sortAggregateIndexes(aggregatesByClassName);
-
- this._aggregatesSortedFlags[key] = sortedIndexes;
- this._aggregates[key] = aggregatesByClassName;
-
+ if (key)
+ this._aggregatesSortedFlags[key] = sortedIndexes;
+ }
return aggregatesByClassName;
},
+ /**
+ * @return {!Array.<!WebInspector.HeapSnapshotCommon.SerializedAllocationNode>}
+ */
allocationTracesTops: function()
{
return this._allocationProfile.serializeTraceTops();
},
+ /**
+ * @param {number} nodeId
+ * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers}
+ */
allocationNodeCallers: function(nodeId)
{
return this._allocationProfile.serializeCallers(nodeId);
},
+ /**
+ * @param {number} nodeIndex
+ * @return {?Array.<!WebInspector.HeapSnapshotCommon.AllocationStackFrame>}
+ */
+ allocationStack: function(nodeIndex)
+ {
+ var node = this.createNode(nodeIndex);
+ var allocationNodeId = node.traceNodeId();
+ if (!allocationNodeId)
+ return null;
+ return this._allocationProfile.serializeAllocationStack(allocationNodeId);
+ },
+
+ /**
+ * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.AggregateForDiff>}
+ */
aggregatesForDiff: function()
{
if (this._aggregatesForDiff)
@@ -876,7 +1270,7 @@ WebInspector.HeapSnapshot.prototype = {
{
var nodeFieldCount = this._nodeFieldCount;
var nodeCount = this.nodeCount;
- var distances = new Int32Array(nodeCount);
+ var distances = this._nodeDistances = new Int32Array(nodeCount);
var noDistance = this._noDistance;
for (var i = 0; i < nodeCount; ++i)
distances[i] = noDistance;
@@ -885,26 +1279,25 @@ WebInspector.HeapSnapshot.prototype = {
var nodesToVisitLength = 0;
/**
+ * @param {number} distance
* @param {!WebInspector.HeapSnapshotNode} node
*/
- function enqueueNode(node)
+ function enqueueNode(distance, node)
{
var ordinal = node._ordinal();
if (distances[ordinal] !== noDistance)
return;
- distances[ordinal] = 0;
+ distances[ordinal] = distance;
nodesToVisit[nodesToVisitLength++] = node.nodeIndex;
}
- this.forEachRoot(enqueueNode, true);
+ this.forEachRoot(enqueueNode.bind(null, 1), true);
this._bfs(nodesToVisit, nodesToVisitLength, distances);
// bfs for the rest of objects
nodesToVisitLength = 0;
- this.forEachRoot(enqueueNode);
+ this.forEachRoot(enqueueNode.bind(null, WebInspector.HeapSnapshotCommon.baseSystemDistance), false);
this._bfs(nodesToVisit, nodesToVisitLength, distances);
-
- this._nodeDistances = distances;
},
/**
@@ -1086,51 +1479,51 @@ WebInspector.HeapSnapshot.prototype = {
var edgeShortcutType = this._edgeShortcutType;
var firstEdgeIndexes = this._firstEdgeIndexes;
var containmentEdges = this._containmentEdges;
- var containmentEdgesLength = this._containmentEdges.length;
var mapAndFlag = this.userObjectsMapAndFlag();
var flags = mapAndFlag ? mapAndFlag.map : null;
var flag = mapAndFlag ? mapAndFlag.flag : 0;
- var nodesToVisit = new Uint32Array(nodeCount);
+ var stackNodes = new Uint32Array(nodeCount);
+ var stackCurrentEdge = new Uint32Array(nodeCount);
var postOrderIndex2NodeOrdinal = new Uint32Array(nodeCount);
var nodeOrdinal2PostOrderIndex = new Uint32Array(nodeCount);
- var painted = new Uint8Array(nodeCount);
- var nodesToVisitLength = 0;
+ var visited = new Uint8Array(nodeCount);
var postOrderIndex = 0;
- var grey = 1;
- var black = 2;
- nodesToVisit[nodesToVisitLength++] = rootNodeOrdinal;
- painted[rootNodeOrdinal] = grey;
+ var stackTop = 0;
+ stackNodes[0] = rootNodeOrdinal;
+ stackCurrentEdge[0] = firstEdgeIndexes[rootNodeOrdinal];
+ visited[rootNodeOrdinal] = 1;
- while (nodesToVisitLength) {
- var nodeOrdinal = nodesToVisit[nodesToVisitLength - 1];
+ while (stackTop >= 0) {
+ var nodeOrdinal = stackNodes[stackTop];
+ var edgeIndex = stackCurrentEdge[stackTop];
+ var edgesEnd = firstEdgeIndexes[nodeOrdinal + 1];
- if (painted[nodeOrdinal] === grey) {
- painted[nodeOrdinal] = black;
+ if (edgeIndex < edgesEnd) {
+ stackCurrentEdge[stackTop] += edgeFieldsCount;
+ if (nodeOrdinal !== rootNodeOrdinal && containmentEdges[edgeIndex + edgeTypeOffset] === edgeShortcutType)
+ continue;
+ var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
+ var childNodeOrdinal = childNodeIndex / nodeFieldCount;
+ if (visited[childNodeOrdinal])
+ continue;
var nodeFlag = !flags || (flags[nodeOrdinal] & flag);
- var beginEdgeIndex = firstEdgeIndexes[nodeOrdinal];
- var endEdgeIndex = firstEdgeIndexes[nodeOrdinal + 1];
- for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
- if (nodeOrdinal !== rootNodeOrdinal && containmentEdges[edgeIndex + edgeTypeOffset] === edgeShortcutType)
- continue;
- var childNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
- var childNodeOrdinal = childNodeIndex / nodeFieldCount;
- var childNodeFlag = !flags || (flags[childNodeOrdinal] & flag);
- // We are skipping the edges from non-page-owned nodes to page-owned nodes.
- // Otherwise the dominators for the objects that also were retained by debugger would be affected.
- if (nodeOrdinal !== rootNodeOrdinal && childNodeFlag && !nodeFlag)
- continue;
- if (!painted[childNodeOrdinal]) {
- painted[childNodeOrdinal] = grey;
- nodesToVisit[nodesToVisitLength++] = childNodeOrdinal;
- }
- }
+ var childNodeFlag = !flags || (flags[childNodeOrdinal] & flag);
+ // We are skipping the edges from non-page-owned nodes to page-owned nodes.
+ // Otherwise the dominators for the objects that also were retained by debugger would be affected.
+ if (nodeOrdinal !== rootNodeOrdinal && childNodeFlag && !nodeFlag)
+ continue;
+ ++stackTop;
+ stackNodes[stackTop] = childNodeOrdinal;
+ stackCurrentEdge[stackTop] = firstEdgeIndexes[childNodeOrdinal];
+ visited[childNodeOrdinal] = 1;
} else {
+ // Done with all the node children
nodeOrdinal2PostOrderIndex[nodeOrdinal] = postOrderIndex;
postOrderIndex2NodeOrdinal[postOrderIndex++] = nodeOrdinal;
- --nodesToVisitLength;
+ --stackTop;
}
}
@@ -1138,7 +1531,7 @@ WebInspector.HeapSnapshot.prototype = {
console.log("Error: Corrupted snapshot. " + (nodeCount - postOrderIndex) + " nodes are unreachable from the root:");
var dumpNode = this.rootNode();
for (var i = 0; i < nodeCount; ++i) {
- if (painted[i] !== black) {
+ if (!visited[i]) {
// Fix it by giving the node a postorder index anyway.
nodeOrdinal2PostOrderIndex[i] = postOrderIndex;
postOrderIndex2NodeOrdinal[postOrderIndex++] = i;
@@ -1282,19 +1675,16 @@ WebInspector.HeapSnapshot.prototype = {
var nodeSelfSizeOffset = this._nodeSelfSizeOffset;
var nodeFieldCount = this._nodeFieldCount;
var dominatorsTree = this._dominatorsTree;
- // Reuse now unused edge_count field to store retained size.
- var nodeRetainedSizeOffset = this._nodeRetainedSizeOffset = this._nodeEdgeCountOffset;
- delete this._nodeEdgeCountOffset;
+ var retainedSizes = this._retainedSizes = new Float64Array(nodeCount);
- for (var nodeIndex = 0, l = nodes.length; nodeIndex < l; nodeIndex += nodeFieldCount)
- nodes[nodeIndex + nodeRetainedSizeOffset] = nodes[nodeIndex + nodeSelfSizeOffset];
+ for (var nodeOrdinal = 0; nodeOrdinal < nodeCount; ++nodeOrdinal)
+ retainedSizes[nodeOrdinal] = nodes[nodeOrdinal * nodeFieldCount + nodeSelfSizeOffset];
// Propagate retained sizes for each node excluding root.
for (var postOrderIndex = 0; postOrderIndex < nodeCount - 1; ++postOrderIndex) {
var nodeOrdinal = postOrderIndex2NodeOrdinal[postOrderIndex];
- var nodeIndex = nodeOrdinal * nodeFieldCount;
- var dominatorIndex = dominatorsTree[nodeOrdinal] * nodeFieldCount;
- nodes[dominatorIndex + nodeRetainedSizeOffset] += nodes[nodeIndex + nodeRetainedSizeOffset];
+ var dominatorOrdinal = dominatorsTree[nodeOrdinal];
+ retainedSizes[dominatorOrdinal] += retainedSizes[nodeOrdinal];
}
},
@@ -1344,12 +1734,12 @@ WebInspector.HeapSnapshot.prototype = {
}
},
- _markInvisibleEdges: function()
+ _calculateFlags: function()
{
throw new Error("Not implemented");
},
- _calculateFlags: function()
+ _calculateStatistics: function()
{
throw new Error("Not implemented");
},
@@ -1359,6 +1749,11 @@ WebInspector.HeapSnapshot.prototype = {
throw new Error("Not implemented");
},
+ /**
+ * @param {string} baseSnapshotId
+ * @param {!Object.<string, !WebInspector.HeapSnapshotCommon.AggregateForDiff>} baseSnapshotAggregates
+ * @return {!Object.<string, !WebInspector.HeapSnapshotCommon.Diff>}
+ */
calculateSnapshotDiff: function(baseSnapshotId, baseSnapshotAggregates)
{
var snapshotDiff = this._snapshotDiffs[baseSnapshotId];
@@ -1373,7 +1768,7 @@ WebInspector.HeapSnapshot.prototype = {
if (diff)
snapshotDiff[className] = diff;
}
- var emptyBaseAggregate = { ids: [], indexes: [], selfSizes: [] };
+ var emptyBaseAggregate = new WebInspector.HeapSnapshotCommon.AggregateForDiff();
for (var className in aggregates) {
if (className in baseSnapshotAggregates)
continue;
@@ -1384,6 +1779,11 @@ WebInspector.HeapSnapshot.prototype = {
return snapshotDiff;
},
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.AggregateForDiff} baseAggregate
+ * @param {!WebInspector.HeapSnapshotCommon.Aggregate} aggregate
+ * @return {?WebInspector.HeapSnapshotCommon.Diff}
+ */
_calculateDiffForClass: function(baseAggregate, aggregate)
{
var baseIds = baseAggregate.ids;
@@ -1394,12 +1794,7 @@ WebInspector.HeapSnapshot.prototype = {
var i = 0, l = baseIds.length;
var j = 0, m = indexes.length;
- var diff = { addedCount: 0,
- removedCount: 0,
- addedSize: 0,
- removedSize: 0,
- deletedIndexes: [],
- addedIndexes: [] };
+ var diff = new WebInspector.HeapSnapshotCommon.Diff();
var nodeB = this.createNode(indexes[j]);
while (i < l && j < m) {
@@ -1447,6 +1842,10 @@ WebInspector.HeapSnapshot.prototype = {
return null;
},
+ /**
+ * @param {string} snapshotObjectId
+ * @return {?string}
+ */
nodeClassName: function(snapshotObjectId)
{
var node = this._nodeForSnapshotObjectId(snapshotObjectId);
@@ -1455,6 +1854,24 @@ WebInspector.HeapSnapshot.prototype = {
return null;
},
+ /**
+ * @param {string} name
+ * @return {!Array.<number>}
+ */
+ idsOfObjectsWithName: function(name)
+ {
+ var ids = [];
+ for (var it = this._allNodes(); it.hasNext(); it.next()) {
+ if (it.item().name() === name)
+ ids.push(it.item().id());
+ }
+ return ids;
+ },
+
+ /**
+ * @param {string} snapshotObjectId
+ * @return {?Array.<string>}
+ */
dominatorIdsForNode: function(snapshotObjectId)
{
var node = this._nodeForSnapshotObjectId(snapshotObjectId);
@@ -1468,44 +1885,63 @@ WebInspector.HeapSnapshot.prototype = {
return result;
},
- _parseFilter: function(filter)
- {
- if (!filter)
- return null;
- var parsedFilter = eval("(function(){return " + filter + "})()");
- return parsedFilter.bind(this);
- },
-
- createEdgesProvider: function(nodeIndex, showHiddenData)
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.HeapSnapshotEdgesProvider}
+ */
+ createEdgesProvider: function(nodeIndex)
{
var node = this.createNode(nodeIndex);
- var filter = this.containmentEdgesFilter(showHiddenData);
- return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges());
+ var filter = this.containmentEdgesFilter();
+ var indexProvider = new WebInspector.HeapSnapshotEdgeIndexProvider(this);
+ return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
},
+ /**
+ * @param {number} nodeIndex
+ * @param {?function(!WebInspector.HeapSnapshotEdge):boolean} filter
+ * @return {!WebInspector.HeapSnapshotEdgesProvider}
+ */
createEdgesProviderForTest: function(nodeIndex, filter)
{
var node = this.createNode(nodeIndex);
- return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges());
+ var indexProvider = new WebInspector.HeapSnapshotEdgeIndexProvider(this);
+ return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
},
- retainingEdgesFilter: function(showHiddenData)
+ /**
+ * @return {?function(!WebInspector.HeapSnapshotEdge):boolean}
+ */
+ retainingEdgesFilter: function()
{
return null;
},
- containmentEdgesFilter: function(showHiddenData)
+ /**
+ * @return {?function(!WebInspector.HeapSnapshotEdge):boolean}
+ */
+ containmentEdgesFilter: function()
{
return null;
},
- createRetainingEdgesProvider: function(nodeIndex, showHiddenData)
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.HeapSnapshotEdgesProvider}
+ */
+ createRetainingEdgesProvider: function(nodeIndex)
{
var node = this.createNode(nodeIndex);
- var filter = this.retainingEdgesFilter(showHiddenData);
- return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.retainers());
+ var filter = this.retainingEdgesFilter();
+ var indexProvider = new WebInspector.HeapSnapshotRetainerEdgeIndexProvider(this);
+ return new WebInspector.HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider);
},
+ /**
+ * @param {string} baseSnapshotId
+ * @param {string} className
+ * @return {!WebInspector.HeapSnapshotNodesProvider}
+ */
createAddedNodesProvider: function(baseSnapshotId, className)
{
var snapshotDiff = this._snapshotDiffs[baseSnapshotId];
@@ -1513,137 +1949,111 @@ WebInspector.HeapSnapshot.prototype = {
return new WebInspector.HeapSnapshotNodesProvider(this, null, diffForClass.addedIndexes);
},
+ /**
+ * @param {!Array.<number>} nodeIndexes
+ * @return {!WebInspector.HeapSnapshotNodesProvider}
+ */
createDeletedNodesProvider: function(nodeIndexes)
{
return new WebInspector.HeapSnapshotNodesProvider(this, null, nodeIndexes);
},
+ /**
+ * @return {?function(!WebInspector.HeapSnapshotNode):boolean}
+ */
classNodesFilter: function()
{
return null;
},
- createNodesProviderForClass: function(className, aggregatesKey)
+ /**
+ * @param {string} className
+ * @param {!WebInspector.HeapSnapshotCommon.NodeFilter} nodeFilter
+ * @return {!WebInspector.HeapSnapshotNodesProvider}
+ */
+ createNodesProviderForClass: function(className, nodeFilter)
{
- return new WebInspector.HeapSnapshotNodesProvider(this, this.classNodesFilter(), this.aggregates(false, aggregatesKey)[className].idxs);
+ return new WebInspector.HeapSnapshotNodesProvider(this, this.classNodesFilter(), this.aggregatesWithFilter(nodeFilter)[className].idxs);
},
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.HeapSnapshotNodesProvider}
+ */
createNodesProviderForDominator: function(nodeIndex)
{
var node = this.createNode(nodeIndex);
return new WebInspector.HeapSnapshotNodesProvider(this, null, this._dominatedNodesOfNode(node));
},
+ /**
+ * @return {number}
+ */
+ _maxJsNodeId: function()
+ {
+ var nodeFieldCount = this._nodeFieldCount;
+ var nodes = this._nodes;
+ var nodesLength = nodes.length;
+ var id = 0;
+ for (var nodeIndex = this._nodeIdOffset; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
+ var nextId = nodes[nodeIndex];
+ // JS objects have odd ids, skip native objects.
+ if (nextId % 2 === 0)
+ continue;
+ if (id < nextId)
+ id = nextId;
+ }
+ return id;
+ },
+
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.StaticData}
+ */
updateStaticData: function()
{
- return {nodeCount: this.nodeCount, rootNodeIndex: this._rootNodeIndex, totalSize: this.totalSize, uid: this.uid};
+ return new WebInspector.HeapSnapshotCommon.StaticData(this.nodeCount, this._rootNodeIndex, this.totalSize, this._maxJsNodeId());
}
};
/**
* @constructor
- * @param {!Array.<number>=} unfilteredIterationOrder
+ * @param {!WebInspector.HeapSnapshotItemIterator} iterator
+ * @param {!WebInspector.HeapSnapshotItemIndexProvider} indexProvider
*/
-WebInspector.HeapSnapshotFilteredOrderedIterator = function(iterator, filter, unfilteredIterationOrder)
+WebInspector.HeapSnapshotItemProvider = function(iterator, indexProvider)
{
- this._filter = filter;
this._iterator = iterator;
- this._unfilteredIterationOrder = unfilteredIterationOrder;
+ this._indexProvider = indexProvider;
+ this._isEmpty = !iterator.hasNext();
+ /** @type {?Array.<number>} */
this._iterationOrder = null;
- this._position = 0;
this._currentComparator = null;
this._sortedPrefixLength = 0;
this._sortedSuffixLength = 0;
}
-WebInspector.HeapSnapshotFilteredOrderedIterator.prototype = {
+WebInspector.HeapSnapshotItemProvider.prototype = {
_createIterationOrder: function()
{
if (this._iterationOrder)
return;
- if (this._unfilteredIterationOrder && !this._filter) {
- this._iterationOrder = this._unfilteredIterationOrder.slice(0);
- this._unfilteredIterationOrder = null;
- return;
- }
this._iterationOrder = [];
- var iterator = this._iterator;
- if (!this._unfilteredIterationOrder && !this._filter) {
- for (iterator.rewind(); iterator.hasNext(); iterator.next())
- this._iterationOrder.push(iterator.index());
- } else if (!this._unfilteredIterationOrder) {
- for (iterator.rewind(); iterator.hasNext(); iterator.next()) {
- if (this._filter(iterator.item()))
- this._iterationOrder.push(iterator.index());
- }
- } else {
- var order = this._unfilteredIterationOrder.constructor === Array ?
- this._unfilteredIterationOrder : this._unfilteredIterationOrder.slice(0);
- for (var i = 0, l = order.length; i < l; ++i) {
- iterator.setIndex(order[i]);
- if (this._filter(iterator.item()))
- this._iterationOrder.push(iterator.index());
- }
- this._unfilteredIterationOrder = null;
- }
- },
-
- rewind: function()
- {
- this._position = 0;
- },
-
- hasNext: function()
- {
- return this._position < this._iterationOrder.length;
+ for (var iterator = this._iterator; iterator.hasNext(); iterator.next())
+ this._iterationOrder.push(iterator.item().itemIndex());
},
+ /**
+ * @return {boolean}
+ */
isEmpty: function()
{
- if (this._iterationOrder)
- return !this._iterationOrder.length;
- if (this._unfilteredIterationOrder && !this._filter)
- return !this._unfilteredIterationOrder.length;
- var iterator = this._iterator;
- if (!this._unfilteredIterationOrder && !this._filter) {
- iterator.rewind();
- return !iterator.hasNext();
- } else if (!this._unfilteredIterationOrder) {
- for (iterator.rewind(); iterator.hasNext(); iterator.next())
- if (this._filter(iterator.item()))
- return false;
- } else {
- var order = this._unfilteredIterationOrder.constructor === Array ?
- this._unfilteredIterationOrder : this._unfilteredIterationOrder.slice(0);
- for (var i = 0, l = order.length; i < l; ++i) {
- iterator.setIndex(order[i]);
- if (this._filter(iterator.item()))
- return false;
- }
- }
- return true;
- },
-
- item: function()
- {
- this._iterator.setIndex(this._iterationOrder[this._position]);
- return this._iterator.item();
- },
-
- get length()
- {
- this._createIterationOrder();
- return this._iterationOrder.length;
- },
-
- next: function()
- {
- ++this._position;
+ return this._isEmpty;
},
/**
* @param {number} begin
* @param {number} end
+ * @return {!WebInspector.HeapSnapshotCommon.ItemsRange}
*/
serializeItemsRange: function(begin, end)
{
@@ -1659,30 +2069,16 @@ WebInspector.HeapSnapshotFilteredOrderedIterator.prototype = {
if (end >= this._iterationOrder.length - this._sortedSuffixLength)
this._sortedSuffixLength = this._iterationOrder.length - begin;
}
-
- this._position = begin;
- var startPosition = this._position;
+ var position = begin;
var count = end - begin;
var result = new Array(count);
- for (var i = 0 ; i < count && this.hasNext(); ++i, this.next())
- result[i] = this.item().serialize();
- result.length = i;
- result.totalLength = this._iterationOrder.length;
-
- result.startPosition = startPosition;
- result.endPosition = this._position;
- return result;
- },
-
- sortAll: function()
- {
- this._createIterationOrder();
- if (this._sortedPrefixLength + this._sortedSuffixLength >= this._iterationOrder.length)
- return;
- this.sort(this._currentComparator, this._sortedPrefixLength, this._iterationOrder.length - 1 - this._sortedSuffixLength,
- this._sortedPrefixLength, this._iterationOrder.length - 1 - this._sortedSuffixLength);
- this._sortedPrefixLength = this._iterationOrder.length;
- this._sortedSuffixLength = 0;
+ var iterator = this._iterator;
+ for (var i = 0 ; i < count; ++i) {
+ var itemIndex = this._iterationOrder[position++];
+ var item = this._indexProvider.itemForIndex(itemIndex);
+ result[i] = item.serialize();
+ }
+ return new WebInspector.HeapSnapshotCommon.ItemsRange(begin, end, this._iterationOrder.length, result);
},
sortAndRewind: function(comparator)
@@ -1690,26 +2086,32 @@ WebInspector.HeapSnapshotFilteredOrderedIterator.prototype = {
this._currentComparator = comparator;
this._sortedPrefixLength = 0;
this._sortedSuffixLength = 0;
- this.rewind();
}
}
-WebInspector.HeapSnapshotFilteredOrderedIterator.prototype.createComparator = function(fieldNames)
-{
- return {fieldName1: fieldNames[0], ascending1: fieldNames[1], fieldName2: fieldNames[2], ascending2: fieldNames[3]};
-}
-
/**
* @constructor
- * @extends {WebInspector.HeapSnapshotFilteredOrderedIterator}
+ * @extends {WebInspector.HeapSnapshotItemProvider}
+ * @param {!WebInspector.HeapSnapshot} snapshot
+ * @param {?function(!WebInspector.HeapSnapshotEdge):boolean} filter
+ * @param {!WebInspector.HeapSnapshotEdgeIterator} edgesIter
+ * @param {!WebInspector.HeapSnapshotItemIndexProvider} indexProvider
*/
-WebInspector.HeapSnapshotEdgesProvider = function(snapshot, filter, edgesIter)
+WebInspector.HeapSnapshotEdgesProvider = function(snapshot, filter, edgesIter, indexProvider)
{
this.snapshot = snapshot;
- WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, edgesIter, filter);
+ var iter = filter ? new WebInspector.HeapSnapshotFilteredIterator(edgesIter, /** @type {function(!WebInspector.HeapSnapshotItem):boolean} */ (filter)) : edgesIter;
+ WebInspector.HeapSnapshotItemProvider.call(this, iter, indexProvider);
}
WebInspector.HeapSnapshotEdgesProvider.prototype = {
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
+ * @param {number} leftBound
+ * @param {number} rightBound
+ * @param {number} windowLeft
+ * @param {number} windowRight
+ */
sort: function(comparator, leftBound, rightBound, windowLeft, windowRight)
{
var fieldName1 = comparator.fieldName1;
@@ -1784,72 +2186,108 @@ WebInspector.HeapSnapshotEdgesProvider.prototype = {
this._iterationOrder.sortRange(compareNodeAndNode, leftBound, rightBound, windowLeft, windowRight);
},
- __proto__: WebInspector.HeapSnapshotFilteredOrderedIterator.prototype
+ __proto__: WebInspector.HeapSnapshotItemProvider.prototype
}
/**
* @constructor
- * @extends {WebInspector.HeapSnapshotFilteredOrderedIterator}
- * @param {!Array.<number>=} nodeIndexes
+ * @extends {WebInspector.HeapSnapshotItemProvider}
+ * @param {!WebInspector.HeapSnapshot} snapshot
+ * @param {?function(!WebInspector.HeapSnapshotNode):boolean} filter
+ * @param {(!Array.<number>|!Uint32Array)} nodeIndexes
*/
WebInspector.HeapSnapshotNodesProvider = function(snapshot, filter, nodeIndexes)
{
this.snapshot = snapshot;
- WebInspector.HeapSnapshotFilteredOrderedIterator.call(this, snapshot._allNodes(), filter, nodeIndexes);
+ var indexProvider = new WebInspector.HeapSnapshotNodeIndexProvider(snapshot);
+ var it = new WebInspector.HeapSnapshotIndexRangeIterator(indexProvider, nodeIndexes);
+
+ if (filter)
+ it = new WebInspector.HeapSnapshotFilteredIterator(it, /** @type {function(!WebInspector.HeapSnapshotItem):boolean} */ (filter));
+ WebInspector.HeapSnapshotItemProvider.call(this, it, indexProvider);
}
WebInspector.HeapSnapshotNodesProvider.prototype = {
+ /**
+ * @param {string} snapshotObjectId
+ * @return {number}
+ */
nodePosition: function(snapshotObjectId)
{
this._createIterationOrder();
- if (this.isEmpty())
- return -1;
- this.sortAll();
-
var node = this.snapshot.createNode();
for (var i = 0; i < this._iterationOrder.length; i++) {
node.nodeIndex = this._iterationOrder[i];
if (node.id() === snapshotObjectId)
- return i;
+ break;
+ }
+ if (i === this._iterationOrder.length)
+ return -1;
+ var targetNodeIndex = this._iterationOrder[i];
+ var smallerCount = 0;
+ var compare = this._buildCompareFunction(this._currentComparator);
+ for (var i = 0; i < this._iterationOrder.length; i++) {
+ if (compare(this._iterationOrder[i], targetNodeIndex) < 0)
+ ++smallerCount;
}
- return -1;
+ return smallerCount;
},
- sort: function(comparator, leftBound, rightBound, windowLeft, windowRight)
+ /**
+ * @return {function(number,number):number}
+ */
+ _buildCompareFunction: function(comparator)
{
- var fieldName1 = comparator.fieldName1;
- var fieldName2 = comparator.fieldName2;
- var ascending1 = comparator.ascending1;
- var ascending2 = comparator.ascending2;
-
var nodeA = this.snapshot.createNode();
var nodeB = this.snapshot.createNode();
+ var fieldAccessor1 = nodeA[comparator.fieldName1];
+ var fieldAccessor2 = nodeA[comparator.fieldName2];
+ var ascending1 = comparator.ascending1 ? 1 : -1;
+ var ascending2 = comparator.ascending2 ? 1 : -1;
- function sortByNodeField(fieldName, ascending)
+ /**
+ * @param {function():*} fieldAccessor
+ * @param {number} ascending
+ * @return {number}
+ */
+ function sortByNodeField(fieldAccessor, ascending)
{
- var valueOrFunctionA = nodeA[fieldName];
- var valueA = typeof valueOrFunctionA !== "function" ? valueOrFunctionA : valueOrFunctionA.call(nodeA);
- var valueOrFunctionB = nodeB[fieldName];
- var valueB = typeof valueOrFunctionB !== "function" ? valueOrFunctionB : valueOrFunctionB.call(nodeB);
- var result = valueA < valueB ? -1 : (valueA > valueB ? 1 : 0);
- return ascending ? result : -result;
+ var valueA = fieldAccessor.call(nodeA);
+ var valueB = fieldAccessor.call(nodeB);
+ return valueA < valueB ? -ascending : (valueA > valueB ? ascending : 0);
}
- function sortByComparator(indexA, indexB) {
+ /**
+ * @param {number} indexA
+ * @param {number} indexB
+ * @return {number}
+ */
+ function sortByComparator(indexA, indexB)
+ {
nodeA.nodeIndex = indexA;
nodeB.nodeIndex = indexB;
- var result = sortByNodeField(fieldName1, ascending1);
+ var result = sortByNodeField(fieldAccessor1, ascending1);
if (result === 0)
- result = sortByNodeField(fieldName2, ascending2);
- if (result === 0)
- return indexA - indexB;
- return result;
+ result = sortByNodeField(fieldAccessor2, ascending2);
+ return result || indexA - indexB;
}
- this._iterationOrder.sortRange(sortByComparator, leftBound, rightBound, windowLeft, windowRight);
+ return sortByComparator;
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotCommon.ComparatorConfig} comparator
+ * @param {number} leftBound
+ * @param {number} rightBound
+ * @param {number} windowLeft
+ * @param {number} windowRight
+ */
+ sort: function(comparator, leftBound, rightBound, windowLeft, windowRight)
+ {
+ this._iterationOrder.sortRange(this._buildCompareFunction(comparator), leftBound, rightBound, windowLeft, windowRight);
},
- __proto__: WebInspector.HeapSnapshotFilteredOrderedIterator.prototype
+ __proto__: WebInspector.HeapSnapshotItemProvider.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotLoader.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotLoader.js
index 2f5aae0e68e..8285fa8ccf5 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotLoader.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotLoader.js
@@ -31,7 +31,6 @@
/**
* @constructor
* @param {!WebInspector.HeapSnapshotWorkerDispatcher} dispatcher
- * @implements {WebInspector.OutputStream}
*/
WebInspector.HeapSnapshotLoader = function(dispatcher)
{
@@ -58,11 +57,14 @@ WebInspector.HeapSnapshotLoader.prototype = {
this._parseStringsArray();
},
- buildSnapshot: function(constructorName)
+ /**
+ * @param {boolean} showHiddenData
+ * @return {!WebInspector.JSHeapSnapshot}
+ */
+ buildSnapshot: function(showHiddenData)
{
this._progress.updateStatus("Processing snapshot\u2026");
- var constructor = WebInspector[constructorName];
- var result = new constructor(this._snapshot, this._progress);
+ var result = new WebInspector.JSHeapSnapshot(this._snapshot, this._progress, showHiddenData);
this._reset();
return result;
},
@@ -134,7 +136,7 @@ WebInspector.HeapSnapshotLoader.prototype = {
break;
}
case "parse-snapshot-info": {
- var closingBracketIndex = WebInspector.findBalancedCurlyBrackets(this._json);
+ var closingBracketIndex = WebInspector.TextUtils.findBalancedCurlyBrackets(this._json);
if (closingBracketIndex === -1)
return;
this._snapshot.snapshot = /** @type {!HeapSnapshotHeader} */ (JSON.parse(this._json.slice(0, closingBracketIndex)));
@@ -191,7 +193,8 @@ WebInspector.HeapSnapshotLoader.prototype = {
return;
this._snapshot.edges = this._array;
this._array = null;
- if (WebInspector.HeapSnapshot.enableAllocationProfiler)
+ // If there is allocation info parse it, otherwise jump straight to strings.
+ if (this._snapshot.snapshot.trace_function_count)
this._state = "find-trace-function-infos";
else
this._state = "find-strings";
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorker.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorker.js
index aadd6cf2216..d187e2dfac9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorker.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorker.js
@@ -29,16 +29,16 @@
*/
WebInspector = {};
-WebInspector.UIString = function(s) { return s; };
+importScripts("../../common/UIString.js");
+importScripts("../../common/utilities.js");
+importScripts("../../ui/TextUtils.js");
+importScripts("../HeapSnapshotCommon.js");
importScripts("AllocationProfile.js");
importScripts("HeapSnapshot.js");
importScripts("HeapSnapshotLoader.js");
importScripts("HeapSnapshotWorkerDispatcher.js");
importScripts("JSHeapSnapshot.js");
-importScripts("FileUtils.js");
-importScripts("UIString.js");
-importScripts("utilities.js");
function postMessageWrapper(message)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorkerDispatcher.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
index 3c17c89b6f3..4f3daa763ff 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/HeapSnapshotWorkerDispatcher.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.js
@@ -59,7 +59,7 @@ WebInspector.HeapSnapshotWorkerDispatcher.prototype = {
dispatchMessage: function(event)
{
- var data = event.data;
+ var data = /** @type {!WebInspector.HeapSnapshotCommon.WorkerCommand } */(event.data);
var response = {callId: data.callId};
try {
switch (data.disposition) {
@@ -91,6 +91,14 @@ WebInspector.HeapSnapshotWorkerDispatcher.prototype = {
response.result = object[data.methodName].apply(object, data.methodArguments);
break;
}
+ case "evaluateForTest": {
+ try {
+ response.result = eval(data.source)
+ } catch (e) {
+ response.result = e.toString();
+ }
+ break;
+ }
}
} catch (e) {
response.error = e.toString();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/JSHeapSnapshot.js b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/JSHeapSnapshot.js
index fc7a6276a4d..f1c592ab7e6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/JSHeapSnapshot.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/heap_snapshot_worker/JSHeapSnapshot.js
@@ -30,10 +30,12 @@
/**
* @constructor
- * @param {!WebInspector.HeapSnapshotProgress} progress
* @extends {WebInspector.HeapSnapshot}
+ * @param {!Object} profile
+ * @param {!WebInspector.HeapSnapshotProgress} progress
+ * @param {boolean} showHiddenData
*/
-WebInspector.JSHeapSnapshot = function(profile, progress)
+WebInspector.JSHeapSnapshot = function(profile, progress, showHiddenData)
{
this._nodeFlags = { // bit flags
canBeQueried: 1,
@@ -44,53 +46,62 @@ WebInspector.JSHeapSnapshot = function(profile, progress)
visitedMarker: 0x10000 // bits: 1,0000,0000,0000,0000
};
this._lazyStringCache = { };
- WebInspector.HeapSnapshot.call(this, profile, progress);
+ WebInspector.HeapSnapshot.call(this, profile, progress, showHiddenData);
}
WebInspector.JSHeapSnapshot.prototype = {
- maxJsNodeId: function()
- {
- var nodeFieldCount = this._nodeFieldCount;
- var nodes = this._nodes;
- var nodesLength = nodes.length;
- var id = 0;
- for (var nodeIndex = this._nodeIdOffset; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
- var nextId = nodes[nodeIndex];
- // JS objects have odd ids, skip native objects.
- if (nextId % 2 === 0)
- continue;
- if (id < nodes[nodeIndex])
- id = nodes[nodeIndex];
- }
- return id;
- },
-
+ /**
+ * @param {number} nodeIndex
+ * @return {!WebInspector.JSHeapSnapshotNode}
+ */
createNode: function(nodeIndex)
{
return new WebInspector.JSHeapSnapshotNode(this, nodeIndex);
},
- createEdge: function(edges, edgeIndex)
+ /**
+ * @override
+ * @param {number} edgeIndex
+ * @return {!WebInspector.JSHeapSnapshotEdge}
+ */
+ createEdge: function(edgeIndex)
{
- return new WebInspector.JSHeapSnapshotEdge(this, edges, edgeIndex);
+ return new WebInspector.JSHeapSnapshotEdge(this, edgeIndex);
},
- createRetainingEdge: function(retainedNodeIndex, retainerIndex)
+ /**
+ * @override
+ * @param {number} retainerIndex
+ * @return {!WebInspector.JSHeapSnapshotRetainerEdge}
+ */
+ createRetainingEdge: function(retainerIndex)
{
- return new WebInspector.JSHeapSnapshotRetainerEdge(this, retainedNodeIndex, retainerIndex);
+ return new WebInspector.JSHeapSnapshotRetainerEdge(this, retainerIndex);
},
+ /**
+ * @override
+ * @return {?function(!WebInspector.JSHeapSnapshotNode):boolean}
+ */
classNodesFilter: function()
{
+ /**
+ * @param {!WebInspector.JSHeapSnapshotNode} node
+ * @return {boolean}
+ */
function filter(node)
{
return node.isUserObject();
}
- return filter;
+ return this._showHiddenData ? null : filter;
},
- containmentEdgesFilter: function(showHiddenData)
+ /**
+ * @return {function(!WebInspector.HeapSnapshotEdge):boolean}
+ */
+ containmentEdgesFilter: function()
{
+ var showHiddenData = this._showHiddenData;
function filter(edge) {
if (edge.isInvisible())
return false;
@@ -101,9 +112,12 @@ WebInspector.JSHeapSnapshot.prototype = {
return filter;
},
- retainingEdgesFilter: function(showHiddenData)
+ /**
+ * @return {function(!WebInspector.HeapSnapshotEdge):boolean}
+ */
+ retainingEdgesFilter: function()
{
- var containmentEdgesFilter = this.containmentEdgesFilter(showHiddenData);
+ var containmentEdgesFilter = this.containmentEdgesFilter();
function filter(edge)
{
return containmentEdgesFilter(edge) && !edge.node().isRoot() && !edge.isWeak();
@@ -117,33 +131,6 @@ WebInspector.JSHeapSnapshot.prototype = {
delete this._flags;
},
- _markInvisibleEdges: function()
- {
- // Mark hidden edges of global objects as invisible.
- // FIXME: This is a temporary measure. Normally, we should
- // really hide all hidden nodes.
- for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
- var edge = iter.edge;
- if (!edge.isShortcut())
- continue;
- var node = edge.node();
- var propNames = {};
- for (var innerIter = node.edges(); innerIter.hasNext(); innerIter.next()) {
- var globalObjEdge = innerIter.edge;
- if (globalObjEdge.isShortcut())
- propNames[globalObjEdge._nameOrIndex()] = true;
- }
- for (innerIter.rewind(); innerIter.hasNext(); innerIter.next()) {
- var globalObjEdge = innerIter.edge;
- if (!globalObjEdge.isShortcut()
- && globalObjEdge.node().isHidden()
- && globalObjEdge._hasStringName()
- && (globalObjEdge._nameOrIndex() in propNames))
- this._containmentEdges[globalObjEdge._edges._start + globalObjEdge.edgeIndex + this._edgeTypeOffset] = this._edgeInvisibleType;
- }
- }
- },
-
_calculateFlags: function()
{
this._flags = new Uint32Array(this.nodeCount);
@@ -169,7 +156,7 @@ WebInspector.JSHeapSnapshot.prototype = {
{
/**
* @param {!WebInspector.HeapSnapshotNode} node
- * @param {!string} name
+ * @param {string} name
* @return {?WebInspector.HeapSnapshotNode}
*/
function getChildNodeByName(node, name)
@@ -182,21 +169,6 @@ WebInspector.JSHeapSnapshot.prototype = {
return null;
}
- /**
- * @param {!WebInspector.HeapSnapshotNode} node
- * @param {!string} name
- * @return {?WebInspector.HeapSnapshotNode}
- */
- function getChildNodeByLinkName(node, name)
- {
- for (var iter = node.edges(); iter.hasNext(); iter.next()) {
- var edge = iter.edge;
- if (edge.name() === name)
- return edge.node();
- }
- return null;
- }
-
var visitedNodes = {};
/**
* @param {!WebInspector.HeapSnapshotNode} node
@@ -217,15 +189,8 @@ WebInspector.JSHeapSnapshot.prototype = {
if (userRootsOnly) {
for (var iter = this.rootNode().edges(); iter.hasNext(); iter.next()) {
var node = iter.edge.node();
- if (node.isDocumentDOMTreesRoot())
+ if (this._isUserRoot(node))
doAction(node);
- else if (node.isUserRoot()) {
- var nativeContextNode = getChildNodeByLinkName(node, "native_context");
- if (nativeContextNode)
- doAction(nativeContextNode);
- else
- doAction(node);
- }
}
} else {
for (var iter = gcRoots.edges(); iter.hasNext(); iter.next()) {
@@ -239,9 +204,12 @@ WebInspector.JSHeapSnapshot.prototype = {
}
},
+ /**
+ * @return {?{map: !Uint32Array, flag: number}}
+ */
userObjectsMapAndFlag: function()
{
- return {
+ return this._showHiddenData ? null : {
map: this._flags,
flag: this._nodeFlags.pageObject
};
@@ -386,6 +354,84 @@ WebInspector.JSHeapSnapshot.prototype = {
}
},
+ _calculateStatistics: function()
+ {
+ var nodeFieldCount = this._nodeFieldCount;
+ var nodes = this._nodes;
+ var nodesLength = nodes.length;
+ var nodeTypeOffset = this._nodeTypeOffset;
+ var nodeSizeOffset = this._nodeSelfSizeOffset;;
+ var nodeNativeType = this._nodeNativeType;
+ var nodeCodeType = this._nodeCodeType;
+ var nodeConsStringType = this._nodeConsStringType;
+ var nodeSlicedStringType = this._nodeSlicedStringType;
+ var sizeNative = 0;
+ var sizeCode = 0;
+ var sizeStrings = 0;
+ var sizeJSArrays = 0;
+ var node = this.rootNode();
+ for (var nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
+ node.nodeIndex = nodeIndex;
+ var nodeType = nodes[nodeIndex + nodeTypeOffset];
+ var nodeSize = nodes[nodeIndex + nodeSizeOffset];
+ if (nodeType === nodeNativeType)
+ sizeNative += nodeSize;
+ else if (nodeType === nodeCodeType)
+ sizeCode += nodeSize;
+ else if (nodeType === nodeConsStringType || nodeType === nodeSlicedStringType || node.type() === "string")
+ sizeStrings += nodeSize;
+ else if (node.name() === "Array")
+ sizeJSArrays += this._calculateArraySize(node);
+ }
+ this._statistics = new WebInspector.HeapSnapshotCommon.Statistics();
+ this._statistics.total = this.totalSize;
+ this._statistics.v8heap = this.totalSize - sizeNative;
+ this._statistics.native = sizeNative;
+ this._statistics.code = sizeCode;
+ this._statistics.jsArrays = sizeJSArrays;
+ this._statistics.strings = sizeStrings;
+ },
+
+ /**
+ * @param {!WebInspector.HeapSnapshotNode} node
+ * @return {number}
+ */
+ _calculateArraySize: function(node)
+ {
+ var size = node.selfSize();
+ var beginEdgeIndex = node._edgeIndexesStart();
+ var endEdgeIndex = node._edgeIndexesEnd();
+ var containmentEdges = this._containmentEdges;
+ var strings = this._strings;
+ var edgeToNodeOffset = this._edgeToNodeOffset;
+ var edgeTypeOffset = this._edgeTypeOffset;
+ var edgeNameOffset = this._edgeNameOffset;
+ var edgeFieldsCount = this._edgeFieldsCount;
+ var edgeInternalType = this._edgeInternalType;
+ for (var edgeIndex = beginEdgeIndex; edgeIndex < endEdgeIndex; edgeIndex += edgeFieldsCount) {
+ var edgeType = containmentEdges[edgeIndex + edgeTypeOffset];
+ if (edgeType !== edgeInternalType)
+ continue;
+ var edgeName = strings[containmentEdges[edgeIndex + edgeNameOffset]];
+ if (edgeName !== "elements")
+ continue;
+ var elementsNodeIndex = containmentEdges[edgeIndex + edgeToNodeOffset];
+ node.nodeIndex = elementsNodeIndex;
+ if (node.retainersCount() === 1)
+ size += node.selfSize();
+ break;
+ }
+ return size;
+ },
+
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.Statistics}
+ */
+ getStatistics: function()
+ {
+ return this._statistics;
+ },
+
__proto__: WebInspector.HeapSnapshot.prototype
};
@@ -401,12 +447,18 @@ WebInspector.JSHeapSnapshotNode = function(snapshot, nodeIndex)
}
WebInspector.JSHeapSnapshotNode.prototype = {
+ /**
+ * @return {boolean}
+ */
canBeQueried: function()
{
var flags = this._snapshot._flagsOfNode(this);
return !!(flags & this._snapshot._nodeFlags.canBeQueried);
},
+ /**
+ * @return {boolean}
+ */
isUserObject: function()
{
var flags = this._snapshot._flagsOfNode(this);
@@ -414,6 +466,9 @@ WebInspector.JSHeapSnapshotNode.prototype = {
},
+ /**
+ * @return {string}
+ */
name: function() {
var snapshot = this._snapshot;
if (this._type() === snapshot._nodeConsStringType) {
@@ -474,6 +529,9 @@ WebInspector.JSHeapSnapshotNode.prototype = {
return name;
},
+ /**
+ * @return {string}
+ */
className: function()
{
var type = this.type();
@@ -490,6 +548,9 @@ WebInspector.JSHeapSnapshotNode.prototype = {
}
},
+ /**
+ * @return {number}
+ */
classIndex: function()
{
var snapshot = this._snapshot;
@@ -500,17 +561,26 @@ WebInspector.JSHeapSnapshotNode.prototype = {
return -1 - type;
},
+ /**
+ * @return {number}
+ */
id: function()
{
var snapshot = this._snapshot;
return snapshot._nodes[this.nodeIndex + snapshot._nodeIdOffset];
},
+ /**
+ * @return {boolean}
+ */
isHidden: function()
{
return this._type() === this._snapshot._nodeHiddenType;
},
+ /**
+ * @return {boolean}
+ */
isSynthetic: function()
{
return this._type() === this._snapshot._nodeSyntheticType;
@@ -532,6 +602,9 @@ WebInspector.JSHeapSnapshotNode.prototype = {
return this.isSynthetic() && this.name() === "(Document DOM trees)";
},
+ /**
+ * @return {!WebInspector.HeapSnapshotCommon.Node}
+ */
serialize: function()
{
var result = WebInspector.HeapSnapshotNode.prototype.serialize.call(this);
@@ -550,20 +623,26 @@ WebInspector.JSHeapSnapshotNode.prototype = {
* @constructor
* @extends {WebInspector.HeapSnapshotEdge}
* @param {!WebInspector.JSHeapSnapshot} snapshot
- * @param {!Array.<number>} edges
* @param {number=} edgeIndex
*/
-WebInspector.JSHeapSnapshotEdge = function(snapshot, edges, edgeIndex)
+WebInspector.JSHeapSnapshotEdge = function(snapshot, edgeIndex)
{
- WebInspector.HeapSnapshotEdge.call(this, snapshot, edges, edgeIndex);
+ WebInspector.HeapSnapshotEdge.call(this, snapshot, edgeIndex);
}
WebInspector.JSHeapSnapshotEdge.prototype = {
+ /**
+ * @return {!WebInspector.JSHeapSnapshotEdge}
+ */
clone: function()
{
- return new WebInspector.JSHeapSnapshotEdge(this._snapshot, this._edges, this.edgeIndex);
+ var snapshot = /** @type {!WebInspector.JSHeapSnapshot} */ (this._snapshot);
+ return new WebInspector.JSHeapSnapshotEdge(snapshot, this.edgeIndex);
},
+ /**
+ * @return {boolean}
+ */
hasStringName: function()
{
if (!this.isShortcut())
@@ -571,36 +650,57 @@ WebInspector.JSHeapSnapshotEdge.prototype = {
return isNaN(parseInt(this._name(), 10));
},
+ /**
+ * @return {boolean}
+ */
isElement: function()
{
return this._type() === this._snapshot._edgeElementType;
},
+ /**
+ * @return {boolean}
+ */
isHidden: function()
{
return this._type() === this._snapshot._edgeHiddenType;
},
+ /**
+ * @return {boolean}
+ */
isWeak: function()
{
return this._type() === this._snapshot._edgeWeakType;
},
+ /**
+ * @return {boolean}
+ */
isInternal: function()
{
return this._type() === this._snapshot._edgeInternalType;
},
+ /**
+ * @return {boolean}
+ */
isInvisible: function()
{
return this._type() === this._snapshot._edgeInvisibleType;
},
+ /**
+ * @return {boolean}
+ */
isShortcut: function()
{
return this._type() === this._snapshot._edgeShortcutType;
},
+ /**
+ * @return {string}
+ */
name: function()
{
if (!this.isShortcut())
@@ -609,6 +709,9 @@ WebInspector.JSHeapSnapshotEdge.prototype = {
return isNaN(numName) ? this._name() : numName;
},
+ /**
+ * @return {string}
+ */
toString: function()
{
var name = this.name();
@@ -633,7 +736,7 @@ WebInspector.JSHeapSnapshotEdge.prototype = {
_hasStringName: function()
{
- return !this.isElement() && !this.isHidden() && !this.isWeak();
+ return !this.isElement() && !this.isHidden();
},
_name: function()
@@ -643,12 +746,12 @@ WebInspector.JSHeapSnapshotEdge.prototype = {
_nameOrIndex: function()
{
- return this._edges.item(this.edgeIndex + this._snapshot._edgeNameOffset);
+ return this._edges[this.edgeIndex + this._snapshot._edgeNameOffset];
},
_type: function()
{
- return this._edges.item(this.edgeIndex + this._snapshot._edgeTypeOffset);
+ return this._edges[this.edgeIndex + this._snapshot._edgeTypeOffset];
},
__proto__: WebInspector.HeapSnapshotEdge.prototype
@@ -659,38 +762,58 @@ WebInspector.JSHeapSnapshotEdge.prototype = {
* @constructor
* @extends {WebInspector.HeapSnapshotRetainerEdge}
* @param {!WebInspector.JSHeapSnapshot} snapshot
+ * @param {number} retainerIndex
*/
-WebInspector.JSHeapSnapshotRetainerEdge = function(snapshot, retainedNodeIndex, retainerIndex)
+WebInspector.JSHeapSnapshotRetainerEdge = function(snapshot, retainerIndex)
{
- WebInspector.HeapSnapshotRetainerEdge.call(this, snapshot, retainedNodeIndex, retainerIndex);
+ WebInspector.HeapSnapshotRetainerEdge.call(this, snapshot, retainerIndex);
}
WebInspector.JSHeapSnapshotRetainerEdge.prototype = {
+ /**
+ * @return {!WebInspector.JSHeapSnapshotRetainerEdge}
+ */
clone: function()
{
- return new WebInspector.JSHeapSnapshotRetainerEdge(this._snapshot, this._retainedNodeIndex, this.retainerIndex());
+ var snapshot = /** @type {!WebInspector.JSHeapSnapshot} */ (this._snapshot);
+ return new WebInspector.JSHeapSnapshotRetainerEdge(snapshot, this.retainerIndex());
},
+ /**
+ * @return {boolean}
+ */
isHidden: function()
{
return this._edge().isHidden();
},
+ /**
+ * @return {boolean}
+ */
isInternal: function()
{
return this._edge().isInternal();
},
+ /**
+ * @return {boolean}
+ */
isInvisible: function()
{
return this._edge().isInvisible();
},
+ /**
+ * @return {boolean}
+ */
isShortcut: function()
{
return this._edge().isShortcut();
},
+ /**
+ * @return {boolean}
+ */
isWeak: function()
{
return this._edge().isWeak();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/profiler/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/module.json
new file mode 100644
index 00000000000..37a56799c4d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profiler/module.json
@@ -0,0 +1,31 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "profiles",
+ "title": "Profiles",
+ "order": 4,
+ "className": "WebInspector.ProfilesPanel"
+ },
+ {
+ "type": "@WebInspector.ContextMenu.Provider",
+ "contextTypes": ["WebInspector.RemoteObject"],
+ "className": "WebInspector.ProfilesPanel.ContextMenuProvider"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Profiler",
+ "title": "Show advanced heap snapshot properties",
+ "settingName": "showAdvancedHeapSnapshotProperties",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Profiler",
+ "title": "High resolution CPU profiling",
+ "settingName": "highResolutionCpuProfiling",
+ "settingType": "checkbox"
+ }
+ ],
+ "scripts": [ "ProfilesPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/profilesPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/profilesPanel.css
index fa321fb1f81..185ef15e247 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/profilesPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/profilesPanel.css
@@ -34,6 +34,37 @@
position: relative;
}
+.profile-view .data-grid table.data {
+ background: white;
+}
+
+.profile-view .data-grid tr:not(.filler):hover td {
+ background-color: rgba(0, 0, 0, 0.1);
+}
+
+.profile-view .data-grid td.numeric-column {
+ text-align: right;
+}
+
+.profile-view .data-grid div.profile-multiple-values {
+ float: right;
+}
+
+.profile-view .data-grid span.percent-column {
+ color: #999;
+ width: 48px;
+ display: inline-block;
+}
+
+.profile-view .data-grid tr.selected span {
+ color: inherit;
+}
+
+.profiles.panel .status-bar {
+ border-bottom: 1px solid rgb(202, 202, 202);
+ border-top: none;
+}
+
.profiles-status-bar {
background-color: rgb(236, 236, 236);
flex: 0 0 23px;
@@ -49,6 +80,11 @@
flex: auto;
}
+.profiles-sidebar-tree-box > ol {
+ overflow: auto;
+ flex: auto;
+}
+
.profile-sidebar-tree-item .icon {
content: url(Images/profileIcon.png);
}
@@ -61,7 +97,17 @@
content: url(Images/profileGroupIcon.png);
}
-.profile-view {
+.sidebar-tree-item .title-container > .save-link {
+ text-decoration: underline;
+ margin-left: auto;
+ display: none;
+}
+
+.sidebar-tree-item.selected .title-container > .save-link {
+ display: block;
+}
+
+.cpu-profile-view {
display: none;
overflow: hidden;
position: absolute;
@@ -71,58 +117,37 @@
bottom: 0;
}
-.profile-view.visible {
- display: block;
+.cpu-profile-view.visible {
+ display: flex;
}
-.profile-view .data-grid {
+.cpu-profile-view .data-grid {
border: none;
- height: 100%;
-}
-
-.profile-view .data-grid th.average-column {
- text-align: center;
-}
-
-.profile-view .data-grid td.average-column {
- text-align: right;
+ flex: auto;
}
-.profile-view .data-grid th.self-column {
+.cpu-profile-view .data-grid th.self-column {
text-align: center;
}
-.profile-view .data-grid td.self-column {
- text-align: right;
-}
-
-.profile-view .data-grid th.total-column {
- text-align: center;
-}
-
-.profile-view .data-grid td.total-column {
- text-align: right;
-}
-
-.profile-view .data-grid .calls-column {
+.cpu-profile-view .data-grid th.total-column {
text-align: center;
}
.profile-node-file {
float: right;
color: gray;
- margin-top: -1px;
}
.profile-warn-marker {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
- background-position: -201px -105px;
- padding-left: 12px;
+ background-size: 320px 144px;
+ background-position: -202px -107px;
width: 10px;
height: 10px;
vertical-align: -1px;
margin-right: 2px;
+ display: inline-block;
}
.data-grid tr.selected .profile-node-file {
@@ -133,10 +158,6 @@
color: white;
}
-.percent-time-status-bar-item .glyph {
- -webkit-mask-position: -192px -24px;
-}
-
.focus-profile-node-status-bar-item .glyph {
-webkit-mask-position: -96px 0;
}
@@ -149,10 +170,6 @@
-webkit-mask-position: 0 0;
}
-.garbage-collect-status-bar-item .glyph {
- -webkit-mask-position: -128px -24px;
-}
-
.profile-launcher-view-content {
padding: 0 16px;
text-align: left;
@@ -160,6 +177,11 @@
.control-profiling {
-webkit-align-self: flex-start;
+ margin-right: 50px;
+}
+
+.profile-launcher-view > .profile-launcher-view-content > .load-profile {
+ margin-left: 20px;
}
.profile-launcher-view-content h1 {
@@ -182,11 +204,6 @@
margin-left: 22px;
}
-.panel-enabler-view.profile-launcher-view button:not(.status-bar-item) {
- color: rgb(6, 6, 6);
- margin: 0 0 16px;
-}
-
.profile-launcher-view-content button.running:not(.status-bar-item) {
color: red;
}
@@ -207,6 +224,7 @@ body.inactive .profile-launcher-view-content button.running:not(.status-bar-item
.profile-canvas-decoration .warning-icon-small {
margin-right: 4px;
}
+
.profile-canvas-decoration {
color: red;
margin: -14px 0 13px 22px;
@@ -216,3 +234,12 @@ body.inactive .profile-launcher-view-content button.running:not(.status-bar-item
.profile-canvas-decoration button {
margin: 0 0 0 10px !important;
}
+
+.profile-entry-info {
+ position: absolute;
+ bottom: 20px;
+ left: 20px;
+ height: 120px;
+ background-color: rgba(255, 255, 255, 0.7);
+ pointer-events: none;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/resourceView.css b/chromium/third_party/WebKit/Source/devtools/front_end/resourceView.css
index 30fa31ef1c4..e99a2f414be 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/resourceView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resourceView.css
@@ -29,16 +29,15 @@
.resource-view {
display: none;
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
overflow: auto;
}
.resource-view.visible {
- display: block;
+ display: flex;
+}
+
+.resource-view > * {
+ flex: none;
}
.resource-view.font {
@@ -113,5 +112,5 @@
word-wrap: break-word;
white-space: pre-wrap;
-webkit-user-select: text;
- background-color: inherit;
+ overflow: auto;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheItemsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js
index a7ea21e955c..efbebdfb76d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheItemsView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js
@@ -25,12 +25,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.ApplicationCacheItemsView = function(model, frameId)
{
- WebInspector.View.call(this);
-
+ WebInspector.VBox.call(this);
+
this._model = model;
this.element.classList.add("storage-view");
@@ -60,10 +60,10 @@ WebInspector.ApplicationCacheItemsView = function(model, frameId)
this._emptyView.show(this.element);
this._markDirty();
-
+
var status = this._model.frameManifestStatus(frameId);
this.updateStatus(status);
-
+
this.updateNetworkState(this._model.onLine);
// FIXME: Status bar items don't work well enough yet, so they are being hidden.
@@ -95,7 +95,7 @@ WebInspector.ApplicationCacheItemsView.prototype = {
{
if (!this.isShowing() || !this._viewDirty)
return;
-
+
this._update();
this._viewDirty = false;
},
@@ -112,9 +112,9 @@ WebInspector.ApplicationCacheItemsView.prototype = {
{
var oldStatus = this._status;
this._status = status;
-
+
var statusInformation = {};
- // We should never have UNCACHED status, since we remove frames with UNCACHED application cache status from the tree.
+ // We should never have UNCACHED status, since we remove frames with UNCACHED application cache status from the tree.
statusInformation[applicationCache.UNCACHED] = { className: "red-ball", text: "UNCACHED" };
statusInformation[applicationCache.IDLE] = { className: "green-ball", text: "IDLE" };
statusInformation[applicationCache.CHECKING] = { className: "orange-ball", text: "CHECKING" };
@@ -162,7 +162,7 @@ WebInspector.ApplicationCacheItemsView.prototype = {
delete this._updateTime;
delete this._size;
delete this._resources;
-
+
this._emptyView.show(this.element);
this.deleteButton.visible = false;
if (this._dataGrid)
@@ -218,10 +218,10 @@ WebInspector.ApplicationCacheItemsView.prototype = {
var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier(), 10)) {
- case 0: comparator = localeCompare.bind(this, "name"); break;
- case 1: comparator = localeCompare.bind(this, "type"); break;
- case 2: comparator = numberCompare.bind(this, "size"); break;
- default: localeCompare.bind(this, "resource"); // FIXME: comparator = ?
+ case 0: comparator = localeCompare.bind(null, "name"); break;
+ case 1: comparator = localeCompare.bind(null, "type"); break;
+ case 2: comparator = numberCompare.bind(null, "size"); break;
+ default: localeCompare.bind(null, "resource"); // FIXME: comparator = ?
}
this._resources.sort(comparator);
@@ -264,6 +264,6 @@ WebInspector.ApplicationCacheItemsView.prototype = {
// this._update();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CookieItemsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
index 4e057744461..8cfdcfd9e5e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CookieItemsView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
@@ -29,11 +29,11 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("storage-view");
@@ -183,5 +183,5 @@ WebInspector.CookieItemsView.prototype = {
}
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMStorageItemsView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
index 7c87517dd88..72e3e730a15 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMStorageItemsView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
@@ -26,11 +26,11 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.DOMStorageItemsView = function(domStorage)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.domStorage = domStorage;
@@ -257,5 +257,5 @@ WebInspector.DOMStorageItemsView.prototype = {
this.domStorage.removeItem(node.data.key);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DatabaseQueryView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
index 13f864792b6..04c0a8fb5e4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DatabaseQueryView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
@@ -25,11 +25,11 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.DatabaseQueryView = function(database)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.database = database;
@@ -44,8 +44,8 @@ WebInspector.DatabaseQueryView = function(database)
this._promptElement.addEventListener("keydown", this._promptKeyDown.bind(this), true);
this.element.appendChild(this._promptElement);
- this.prompt = new WebInspector.TextPromptWithHistory(this.completions.bind(this), " ");
- this.prompt.attach(this._promptElement);
+ this._prompt = new WebInspector.TextPromptWithHistory(this.completions.bind(this), " ");
+ this._prompt.attach(this._promptElement);
this.element.addEventListener("click", this._messagesClicked.bind(this), true);
}
@@ -57,10 +57,10 @@ WebInspector.DatabaseQueryView.Events = {
WebInspector.DatabaseQueryView.prototype = {
_messagesClicked: function()
{
- if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
- this.prompt.moveCaretToEndOfPrompt();
+ if (!this._prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
+ this._prompt.moveCaretToEndOfPrompt();
},
-
+
/**
* @param {!Element} proxyElement
* @param {!Range} wordRange
@@ -101,7 +101,7 @@ WebInspector.DatabaseQueryView.prototype = {
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);
- this.prompt.clearAutoComplete();
+ this._prompt.clearAutoComplete();
/**
* @this {WebInspector.DatabaseQueryView}
@@ -109,9 +109,9 @@ WebInspector.DatabaseQueryView.prototype = {
function moveBackIfOutside()
{
delete this._selectionTimeout;
- if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
- this.prompt.moveCaretToEndOfPrompt();
- this.prompt.autoCompleteSoon();
+ if (!this._prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
+ this._prompt.moveCaretToEndOfPrompt();
+ this._prompt.autoCompleteSoon();
}
this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
@@ -129,14 +129,14 @@ WebInspector.DatabaseQueryView.prototype = {
{
event.consume(true);
- this.prompt.clearAutoComplete(true);
+ this._prompt.clearAutoComplete(true);
- var query = this.prompt.text;
+ var query = this._prompt.text;
if (!query.length)
return;
- this.prompt.pushHistoryItem(query);
- this.prompt.text = "";
+ this._prompt.pushHistoryItem(query);
+ this._prompt.text = "";
this.database.executeSql(query, this._queryFinished.bind(this, query), this._queryError.bind(this, query));
},
@@ -190,7 +190,7 @@ WebInspector.DatabaseQueryView.prototype = {
{
var element = document.createElement("div");
element.className = "database-user-query";
- this.element.insertBefore(element, this.prompt.proxyElement);
+ this.element.insertBefore(element, this._prompt.proxyElement);
var commandTextElement = document.createElement("span");
commandTextElement.className = "database-query-text";
@@ -203,5 +203,5 @@ WebInspector.DatabaseQueryView.prototype = {
return resultElement;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DatabaseTableView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js
index fb2335f6d2b..cb2f77c50cb 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DatabaseTableView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js
@@ -25,11 +25,11 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.DatabaseTableView = function(database, tableName)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.database = database;
this.tableName = tableName;
@@ -60,7 +60,7 @@ WebInspector.DatabaseTableView.prototype = {
{
return tableName.replace(/\"/g, "\"\"");
},
-
+
update: function()
{
this.database.executeSql("SELECT * FROM \"" + this._escapeTableName(this.tableName) + "\"", this._queryFinished.bind(this), this._queryError.bind(this));
@@ -97,5 +97,5 @@ WebInspector.DatabaseTableView.prototype = {
this.update();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DirectoryContentView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DirectoryContentView.js
index 8fa30629fae..0719f8a7f84 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DirectoryContentView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/DirectoryContentView.js
@@ -101,6 +101,7 @@ WebInspector.DirectoryContentView.Node = function(entry)
/**
* @param {string} column
* @param {boolean} reverse
+ * @return {function(!WebInspector.DirectoryContentView.Node, !WebInspector.DirectoryContentView.Node):number|undefined}
*/
WebInspector.DirectoryContentView.Node.comparator = function(column, reverse)
{
@@ -176,7 +177,7 @@ WebInspector.DirectoryContentView.Node.prototype = {
data[indexes.Size] = WebInspector.UIString("-");
else
data[indexes.Size] = Number.bytesToString(metadata.size);
- data[indexes.ModificationTime] = new Date(metadata.modificationTime).toGMTString();
+ data[indexes.ModificationTime] = new Date(metadata.modificationTime).toISOString();
this.data = data;
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileContentView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/FileContentView.js
index 3fc611b38e8..247dbd99bf7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileContentView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/FileContentView.js
@@ -30,12 +30,12 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.FileSystemModel.File} file
*/
WebInspector.FileContentView = function(file)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._innerView = /** @type {?WebInspector.View} */ (null);
this._file = file;
@@ -89,7 +89,7 @@ WebInspector.FileContentView.prototype = {
this._file.requestMetadata(this._metadataReceived.bind(this));
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemView.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js
index 0b57300bc19..6d67ebd4a52 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/FileSystemView.js
@@ -30,20 +30,19 @@
/**
* @constructor
- * @extends {WebInspector.SidebarView}
+ * @extends {WebInspector.SplitView}
* @param {!WebInspector.FileSystemModel.FileSystem} fileSystem
*/
WebInspector.FileSystemView = function(fileSystem)
{
- WebInspector.SidebarView.call(this, WebInspector.SidebarView.SidebarPosition.Start, "FileSystemViewSidebarWidth");
+ WebInspector.SplitView.call(this, true, false, "fileSystemViewSplitViewState");
this.element.classList.add("file-system-view");
this.element.classList.add("storage-view");
var directoryTreeElement = this.element.createChild("ol", "filesystem-directory-tree");
this._directoryTree = new TreeOutline(directoryTreeElement);
- this.sidebarElement.appendChild(directoryTreeElement);
- this.sidebarElement.classList.add("outline-disclosure");
- this.sidebarElement.classList.add("sidebar");
+ this.sidebarElement().appendChild(directoryTreeElement);
+ this.sidebarElement().classList.add("outline-disclosure", "sidebar");
var rootItem = new WebInspector.FileSystemView.EntryTreeElement(this, fileSystem.root);
rootItem.expanded = true;
@@ -86,7 +85,7 @@ WebInspector.FileSystemView.prototype = {
if (this._visibleView)
this._visibleView.detach();
this._visibleView = view;
- view.show(this.mainElement);
+ view.show(this.mainElement());
},
_refresh: function()
@@ -105,7 +104,7 @@ WebInspector.FileSystemView.prototype = {
this._directoryTree.selectedTreeElement.deleteEntry();
},
- __proto__: WebInspector.SidebarView.prototype
+ __proto__: WebInspector.SplitView.prototype
}
/**
@@ -134,6 +133,7 @@ WebInspector.FileSystemView.EntryTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function()
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBViews.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
index d2fabb25fe3..2dac34853e3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBViews.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
@@ -30,15 +30,14 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.IndexedDBModel.Database} database
*/
WebInspector.IDBDatabaseView = function(database)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("indexedDBViews.css");
- this.element.classList.add("fill");
this.element.classList.add("indexed-db-database-view");
this._headersListElement = this.element.createChild("ol", "outline-disclosure");
@@ -95,13 +94,13 @@ WebInspector.IDBDatabaseView.prototype = {
this._refreshDatabase();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.IndexedDBModel} model
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {!WebInspector.IndexedDBModel.ObjectStore} objectStore
@@ -109,7 +108,7 @@ WebInspector.IDBDatabaseView.prototype = {
*/
WebInspector.IDBDataView = function(model, databaseId, objectStore, index)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("indexedDBViews.css");
this._model = model;
@@ -226,10 +225,10 @@ WebInspector.IDBDataView.prototype = {
this._keyInputElement = editorToolbar.createChild("input", "key-input");
this._keyInputElement.placeholder = WebInspector.UIString("Start from key");
- this._keyInputElement.addEventListener("paste", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("cut", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("keypress", this._keyInputChanged.bind(this));
- this._keyInputElement.addEventListener("keydown", this._keyInputChanged.bind(this));
+ this._keyInputElement.addEventListener("paste", this._keyInputChanged.bind(this), false);
+ this._keyInputElement.addEventListener("cut", this._keyInputChanged.bind(this), false);
+ this._keyInputElement.addEventListener("keypress", this._keyInputChanged.bind(this), false);
+ this._keyInputElement.addEventListener("keydown", this._keyInputChanged.bind(this), false);
return editorToolbar;
},
@@ -284,16 +283,6 @@ WebInspector.IDBDataView.prototype = {
},
/**
- * @return {string}
- */
- _stringifyKey: function(key)
- {
- if (typeof(key) === "string")
- return key;
- return JSON.stringify(key);
- },
-
- /**
* @param {boolean} force
*/
_updateData: function(force)
@@ -374,15 +363,10 @@ WebInspector.IDBDataView.prototype = {
clear: function()
{
this._dataGrid.rootNode().removeChildren();
- for (var i = 0; i < this._entries.length; ++i) {
- this._entries[i].key.release();
- this._entries[i].primaryKey.release();
- this._entries[i].value.release();
- }
this._entries = [];
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourcesPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
index 9c70c708393..760440a94d7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourcesPanel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/ResourcesPanel.js
@@ -29,6 +29,7 @@
*/
importScript("ApplicationCacheItemsView.js");
+importScript("CookieItemsView.js");
importScript("DOMStorageItemsView.js");
importScript("DatabaseQueryView.js");
importScript("DatabaseTableView.js");
@@ -39,22 +40,17 @@ importScript("FileSystemView.js");
/**
* @constructor
- * @extends {WebInspector.Panel}
+ * @extends {WebInspector.PanelWithSidebarTree}
*/
WebInspector.ResourcesPanel = function(database)
{
- WebInspector.Panel.call(this, "resources");
+ WebInspector.PanelWithSidebarTree.call(this, "resources");
this.registerRequiredCSS("resourcesPanel.css");
WebInspector.settings.resourcesLastSelectedItem = WebInspector.settings.createSetting("resourcesLastSelectedItem", {});
- this.createSidebarViewWithTree();
- this.sidebarElement.classList.add("outline-disclosure");
- this.sidebarElement.classList.add("filter-all");
- this.sidebarElement.classList.add("children");
- this.sidebarElement.classList.add("small");
-
- this.sidebarTreeElement.classList.remove("sidebar-tree");
+ this.sidebarElement().classList.add("filter-all", "children", "small", "outline-disclosure");
+ this.sidebarTree.element.classList.remove("sidebar-tree");
this.resourcesListTreeElement = new WebInspector.StorageCategoryTreeElement(this, WebInspector.UIString("Frames"), "Frames", ["frame-storage-tree-item"]);
this.sidebarTree.appendChild(this.resourcesListTreeElement);
@@ -82,11 +78,11 @@ WebInspector.ResourcesPanel = function(database)
this.sidebarTree.appendChild(this.fileSystemListTreeElement);
}
- var mainElement = this.splitView.mainElement;
- this.storageViews = mainElement.createChild("div", "resources-main");
- var statusBarContainer = mainElement.createChild("div", "resources-status-bar");
+ var mainView = new WebInspector.VBox();
+ this.storageViews = mainView.element.createChild("div", "resources-main diff-container");
+ var statusBarContainer = mainView.element.createChild("div", "resources-status-bar");
this.storageViewStatusBarItemsContainer = statusBarContainer.createChild("div", "status-bar");
- this.storageViews.classList.add("diff-container");
+ mainView.show(this.mainElement());
/** @type {!Map.<!WebInspector.Database, !Object.<string, !WebInspector.DatabaseTableView>>} */
this._databaseTableViews = new Map();
@@ -103,18 +99,21 @@ WebInspector.ResourcesPanel = function(database)
/** @type {!Object.<string, boolean>} */
this._domains = {};
- this.sidebarElement.addEventListener("mousemove", this._onmousemove.bind(this), false);
- this.sidebarElement.addEventListener("mouseout", this._onmouseout.bind(this), false);
+ this.sidebarElement().addEventListener("mousemove", this._onmousemove.bind(this), false);
+ this.sidebarElement().addEventListener("mouseout", this._onmouseout.bind(this), false);
/**
- * @return {!WebInspector.View}
* @this {WebInspector.ResourcesPanel}
+ * @return {?WebInspector.SourceFrame}
*/
- function viewGetter()
+ function sourceFrameGetter()
{
- return this.visibleView;
+ var view = this.visibleView;
+ if (view && view instanceof WebInspector.SourceFrame)
+ return /** @type {!WebInspector.SourceFrame} */ (view);
+ return null;
}
- WebInspector.GoToLineDialog.install(this, viewGetter.bind(this));
+ WebInspector.GoToLineDialog.install(this, sourceFrameGetter.bind(this));
if (WebInspector.resourceTreeModel.cachedResourcesLoaded())
this._cachedResourcesLoaded();
@@ -145,9 +144,10 @@ WebInspector.ResourcesPanel.prototype = {
_initialize: function()
{
if (!this._initialized && this.isShowing() && this._cachedResourcesWereLoaded) {
+ var target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
this._populateResourceTree();
this._populateDOMStorageTree();
- this._populateApplicationCacheTree();
+ this._populateApplicationCacheTree(target);
this.indexedDBListTreeElement._initialize();
if (WebInspector.experimentsSettings.fileSystemInspection.isEnabled())
this.fileSystemListTreeElement._initialize();
@@ -176,7 +176,9 @@ WebInspector.ResourcesPanel.prototype = {
}
}
- var mainResource = WebInspector.inspectedPageURL && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded && WebInspector.resourceTreeModel.resourceForURL(WebInspector.inspectedPageURL);
+ var mainResource = WebInspector.resourceTreeModel.inspectedPageURL() && this.resourcesListTreeElement && this.resourcesListTreeElement.expanded
+ ? WebInspector.resourceTreeModel.resourceForURL(WebInspector.resourceTreeModel.inspectedPageURL())
+ : null;
if (mainResource)
this.showResource(mainResource);
},
@@ -389,7 +391,7 @@ WebInspector.ResourcesPanel.prototype = {
parentListTreeElement.removeChild(treeElement);
if (wasSelected)
parentListTreeElement.select();
- this._domStorageTreeElements.remove(treeElement);
+ this._domStorageTreeElements.remove(domStorage);
this._domStorageViews.remove(domStorage);
},
@@ -416,23 +418,10 @@ WebInspector.ResourcesPanel.prototype = {
},
/**
- * @param {!Element} anchor
- * @return {boolean}
- */
- showAnchorLocation: function(anchor)
- {
- var resource = WebInspector.resourceForURL(anchor.href);
- if (!resource)
- return false;
- this.showResource(resource, anchor.lineNumber);
- WebInspector.inspectorView.setCurrentPanel(this);
- return true;
- },
-
- /**
* @param {!WebInspector.Resource} resource
* @param {number=} line
* @param {number=} column
+ * @return {boolean}
*/
showResource: function(resource, line, column)
{
@@ -441,9 +430,9 @@ WebInspector.ResourcesPanel.prototype = {
resourceTreeElement.revealAndSelect(true);
if (typeof line === "number") {
- var view = this._resourceViewForResource(resource);
- if (view.canHighlightPosition())
- view.highlightPosition(line, column);
+ var resourceSourceFrame = this._resourceSourceFrameViewForResource(resource);
+ if (resourceSourceFrame)
+ resourceSourceFrame.revealPosition(line, column, true);
}
return true;
},
@@ -458,6 +447,10 @@ WebInspector.ResourcesPanel.prototype = {
this._innerShowView(view);
},
+ /**
+ * @param {!WebInspector.Resource} resource
+ * @return {?WebInspector.View}
+ */
_resourceViewForResource: function(resource)
{
if (WebInspector.ResourceView.hasTextContent(resource)) {
@@ -470,6 +463,18 @@ WebInspector.ResourcesPanel.prototype = {
},
/**
+ * @param {!WebInspector.Resource} resource
+ * @return {?WebInspector.ResourceSourceFrame}
+ */
+ _resourceSourceFrameViewForResource: function(resource)
+ {
+ var resourceView = this._resourceViewForResource(resource);
+ if (resourceView && resourceView instanceof WebInspector.ResourceSourceFrame)
+ return /** @type {!WebInspector.ResourceSourceFrame} */ (resourceView);
+ return null;
+ },
+
+ /**
* @param {!WebInspector.Database} database
* @param {string=} tableName
*/
@@ -643,9 +648,12 @@ WebInspector.ResourcesPanel.prototype = {
WebInspector.domStorageModel.addEventListener(WebInspector.DOMStorageModel.Events.DOMStorageRemoved, this._domStorageRemoved, this);
},
- _populateApplicationCacheTree: function()
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ _populateApplicationCacheTree: function(target)
{
- this._applicationCacheModel = new WebInspector.ApplicationCacheModel();
+ this._applicationCacheModel = new WebInspector.ApplicationCacheModel(target);
this._applicationCacheViews = {};
this._applicationCacheFrameElements = {};
@@ -714,30 +722,15 @@ WebInspector.ResourcesPanel.prototype = {
this._applicationCacheViews[manifestURL].updateNetworkState(isNowOnline);
},
- _forAllResourceTreeElements: function(callback)
- {
- var stop = false;
- for (var treeElement = this.resourcesListTreeElement; !stop && treeElement; treeElement = treeElement.traverseNextTreeElement(false, this.resourcesListTreeElement, true)) {
- if (treeElement instanceof WebInspector.FrameResourceTreeElement)
- stop = callback(treeElement);
- }
- },
-
_findTreeElementForResource: function(resource)
{
- function isAncestor(ancestor, object)
- {
- // Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
- return false;
- }
-
function getParent(object)
{
// Redirects, XHRs do not belong to the tree, it is fine to silently return false here.
return null;
}
- return this.sidebarTree.findTreeElement(resource, isAncestor, getParent);
+ return this.sidebarTree.findTreeElement(resource, getParent);
},
showView: function(view)
@@ -779,12 +772,36 @@ WebInspector.ResourcesPanel.prototype = {
}
},
- __proto__: WebInspector.Panel.prototype
+ __proto__: WebInspector.PanelWithSidebarTree.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.ResourcesPanel.ResourceRevealer = function()
+{
+}
+
+WebInspector.ResourcesPanel.ResourceRevealer.prototype = {
+ /**
+ * @param {!Object} resource
+ * @param {number=} lineNumber
+ */
+ reveal: function(resource, lineNumber)
+ {
+ if (resource instanceof WebInspector.Resource)
+ /** @type {!WebInspector.ResourcesPanel} */ (WebInspector.inspectorView.showPanel("resources")).showResource(resource, lineNumber);
+ }
}
/**
* @constructor
* @extends {TreeElement}
+ * @param {!WebInspector.ResourcesPanel} storagePanel
+ * @param {?Object} representedObject
+ * @param {string} title
+ * @param {?Array.<string>=} iconClasses
* @param {boolean=} hasChildren
* @param {boolean=} noIcon
*/
@@ -869,6 +886,7 @@ WebInspector.BaseStorageTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -917,6 +935,10 @@ WebInspector.BaseStorageTreeElement.prototype = {
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
+ * @param {!WebInspector.ResourcesPanel} storagePanel
+ * @param {string} categoryName
+ * @param {string} settingsKey
+ * @param {?Array.<string>=} iconClasses
* @param {boolean=} noIcon
*/
WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, settingsKey, iconClasses, noIcon)
@@ -925,9 +947,18 @@ WebInspector.StorageCategoryTreeElement = function(storagePanel, categoryName, s
this._expandedSettingKey = "resources" + settingsKey + "Expanded";
WebInspector.settings[this._expandedSettingKey] = WebInspector.settings.createSetting(this._expandedSettingKey, settingsKey === "Frames");
this._categoryName = categoryName;
+ this._target = /** @type {!WebInspector.Target} */ (WebInspector.targetManager.activeTarget());
}
WebInspector.StorageCategoryTreeElement.prototype = {
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ },
+
get itemURL()
{
return "category://" + this._categoryName;
@@ -935,6 +966,7 @@ WebInspector.StorageCategoryTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1005,6 +1037,7 @@ WebInspector.FrameTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1043,6 +1076,10 @@ WebInspector.FrameTreeElement.prototype = {
this._treeElementForResource[resource.url] = resourceTreeElement;
},
+ /**
+ * @param {string} url
+ * @return {?WebInspector.Resource}
+ */
resourceByURL: function(url)
{
var treeElement = this._treeElementForResource[url];
@@ -1117,6 +1154,7 @@ WebInspector.FrameResourceTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1127,6 +1165,7 @@ WebInspector.FrameResourceTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
ondblclick: function(event)
{
@@ -1235,6 +1274,9 @@ WebInspector.FrameResourceTreeElement.prototype = {
this._updateErrorsAndWarningsBubbles();
},
+ /**
+ * @return {!WebInspector.ResourceSourceFrame}
+ */
sourceView: function()
{
if (!this._sourceView) {
@@ -1255,6 +1297,7 @@ WebInspector.FrameResourceTreeElement.prototype = {
/**
* @constructor
* @extends {WebInspector.BaseStorageTreeElement}
+ * @param {!WebInspector.ResourcesPanel} storagePanel
* @param {!WebInspector.Database} database
*/
WebInspector.DatabaseTreeElement = function(storagePanel, database)
@@ -1271,6 +1314,7 @@ WebInspector.DatabaseTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1326,6 +1370,7 @@ WebInspector.DatabaseTableTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1368,7 +1413,7 @@ WebInspector.IndexedDBTreeElement.prototype = {
_createIndexedDBModel: function()
{
- this._indexedDBModel = new WebInspector.IndexedDBModel();
+ this._indexedDBModel = new WebInspector.IndexedDBModel(this.target());
this._idbDatabaseTreeElements = [];
this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, this._indexedDBAdded, this);
this._indexedDBModel.addEventListener(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, this._indexedDBRemoved, this);
@@ -1509,7 +1554,7 @@ WebInspector.FileSystemListTreeElement.prototype = {
_refreshFileSystem: function()
{
if (!this._fileSystemModel) {
- this._fileSystemModel = new WebInspector.FileSystemModel();
+ this._fileSystemModel = new WebInspector.FileSystemModel(this.target());
this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemAdded, this._fileSystemAdded, this);
this._fileSystemModel.addEventListener(WebInspector.FileSystemModel.EventTypes.FileSystemRemoved, this._fileSystemRemoved, this);
}
@@ -1599,6 +1644,7 @@ WebInspector.IDBDatabaseTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1728,6 +1774,7 @@ WebInspector.IDBObjectStoreTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1812,6 +1859,7 @@ WebInspector.IDBIndexTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1850,6 +1898,7 @@ WebInspector.DOMStorageTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1903,6 +1952,7 @@ WebInspector.CookieTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1939,6 +1989,7 @@ WebInspector.ApplicationCacheManifestTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -1996,6 +2047,7 @@ WebInspector.ApplicationCacheFrameTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -2033,6 +2085,7 @@ WebInspector.FileSystemTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onselect: function(selectedByUser)
{
@@ -2053,11 +2106,11 @@ WebInspector.FileSystemTreeElement.prototype = {
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.StorageCategoryView = function()
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("storage-view");
this._emptyView = new WebInspector.EmptyView("");
@@ -2070,5 +2123,5 @@ WebInspector.StorageCategoryView.prototype = {
this._emptyView.text = text;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/resources/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/resources/module.json
new file mode 100644
index 00000000000..442e2e1ae80
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resources/module.json
@@ -0,0 +1,18 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "resources",
+ "title": "Resources",
+ "order": 5,
+ "className": "WebInspector.ResourcesPanel"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.Resource"],
+ "className": "WebInspector.ResourcesPanel.ResourceRevealer"
+ }
+ ],
+ "dependencies": [ "source_frame" ],
+ "scripts": [ "ResourcesPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/resourcesPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/resourcesPanel.css
index 5ec05ce0c30..6a9bcbe2248 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/resourcesPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/resourcesPanel.css
@@ -34,6 +34,7 @@
.resources.panel .sidebar {
padding-left: 0;
z-index: 10;
+ display: block;
}
.resources.panel .sidebar li {
@@ -47,18 +48,18 @@
}
.resources.panel .sidebar li.selected .selection {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(162, 177, 207)), to(rgb(120, 138, 177)));
+ background-image: linear-gradient(to bottom, rgb(162, 177, 207), rgb(120, 138, 177));
border-top: 1px solid #979797;
height: 18px;
}
.resources.panel .sidebar :focus li.selected .selection {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170)));
+ background-image: linear-gradient(to bottom, rgb(92, 147, 213), rgb(21, 83, 170));
border-top: 1px solid rgb(68, 128, 200);
}
body.inactive .resources.panel .sidebar li.selected .selection {
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(180, 180, 180)), to(rgb(138, 138, 138)));
+ background-image: linear-gradient(to bottom, rgb(180, 180, 180), rgb(138, 138, 138));
border-top: 1px solid rgb(151, 151, 151);
}
@@ -82,6 +83,7 @@ body.inactive .resources.panel .sidebar li.selected .selection {
bottom: 23px;
left: 0;
right: 0;
+ display: flex;
}
.resources-status-bar {
@@ -127,7 +129,7 @@ li.selected .base-storage-tree-element-subtitle {
}
.storage-view.visible {
- display: block;
+ display: flex;
}
.storage-view {
@@ -136,7 +138,7 @@ li.selected .base-storage-tree-element-subtitle {
.storage-view .data-grid:not(.inline) {
border: none;
- height: 100%;
+ flex: auto;
}
.storage-view .storage-table-error {
@@ -171,14 +173,14 @@ li.selected .base-storage-tree-element-subtitle {
margin-top: -7px;
-webkit-user-select: none;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
}
@media (-webkit-min-device-pixel-ratio: 1.5) {
.database-user-query::before,
.database-query-prompt::before,
.database-query-result::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/responsiveDesignView.css b/chromium/third_party/WebKit/Source/devtools/front_end/responsiveDesignView.css
new file mode 100644
index 00000000000..72061c09871
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/responsiveDesignView.css
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+.responsive-design {
+ overflow: hidden;
+ position: relative;
+}
+
+.responsive-design-sliders-container {
+ position: absolute;
+ overflow: visible;
+}
+
+.responsive-design-slider-width,
+.responsive-design-slider-height {
+ flex: none;
+ justify-content: center;
+}
+
+.responsive-design-slider-thumb {
+ border: 1px solid rgb(231, 231, 231);
+ background-color: lightgray;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
+ background-repeat: no-repeat;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex: 0 1 100px;
+}
+
+.responsive-design-slider-width .responsive-design-slider-thumb {
+ border-radius: 0 3px 3px 0;
+ border-left: none;
+}
+
+.responsive-design-slider-height .responsive-design-slider-thumb {
+ border-radius: 0 0 3px 3px;
+ border-top: none;
+}
+
+.responsive-design-thumb-handle {
+ content: url(Images/statusbarResizerHorizontal.png);
+ pointer-events: none;
+}
+
+.responsive-design-slider-height .responsive-design-thumb-handle {
+ transform: rotate(90deg);
+}
+
+/* Toolbar */
+
+.responsive-design-toolbar {
+ display: flex;
+ flex: none;
+ background: linear-gradient(to bottom, rgb(64, 64, 64), rgb(58, 58, 58));
+ color: rgb(255, 255, 255);
+ overflow: hidden;
+ border-bottom: 1px solid rgb(104, 104, 104);
+}
+
+.responsive-design-separator {
+ flex: none;
+ width: 2px;
+ background-color: rgb(43, 43, 43);
+ margin: 2px;
+}
+
+.responsive-design-section {
+ display: flex;
+ flex: none;
+ flex-direction: column;
+ white-space: nowrap;
+ align-items: stretch;
+ justify-content: flex-start;
+ padding: 0 10px;
+}
+
+.responsive-design-section .status-bar-item .glyph.shadow {
+ background-color: black !important;
+}
+
+
+.responsive-design-section-separator {
+ height: 2px;
+}
+
+.responsive-design-suite {
+ display: flex;
+ flex-direction: row;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ color: rgb(180, 180, 180);
+}
+
+.responsive-design-suite.responsive-design-suite-top {
+ color: rgb(255, 255, 255);
+}
+
+.responsive-design-suite-separator {
+ flex: none;
+ width: 1px;
+ background-color: rgb(43, 43, 43);
+ margin: 0 3px;
+}
+
+.responsive-design-suite > div:not(.responsive-design-suite-separator) {
+ flex: none;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ height: 23px;
+ overflow: hidden;
+}
+
+/* Toolbar controls */
+
+.responsive-design-toolbar fieldset,
+.responsive-design-toolbar p {
+ margin: 0;
+ border: 0;
+ padding: 0;
+ display: inline-block;
+}
+
+.responsive-design-toolbar .field-error-message {
+ display: none;
+}
+
+.responsive-design-toolbar label {
+ margin-right: 5px;
+ cursor: default !important;
+}
+
+.responsive-design-toolbar input[type='text'] {
+ text-align: left;
+ background-color: transparent;
+ border: none;
+ margin: 0 1px 1px 0;
+ padding: 3px 2px;
+}
+
+.responsive-design-toolbar input[type='text'].numeric {
+ text-align: center;
+}
+
+.responsive-design-toolbar input:focus::-webkit-input-placeholder {
+ color: transparent !important;
+}
+
+.responsive-design-toolbar fieldset:disabled input,
+.responsive-design-toolbar fieldset:disabled button {
+ opacity: 0.7;
+}
+
+.responsive-design-toolbar input[type='checkbox'] {
+ -webkit-appearance: none;
+ margin: auto 5px auto 0;
+ border: 1px solid rgb(45, 45, 45);
+ border-radius: 3px;
+ background-color: rgb(102, 102, 102);
+ position: relative;
+ top: 1px;
+}
+
+.responsive-design-toolbar input[type='checkbox']:after {
+ content: '';
+ line-height: 10px;
+ position: absolute;
+ cursor: pointer;
+ width: 12px;
+ height: 12px;
+ background: none;
+}
+
+.responsive-design-toolbar input[type='checkbox']:checked:after {
+ background: rgb(220, 220, 220);
+}
+
+.responsive-design-toolbar input.error-input {
+ color: red !important;
+ text-decoration: line-through;
+}
+
+.responsive-design-toolbar select {
+ height: 18px;
+ background-color: rgb(81, 81, 81);
+ border: 0;
+ margin-left: 10px;
+ line-height: 16px;
+}
+
+body.platform-mac .responsive-design-toolbar select {
+ position: relative;
+ top: 1px;
+}
+
+.responsive-design-toolbar input:focus {
+ background-color: rgb(81, 81, 81);
+}
+
+/* Toolbar icons */
+
+.responsive-design-icon.status-bar-item > .glyph {
+ background-color: rgb(180, 180, 180);
+ -webkit-mask-image: url(Images/responsiveDesign.png);
+ -webkit-mask-size: 64px 16px;
+}
+
+.responsive-design-icon.status-bar-item {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ position: relative;
+ top: 4px;
+}
+
+.responsive-design-icon.status-bar-item:disabled .glyph {
+ opacity: 1 !important;
+}
+
+@media (-webkit-min-device-pixel-ratio: 1.5) {
+ .responsive-design-icon.status-bar-item > .glyph {
+ -webkit-mask-image: url(Images/responsiveDesign_2x.png);
+ }
+} /* media */
+
+.responsive-design-toolbar input[type='checkbox']:after {
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
+ -webkit-mask-size: 320px 144px;
+ -webkit-mask-position: -128px -110px;
+}
+
+@media (-webkit-min-device-pixel-ratio: 1.5) {
+ .responsive-design-toolbar input[type='checkbox']:after {
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
+ }
+} /* media */
+
+.responsive-design-icon-resolution.status-bar-item > .glyph {
+ -webkit-mask-position: 0 0;
+}
+
+.responsive-design-icon-dpr.status-bar-item > .glyph {
+ -webkit-mask-position: -16px 0;
+}
+
+.responsive-design-icon-swap.status-bar-item > .glyph {
+ background-color: rgb(255, 170, 0);
+ -webkit-mask-position: -32px 0;
+ -webkit-appearance: none;
+ padding: 0;
+ border: 0;
+}
+
+.responsive-design-icon-swap.status-bar-item:hover > .glyph {
+ background-color: rgb(255, 180, 0);
+}
+
+.responsive-design-icon-swap:active {
+ opacity: 0.8;
+}
+
+/* Buttons section */
+
+.responsive-design-section-buttons {
+ padding: 0;
+}
+
+.responsive-design-section-buttons .status-bar-item {
+ margin: 2px 0;
+}
+
+.responsive-design-section-buttons .status-bar-item .glyph {
+ background-color: white;
+}
+
+.responsive-design-more-button-container {
+ flex: auto;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-end;
+ overflow: hidden;
+}
+
+.responsive-design-more-button {
+ -webkit-appearance: none;
+ border: 0;
+ background-color: transparent;
+ color: white;
+ opacity: 0.8;
+ font-size: 16px;
+ text-shadow: black 1px 1px;
+}
+
+.responsive-design-more-button:hover {
+ opacity: 1;
+}
+
+.responsive-design-more-button:active {
+ opacity: 0.8;
+}
+
+/* Device section */
+
+.responsive-design-section-device .responsive-design-section-separator {
+ background: linear-gradient(to bottom, rgb(255, 186, 68), rgb(255, 119, 0));
+}
+
+.responsive-design-section-device select {
+ width: 180px;
+}
+
+.responsive-design-section-device input[type='text'],
+.responsive-design-section-device input[type='text']::-webkit-input-placeholder,
+.responsive-design-section-device select {
+ color: rgb(255, 156, 0);
+}
+
+.responsive-design-section-device input[type='checkbox']:checked:after {
+ background: rgb(255, 156, 0);
+}
+
+/* Network section */
+
+.responsive-design-section-network select {
+ width: 150px;
+}
+
+.responsive-design-section-network input[type='text'] {
+ width: 192px;
+}
+
+.responsive-design-section-network input[type='text'],
+.responsive-design-section-network input[type='text']::-webkit-input-placeholder,
+.responsive-design-section-network select {
+ color: rgb(65, 175, 255);
+}
+
+.responsive-design-section-network .responsive-design-section-separator {
+ background: linear-gradient(to bottom, rgb(77, 170, 243), rgb(0, 130, 255));
+}
+
+/* Warning message */
+
+.responsive-design-warning {
+ background-color: rgb(252, 234, 156);
+ color: #222;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ padding: 2px 4px;
+ white-space: nowrap;
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid rgb(171, 171, 171);
+}
+
+.responsive-design-warning > span {
+ flex: auto;
+ padding-left: 3px;
+ overflow: hidden;
+}
+
+.responsive-design-warning > div {
+ flex: none;
+}
+
+.responsive-design-ruler-glasspane {
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ background-color: transparent;
+}
+
+.responsive-design-toggle-media-inspector .glyph {
+ background-color: rgb(180, 180, 180);
+ -webkit-mask-position: -128px -48px;
+}
+
+.responsive-design-toolbar button.responsive-design-toggle-media-inspector.toggled-on .glyph:not(.shadow) {
+ background-color: rgb(105, 194, 236) !important;
+}
+
+/* media */
+
+.view.media-inspector-view {
+ overflow-y: auto;
+ overflow-x: hidden;
+ background-color: rgb(0, 0, 0);
+ border-bottom: 1px solid rgb(163, 163, 163);
+ flex: none;
+}
+
+.view.media-inspector-view-fixed-height {
+ height: 100px;
+}
+
+.media-inspector-view::-webkit-scrollbar {
+ background: rgb(54, 54, 54);
+}
+
+.media-inspector-view::-webkit-scrollbar-thumb {
+ background: rgb(94, 94, 94);
+}
+
+.media-inspector-marker-container {
+ position: relative;
+ margin: 2px 0 2px 0;
+}
+
+.media-inspector-min-width-label-container {
+ position: relative;
+}
+
+.media-inspector-marker {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ white-space: nowrap;
+}
+
+.media-inspector-marker-container:hover {
+ background-color: rgb(32, 32, 32);
+}
+
+.media-inspector-marker-container:hover .media-inspector-marker {
+ -webkit-filter: brightness(125%);
+}
+
+.media-inspector-marker-max-width {
+ background-color: rgba(111, 168, 220, 0.66);
+ border-right: 5px solid rgba(111, 168, 220, 0.86);
+}
+
+.media-inspector-marker-min-max-width {
+ background-color: rgba(100, 200, 0, 0.66);
+ border-left: 5px solid rgba(100, 200, 0, 0.86);
+ border-right: 5px solid rgba(100, 200, 0, 0.86);
+}
+
+.media-inspector-marker-min-width {
+ background-color: rgba(225, 124, 0, 0.66);
+ border-left: 5px solid rgba(225, 124, 0, 0.86);
+}
+
+.media-inspector-marker-label {
+ position: absolute;
+ color: rgb(180, 180, 180);
+}
+
+.media-inspector-min-label::after {
+ padding-left: 2px;
+ height: 6px;
+ width: 11px;
+ content: url(Images/graphLabelCalloutLeft.png);
+ -webkit-filter: invert(0.8);
+}
+
+.media-inspector-max-label::before {
+ padding-right: 2px;
+ height: 6px;
+ content: url(Images/graphLabelCalloutRight.png);
+ -webkit-filter: invert(0.8);
+}
+
+.media-inspector-threshold-serif {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ width: 5px;
+ margin-left: -2px;
+}
+
+.media-inspector-threshold-serif::before {
+ content: ".";
+ color: transparent;
+ position: absolute;
+ left: 2px;
+ right: 2px;
+ top: 0px;
+ bottom: 0px;
+ background-color: rgba(225, 124, 0, 0.86);
+}
+
+.media-inspector-threshold-serif:hover::before {
+ left: 1px;
+ right: 1px;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/screencastView.css b/chromium/third_party/WebKit/Source/devtools/front_end/screencastView.css
index b602ebc579f..3f19eff9566 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/screencastView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/screencastView.css
@@ -28,15 +28,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+.screencast {
+ overflow: hidden;
+}
+
.screencast-navigation {
- -webkit-flex-direction: row;
- display: -webkit-flex;
- height: 25px;
+ flex-direction: row;
+ display: flex;
+ flex: 24px 0 0;
position: relative;
}
.screencast-navigation button {
- -webkit-border-radius: 2px;
+ border-radius: 2px;
background-color: transparent;
background-image: -webkit-image-set(
url(Images/navigationControls.png) 1x,
@@ -46,7 +50,7 @@
background-repeat: no-repeat;
border: 1px solid transparent;
height: 23px;
- padding: 3px 2px 1px;
+ padding: 2px;
width: 23px;
}
@@ -98,19 +102,25 @@
}
.screencast-viewport {
- border: 20px solid #333;
+ display: flex;
+ border: 1px solid #999;
border-radius: 20px;
- position: absolute;
- top: 36px;
- left: 10px;
- right: 10px;
- bottom: 10px;
+ flex: none;
+ padding: 20px;
+ margin: 10px;
+ background-color: #eee;
+}
+
+.screencast-canvas-container {
+ flex: auto;
+ display: flex;
+ border: 1px solid #999;
+ position: relative;
}
.screencast canvas {
- position: absolute;
- width: 100%;
- height: 100%;
+ flex: auto;
+ position: relative;
}
.screencast-px {
@@ -138,15 +148,15 @@
}
.screencast-glasspane {
- -webkit-box-orient: horizontal;
- -webkit-box-align: center;
- -webkit-box-pack: center;
- background-color: rgba(255, 255, 255, 0.8);
- bottom: 0;
- display: -webkit-box;
- left: 0;
position: absolute;
+ top: 0;
right: 0;
- top: 25px; /* Align with the botton edge of .screencast .navigation. */
+ bottom: 0;
+ left: 0;
+ background-color: rgba(255, 255, 255, 0.8);
font-size: 30px;
+ z-index: 100;
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSFormatter.js b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/CSSFormatter.js
index c20c88ac6a5..b03d98230ef 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSFormatter.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/CSSFormatter.js
@@ -45,7 +45,7 @@ FormatterWorker.CSSFormatter.prototype = {
format: function()
{
this._lineEndings = this._lineEndings(this._content);
- var tokenize = WebInspector.CodeMirrorUtils.createTokenizer("text/css");
+ var tokenize = FormatterWorker.createTokenizer("text/css");
var lines = this._content.split("\n");
for (var i = 0; i < lines.length; ++i) {
@@ -73,14 +73,14 @@ FormatterWorker.CSSFormatter.prototype = {
/**
* @param {number} startLine
* @param {string} token
- * @param {string} type
+ * @param {?string} type
* @param {number} startColumn
*/
_tokenCallback: function(startLine, token, type, startColumn)
{
if (startLine !== this._lastLine)
this._state.eatWhitespace = true;
- if (/^css-property/.test(type) && !this._state.inPropertyValue)
+ if (/^property/.test(type) && !this._state.inPropertyValue)
this._state.seenProperty = true;
this._lastLine = startLine;
var isWhitespace = /^\s+$/.test(token);
@@ -122,7 +122,7 @@ FormatterWorker.CSSFormatter.prototype = {
this._builder.addToken(token, startPosition, startLine, startColumn);
- if (type === "css-comment" && !this._state.inPropertyValue && !this._state.seenProperty)
+ if (type === "comment" && !this._state.inPropertyValue && !this._state.seenProperty)
this._builder.addNewLine();
if (token === ";" && this._state.inPropertyValue) {
this._state.inPropertyValue = false;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptFormatter.js b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/JavaScriptFormatter.js
index 79a4a0bd5d1..0d41c275293 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptFormatter.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/JavaScriptFormatter.js
@@ -49,7 +49,7 @@ FormatterWorker.JavaScriptFormatter.prototype = {
},
/**
- * @return {string}
+ * @return {number}
*/
_peek: function()
{
@@ -57,7 +57,7 @@ FormatterWorker.JavaScriptFormatter.prototype = {
},
/**
- * @return {string}
+ * @return {number}
*/
_next: function()
{
@@ -72,7 +72,7 @@ FormatterWorker.JavaScriptFormatter.prototype = {
},
/**
- * @param {string} token
+ * @param {number} token
*/
_consume: function(token)
{
@@ -82,7 +82,7 @@ FormatterWorker.JavaScriptFormatter.prototype = {
},
/**
- * @param {string} token
+ * @param {number} token
*/
_expect: function(token)
{
@@ -106,7 +106,7 @@ FormatterWorker.JavaScriptFormatter.prototype = {
},
/**
- * @param {string} endToken
+ * @param {number} endToken
*/
_parseSourceElements: function(endToken)
{
@@ -1001,6 +1001,7 @@ FormatterWorker.JavaScriptTokenizer.prototype = {
/**
* @param {boolean=} forceRegexp
+ * @return {!{comments_before: !Array.<string>, line: number, pos: number, endLine: number, nlb: boolean, token: number, type: string, value: *}}
*/
next: function(forceRegexp)
{
@@ -1011,6 +1012,9 @@ FormatterWorker.JavaScriptTokenizer.prototype = {
return uglifyToken;
},
+ /**
+ * @return {number}
+ */
_convertUglifyToken: function(uglifyToken)
{
var token = FormatterWorker.JavaScriptTokensByType[uglifyToken.type];
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatterWorker.js b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/ScriptFormatterWorker.js
index 505d7dc3da3..d278ecb7eb5 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatterWorker.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/script_formatter_worker/ScriptFormatterWorker.js
@@ -27,25 +27,51 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-importScripts("utilities.js");
-importScripts("cm/headlesscodemirror.js");
-importScripts("cm/css.js");
-importScripts("cm/javascript.js");
-importScripts("cm/xml.js");
-importScripts("cm/htmlmixed.js");
+importScripts("../common/utilities.js");
+importScripts("../cm/headlesscodemirror.js");
+importScripts("../cm/css.js");
+importScripts("../cm/javascript.js");
+importScripts("../cm/xml.js");
+importScripts("../cm/htmlmixed.js");
WebInspector = {};
-FormatterWorker = {};
-importScripts("CodeMirrorUtils.js");
+FormatterWorker = {
+ /**
+ * @param {string} mimeType
+ * @return {function(string, function(string, ?string, number, number))}
+ */
+ createTokenizer: function(mimeType)
+ {
+ var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
+ var state = CodeMirror.startState(mode);
+ function tokenize(line, callback)
+ {
+ var stream = new CodeMirror.StringStream(line);
+ while (!stream.eol()) {
+ var style = mode.token(stream, state);
+ var value = stream.current();
+ callback(value, style, stream.start, stream.start + value.length);
+ stream.start = stream.pos;
+ }
+ }
+ return tokenize;
+ }
+};
+
+/**
+ * @typedef {{indentString: string, content: string, mimeType: string}}
+ */
+var FormatterParameters;
var onmessage = function(event) {
- if (!event.data.method)
+ var data = /** @type !{method: string, params: !FormatterParameters} */ (event.data);
+ if (!data.method)
return;
- FormatterWorker[event.data.method](event.data.params);
+ FormatterWorker[data.method](data.params);
};
/**
- * @param {!Object} params
+ * @param {!FormatterParameters} params
*/
FormatterWorker.format = function(params)
{
@@ -83,12 +109,12 @@ FormatterWorker._chunkCount = function(totalLength, chunkSize)
/**
* @param {!Object} params
*/
-FormatterWorker.outline = function(params)
+FormatterWorker.javaScriptOutline = function(params)
{
- const chunkSize = 100000; // characters per data chunk
- const totalLength = params.content.length;
- const lines = params.content.split("\n");
- const chunkCount = FormatterWorker._chunkCount(totalLength, chunkSize);
+ var chunkSize = 100000; // characters per data chunk
+ var totalLength = params.content.length;
+ var lines = params.content.split("\n");
+ var chunkCount = FormatterWorker._chunkCount(totalLength, chunkSize);
var outlineChunk = [];
var previousIdentifier = null;
var previousToken = null;
@@ -99,22 +125,32 @@ FormatterWorker.outline = function(params)
var isReadingArguments = false;
var argumentsText = "";
var currentFunction = null;
- var tokenizer = WebInspector.CodeMirrorUtils.createTokenizer("text/javascript");
+ var tokenizer = FormatterWorker.createTokenizer("text/javascript");
for (var i = 0; i < lines.length; ++i) {
var line = lines[i];
tokenizer(line, processToken);
}
/**
+ * @param {?string} tokenType
+ * @return {boolean}
+ */
+ function isJavaScriptIdentifier(tokenType)
+ {
+ if (!tokenType)
+ return false;
+ return tokenType.startsWith("variable") || tokenType.startsWith("property") || tokenType === "def";
+ }
+
+ /**
* @param {string} tokenValue
- * @param {string} tokenType
+ * @param {?string} tokenType
* @param {number} column
* @param {number} newColumn
*/
function processToken(tokenValue, tokenType, column, newColumn)
{
- tokenType = tokenType ? WebInspector.CodeMirrorUtils.convertTokenType(tokenType) : null;
- if (tokenType === "javascript-ident") {
+ if (isJavaScriptIdentifier(tokenType)) {
previousIdentifier = tokenValue;
if (tokenValue && previousToken === "function") {
// A named function: "function f...".
@@ -122,7 +158,7 @@ FormatterWorker.outline = function(params)
addedFunction = true;
previousIdentifier = null;
}
- } else if (tokenType === "javascript-keyword") {
+ } else if (tokenType === "keyword") {
if (tokenValue === "function") {
if (previousIdentifier && (previousToken === "=" || previousToken === ":")) {
// Anonymous function assigned to an identifier: "...f = function..."
@@ -132,7 +168,7 @@ FormatterWorker.outline = function(params)
previousIdentifier = null;
}
}
- } else if (tokenValue === "." && previousTokenType === "javascript-ident")
+ } else if (tokenValue === "." && isJavaScriptIdentifier(previousTokenType))
previousIdentifier += ".";
else if (tokenValue === "(" && addedFunction)
isReadingArguments = true;
@@ -164,6 +200,125 @@ FormatterWorker.outline = function(params)
postMessage({ chunk: outlineChunk, total: chunkCount, index: chunkCount });
}
+FormatterWorker.CSSParserStates = {
+ Initial: "Initial",
+ Selector: "Selector",
+ Style: "Style",
+ PropertyName: "PropertyName",
+ PropertyValue: "PropertyValue",
+ AtRule: "AtRule",
+};
+
+FormatterWorker.parseCSS = function(params)
+{
+ var chunkSize = 100000; // characters per data chunk
+ var lines = params.content.split("\n");
+ var rules = [];
+ var processedChunkCharacters = 0;
+
+ var state = FormatterWorker.CSSParserStates.Initial;
+ var rule;
+ var property;
+ var UndefTokenType = {};
+
+ /**
+ * @param {string} tokenValue
+ * @param {?string} tokenTypes
+ * @param {number} column
+ * @param {number} newColumn
+ */
+ function processToken(tokenValue, tokenTypes, column, newColumn)
+ {
+ var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType;
+ switch (state) {
+ case FormatterWorker.CSSParserStates.Initial:
+ if (tokenType["qualifier"] || tokenType["builtin"] || tokenType["tag"]) {
+ rule = {
+ selectorText: tokenValue,
+ lineNumber: lineNumber,
+ columNumber: column,
+ properties: [],
+ };
+ state = FormatterWorker.CSSParserStates.Selector;
+ } else if (tokenType["def"]) {
+ rule = {
+ atRule: tokenValue,
+ lineNumber: lineNumber,
+ columNumber: column,
+ };
+ state = FormatterWorker.CSSParserStates.AtRule;
+ }
+ break;
+ case FormatterWorker.CSSParserStates.Selector:
+ if (tokenValue === "{" && tokenType === UndefTokenType) {
+ rule.selectorText = rule.selectorText.trim();
+ state = FormatterWorker.CSSParserStates.Style;
+ } else {
+ rule.selectorText += tokenValue;
+ }
+ break;
+ case FormatterWorker.CSSParserStates.AtRule:
+ if ((tokenValue === ";" || tokenValue === "{") && tokenType === UndefTokenType) {
+ rule.atRule = rule.atRule.trim();
+ rules.push(rule);
+ state = FormatterWorker.CSSParserStates.Initial;
+ } else {
+ rule.atRule += tokenValue;
+ }
+ break;
+ case FormatterWorker.CSSParserStates.Style:
+ if (tokenType["meta"] || tokenType["property"]) {
+ property = {
+ name: tokenValue,
+ value: "",
+ };
+ state = FormatterWorker.CSSParserStates.PropertyName;
+ } else if (tokenValue === "}" && tokenType === UndefTokenType) {
+ rules.push(rule);
+ state = FormatterWorker.CSSParserStates.Initial;
+ }
+ break;
+ case FormatterWorker.CSSParserStates.PropertyName:
+ if (tokenValue === ":" && tokenType["operator"]) {
+ property.name = property.name.trim();
+ state = FormatterWorker.CSSParserStates.PropertyValue;
+ } else if (tokenType["property"]) {
+ property.name += tokenValue;
+ }
+ break;
+ case FormatterWorker.CSSParserStates.PropertyValue:
+ if (tokenValue === ";" && tokenType === UndefTokenType) {
+ property.value = property.value.trim();
+ rule.properties.push(property);
+ state = FormatterWorker.CSSParserStates.Style;
+ } else if (tokenValue === "}" && tokenType === UndefTokenType) {
+ property.value = property.value.trim();
+ rule.properties.push(property);
+ rules.push(rule);
+ state = FormatterWorker.CSSParserStates.Initial;
+ } else if (!tokenType["comment"]) {
+ property.value += tokenValue;
+ }
+ break;
+ default:
+ console.assert(false, "Unknown CSS parser state.");
+ }
+ processedChunkCharacters += newColumn - column;
+ if (processedChunkCharacters > chunkSize) {
+ postMessage({ chunk: rules, isLastChunk: false });
+ rules = [];
+ processedChunkCharacters = 0;
+ }
+ }
+ var tokenizer = FormatterWorker.createTokenizer("text/css");
+ var lineNumber;
+ for (lineNumber = 0; lineNumber < lines.length; ++lineNumber) {
+ var line = lines[lineNumber];
+ tokenizer(line, processToken);
+ }
+ postMessage({ chunk: rules, isLastChunk: true });
+}
+
/**
* @param {string} content
* @param {!{original: !Array.<number>, formatted: !Array.<number>}} mapping
@@ -221,6 +376,7 @@ FormatterWorker.HTMLFormatter = function(indentString)
FormatterWorker.HTMLFormatter.prototype = {
/**
* @param {string} content
+ * @return {!{content: string, mapping: {original: !Array.<number>, formatted: !Array.<number>}}}
*/
format: function(content)
{
@@ -232,13 +388,13 @@ FormatterWorker.HTMLFormatter.prototype = {
var scriptOpened = false;
var styleOpened = false;
- var tokenizer = WebInspector.CodeMirrorUtils.createTokenizer("text/html");
+ var tokenizer = FormatterWorker.createTokenizer("text/html");
/**
* @this {FormatterWorker.HTMLFormatter}
*/
function processToken(tokenValue, tokenType, tokenStart, tokenEnd) {
- if (tokenType !== "xml-tag")
+ if (tokenType !== "tag")
return;
if (tokenValue.toLowerCase() === "<script") {
scriptOpened = true;
@@ -305,7 +461,7 @@ FormatterWorker.HTMLFormatter.prototype = {
},
/**
- * @param {function(string, {formatted: !Array.<number>, original: !Array.<number>}, number, number, string)} formatFunction
+ * @param {function(string, !{formatted: !Array.<number>, original: !Array.<number>}, number, number, string)} formatFunction
* @param {number} cursor
*/
_handleSubFormatterEnd: function(formatFunction, cursor)
@@ -323,14 +479,9 @@ FormatterWorker.HTMLFormatter.prototype = {
}
}
-Array.prototype.keySet = function()
-{
- var keys = {};
- for (var i = 0; i < this.length; ++i)
- keys[this[i]] = true;
- return keys;
-};
-
+/**
+ * @return {!Object}
+ */
function require()
{
return parse;
@@ -340,7 +491,7 @@ function require()
* @type {!{tokenizer}}
*/
var exports = { tokenizer: null };
-importScripts("UglifyJS/parse-js.js");
+importScripts("../UglifyJS/parse-js.js");
var parse = exports;
importScripts("JavaScriptFormatter.js");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ApplicationCacheModel.js
index f8a383d82f7..ea9d3e1e78d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ApplicationCacheModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ApplicationCacheModel.js
@@ -28,15 +28,19 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.ApplicationCacheModel = function()
+WebInspector.ApplicationCacheModel = function(target)
{
- ApplicationCacheAgent.enable();
- InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
+ WebInspector.TargetAwareObject.call(this, target);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
+ target.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
+ this._agent = target.applicationCacheAgent();
+ this._agent.enable();
+
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
this._statuses = {};
this._manifestURLsByFrame = {};
@@ -62,7 +66,7 @@ WebInspector.ApplicationCacheModel.prototype = {
return;
}
- ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
+ this._agent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
},
/**
@@ -76,7 +80,7 @@ WebInspector.ApplicationCacheModel.prototype = {
_mainFrameNavigated: function()
{
- ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
+ this._agent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
},
/**
@@ -212,7 +216,7 @@ WebInspector.ApplicationCacheModel.prototype = {
callback(applicationCache);
}
- ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
+ this._agent.getApplicationCacheForFrame(frameId, callbackWrapper);
},
/**
@@ -224,7 +228,7 @@ WebInspector.ApplicationCacheModel.prototype = {
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/BreakpointManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/BreakpointManager.js
index dfef626b888..69f3d155ad9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/BreakpointManager.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/BreakpointManager.js
@@ -32,22 +32,21 @@
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.Setting} breakpointStorage
- * @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
+ * @param {!WebInspector.TargetManager} targetManager
*/
-WebInspector.BreakpointManager = function(breakpointStorage, debuggerModel, workspace)
+WebInspector.BreakpointManager = function(breakpointStorage, workspace, targetManager)
{
this._storage = new WebInspector.BreakpointManager.Storage(this, breakpointStorage);
- this._debuggerModel = debuggerModel;
this._workspace = workspace;
+ this._targetManager = targetManager;
- this._breakpointForDebuggerId = {};
this._breakpointsForUISourceCode = new Map();
this._breakpointsForPrimaryUISourceCode = new Map();
- this._sourceFilesWithRestoredBreakpoints = {};
+ /** @type {!StringMultimap.<!WebInspector.BreakpointManager.Breakpoint>} */
+ this._provisionalBreakpoints = new StringMultimap();
- this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointResolved, this._breakpointResolved, this);
- this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
}
@@ -61,63 +60,71 @@ WebInspector.BreakpointManager._sourceFileId = function(uiSourceCode)
{
if (!uiSourceCode.url)
return "";
- var deobfuscatedPrefix = uiSourceCode.formatted() ? "deobfuscated:" : "";
- return deobfuscatedPrefix + uiSourceCode.uri();
+ return uiSourceCode.uri();
}
/**
* @param {string} sourceFileId
* @param {number} lineNumber
+ * @param {number} columnNumber
* @return {string}
*/
-WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lineNumber)
+WebInspector.BreakpointManager._breakpointStorageId = function(sourceFileId, lineNumber, columnNumber)
{
if (!sourceFileId)
return "";
- return sourceFileId + ":" + lineNumber;
+ return sourceFileId + ":" + lineNumber + ":" + columnNumber;
}
WebInspector.BreakpointManager.prototype = {
+
/**
* @param {string} sourceFileId
+ * @return {!StringMap.<!WebInspector.BreakpointManager.Breakpoint>}
*/
_provisionalBreakpointsForSourceFileId: function(sourceFileId)
{
var result = new StringMap();
- for (var debuggerId in this._breakpointForDebuggerId) {
- var breakpoint = this._breakpointForDebuggerId[debuggerId];
- if (breakpoint._sourceFileId === sourceFileId)
- result.put(breakpoint._breakpointStorageId(), breakpoint);
- }
+ var breakpoints = this._provisionalBreakpoints.get(sourceFileId).values();
+ for (var i = 0; i < breakpoints.length; ++i)
+ result.put(breakpoints[i]._breakpointStorageId(), breakpoints[i]);
return result;
},
+ removeProvisionalBreakpointsForTest: function()
+ {
+ var breakpoints = this._provisionalBreakpoints.values();
+ for (var i = 0; i < breakpoints.length; ++i)
+ breakpoints[i].remove();
+ this._provisionalBreakpoints.clear();
+ },
+
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_restoreBreakpoints: function(uiSourceCode)
{
var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSourceCode);
- if (!sourceFileId || this._sourceFilesWithRestoredBreakpoints[sourceFileId])
+ if (!sourceFileId)
return;
- this._sourceFilesWithRestoredBreakpoints[sourceFileId] = true;
this._storage.mute();
var breakpointItems = this._storage.breakpointItems(uiSourceCode);
var provisionalBreakpoints = this._provisionalBreakpointsForSourceFileId(sourceFileId);
for (var i = 0; i < breakpointItems.length; ++i) {
var breakpointItem = breakpointItems[i];
- var itemStorageId = WebInspector.BreakpointManager._breakpointStorageId(breakpointItem.sourceFileId, breakpointItem.lineNumber);
+ var itemStorageId = WebInspector.BreakpointManager._breakpointStorageId(breakpointItem.sourceFileId, breakpointItem.lineNumber, breakpointItem.columnNumber);
var provisionalBreakpoint = provisionalBreakpoints.get(itemStorageId);
if (provisionalBreakpoint) {
if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []);
this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(provisionalBreakpoint);
- provisionalBreakpoint._updateInDebugger();
+ provisionalBreakpoint._updateBreakpoint();
} else {
- this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber, breakpointItem.condition, breakpointItem.enabled);
+ this._innerSetBreakpoint(uiSourceCode, breakpointItem.lineNumber, breakpointItem.columnNumber, breakpointItem.condition, breakpointItem.enabled);
}
}
+ this._provisionalBreakpoints.removeAll(sourceFileId);
this._storage.unmute();
},
@@ -128,19 +135,8 @@ WebInspector.BreakpointManager.prototype = {
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
this._restoreBreakpoints(uiSourceCode);
- if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document) {
+ if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script || uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this);
- uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormatted, this);
- }
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _uiSourceCodeFormatted: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
- this._restoreBreakpoints(uiSourceCode);
},
/**
@@ -158,9 +154,13 @@ WebInspector.BreakpointManager.prototype = {
_uiSourceCodeMappingChanged: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
+ var isIdentity = /** @type {boolean} */ (event.data.isIdentity);
+ var target = /** @type {!WebInspector.Target} */ (event.data.target);
+ if (isIdentity)
+ return;
var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [];
for (var i = 0; i < breakpoints.length; ++i)
- breakpoints[i]._updateInDebugger();
+ breakpoints[i]._updateInDebuggerForTarget(target);
},
/**
@@ -169,11 +169,12 @@ WebInspector.BreakpointManager.prototype = {
_removeUISourceCode: function(uiSourceCode)
{
var breakpoints = this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [];
- for (var i = 0; i < breakpoints.length; ++i)
- breakpoints[i]._resetLocations();
var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSourceCode);
- delete this._sourceFilesWithRestoredBreakpoints[sourceFileId];
- uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormatted, this);
+ for (var i = 0; i < breakpoints.length; ++i) {
+ breakpoints[i]._resetLocations();
+ if (breakpoints[i].enabled())
+ this._provisionalBreakpoints.put(sourceFileId, breakpoints[i]);
+ }
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this);
this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode);
},
@@ -181,34 +182,38 @@ WebInspector.BreakpointManager.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
+ * @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @return {!WebInspector.BreakpointManager.Breakpoint}
*/
- setBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
+ setBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, enabled)
{
- this._debuggerModel.setBreakpointsActive(true);
- return this._innerSetBreakpoint(uiSourceCode, lineNumber, condition, enabled);
+ var targets = this._targetManager.targets();
+ for (var i = 0; i < targets.length; ++i)
+ targets[i].debuggerModel.setBreakpointsActive(true);
+ return this._innerSetBreakpoint(uiSourceCode, lineNumber, columnNumber, condition, enabled);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
+ * @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @return {!WebInspector.BreakpointManager.Breakpoint}
*/
- _innerSetBreakpoint: function(uiSourceCode, lineNumber, condition, enabled)
+ _innerSetBreakpoint: function(uiSourceCode, lineNumber, columnNumber, condition, enabled)
{
- var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber);
+ var breakpoint = this.findBreakpoint(uiSourceCode, lineNumber, columnNumber);
if (breakpoint) {
- breakpoint._updateBreakpoint(condition, enabled);
+ breakpoint._updateState(condition, enabled);
return breakpoint;
}
var projectId = uiSourceCode.project().id();
var path = uiSourceCode.path();
var sourceFileId = WebInspector.BreakpointManager._sourceFileId(uiSourceCode);
- breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, projectId, path, sourceFileId, lineNumber, condition, enabled);
+ breakpoint = new WebInspector.BreakpointManager.Breakpoint(this, projectId, path, sourceFileId, lineNumber, columnNumber, condition, enabled);
if (!this._breakpointsForPrimaryUISourceCode.get(uiSourceCode))
this._breakpointsForPrimaryUISourceCode.put(uiSourceCode, []);
this._breakpointsForPrimaryUISourceCode.get(uiSourceCode).push(breakpoint);
@@ -218,13 +223,27 @@ WebInspector.BreakpointManager.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {?WebInspector.BreakpointManager.Breakpoint}
+ */
+ findBreakpoint: function(uiSourceCode, lineNumber, columnNumber)
+ {
+ var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
+ var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
+ var columnBreakpoints = lineBreakpoints ? lineBreakpoints.get(String(columnNumber)) : null;
+ return columnBreakpoints ? columnBreakpoints[0] : null;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number} lineNumber
* @return {?WebInspector.BreakpointManager.Breakpoint}
*/
- findBreakpoint: function(uiSourceCode, lineNumber)
+ findBreakpointOnLine: function(uiSourceCode, lineNumber)
{
var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- var lineBreakpoints = breakpoints ? breakpoints[lineNumber] : null;
- return lineBreakpoints ? lineBreakpoints[0] : null;
+ var lineBreakpoints = breakpoints ? breakpoints.get(String(lineNumber)) : null;
+ return lineBreakpoints ? lineBreakpoints.values()[0][0] : null;
},
/**
@@ -233,11 +252,14 @@ WebInspector.BreakpointManager.prototype = {
*/
breakpointsForUISourceCode: function(uiSourceCode)
{
- var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- var allLineBreakpoints = breakpoints ? Object.values(breakpoints) : [];
var result = [];
- for (var i = 0; i < allLineBreakpoints.length; ++i)
- result = result.concat(allLineBreakpoints[i]);
+ var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
+ var breakpoints = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.values() : [];
+ for (var i = 0; i < breakpoints.length; ++i) {
+ var lineBreakpoints = breakpoints[i];
+ var columnBreakpointArrays = lineBreakpoints ? lineBreakpoints.values() : [];
+ result = result.concat.apply(result, columnBreakpointArrays);
+ }
return result;
},
@@ -255,29 +277,32 @@ WebInspector.BreakpointManager.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!Array.<{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
+ * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
breakpointLocationsForUISourceCode: function(uiSourceCode)
{
- var breakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
- var breakpointLines = breakpoints ? Object.keys(breakpoints) : [];
+ var uiSourceCodeBreakpoints = this._breakpointsForUISourceCode.get(uiSourceCode);
+ var lineNumbers = uiSourceCodeBreakpoints ? uiSourceCodeBreakpoints.keys() : [];
var result = [];
- for (var i = 0; i < breakpointLines.length; ++i) {
- var lineNumber = parseInt(breakpointLines[i], 10);
- if (isNaN(lineNumber))
- continue;
- var lineBreakpoints = breakpoints[lineNumber];
- for (var j = 0; j < lineBreakpoints.length; ++j) {
- var breakpoint = lineBreakpoints[j];
- var uiLocation = new WebInspector.UILocation(uiSourceCode, lineNumber, 0);
- result.push({breakpoint: breakpoint, uiLocation: uiLocation});
+ for (var i = 0; i < lineNumbers.length; ++i) {
+ var lineBreakpoints = uiSourceCodeBreakpoints.get(lineNumbers[i]);
+ var columnNumbers = lineBreakpoints.keys();
+ for (var j = 0; j < columnNumbers.length; ++j) {
+ var columnBreakpoints = lineBreakpoints.get(columnNumbers[j]);
+ var lineNumber = parseInt(lineNumbers[i], 10);
+ var columnNumber = parseInt(columnNumbers[j], 10);
+ for (var k = 0; k < columnBreakpoints.length; ++k) {
+ var breakpoint = columnBreakpoints[k];
+ var uiLocation = uiSourceCode.uiLocation(lineNumber, columnNumber);
+ result.push({breakpoint: breakpoint, uiLocation: uiLocation});
+ }
}
}
return result;
},
/**
- * @return {!Array.<{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
+ * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
allBreakpointLocations: function()
{
@@ -305,13 +330,7 @@ WebInspector.BreakpointManager.prototype = {
breakpoints[i].remove();
},
- removeProvisionalBreakpoints: function()
- {
- for (var debuggerId in this._breakpointForDebuggerId)
- this._debuggerModel.removeBreakpoint(debuggerId);
- },
-
- _projectWillReset: function(event)
+ _projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var uiSourceCodes = project.uiSourceCodes();
@@ -319,16 +338,6 @@ WebInspector.BreakpointManager.prototype = {
this._removeUISourceCode(uiSourceCodes[i]);
},
- _breakpointResolved: function(event)
- {
- var breakpointId = /** @type {!DebuggerAgent.BreakpointId} */ (event.data.breakpointId);
- var location = /** @type {!WebInspector.DebuggerModel.Location} */ (event.data.location);
- var breakpoint = this._breakpointForDebuggerId[breakpointId];
- if (!breakpoint)
- return;
- breakpoint._addResolvedLocation(location);
- },
-
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
* @param {boolean} removeFromStorage
@@ -337,12 +346,10 @@ WebInspector.BreakpointManager.prototype = {
{
var uiSourceCode = breakpoint.uiSourceCode();
var breakpoints = uiSourceCode ? this._breakpointsForPrimaryUISourceCode.get(uiSourceCode) || [] : [];
- var index = breakpoints.indexOf(breakpoint);
- if (index > -1)
- breakpoints.splice(index, 1);
- console.assert(!breakpoint._debuggerId)
+ breakpoints.remove(breakpoint);
if (removeFromStorage)
this._storage._removeBreakpoint(breakpoint);
+ this._provisionalBreakpoints.remove(breakpoint._sourceFileId, breakpoint);
},
/**
@@ -353,17 +360,20 @@ WebInspector.BreakpointManager.prototype = {
{
var breakpoints = this._breakpointsForUISourceCode.get(uiLocation.uiSourceCode);
if (!breakpoints) {
- breakpoints = {};
+ breakpoints = new StringMap();
this._breakpointsForUISourceCode.put(uiLocation.uiSourceCode, breakpoints);
}
-
- var lineBreakpoints = breakpoints[uiLocation.lineNumber];
+ var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
if (!lineBreakpoints) {
- lineBreakpoints = [];
- breakpoints[uiLocation.lineNumber] = lineBreakpoints;
+ lineBreakpoints = new StringMap();
+ breakpoints.put(String(uiLocation.lineNumber), lineBreakpoints);
}
-
- lineBreakpoints.push(breakpoint);
+ var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber));
+ if (!columnBreakpoints) {
+ columnBreakpoints = [];
+ lineBreakpoints.put(String(uiLocation.columnNumber), columnBreakpoints);
+ }
+ columnBreakpoints.push(breakpoint);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointAdded, {breakpoint: breakpoint, uiLocation: uiLocation});
},
@@ -377,14 +387,18 @@ WebInspector.BreakpointManager.prototype = {
if (!breakpoints)
return;
- var lineBreakpoints = breakpoints[uiLocation.lineNumber];
+ var lineBreakpoints = breakpoints.get(String(uiLocation.lineNumber));
if (!lineBreakpoints)
return;
-
- lineBreakpoints.remove(breakpoint);
- if (!lineBreakpoints.length)
- delete breakpoints[uiLocation.lineNumber];
- if (Object.keys(breakpoints).length === 0)
+ var columnBreakpoints = lineBreakpoints.get(String(uiLocation.columnNumber));
+ if (!columnBreakpoints)
+ return;
+ columnBreakpoints.remove(breakpoint);
+ if (!columnBreakpoints.length)
+ lineBreakpoints.remove(String(uiLocation.columnNumber));
+ if (!lineBreakpoints.size())
+ breakpoints.remove(String(uiLocation.lineNumber));
+ if (!breakpoints.size())
this._breakpointsForUISourceCode.remove(uiLocation.uiSourceCode);
this.dispatchEventToListeners(WebInspector.BreakpointManager.Events.BreakpointRemoved, {breakpoint: breakpoint, uiLocation: uiLocation});
},
@@ -394,34 +408,60 @@ WebInspector.BreakpointManager.prototype = {
/**
* @constructor
+ * @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.BreakpointManager} breakpointManager
* @param {string} projectId
* @param {string} path
* @param {string} sourceFileId
* @param {number} lineNumber
+ * @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
*/
-WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectId, path, sourceFileId, lineNumber, condition, enabled)
+WebInspector.BreakpointManager.Breakpoint = function(breakpointManager, projectId, path, sourceFileId, lineNumber, columnNumber, condition, enabled)
{
this._breakpointManager = breakpointManager;
this._projectId = projectId;
this._path = path;
this._lineNumber = lineNumber;
+ this._columnNumber = columnNumber;
this._sourceFileId = sourceFileId;
- /** @type {!Array.<!WebInspector.Script.Location>} */
- this._liveLocations = [];
- /** @type {!Object.<string, !WebInspector.UILocation>} */
- this._uiLocations = {};
+
+ /** @type {!Object.<string, number>} */
+ this._numberOfDebuggerLocationForUILocation = {};
// Force breakpoint update.
/** @type {string} */ this._condition;
/** @type {boolean} */ this._enabled;
- this._updateBreakpoint(condition, enabled);
+ /** @type {boolean} */ this._isRemoved;
+ /** @type {!WebInspector.UILocation|undefined} */ this._fakePrimaryLocation;
+
+ /** @type {!Map.<!WebInspector.Target, !WebInspector.BreakpointManager.TargetBreakpoint>}*/
+ this._targetBreakpoints = new Map();
+ this._updateState(condition, enabled);
+ this._breakpointManager._targetManager.observeTargets(this);
}
WebInspector.BreakpointManager.Breakpoint.prototype = {
/**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ this._targetBreakpoints.put(target, new WebInspector.BreakpointManager.TargetBreakpoint(target, this));
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ var targetBreakpoint = this._targetBreakpoints.remove(target);
+ targetBreakpoint._cleanUpAfterDebuggerIsGone();
+ targetBreakpoint._removeEventListeners();
+ },
+
+ /**
* @return {string}
*/
projectId: function()
@@ -446,6 +486,14 @@ WebInspector.BreakpointManager.Breakpoint.prototype = {
},
/**
+ * @return {number}
+ */
+ columnNumber: function()
+ {
+ return this._columnNumber;
+ },
+
+ /**
* @return {?WebInspector.UISourceCode}
*/
uiSourceCode: function()
@@ -454,30 +502,37 @@ WebInspector.BreakpointManager.Breakpoint.prototype = {
},
/**
- * @param {!WebInspector.DebuggerModel.Location} location
+ * @param {?WebInspector.UILocation} oldUILocation
+ * @param {!WebInspector.UILocation} newUILocation
*/
- _addResolvedLocation: function(location)
+ _replaceUILocation: function(oldUILocation, newUILocation)
{
- this._liveLocations.push(this._breakpointManager._debuggerModel.createLiveLocation(location, this._locationUpdated.bind(this, location)));
+ if (this._isRemoved)
+ return;
+
+ this._removeUILocation(oldUILocation, true);
+ this._removeFakeBreakpointAtPrimaryLocation();
+
+ if (!this._numberOfDebuggerLocationForUILocation[newUILocation.id()])
+ this._numberOfDebuggerLocationForUILocation[newUILocation.id()] = 0;
+
+ if (++this._numberOfDebuggerLocationForUILocation[newUILocation.id()] === 1)
+ this._breakpointManager._uiLocationAdded(this, newUILocation);
},
/**
- * @param {!WebInspector.DebuggerModel.Location} location
- * @param {!WebInspector.UILocation} uiLocation
+ * @param {?WebInspector.UILocation} uiLocation
+ * @param {boolean=} muteCreationFakeBreakpoint
*/
- _locationUpdated: function(location, uiLocation)
+ _removeUILocation: function(uiLocation, muteCreationFakeBreakpoint)
{
- var stringifiedLocation = location.scriptId + ":" + location.lineNumber + ":" + location.columnNumber;
- var oldUILocation = /** @type {!WebInspector.UILocation} */ (this._uiLocations[stringifiedLocation]);
- if (oldUILocation)
- this._breakpointManager._uiLocationRemoved(this, oldUILocation);
- if (this._uiLocations[""]) {
- var defaultLocation = this._uiLocations[""];
- delete this._uiLocations[""];
- this._breakpointManager._uiLocationRemoved(this, defaultLocation);
- }
- this._uiLocations[stringifiedLocation] = uiLocation;
- this._breakpointManager._uiLocationAdded(this, uiLocation);
+ if (!uiLocation || --this._numberOfDebuggerLocationForUILocation[uiLocation.id()] !== 0)
+ return;
+
+ delete this._numberOfDebuggerLocationForUILocation[uiLocation.id()];
+ this._breakpointManager._uiLocationRemoved(this, uiLocation);
+ if (!muteCreationFakeBreakpoint)
+ this._fakeBreakpointAtPrimaryLocation();
},
/**
@@ -493,7 +548,7 @@ WebInspector.BreakpointManager.Breakpoint.prototype = {
*/
setEnabled: function(enabled)
{
- this._updateBreakpoint(this._condition, enabled);
+ this._updateState(this._condition, enabled);
},
/**
@@ -509,33 +564,30 @@ WebInspector.BreakpointManager.Breakpoint.prototype = {
*/
setCondition: function(condition)
{
- this._updateBreakpoint(condition, this._enabled);
+ this._updateState(condition, this._enabled);
},
/**
* @param {string} condition
* @param {boolean} enabled
*/
- _updateBreakpoint: function(condition, enabled)
+ _updateState: function(condition, enabled)
{
if (this._enabled === enabled && this._condition === condition)
return;
- this._removeFromDebugger();
this._enabled = enabled;
this._condition = condition;
this._breakpointManager._storage._updateBreakpoint(this);
- this._fakeBreakpointAtPrimaryLocation();
- this._updateInDebugger();
+ this._updateBreakpoint();
},
- _updateInDebugger: function()
+ _updateBreakpoint: function()
{
- var uiSourceCode = this.uiSourceCode();
- if (!uiSourceCode || !uiSourceCode.hasSourceMapping())
- return;
- var scriptFile = uiSourceCode && uiSourceCode.scriptFile();
- if (this._enabled && !(scriptFile && scriptFile.hasDivergedFromVM()))
- this._setInDebugger();
+ this._removeFakeBreakpointAtPrimaryLocation();
+ this._fakeBreakpointAtPrimaryLocation();
+ var targetBreakpoints = this._targetBreakpoints.values();
+ for (var i = 0; i < targetBreakpoints.length; ++i)
+ targetBreakpoints[i]._updateInDebugger();
},
/**
@@ -543,101 +595,223 @@ WebInspector.BreakpointManager.Breakpoint.prototype = {
*/
remove: function(keepInStorage)
{
+ this._isRemoved = true;
var removeFromStorage = !keepInStorage;
- this._resetLocations();
- this._removeFromDebugger();
+ this._removeFakeBreakpointAtPrimaryLocation();
+ var targetBreakpoints = this._targetBreakpoints.values();
+ for (var i = 0; i < targetBreakpoints.length; ++i) {
+ targetBreakpoints[i]._removeFromDebugger();
+ targetBreakpoints[i]._removeEventListeners();
+ }
+
this._breakpointManager._removeBreakpoint(this, removeFromStorage);
+ this._breakpointManager._targetManager.unobserveTargets(this);
},
- _setInDebugger: function()
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ _updateInDebuggerForTarget: function(target)
{
- this._removeFromDebugger();
+ this._targetBreakpoints.get(target)._updateInDebugger();
+ },
+
+ /**
+ * @return {string}
+ */
+ _breakpointStorageId: function()
+ {
+ return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId, this._lineNumber, this._columnNumber);
+ },
+
+ _fakeBreakpointAtPrimaryLocation: function()
+ {
+ if (this._isRemoved || !Object.isEmpty(this._numberOfDebuggerLocationForUILocation) || this._fakePrimaryLocation)
+ return;
+
var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
if (!uiSourceCode)
return;
- var rawLocation = uiSourceCode.uiLocationToRawLocation(this._lineNumber, 0);
+
+ this._fakePrimaryLocation = uiSourceCode.uiLocation(this._lineNumber, this._columnNumber);
+ this._breakpointManager._uiLocationAdded(this, this._fakePrimaryLocation);
+ },
+
+ _removeFakeBreakpointAtPrimaryLocation: function()
+ {
+ if (this._fakePrimaryLocation) {
+ this._breakpointManager._uiLocationRemoved(this, this._fakePrimaryLocation);
+ delete this._fakePrimaryLocation;
+ }
+ },
+
+ _resetLocations: function()
+ {
+ this._removeFakeBreakpointAtPrimaryLocation();
+ var targetBreakpoints = this._targetBreakpoints.values();
+ for (var i = 0; i < targetBreakpoints.length; ++i)
+ targetBreakpoints[i]._resetLocations();
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
+ * @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
+ */
+WebInspector.BreakpointManager.TargetBreakpoint = function(target, breakpoint)
+{
+ WebInspector.TargetAware.call(this, target);
+ this._breakpoint = breakpoint;
+ /** @type {!Array.<!WebInspector.Script.Location>} */
+ this._liveLocations = [];
+
+ /** @type {!Object.<string, !WebInspector.UILocation>} */
+ this._uiLocations = {};
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._updateInDebugger, this);
+ if (target.debuggerModel.debuggerEnabled())
+ this._updateInDebugger();
+}
+
+WebInspector.BreakpointManager.TargetBreakpoint.prototype = {
+
+ _resetLocations: function()
+ {
+ var uiLocations = Object.values(this._uiLocations);
+ for (var i = 0; i < uiLocations.length; ++i)
+ this._breakpoint._removeUILocation(uiLocations[i]);
+
+ this._uiLocations = {};
+
+ for (var i = 0; i < this._liveLocations.length; ++i)
+ this._liveLocations[i].dispose();
+ this._liveLocations = [];
+ },
+
+ /**
+ * @param {boolean=} callbackImmediately
+ */
+ _removeFromDebugger: function(callbackImmediately)
+ {
+ this._resetLocations();
+ if (!this._debuggerId)
+ return;
+ var debuggerId = this._debuggerId;
+ this.target().debuggerModel.removeBreakpoint(this._debuggerId, callbackImmediately ? undefined : didRemoveFromDebugger.bind(this));
+
+ /**
+ * @this {WebInspector.BreakpointManager.TargetBreakpoint}
+ */
+ function didRemoveFromDebugger()
+ {
+ if (this._debuggerId === debuggerId)
+ this._didRemoveFromDebugger();
+ }
+ if (callbackImmediately)
+ this._didRemoveFromDebugger();
+ },
+
+ _updateInDebugger: function()
+ {
+ this._removeFromDebugger();
+ var uiSourceCode = this._breakpoint.uiSourceCode();
+ if (!uiSourceCode || !this._breakpoint._enabled)
+ return;
+ var scriptFile = uiSourceCode.scriptFileForTarget(this._target);
+ if (scriptFile && scriptFile.hasDivergedFromVM())
+ return;
+
+ var lineNumber = this._breakpoint._lineNumber;
+ var columnNumber = this._breakpoint._columnNumber;
+ var rawLocation = uiSourceCode.uiLocationToRawLocation(this._target, lineNumber, columnNumber);
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
+ var condition = this._breakpoint.condition();
if (debuggerModelLocation)
- this._breakpointManager._debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, this._condition, this._didSetBreakpointInDebugger.bind(this));
+ this.target().debuggerModel.setBreakpointByScriptLocation(debuggerModelLocation, condition, this._didSetBreakpointInDebugger.bind(this));
else if (uiSourceCode.url)
- this._breakpointManager._debuggerModel.setBreakpointByURL(uiSourceCode.url, this._lineNumber, 0, this._condition, this._didSetBreakpointInDebugger.bind(this));
+ this.target().debuggerModel.setBreakpointByURL(uiSourceCode.url, lineNumber, columnNumber, condition, this._didSetBreakpointInDebugger.bind(this));
},
/**
- * @this {WebInspector.BreakpointManager.Breakpoint}
- * @param {?DebuggerAgent.BreakpointId} breakpointId
- * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
- */
+ * @param {?DebuggerAgent.BreakpointId} breakpointId
+ * @param {!Array.<!WebInspector.DebuggerModel.Location>} locations
+ */
_didSetBreakpointInDebugger: function(breakpointId, locations)
{
if (!breakpointId) {
- this._resetLocations();
- this._breakpointManager._removeBreakpoint(this, false);
+ this._breakpoint.remove(true);
return;
}
- this._debuggerId = breakpointId;
- this._breakpointManager._breakpointForDebuggerId[breakpointId] = this;
-
- if (!locations.length) {
- this._fakeBreakpointAtPrimaryLocation();
- return;
- }
-
- this._resetLocations();
- for (var i = 0; i < locations.length; ++i) {
- var script = this._breakpointManager._debuggerModel.scriptForId(locations[i].scriptId);
- var uiLocation = script.rawLocationToUILocation(locations[i].lineNumber, locations[i].columnNumber);
- if (this._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber)) {
- // location clash
- this.remove();
- return;
- }
- }
+ if (this._debuggerId)
+ this._removeFromDebugger(true);
+ this._debuggerId = breakpointId;
+ this.target().debuggerModel.addBreakpointListener(this._debuggerId, this._breakpointResolved, this);
for (var i = 0; i < locations.length; ++i)
- this._addResolvedLocation(locations[i]);
+ if (!this._addResolvedLocation(locations[i]))
+ return;
},
- _removeFromDebugger: function()
+ _didRemoveFromDebugger: function()
{
- if (!this._debuggerId)
- return;
- this._breakpointManager._debuggerModel.removeBreakpoint(this._debuggerId);
- delete this._breakpointManager._breakpointForDebuggerId[this._debuggerId];
+ this.target().debuggerModel.removeBreakpointListener(this._debuggerId, this._breakpointResolved, this);
delete this._debuggerId;
},
- _resetLocations: function()
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _breakpointResolved: function(event)
{
- for (var stringifiedLocation in this._uiLocations)
- this._breakpointManager._uiLocationRemoved(this, this._uiLocations[stringifiedLocation]);
-
- for (var i = 0; i < this._liveLocations.length; ++i)
- this._liveLocations[i].dispose();
- this._liveLocations = [];
+ this._addResolvedLocation(/** @type {!WebInspector.DebuggerModel.Location}*/ (event.data));
+ },
- this._uiLocations = {};
+ /**
+ * @param {!WebInspector.DebuggerModel.Location} location
+ * @param {!WebInspector.UILocation} uiLocation
+ */
+ _locationUpdated: function(location, uiLocation)
+ {
+ var oldUILocation = this._uiLocations[location.id()] || null;
+ this._uiLocations[location.id()] = uiLocation;
+ this._breakpoint._replaceUILocation(oldUILocation, uiLocation);
},
/**
- * @return {string}
+ * @param {!WebInspector.DebuggerModel.Location} location
+ * @return {boolean}
*/
- _breakpointStorageId: function()
+ _addResolvedLocation: function(location)
{
- return WebInspector.BreakpointManager._breakpointStorageId(this._sourceFileId, this._lineNumber);
+ var script = location.script();
+ var uiLocation = script.rawLocationToUILocation(location.lineNumber, location.columnNumber);
+ var breakpoint = this._breakpoint._breakpointManager.findBreakpoint(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
+ if (breakpoint && breakpoint != this._breakpoint) {
+ // location clash
+ this._breakpoint.remove();
+ return false;
+ }
+ this._liveLocations.push(location.createLiveLocation(this._locationUpdated.bind(this, location)));
+ return true;
},
- _fakeBreakpointAtPrimaryLocation: function()
+ _cleanUpAfterDebuggerIsGone: function()
{
this._resetLocations();
- var uiSourceCode = this._breakpointManager._workspace.uiSourceCode(this._projectId, this._path);
- if (!uiSourceCode)
- return;
- var uiLocation = new WebInspector.UILocation(uiSourceCode, this._lineNumber, 0);
- this._uiLocations[""] = uiLocation;
- this._breakpointManager._uiLocationAdded(this, uiLocation);
- }
+ if (this._debuggerId)
+ this._didRemoveFromDebugger();
+ },
+
+ _removeEventListeners: function()
+ {
+ this.target().debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._cleanUpAfterDebuggerIsGone, this);
+ this.target().debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._updateInDebugger, this);
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
/**
@@ -654,7 +828,8 @@ WebInspector.BreakpointManager.Storage = function(breakpointManager, setting)
this._breakpoints = {};
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = /** @type {!WebInspector.BreakpointManager.Storage.Item} */ (breakpoints[i]);
- this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber] = breakpoint;
+ breakpoint.columnNumber = breakpoint.columnNumber || 0;
+ this._breakpoints[breakpoint.sourceFileId + ":" + breakpoint.lineNumber + ":" + breakpoint.columnNumber] = breakpoint;
}
}
@@ -724,6 +899,7 @@ WebInspector.BreakpointManager.Storage.Item = function(breakpoint)
{
this.sourceFileId = breakpoint._sourceFileId;
this.lineNumber = breakpoint.lineNumber();
+ this.columnNumber = breakpoint.columnNumber();
this.condition = breakpoint.condition();
this.enabled = breakpoint.enabled();
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileModel.js
new file mode 100644
index 00000000000..3efd7c106a6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfileModel.js
@@ -0,0 +1,288 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * @constructor
+ * @param {!ProfilerAgent.CPUProfile} profile
+ */
+WebInspector.CPUProfileDataModel = function(profile)
+{
+ this.profileHead = profile.head;
+ this.samples = profile.samples;
+ this.timestamps = profile.timestamps;
+ this.profileStartTime = profile.startTime * 1000;
+ this.profileEndTime = profile.endTime * 1000;
+ this._assignParentsInProfile();
+ if (this.samples) {
+ this._normalizeTimestamps();
+ this._buildIdToNodeMap();
+ this._fixMissingSamples();
+ }
+ this._calculateTimes(profile);
+}
+
+WebInspector.CPUProfileDataModel.prototype = {
+ /**
+ * @param {!ProfilerAgent.CPUProfile} profile
+ */
+ _calculateTimes: function(profile)
+ {
+ function totalHitCount(node) {
+ var result = node.hitCount;
+ for (var i = 0; i < node.children.length; i++)
+ result += totalHitCount(node.children[i]);
+ return result;
+ }
+ profile.totalHitCount = totalHitCount(profile.head);
+
+ var duration = this.profileEndTime - this.profileStartTime;
+ var samplingInterval = duration / profile.totalHitCount;
+ this.samplingInterval = samplingInterval;
+
+ function calculateTimesForNode(node) {
+ node.selfTime = node.hitCount * samplingInterval;
+ var totalHitCount = node.hitCount;
+ for (var i = 0; i < node.children.length; i++)
+ totalHitCount += calculateTimesForNode(node.children[i]);
+ node.totalTime = totalHitCount * samplingInterval;
+ return totalHitCount;
+ }
+ calculateTimesForNode(profile.head);
+ },
+
+ _assignParentsInProfile: function()
+ {
+ var head = this.profileHead;
+ head.parent = null;
+ head.depth = -1;
+ this.maxDepth = 0;
+ var nodesToTraverse = [ head ];
+ while (nodesToTraverse.length) {
+ var parent = nodesToTraverse.pop();
+ var depth = parent.depth + 1;
+ if (depth > this.maxDepth)
+ this.maxDepth = depth;
+ var children = parent.children;
+ var length = children.length;
+ for (var i = 0; i < length; ++i) {
+ var child = children[i];
+ child.parent = parent;
+ child.depth = depth;
+ if (child.children.length)
+ nodesToTraverse.push(child);
+ }
+ }
+ },
+
+ _normalizeTimestamps: function()
+ {
+ var timestamps = this.timestamps;
+ if (!timestamps) {
+ // Support loading old CPU profiles that are missing timestamps.
+ // Derive timestamps from profile start and stop times.
+ var profileStartTime = this.profileStartTime;
+ var interval = (this.profileEndTime - profileStartTime) / this.samples.length;
+ timestamps = new Float64Array(this.samples.length + 1);
+ for (var i = 0; i < timestamps.length; ++i)
+ timestamps[i] = profileStartTime + i * interval;
+ this.timestamps = timestamps;
+ return;
+ }
+
+ // Convert samples from usec to msec
+ for (var i = 0; i < timestamps.length; ++i)
+ timestamps[i] /= 1000;
+ var averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1);
+ // Add an extra timestamp used to calculate the last sample duration.
+ this.timestamps.push(timestamps.peekLast() + averageSample);
+ this.profileStartTime = timestamps[0];
+ this.profileEndTime = timestamps.peekLast();
+ },
+
+ _buildIdToNodeMap: function()
+ {
+ /** @type {!Object.<number, !ProfilerAgent.CPUProfileNode>} */
+ this._idToNode = {};
+ var idToNode = this._idToNode;
+ var stack = [this.profileHead];
+ while (stack.length) {
+ var node = stack.pop();
+ idToNode[node.id] = node;
+ for (var i = 0; i < node.children.length; i++)
+ stack.push(node.children[i]);
+ }
+
+ var topLevelNodes = this.profileHead.children;
+ for (var i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {
+ var node = topLevelNodes[i];
+ if (node.functionName === "(garbage collector)")
+ this.gcNode = node;
+ else if (node.functionName === "(program)")
+ this.programNode = node;
+ else if (node.functionName === "(idle)")
+ this.idleNode = node;
+ }
+ },
+
+ _fixMissingSamples: function()
+ {
+ // Sometimes sampler is not able to parse the JS stack and returns
+ // a (program) sample instead. The issue leads to call frames belong
+ // to the same function invocation being split apart.
+ // Here's a workaround for that. When there's a single (program) sample
+ // between two call stacks sharing the same bottom node, it is replaced
+ // with the preceeding sample.
+ var samples = this.samples;
+ var samplesCount = samples.length;
+ if (!this.programNode || samplesCount < 3)
+ return;
+ var idToNode = this._idToNode;
+ var programNodeId = this.programNode.id;
+ var gcNodeId = this.gcNode ? this.gcNode.id : -1;
+ var idleNodeId = this.idleNode ? this.idleNode.id : -1;
+ var prevNodeId = samples[0];
+ var nodeId = samples[1];
+ for (var sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {
+ var nextNodeId = samples[sampleIndex + 1];
+ if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId)
+ && bottomNode(idToNode[prevNodeId]) === bottomNode(idToNode[nextNodeId])) {
+ samples[sampleIndex] = prevNodeId;
+ }
+ prevNodeId = nodeId;
+ nodeId = nextNodeId;
+ }
+
+ /**
+ * @param {!ProfilerAgent.CPUProfileNode} node
+ * @return {!ProfilerAgent.CPUProfileNode}
+ */
+ function bottomNode(node)
+ {
+ while (node.parent)
+ node = node.parent;
+ return node;
+ }
+
+ /**
+ * @param {number} nodeId
+ * @return {boolean}
+ */
+ function isSystemNode(nodeId)
+ {
+ return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;
+ }
+ },
+
+ /**
+ * @param {function(number, !ProfilerAgent.CPUProfileNode, number)} openFrameCallback
+ * @param {function(number, !ProfilerAgent.CPUProfileNode, number, number, number)} closeFrameCallback
+ * @param {number=} startTime
+ * @param {number=} stopTime
+ */
+ forEachFrame: function(openFrameCallback, closeFrameCallback, startTime, stopTime)
+ {
+ if (!this.profileHead)
+ return;
+
+ startTime = startTime || 0;
+ stopTime = stopTime || Infinity;
+ var samples = this.samples;
+ var timestamps = this.timestamps;
+ var idToNode = this._idToNode;
+ var gcNode = this.gcNode;
+ var samplesCount = samples.length;
+ var startIndex = timestamps.lowerBound(startTime);
+ var stackTop = 0;
+ var stackNodes = [];
+ var prevId = this.profileHead.id;
+ var prevHeight = this.profileHead.depth;
+ var sampleTime = timestamps[samplesCount];
+ var gcParentNode = null;
+
+ if (!this._stackStartTimes)
+ this._stackStartTimes = new Float64Array(this.maxDepth + 2);
+ var stackStartTimes = this._stackStartTimes;
+ if (!this._stackChildrenDuration)
+ this._stackChildrenDuration = new Float64Array(this.maxDepth + 2);
+ var stackChildrenDuration = this._stackChildrenDuration;
+
+ for (var sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {
+ sampleTime = timestamps[sampleIndex];
+ if (sampleTime >= stopTime)
+ break;
+ var id = samples[sampleIndex];
+ if (id === prevId)
+ continue;
+ var node = idToNode[id];
+ var prevNode = idToNode[prevId];
+
+ if (node === gcNode) {
+ // GC samples have no stack, so we just put GC node on top of the last recorded sample.
+ gcParentNode = prevNode;
+ openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);
+ stackStartTimes[++stackTop] = sampleTime;
+ stackChildrenDuration[stackTop] = 0;
+ prevId = id;
+ continue;
+ }
+ if (prevNode === gcNode) {
+ // end of GC frame
+ var start = stackStartTimes[stackTop];
+ var duration = sampleTime - start;
+ stackChildrenDuration[stackTop - 1] += duration;
+ closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);
+ --stackTop;
+ prevNode = gcParentNode;
+ prevId = prevNode.id;
+ gcParentNode = null;
+ }
+
+ while (node.depth > prevNode.depth) {
+ stackNodes.push(node);
+ node = node.parent;
+ }
+
+ // Go down to the LCA and close current intervals.
+ while (prevNode !== node) {
+ var start = stackStartTimes[stackTop];
+ var duration = sampleTime - start;
+ stackChildrenDuration[stackTop - 1] += duration;
+ closeFrameCallback(prevNode.depth, prevNode, start, duration, duration - stackChildrenDuration[stackTop]);
+ --stackTop;
+ if (node.depth === prevNode.depth) {
+ stackNodes.push(node);
+ node = node.parent;
+ }
+ prevNode = prevNode.parent;
+ }
+
+ // Go up the nodes stack and open new intervals.
+ while (stackNodes.length) {
+ node = stackNodes.pop();
+ openFrameCallback(node.depth, node, sampleTime);
+ stackStartTimes[++stackTop] = sampleTime;
+ stackChildrenDuration[stackTop] = 0;
+ }
+
+ prevId = id;
+ }
+
+ if (idToNode[prevId] === gcNode) {
+ var start = stackStartTimes[stackTop];
+ var duration = sampleTime - start;
+ stackChildrenDuration[stackTop - 1] += duration;
+ closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);
+ --stackTop;
+ }
+
+ for (var node = idToNode[prevId]; node.parent; node = node.parent) {
+ var start = stackStartTimes[stackTop];
+ var duration = sampleTime - start;
+ stackChildrenDuration[stackTop - 1] += duration;
+ closeFrameCallback(node.depth, node, start, duration, duration - stackChildrenDuration[stackTop]);
+ --stackTop;
+ }
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js
index 67ecf978b9b..ef16cb9cbce 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ProfilesPanelDescriptor.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CPUProfilerModel.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,61 +28,15 @@
/**
* @constructor
- * @extends {WebInspector.PanelDescriptor}
- */
-WebInspector.ProfilesPanelDescriptor = function()
-{
- WebInspector.PanelDescriptor.call(this, "profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js");
-}
-
-WebInspector.ProfilesPanelDescriptor.prototype = {
- registerShortcuts: function()
- {
- var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Profiles Panel"));
- section.addAlternateKeys(WebInspector.ProfilesPanelDescriptor.ShortcutKeys.StartStopRecording, WebInspector.UIString("Start/stop recording"));
- },
-
- __proto__: WebInspector.PanelDescriptor.prototype
-}
-
-WebInspector.ProfilesPanelDescriptor.ShortcutKeys = {
- StartStopRecording: [
- WebInspector.KeyboardShortcut.makeDescriptor("e", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)
- ]
-}
-
-WebInspector.ProfilesPanelDescriptor.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)/;
-
-/** @interface */
-WebInspector.CPUProfilerModelDelegate = function() {};
-
-WebInspector.CPUProfilerModelDelegate.prototype = {
- /**
- * @param {string} protocolId
- * @param {!DebuggerAgent.Location} scriptLocation
- * @param {string=} title
- */
- consoleProfile: function(protocolId, scriptLocation, title) {},
-
- /**
- * @param {string} protocolId
- * @param {!DebuggerAgent.Location} scriptLocation
- * @param {!ProfilerAgent.CPUProfile} cpuProfile
- * @param {string=} title
- */
- consoleProfileEnd: function(protocolId, scriptLocation, cpuProfile, title) {},
-
- resetProfiles: function() {}
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
* @implements {ProfilerAgent.Dispatcher}
*/
-WebInspector.CPUProfilerModel = function()
+WebInspector.CPUProfilerModel = function(target)
{
- /** @type {?WebInspector.CPUProfilerModelDelegate} */
+ WebInspector.TargetAwareObject.call(this, target);
+
+ /** @type {?WebInspector.CPUProfilerModel.Delegate} */
this._delegate = null;
this._isRecording = false;
InspectorBackend.registerProfilerDispatcher(this);
@@ -96,7 +50,7 @@ WebInspector.CPUProfilerModel.EventTypes = {
WebInspector.CPUProfilerModel.prototype = {
/**
- * @param {!WebInspector.CPUProfilerModelDelegate} delegate
+ * @param {!WebInspector.CPUProfilerModel.Delegate} delegate
*/
setDelegate: function(delegate)
{
@@ -109,11 +63,11 @@ WebInspector.CPUProfilerModel.prototype = {
* @param {!ProfilerAgent.CPUProfile} cpuProfile
* @param {string=} title
*/
- addProfileHeader: function(id, scriptLocation, cpuProfile, title)
+ consoleProfileFinished: function(id, scriptLocation, cpuProfile, title)
{
// Make sure ProfilesPanel is initialized and CPUProfileType is created.
- WebInspector.inspectorView.panel("profiles");
- this._delegate.consoleProfileEnd(id, scriptLocation, cpuProfile, title);
+ WebInspector.moduleManager.loadModule("profiler");
+ this._delegate.consoleProfileFinished(id, WebInspector.DebuggerModel.Location.fromPayload(this.target(), scriptLocation), cpuProfile, title);
},
/**
@@ -121,20 +75,11 @@ WebInspector.CPUProfilerModel.prototype = {
* @param {!DebuggerAgent.Location} scriptLocation
* @param {string=} title
*/
- consoleProfile: function(id, scriptLocation, title)
+ consoleProfileStarted: function(id, scriptLocation, title)
{
// Make sure ProfilesPanel is initialized and CPUProfileType is created.
- WebInspector.inspectorView.panel("profiles");
- this._delegate.consoleProfile(id, scriptLocation, title);
- },
-
- /**
- * @override
- */
- resetProfiles: function()
- {
- if (this._delegate)
- this._delegate.resetProfiles();
+ WebInspector.moduleManager.loadModule("profiler");
+ this._delegate.consoleProfileStarted(id, WebInspector.DebuggerModel.Location.fromPayload(this.target(), scriptLocation), title);
},
/**
@@ -156,7 +101,27 @@ WebInspector.CPUProfilerModel.prototype = {
return this._isRecording;
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/** @interface */
+WebInspector.CPUProfilerModel.Delegate = function() {};
+
+WebInspector.CPUProfilerModel.Delegate.prototype = {
+ /**
+ * @param {string} protocolId
+ * @param {!WebInspector.DebuggerModel.Location} scriptLocation
+ * @param {string=} title
+ */
+ consoleProfileStarted: function(protocolId, scriptLocation, title) {},
+
+ /**
+ * @param {string} protocolId
+ * @param {!WebInspector.DebuggerModel.Location} scriptLocation
+ * @param {!ProfilerAgent.CPUProfile} cpuProfile
+ * @param {string=} title
+ */
+ consoleProfileFinished: function(protocolId, scriptLocation, cpuProfile, title) {}
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSMetadata.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
index 1d3376d5f1e..c6e0da717fe 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSMetadata.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -32,7 +32,7 @@
/**
* @constructor
- * @param {!Array.<!CSSAgent.CSSPropertyInfo|string>} properties
+ * @param {!Array.<!{name: string, longhands: !Array.<string>}|string>} properties
*/
WebInspector.CSSMetadata = function(properties)
{
@@ -45,7 +45,6 @@ WebInspector.CSSMetadata = function(properties)
this._values.push(property);
continue;
}
-
var propertyName = property.name;
this._values.push(propertyName);
@@ -71,11 +70,18 @@ WebInspector.CSSMetadata = function(properties)
*/
WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata([]);
+/**
+ * @param {string} propertyName
+ * @return {boolean}
+ */
WebInspector.CSSMetadata.isColorAwareProperty = function(propertyName)
{
return WebInspector.CSSMetadata._colorAwareProperties[propertyName] === true;
}
+/**
+ * @return {!Object.<string, boolean>}
+ */
WebInspector.CSSMetadata.colors = function()
{
if (!WebInspector.CSSMetadata._colorsKeySet)
@@ -107,7 +113,9 @@ WebInspector.CSSMetadata.canonicalPropertyName = function(name)
if (!name || name.length < 9 || name.charAt(0) !== "-")
return name.toLowerCase();
var match = name.match(/(?:-webkit-)(.+)/);
- if (!match)
+ var propertiesSet = WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet();
+ var hasSupportedProperties = WebInspector.CSSMetadata.cssPropertiesMetainfo._values.length > 0;
+ if (!match || (hasSupportedProperties && !propertiesSet.hasOwnProperty(match[1].toLowerCase())))
return name.toLowerCase();
return match[1].toLowerCase();
}
@@ -214,6 +222,9 @@ WebInspector.CSSMetadata._propertyDataMap = {
"border-left-width": { values: [
"medium", "thick", "thin"
] },
+ "box-shadow": { values: [
+ "inset", "none"
+ ] },
"-webkit-writing-mode": { values: [
"lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
] },
@@ -248,6 +259,9 @@ WebInspector.CSSMetadata._propertyDataMap = {
"border-width": { values: [
"medium", "thick", "thin"
] },
+ "border-style": { values: [
+ "none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
+ ] },
"size": { values: [
"a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
] },
@@ -429,7 +443,7 @@ WebInspector.CSSMetadata._propertyDataMap = {
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
] },
"unicode-bidi": { values: [
- "normal", "bidi-override", "embed"
+ "normal", "bidi-override", "embed", "isolate", "isolate-override", "plaintext"
] },
"clip-rule": { values: [
"nonzero", "evenodd"
@@ -516,7 +530,7 @@ WebInspector.CSSMetadata._propertyDataMap = {
"-webkit-text-emphasis-style": { values: [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
] },
- "-webkit-transform": { values: [
+ "transform": { values: [
"scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY",
"translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
] },
@@ -655,12 +669,11 @@ WebInspector.CSSMetadata._propertyDataMap = {
"border-left": { m: "background" },
"border-radius": { m: "background" },
"bottom": { m: "visuren" },
- "box-shadow": { m: "background" },
"color": { m: "color", a: "foreground" },
"counter-increment": { m: "generate" },
"counter-reset": { m: "generate" },
- "grid-definition-columns": { m: "grid" },
- "grid-definition-rows": { m: "grid" },
+ "grid-template-columns": { m: "grid" },
+ "grid-template-rows": { m: "grid" },
"height": { m: "box" },
"image-orientation": { m: "images" },
"left": { m: "visuren" },
@@ -718,16 +731,14 @@ WebInspector.CSSMetadata.descriptor = function(propertyName)
return entry || null;
}
-WebInspector.CSSMetadata.requestCSSShorthandData = function()
+WebInspector.CSSMetadata.initializeWithSupportedProperties = function(properties)
{
- function propertyNamesCallback(error, properties)
- {
- if (!error)
- WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
- }
- CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
+ WebInspector.CSSMetadata.cssPropertiesMetainfo = new WebInspector.CSSMetadata(properties);
}
+/**
+ * @return {!Object.<string, boolean>}
+ */
WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet = function()
{
if (!WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet)
@@ -735,7 +746,7 @@ WebInspector.CSSMetadata.cssPropertiesMetainfoKeySet = function()
return WebInspector.CSSMetadata._cssPropertiesMetainfoKeySet;
}
-// Weight of CSS properties based their usage on few popular websites https://gist.github.com/3751436
+// Weight of CSS properties based on their usage on a few popular websites: https://gist.github.com/3751436
WebInspector.CSSMetadata.Weight = {
"-webkit-animation": 1,
"-webkit-animation-duration": 1,
@@ -748,7 +759,6 @@ WebInspector.CSSMetadata.Weight = {
"-webkit-border-vertical-spacing": 1,
"-webkit-box-shadow": 24,
"-webkit-font-smoothing": 2,
- "-webkit-transform": 1,
"-webkit-transition": 8,
"-webkit-transition-delay": 7,
"-webkit-transition-duration": 7,
@@ -844,6 +854,7 @@ WebInspector.CSSMetadata.Weight = {
"text-shadow": 19,
"text-transform": 5,
"top": 71,
+ "transform": 1,
"unicode-bidi": 1,
"vertical-align": 37,
"visibility": 11,
@@ -882,6 +893,8 @@ WebInspector.CSSMetadata.prototype = {
var index = 0;
for (var i = 0; i < properties.length; i++) {
var weight = WebInspector.CSSMetadata.Weight[properties[i]];
+ if (!weight)
+ weight = WebInspector.CSSMetadata.Weight[WebInspector.CSSMetadata.canonicalPropertyName(properties[i])];
if (weight > maxWeight) {
maxWeight = weight;
index = i;
@@ -922,6 +935,9 @@ WebInspector.CSSMetadata.prototype = {
return foundIndex;
},
+ /**
+ * @return {!Object.<string, boolean>}
+ */
keySet: function()
{
if (!this._keySet)
@@ -929,16 +945,32 @@ WebInspector.CSSMetadata.prototype = {
return this._keySet;
},
+ /**
+ * @param {string} str
+ * @param {string} prefix
+ * @return {string}
+ */
next: function(str, prefix)
{
return this._closest(str, prefix, 1);
},
+ /**
+ * @param {string} str
+ * @param {string} prefix
+ * @return {string}
+ */
previous: function(str, prefix)
{
return this._closest(str, prefix, -1);
},
+ /**
+ * @param {string} str
+ * @param {string} prefix
+ * @param {number} shift
+ * @return {string}
+ */
_closest: function(str, prefix, shift)
{
if (!str)
@@ -977,3 +1009,5 @@ WebInspector.CSSMetadata.prototype = {
return this._shorthands[longhand];
}
}
+
+WebInspector.CSSMetadata.initializeWithSupportedProperties([]);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js
new file mode 100644
index 00000000000..bbcf8f114b7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSParser.js
@@ -0,0 +1,129 @@
+/**
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.CSSParser = function()
+{
+ this._worker = new Worker("script_formatter_worker/ScriptFormatterWorker.js");
+ this._worker.onmessage = this._onRuleChunk.bind(this);
+ this._rules = [];
+}
+
+WebInspector.CSSParser.Events = {
+ RulesParsed: "RulesParsed"
+}
+
+WebInspector.CSSParser.prototype = {
+ /**
+ * @param {!WebInspector.CSSStyleSheetHeader} styleSheetHeader
+ * @param {function(!Array.<!WebInspector.CSSParser.Rule>)=} callback
+ */
+ fetchAndParse: function(styleSheetHeader, callback)
+ {
+ this._lock();
+ this._finishedCallback = callback;
+ styleSheetHeader.requestContent(this._innerParse.bind(this));
+ },
+
+ /**
+ * @param {string} text
+ * @param {function(!Array.<!WebInspector.CSSParser.Rule>)=} callback
+ */
+ parse: function(text, callback)
+ {
+ this._lock();
+ this._finishedCallback = callback;
+ this._innerParse(text);
+ },
+
+ dispose: function()
+ {
+ if (this._worker) {
+ this._worker.terminate();
+ delete this._worker;
+ }
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.CSSParser.Rule>}
+ */
+ rules: function()
+ {
+ return this._rules;
+ },
+
+ _lock: function()
+ {
+ console.assert(!this._parsingStyleSheet, "Received request to parse stylesheet before previous was completed.");
+ this._parsingStyleSheet = true;
+ },
+
+ _unlock: function()
+ {
+ delete this._parsingStyleSheet;
+ },
+
+ /**
+ * @param {?string} text
+ */
+ _innerParse: function(text)
+ {
+ this._rules = [];
+ this._worker.postMessage({ method: "parseCSS", params: { content: text } });
+ },
+
+ /**
+ * @param {!MessageEvent} event
+ */
+ _onRuleChunk: function(event)
+ {
+ var data = /** @type {!WebInspector.CSSParser.DataChunk} */ (event.data);
+ var chunk = data.chunk;
+ for (var i = 0; i < chunk.length; ++i)
+ this._rules.push(chunk[i]);
+
+ if (data.isLastChunk)
+ this._onFinishedParsing();
+ this.dispatchEventToListeners(WebInspector.CSSParser.Events.RulesParsed);
+ },
+
+ _onFinishedParsing: function()
+ {
+ this._unlock();
+ if (this._finishedCallback)
+ this._finishedCallback(this._rules);
+ },
+
+ __proto__: WebInspector.Object.prototype,
+}
+
+/**
+ * @typedef {{isLastChunk: boolean, chunk: !Array.<!WebInspector.CSSParser.Rule>}}
+ */
+WebInspector.CSSParser.DataChunk;
+
+/**
+ * @typedef {{selectorText: string, lineNumber: number, columnNumber: number, properties: !Array.<!WebInspector.CSSParser.Property>}}
+ */
+WebInspector.CSSParser.StyleRule;
+
+/**
+ * @typedef {{atRule: string, lineNumber: number, columnNumber: number}}
+ */
+WebInspector.CSSParser.AtRule;
+
+/**
+ * @typedef {(WebInspector.CSSParser.StyleRule|WebInspector.CSSParser.AtRule)}
+ */
+WebInspector.CSSParser.Rule;
+
+/**
+ * @typedef {{name: string, value: string}}
+ */
+WebInspector.CSSParser.Property;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js
index 3fc26ef4373..c63a310d7a4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleModel.js
@@ -30,35 +30,39 @@
/**
* @constructor
- * @extends {WebInspector.Object}
- * @param {!WebInspector.Workspace} workspace
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.CSSStyleModel = function(workspace)
+WebInspector.CSSStyleModel = function(target)
{
- this._workspace = workspace;
+ WebInspector.TargetAwareObject.call(this, target);
+ this._domModel = target.domModel;
+ this._agent = target.cssAgent();
this._pendingCommandsMajorState = [];
this._styleLoader = new WebInspector.CSSStyleModel.ComputedStyleLoader(this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this);
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, this._mainFrameCreatedOrNavigated, this);
- this._namedFlowCollections = {};
- WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this);
- InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
- CSSAgent.enable(this._wasEnabled.bind(this));
+ this._domModel.addEventListener(WebInspector.DOMModel.Events.UndoRedoRequested, this._undoRedoRequested, this);
+ this._domModel.addEventListener(WebInspector.DOMModel.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ target.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
+ this._agent.enable(this._wasEnabled.bind(this));
this._resetStyleSheets();
}
+WebInspector.CSSStyleModel.PseudoStatePropertyName = "pseudoState";
+
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!Array.<!CSSAgent.RuleMatch>|undefined} matchArray
+ * @return {!Array.<!WebInspector.CSSRule>}
*/
-WebInspector.CSSStyleModel.parseRuleMatchArrayPayload = function(matchArray)
+WebInspector.CSSStyleModel.parseRuleMatchArrayPayload = function(cssModel, matchArray)
{
if (!matchArray)
return [];
var result = [];
for (var i = 0; i < matchArray.length; ++i)
- result.push(WebInspector.CSSRule.parsePayload(matchArray[i].rule, matchArray[i].matchingSelectors));
+ result.push(WebInspector.CSSRule.parsePayload(cssModel, matchArray[i].rule, matchArray[i].matchingSelectors));
return result;
}
@@ -68,16 +72,32 @@ WebInspector.CSSStyleModel.Events = {
StyleSheetChanged: "StyleSheetChanged",
StyleSheetRemoved: "StyleSheetRemoved",
MediaQueryResultChanged: "MediaQueryResultChanged",
- NamedFlowCreated: "NamedFlowCreated",
- NamedFlowRemoved: "NamedFlowRemoved",
- RegionLayoutUpdated: "RegionLayoutUpdated",
- RegionOversetChanged: "RegionOversetChanged"
}
WebInspector.CSSStyleModel.MediaTypes = ["all", "braille", "embossed", "handheld", "print", "projection", "screen", "speech", "tty", "tv"];
WebInspector.CSSStyleModel.prototype = {
/**
+ * @param {function(!Array.<!WebInspector.CSSMedia>)} userCallback
+ */
+ getMediaQueries: function(userCallback)
+ {
+ /**
+ * @param {?Protocol.Error} error
+ * @param {?Array.<!CSSAgent.CSSMedia>} payload
+ * @this {!WebInspector.CSSStyleModel}
+ */
+ function callback(error, payload)
+ {
+ var models = [];
+ if (!error && payload)
+ models = WebInspector.CSSMedia.parseMediaArrayPayload(this, payload);
+ userCallback(models);
+ }
+ this._agent.getMediaQueries(callback.bind(this));
+ },
+
+ /**
* @return {boolean}
*/
isEnabled: function()
@@ -105,6 +125,7 @@ WebInspector.CSSStyleModel.prototype = {
* @param {!Array.<!CSSAgent.RuleMatch>=} matchedPayload
* @param {!Array.<!CSSAgent.PseudoIdMatches>=} pseudoPayload
* @param {!Array.<!CSSAgent.InheritedStyleEntry>=} inheritedPayload
+ * @this {WebInspector.CSSStyleModel}
*/
function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload)
{
@@ -115,13 +136,13 @@ WebInspector.CSSStyleModel.prototype = {
}
var result = {};
- result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(matchedPayload);
+ result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(this, matchedPayload);
result.pseudoElements = [];
if (pseudoPayload) {
for (var i = 0; i < pseudoPayload.length; ++i) {
var entryPayload = pseudoPayload[i];
- result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matches) });
+ result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(this, entryPayload.matches) });
}
}
@@ -131,9 +152,9 @@ WebInspector.CSSStyleModel.prototype = {
var entryPayload = inheritedPayload[i];
var entry = {};
if (entryPayload.inlineStyle)
- entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
+ entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(this, entryPayload.inlineStyle);
if (entryPayload.matchedCSSRules)
- entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(entryPayload.matchedCSSRules);
+ entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleMatchArrayPayload(this, entryPayload.matchedCSSRules);
result.inherited.push(entry);
}
}
@@ -142,7 +163,7 @@ WebInspector.CSSStyleModel.prototype = {
userCallback(result);
}
- CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback));
+ this._agent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(this, userCallback));
},
/**
@@ -167,110 +188,91 @@ WebInspector.CSSStyleModel.prototype = {
else
callback(cssFamilyName, fonts);
}
- CSSAgent.getPlatformFontsForNode(nodeId, platformFontsCallback);
+ this._agent.getPlatformFontsForNode(nodeId, platformFontsCallback);
},
/**
- * @param {!DOMAgent.NodeId} nodeId
- * @param {function(?WebInspector.CSSStyleDeclaration, ?WebInspector.CSSStyleDeclaration)} userCallback
+ * @return {!Array.<!WebInspector.CSSStyleSheetHeader>}
*/
- getInlineStylesAsync: function(nodeId, userCallback)
+ allStyleSheets: function()
{
+ var values = Object.values(this._styleSheetIdToHeader);
/**
- * @param {function(?WebInspector.CSSStyleDeclaration, ?WebInspector.CSSStyleDeclaration)} userCallback
- * @param {?Protocol.Error} error
- * @param {?CSSAgent.CSSStyle=} inlinePayload
- * @param {?CSSAgent.CSSStyle=} attributesStylePayload
+ * @param {!WebInspector.CSSStyleSheetHeader} a
+ * @param {!WebInspector.CSSStyleSheetHeader} b
+ * @return {number}
*/
- function callback(userCallback, error, inlinePayload, attributesStylePayload)
+ function styleSheetComparator(a, b)
{
- if (error || !inlinePayload)
- userCallback(null, null);
- else
- userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null);
+ if (a.sourceURL < b.sourceURL)
+ return -1;
+ else if (a.sourceURL > b.sourceURL)
+ return 1;
+ return a.startLine - b.startLine || a.startColumn - b.startColumn;
}
+ values.sort(styleSheetComparator);
- CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback));
+ return values;
},
/**
* @param {!DOMAgent.NodeId} nodeId
- * @param {?Array.<string>|undefined} forcedPseudoClasses
- * @param {function()=} userCallback
- */
- forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback)
- {
- CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback);
- },
-
- /**
- * @param {!DOMAgent.NodeId} documentNodeId
- * @param {function(?WebInspector.NamedFlowCollection)} userCallback
+ * @param {function(?WebInspector.CSSStyleDeclaration, ?WebInspector.CSSStyleDeclaration)} userCallback
*/
- getNamedFlowCollectionAsync: function(documentNodeId, userCallback)
+ getInlineStylesAsync: function(nodeId, userCallback)
{
- var namedFlowCollection = this._namedFlowCollections[documentNodeId];
- if (namedFlowCollection) {
- userCallback(namedFlowCollection);
- return;
- }
-
/**
- * @param {function(?WebInspector.NamedFlowCollection)} userCallback
+ * @param {function(?WebInspector.CSSStyleDeclaration, ?WebInspector.CSSStyleDeclaration)} userCallback
* @param {?Protocol.Error} error
- * @param {?Array.<!CSSAgent.NamedFlow>} namedFlowPayload
+ * @param {?CSSAgent.CSSStyle=} inlinePayload
+ * @param {?CSSAgent.CSSStyle=} attributesStylePayload
* @this {WebInspector.CSSStyleModel}
*/
- function callback(userCallback, error, namedFlowPayload)
+ function callback(userCallback, error, inlinePayload, attributesStylePayload)
{
- if (error || !namedFlowPayload)
- userCallback(null);
- else {
- var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload);
- this._namedFlowCollections[documentNodeId] = namedFlowCollection;
- userCallback(namedFlowCollection);
- }
+ if (error || !inlinePayload)
+ userCallback(null, null);
+ else
+ userCallback(WebInspector.CSSStyleDeclaration.parsePayload(this, inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(this, attributesStylePayload) : null);
}
- CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback));
+ this._agent.getInlineStylesForNode(nodeId, callback.bind(this, userCallback));
},
/**
- * @param {!DOMAgent.NodeId} documentNodeId
- * @param {string} flowName
- * @param {function(?WebInspector.NamedFlow)} userCallback
+ * @param {!WebInspector.DOMNode} node
+ * @param {string} pseudoClass
+ * @param {boolean} enable
+ * @return {boolean}
*/
- getFlowByNameAsync: function(documentNodeId, flowName, userCallback)
- {
- var namedFlowCollection = this._namedFlowCollections[documentNodeId];
- if (namedFlowCollection) {
- userCallback(namedFlowCollection.flowByName(flowName));
- return;
+ forcePseudoState: function(node, pseudoClass, enable)
+ {
+ var pseudoClasses = node.getUserProperty(WebInspector.CSSStyleModel.PseudoStatePropertyName) || [];
+ if (enable) {
+ if (pseudoClasses.indexOf(pseudoClass) >= 0)
+ return false;
+ pseudoClasses.push(pseudoClass);
+ node.setUserProperty(WebInspector.CSSStyleModel.PseudoStatePropertyName, pseudoClasses);
+ } else {
+ if (pseudoClasses.indexOf(pseudoClass) < 0)
+ return false;
+ pseudoClasses.remove(pseudoClass);
+ if (!pseudoClasses.length)
+ node.removeUserProperty(WebInspector.CSSStyleModel.PseudoStatePropertyName);
}
- /**
- * @param {function(?WebInspector.NamedFlow)} userCallback
- * @param {?WebInspector.NamedFlowCollection} namedFlowCollection
- */
- function callback(userCallback, namedFlowCollection)
- {
- if (!namedFlowCollection)
- userCallback(null);
- else
- userCallback(namedFlowCollection.flowByName(flowName));
- }
-
- this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback));
+ this._agent.forcePseudoState(node.id, pseudoClasses);
+ return true;
},
/**
- * @param {!CSSAgent.CSSRuleId} ruleId
+ * @param {!CSSAgent.CSSRule} rule
* @param {!DOMAgent.NodeId} nodeId
* @param {string} newSelector
* @param {function(!WebInspector.CSSRule)} successCallback
* @param {function()} failureCallback
*/
- setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
+ setRuleSelector: function(rule, nodeId, newSelector, successCallback, failureCallback)
{
/**
* @param {!DOMAgent.NodeId} nodeId
@@ -288,13 +290,14 @@ WebInspector.CSSStyleModel.prototype = {
failureCallback();
return;
}
- WebInspector.domAgent.markUndoableState();
+ this._domModel.markUndoableState();
this._computeMatchingSelectors(rulePayload, nodeId, successCallback, failureCallback);
}
-
+ if (!rule.styleSheetId)
+ throw "No rule stylesheet id";
this._pendingCommandsMajorState.push(true);
- CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
+ this._agent.setRuleSelector(rule.styleSheetId, rule.selectorRange, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
},
/**
@@ -310,13 +313,13 @@ WebInspector.CSSStyleModel.prototype = {
failureCallback();
return;
}
- var rule = WebInspector.CSSRule.parsePayload(rulePayload);
+ var rule = WebInspector.CSSRule.parsePayload(this, rulePayload);
var matchingSelectors = [];
var allSelectorsBarrier = new CallbackBarrier();
for (var i = 0; i < rule.selectors.length; ++i) {
var selector = rule.selectors[i];
- var boundCallback = allSelectorsBarrier.createCallback(selectorQueried.bind(this, i, nodeId, matchingSelectors));
- WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector.value, boundCallback);
+ var boundCallback = allSelectorsBarrier.createCallback(selectorQueried.bind(null, i, nodeId, matchingSelectors));
+ this._domModel.querySelectorAll(ownerDocumentId, selector.value, boundCallback);
}
allSelectorsBarrier.callWhenDone(function() {
rule.matchingSelectors = matchingSelectors;
@@ -339,13 +342,17 @@ WebInspector.CSSStyleModel.prototype = {
},
/**
- * @param {!DOMAgent.NodeId} nodeId
+ * @param {!CSSAgent.StyleSheetId} styleSheetId
+ * @param {!WebInspector.DOMNode} node
* @param {string} selector
* @param {function(!WebInspector.CSSRule)} successCallback
* @param {function()} failureCallback
*/
- addRule: function(nodeId, selector, successCallback, failureCallback)
+ addRule: function(styleSheetId, node, selector, successCallback, failureCallback)
{
+ this._pendingCommandsMajorState.push(true);
+ this._agent.addRule(styleSheetId, selector, callback.bind(this));
+
/**
* @param {?Protocol.Error} error
* @param {!CSSAgent.CSSRule} rulePayload
@@ -358,18 +365,47 @@ WebInspector.CSSStyleModel.prototype = {
// Invalid syntax for a selector
failureCallback();
} else {
- WebInspector.domAgent.markUndoableState();
- this._computeMatchingSelectors(rulePayload, nodeId, successCallback, failureCallback);
+ this._domModel.markUndoableState();
+ this._computeMatchingSelectors(rulePayload, node.id, successCallback, failureCallback);
}
}
+ },
- this._pendingCommandsMajorState.push(true);
- CSSAgent.addRule(nodeId, selector, callback.bind(this));
+ /**
+ * @param {!WebInspector.DOMNode} node
+ * @param {function(?WebInspector.CSSStyleSheetHeader)} callback
+ */
+ requestViaInspectorStylesheet: function(node, callback)
+ {
+ var frameId = node.frameId() || this.target().resourceTreeModel.mainFrame.id;
+ for (var styleSheetId in this._styleSheetIdToHeader) {
+ var styleSheetHeader = this._styleSheetIdToHeader[styleSheetId];
+ if (styleSheetHeader.frameId === frameId && styleSheetHeader.isViaInspector()) {
+ callback(styleSheetHeader);
+ return;
+ }
+ }
+
+ /**
+ * @this {WebInspector.CSSStyleModel}
+ * @param {?Protocol.Error} error
+ * @param {!CSSAgent.StyleSheetId} styleSheetId
+ */
+ function innerCallback(error, styleSheetId)
+ {
+ if (error) {
+ console.error(error);
+ callback(null);
+ }
+
+ callback(this._styleSheetIdToHeader[styleSheetId]);
+ }
+
+ this._agent.createStyleSheet(frameId, innerCallback.bind(this));
},
mediaQueryResultChanged: function()
{
- this._styleLoader.reset();
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged);
},
@@ -396,7 +432,7 @@ WebInspector.CSSStyleModel.prototype = {
*/
_ownerDocumentId: function(nodeId)
{
- var node = WebInspector.domAgent.nodeForId(nodeId);
+ var node = this._domModel.nodeForId(nodeId);
if (!node)
return null;
return node.ownerDocument ? node.ownerDocument.id : null;
@@ -407,7 +443,6 @@ WebInspector.CSSStyleModel.prototype = {
*/
_fireStyleSheetChanged: function(styleSheetId)
{
- this._styleLoader.reset();
if (!this._pendingCommandsMajorState.length)
return;
@@ -425,7 +460,7 @@ WebInspector.CSSStyleModel.prototype = {
_styleSheetAdded: function(header)
{
console.assert(!this._styleSheetIdToHeader[header.styleSheetId]);
- var styleSheetHeader = new WebInspector.CSSStyleSheetHeader(header);
+ var styleSheetHeader = new WebInspector.CSSStyleSheetHeader(this, header);
this._styleSheetIdToHeader[header.styleSheetId] = styleSheetHeader;
var url = styleSheetHeader.resourceURL();
if (!this._styleSheetIdsForURL[url])
@@ -437,7 +472,6 @@ WebInspector.CSSStyleModel.prototype = {
frameIdToStyleSheetIds[styleSheetHeader.frameId] = styleSheetIds;
}
styleSheetIds.push(styleSheetHeader.id);
- this._styleLoader.reset();
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetAdded, styleSheetHeader);
},
@@ -448,6 +482,8 @@ WebInspector.CSSStyleModel.prototype = {
{
var header = this._styleSheetIdToHeader[id];
console.assert(header);
+ if (!header)
+ return;
delete this._styleSheetIdToHeader[id];
var url = header.resourceURL();
var frameIdToStyleSheetIds = this._styleSheetIdsForURL[url];
@@ -457,7 +493,6 @@ WebInspector.CSSStyleModel.prototype = {
if (!Object.keys(this._styleSheetIdsForURL[url]).length)
delete this._styleSheetIdsForURL[url];
}
- this._styleLoader.reset();
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, header);
},
@@ -490,66 +525,6 @@ WebInspector.CSSStyleModel.prototype = {
},
/**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- _namedFlowCreated: function(namedFlowPayload)
- {
- var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
- var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
-
- if (!namedFlowCollection)
- return;
-
- namedFlowCollection._appendNamedFlow(namedFlow);
- this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow);
- },
-
- /**
- * @param {!DOMAgent.NodeId} documentNodeId
- * @param {string} flowName
- */
- _namedFlowRemoved: function(documentNodeId, flowName)
- {
- var namedFlowCollection = this._namedFlowCollections[documentNodeId];
-
- if (!namedFlowCollection)
- return;
-
- namedFlowCollection._removeNamedFlow(flowName);
- this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName });
- },
-
- /**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- _regionLayoutUpdated: function(namedFlowPayload)
- {
- var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
- var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
-
- if (!namedFlowCollection)
- return;
-
- namedFlowCollection._appendNamedFlow(namedFlow);
- this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow);
- },
-
- /**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- _regionOversetChanged: function(namedFlowPayload)
- {
- var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
- var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
-
- if (!namedFlowCollection)
- return;
-
- namedFlowCollection._appendNamedFlow(namedFlow);
- this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionOversetChanged, namedFlow);
- },
-
- /**
* @param {!CSSAgent.StyleSheetId} styleSheetId
* @param {string} newText
* @param {boolean} majorChange
@@ -557,6 +532,11 @@ WebInspector.CSSStyleModel.prototype = {
*/
setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
{
+ var header = this._styleSheetIdToHeader[styleSheetId];
+ console.assert(header);
+ this._pendingCommandsMajorState.push(majorChange);
+ header.setContent(newText, callback.bind(this));
+
/**
* @param {?Protocol.Error} error
* @this {WebInspector.CSSStyleModel}
@@ -565,13 +545,11 @@ WebInspector.CSSStyleModel.prototype = {
{
this._pendingCommandsMajorState.pop();
if (!error && majorChange)
- WebInspector.domAgent.markUndoableState();
-
+ this._domModel.markUndoableState();
+
if (!error && userCallback)
userCallback(error);
}
- this._pendingCommandsMajorState.push(majorChange);
- CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
},
_undoRedoRequested: function()
@@ -584,7 +562,7 @@ WebInspector.CSSStyleModel.prototype = {
this._pendingCommandsMajorState.pop();
},
- _mainFrameCreatedOrNavigated: function()
+ _mainFrameNavigated: function()
{
this._resetStyleSheets();
},
@@ -597,11 +575,6 @@ WebInspector.CSSStyleModel.prototype = {
this._styleSheetIdToHeader = {};
},
- _resetNamedFlowCollections: function()
- {
- this._namedFlowCollections = {};
- },
-
updateLocations: function()
{
var headers = Object.values(this._styleSheetIdToHeader);
@@ -644,7 +617,7 @@ WebInspector.CSSStyleModel.prototype = {
return uiLocation || null;
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
@@ -719,12 +692,14 @@ WebInspector.CSSStyleModel.LiveLocation.prototype = {
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(cssLocation.url);
if (!uiSourceCode)
return null;
- return new WebInspector.UILocation(uiSourceCode, cssLocation.lineNumber, cssLocation.columnNumber);
+ return uiSourceCode.uiLocation(cssLocation.lineNumber, cssLocation.columnNumber);
},
dispose: function()
{
WebInspector.LiveLocation.prototype.dispose.call(this);
+ if (this._header)
+ this._header._removeLocation(this);
this._model.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
this._model.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
},
@@ -735,37 +710,67 @@ WebInspector.CSSStyleModel.LiveLocation.prototype = {
/**
* @constructor
* @implements {WebInspector.RawLocation}
+ * @param {!WebInspector.Target} target
* @param {string} url
* @param {number} lineNumber
* @param {number=} columnNumber
*/
-WebInspector.CSSLocation = function(url, lineNumber, columnNumber)
+WebInspector.CSSLocation = function(target, url, lineNumber, columnNumber)
{
+ this._cssModel = target.cssModel;
this.url = url;
this.lineNumber = lineNumber;
this.columnNumber = columnNumber || 0;
}
+WebInspector.CSSLocation.prototype = {
+ /**
+ * @param {?CSSAgent.StyleSheetId} styleSheetId
+ * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegate
+ * @return {?WebInspector.LiveLocation}
+ */
+ createLiveLocation: function(styleSheetId, updateDelegate)
+ {
+ var header = styleSheetId ? this._cssModel.styleSheetHeaderForId(styleSheetId) : null;
+ return new WebInspector.CSSStyleModel.LiveLocation(this._cssModel, header, this, updateDelegate);
+ },
+
+ /**
+ * @return {?WebInspector.UILocation}
+ */
+ toUILocation: function()
+ {
+ return this._cssModel.rawLocationToUILocation(this);
+ }
+}
+
/**
* @constructor
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSStyle} payload
*/
-WebInspector.CSSStyleDeclaration = function(payload)
+WebInspector.CSSStyleDeclaration = function(cssModel, payload)
{
- this.id = payload.styleId;
- this.width = payload.width;
- this.height = payload.height;
- this.range = payload.range;
+ this._cssModel = cssModel;
+ this.styleSheetId = payload.styleSheetId;
+ this.range = payload.range ? WebInspector.TextRange.fromObject(payload.range) : null;
this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
this._livePropertyMap = {}; // LIVE properties (source-based or style-based) : { name -> CSSProperty }
this._allProperties = []; // ALL properties: [ CSSProperty ]
this.__disabledProperties = {}; // DISABLED properties: { index -> CSSProperty }
var payloadPropertyCount = payload.cssProperties.length;
- var propertyIndex = 0;
+
for (var i = 0; i < payloadPropertyCount; ++i) {
var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
this._allProperties.push(property);
+ }
+
+ this._computeActiveProperties();
+
+ var propertyIndex = 0;
+ for (var i = 0; i < this._allProperties.length; ++i) {
+ var property = this._allProperties[i];
if (property.disabled)
this.__disabledProperties[i] = property;
if (!property.active && !property.styleBased)
@@ -793,28 +798,66 @@ WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntr
}
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSStyle} payload
* @return {!WebInspector.CSSStyleDeclaration}
*/
-WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
+WebInspector.CSSStyleDeclaration.parsePayload = function(cssModel, payload)
{
- return new WebInspector.CSSStyleDeclaration(payload);
+ return new WebInspector.CSSStyleDeclaration(cssModel, payload);
}
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!Array.<!CSSAgent.CSSComputedStyleProperty>} payload
* @return {!WebInspector.CSSStyleDeclaration}
*/
-WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload)
+WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(cssModel, payload)
{
var newPayload = /** @type {!CSSAgent.CSSStyle} */ ({ cssProperties: [], shorthandEntries: [], width: "", height: "" });
if (payload)
newPayload.cssProperties = /** @type {!Array.<!CSSAgent.CSSProperty>} */ (payload);
- return new WebInspector.CSSStyleDeclaration(newPayload);
+ return new WebInspector.CSSStyleDeclaration(cssModel, newPayload);
}
WebInspector.CSSStyleDeclaration.prototype = {
+ /**
+ * @param {string} styleSheetId
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ sourceStyleSheetEdited: function(styleSheetId, oldRange, newRange)
+ {
+ if (this.styleSheetId !== styleSheetId)
+ return;
+ if (this.range)
+ this.range = this.range.rebaseAfterTextEdit(oldRange, newRange);
+ for (var i = 0; i < this._allProperties.length; ++i)
+ this._allProperties[i].sourceStyleSheetEdited(styleSheetId, oldRange, newRange);
+ },
+
+ _computeActiveProperties: function()
+ {
+ var activeProperties = {};
+ for (var i = this._allProperties.length - 1; i >= 0; --i) {
+ var property = this._allProperties[i];
+ if (property.styleBased || property.disabled)
+ continue;
+ property._setActive(false);
+ if (!property.parsedOk)
+ continue;
+ var canonicalName = WebInspector.CSSMetadata.canonicalPropertyName(property.name);
+ var activeProperty = activeProperties[canonicalName];
+ if (!activeProperty || (!activeProperty.important && property.important))
+ activeProperties[canonicalName] = property;
+ }
+ for (var propertyName in activeProperties) {
+ var property = activeProperties[propertyName];
+ property._setActive(true);
+ }
+ },
+
get allProperties()
{
return this._allProperties;
@@ -841,16 +884,6 @@ WebInspector.CSSStyleDeclaration.prototype = {
/**
* @param {string} name
- * @return {string}
- */
- getPropertyPriority: function(name)
- {
- var property = this._livePropertyMap[name];
- return property ? property.priority : "";
- },
-
- /**
- * @param {string} name
* @return {boolean}
*/
isPropertyImplicit: function(name)
@@ -899,20 +932,32 @@ WebInspector.CSSStyleDeclaration.prototype = {
pastLastSourcePropertyIndex: function()
{
for (var i = this.allProperties.length - 1; i >= 0; --i) {
- var property = this.allProperties[i];
- if (property.active || property.disabled)
+ if (this.allProperties[i].range)
return i + 1;
}
return 0;
},
/**
+ * @param {number} index
+ * @return {!WebInspector.TextRange}
+ */
+ _insertionRange: function(index)
+ {
+ var property = this.propertyAt(index);
+ return property && property.range ? property.range.collapseToStart() : this.range.collapseToEnd();
+ },
+
+ /**
* @param {number=} index
+ * @return {!WebInspector.CSSProperty}
*/
newBlankProperty: function(index)
{
index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
- return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, "");
+ var property = new WebInspector.CSSProperty(this, index, "", "", false, false, true, false, "", this._insertionRange(index));
+ property._setActive(true);
+ return property;
},
/**
@@ -926,10 +971,11 @@ WebInspector.CSSStyleDeclaration.prototype = {
/**
* @param {?string} error
* @param {!CSSAgent.CSSStyle} payload
+ * @this {!WebInspector.CSSStyleDeclaration}
*/
function callback(error, payload)
{
- WebInspector.cssModel._pendingCommandsMajorState.pop();
+ this._cssModel._pendingCommandsMajorState.pop();
if (!userCallback)
return;
@@ -937,14 +983,14 @@ WebInspector.CSSStyleDeclaration.prototype = {
console.error(error);
userCallback(null);
} else
- userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
+ userCallback(WebInspector.CSSStyleDeclaration.parsePayload(this._cssModel, payload));
}
- if (!this.id)
- throw "No style id";
+ if (!this.styleSheetId)
+ throw "No stylesheet id";
- WebInspector.cssModel._pendingCommandsMajorState.push(true);
- CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this));
+ this._cssModel._pendingCommandsMajorState.push(true);
+ this._cssModel._agent.setPropertyText(this.styleSheetId, this._insertionRange(index), name + ": " + value + ";", callback.bind(this));
},
/**
@@ -955,55 +1001,27 @@ WebInspector.CSSStyleDeclaration.prototype = {
appendProperty: function(name, value, userCallback)
{
this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
- },
-
- /**
- * @param {string} text
- * @param {function(?WebInspector.CSSStyleDeclaration)=} userCallback
- */
- setText: function(text, userCallback)
- {
- /**
- * @param {?string} error
- * @param {!CSSAgent.CSSStyle} payload
- */
- function callback(error, payload)
- {
- WebInspector.cssModel._pendingCommandsMajorState.pop();
- if (!userCallback)
- return;
-
- if (error) {
- console.error(error);
- userCallback(null);
- } else
- userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
- }
-
- if (!this.id)
- throw "No style id";
-
- if (typeof this.cssText === "undefined") {
- userCallback(null);
- return;
- }
-
- WebInspector.cssModel._pendingCommandsMajorState.push(true);
- CSSAgent.setStyleText(this.id, text, callback);
}
}
/**
* @constructor
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSRule} payload
* @param {!Array.<number>=} matchingSelectors
*/
-WebInspector.CSSRule = function(payload, matchingSelectors)
+WebInspector.CSSRule = function(cssModel, payload, matchingSelectors)
{
- this.id = payload.ruleId;
+ this._cssModel = cssModel;
+ this.styleSheetId = payload.styleSheetId;
if (matchingSelectors)
this.matchingSelectors = matchingSelectors;
this.selectors = payload.selectorList.selectors;
+ for (var i = 0; i < this.selectors.length; ++i) {
+ var selector = this.selectors[i];
+ if (selector.range)
+ selector.range = WebInspector.TextRange.fromObject(selector.range);
+ }
this.selectorText = this.selectors.select("value").join(", ");
var firstRange = this.selectors[0].range;
@@ -1011,36 +1029,63 @@ WebInspector.CSSRule = function(payload, matchingSelectors)
var lastRange = this.selectors.peekLast().range;
this.selectorRange = new WebInspector.TextRange(firstRange.startLine, firstRange.startColumn, lastRange.endLine, lastRange.endColumn);
}
- this.sourceURL = payload.sourceURL;
+ if (this.styleSheetId) {
+ var styleSheetHeader = cssModel.styleSheetHeaderForId(this.styleSheetId);
+ this.sourceURL = styleSheetHeader.sourceURL;
+ }
this.origin = payload.origin;
- this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
+ this.style = WebInspector.CSSStyleDeclaration.parsePayload(this._cssModel, payload.style);
this.style.parentRule = this;
if (payload.media)
- this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
+ this.media = WebInspector.CSSMedia.parseMediaArrayPayload(cssModel, payload.media);
this._setRawLocationAndFrameId();
}
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSRule} payload
* @param {!Array.<number>=} matchingIndices
* @return {!WebInspector.CSSRule}
*/
-WebInspector.CSSRule.parsePayload = function(payload, matchingIndices)
+WebInspector.CSSRule.parsePayload = function(cssModel, payload, matchingIndices)
{
- return new WebInspector.CSSRule(payload, matchingIndices);
+ return new WebInspector.CSSRule(cssModel, payload, matchingIndices);
}
WebInspector.CSSRule.prototype = {
+ /**
+ * @param {string} styleSheetId
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ sourceStyleSheetEdited: function(styleSheetId, oldRange, newRange)
+ {
+ if (this.styleSheetId === styleSheetId) {
+ if (this.selectorRange)
+ this.selectorRange = this.selectorRange.rebaseAfterTextEdit(oldRange, newRange);
+ for (var i = 0; i < this.selectors.length; ++i) {
+ var selector = this.selectors[i];
+ if (selector.range)
+ selector.range = selector.range.rebaseAfterTextEdit(oldRange, newRange);
+ }
+ }
+ if (this.media) {
+ for (var i = 0; i < this.media.length; ++i)
+ this.media[i].sourceStyleSheetEdited(styleSheetId, oldRange, newRange);
+ }
+ this.style.sourceStyleSheetEdited(styleSheetId, oldRange, newRange);
+ },
+
_setRawLocationAndFrameId: function()
{
- if (!this.id)
+ if (!this.styleSheetId)
return;
- var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(this.id.styleSheetId);
+ var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
this.frameId = styleSheetHeader.frameId;
var url = styleSheetHeader.resourceURL();
if (!url)
return;
- this.rawLocation = new WebInspector.CSSLocation(url, this.lineNumberInSource(0), this.columnNumberInSource(0));
+ this.rawLocation = new WebInspector.CSSLocation(this._cssModel.target(), url, this.lineNumberInSource(0), this.columnNumberInSource(0));
},
/**
@@ -1048,9 +1093,9 @@ WebInspector.CSSRule.prototype = {
*/
resourceURL: function()
{
- if (!this.id)
+ if (!this.styleSheetId)
return "";
- var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(this.id.styleSheetId);
+ var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
return styleSheetHeader.resourceURL();
},
@@ -1061,9 +1106,9 @@ WebInspector.CSSRule.prototype = {
lineNumberInSource: function(selectorIndex)
{
var selector = this.selectors[selectorIndex];
- if (!selector || !selector.range)
+ if (!selector || !selector.range || !this.styleSheetId)
return 0;
- var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(this.id.styleSheetId);
+ var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
return styleSheetHeader.lineNumberInSource(selector.range.startLine);
},
@@ -1074,9 +1119,9 @@ WebInspector.CSSRule.prototype = {
columnNumberInSource: function(selectorIndex)
{
var selector = this.selectors[selectorIndex];
- if (!selector || !selector.range)
+ if (!selector || !selector.range || !this.styleSheetId)
return undefined;
- var styleSheetHeader = WebInspector.cssModel.styleSheetHeaderForId(this.id.styleSheetId);
+ var styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId);
console.assert(styleSheetHeader);
return styleSheetHeader.columnNumberInSource(selector.range.startLine, selector.range.startColumn);
},
@@ -1108,25 +1153,25 @@ WebInspector.CSSRule.prototype = {
* @param {number} index
* @param {string} name
* @param {string} value
- * @param {?string} priority
- * @param {string} status
+ * @param {boolean} important
+ * @param {boolean} disabled
* @param {boolean} parsedOk
* @param {boolean} implicit
* @param {?string=} text
* @param {!CSSAgent.SourceRange=} range
*/
-WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text, range)
+WebInspector.CSSProperty = function(ownerStyle, index, name, value, important, disabled, parsedOk, implicit, text, range)
{
this.ownerStyle = ownerStyle;
this.index = index;
this.name = name;
this.value = value;
- this.priority = priority;
- this.status = status;
+ this.important = important;
+ this.disabled = disabled;
this.parsedOk = parsedOk;
this.implicit = implicit;
this.text = text;
- this.range = range;
+ this.range = range ? WebInspector.TextRange.fromObject(range) : null;
}
/**
@@ -1138,16 +1183,37 @@ WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, st
WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{
// The following default field values are used in the payload:
- // priority: ""
+ // important: false
// parsedOk: true
// implicit: false
- // status: "style"
+ // disabled: false
var result = new WebInspector.CSSProperty(
- ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text, payload.range);
+ ownerStyle, index, payload.name, payload.value, payload.important || false, payload.disabled || false, ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text, payload.range);
return result;
}
WebInspector.CSSProperty.prototype = {
+ /**
+ * @param {string} styleSheetId
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ sourceStyleSheetEdited: function(styleSheetId, oldRange, newRange)
+ {
+ if (this.ownerStyle.styleSheetId !== styleSheetId)
+ return;
+ if (this.range)
+ this.range = this.range.rebaseAfterTextEdit(oldRange, newRange);
+ },
+
+ /**
+ * @param {boolean} active
+ */
+ _setActive: function(active)
+ {
+ this._active = active;
+ },
+
get propertyText()
{
if (this.text !== undefined)
@@ -1155,7 +1221,7 @@ WebInspector.CSSProperty.prototype = {
if (this.name === "")
return "";
- return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";";
+ return this.name + ": " + this.value + (this.important ? " !important" : "") + ";";
},
get isLive()
@@ -1165,27 +1231,20 @@ WebInspector.CSSProperty.prototype = {
get active()
{
- return this.status === "active";
+ return typeof this._active === "boolean" && this._active;
},
get styleBased()
{
- return this.status === "style";
+ return !this.range;
},
get inactive()
{
- return this.status === "inactive";
- },
-
- get disabled()
- {
- return this.status === "disabled";
+ return typeof this._active === "boolean" && !this._active;
},
/**
- * Replaces "propertyName: propertyValue [!important];" in the stylesheet by an arbitrary propertyText.
- *
* @param {string} propertyText
* @param {boolean} majorChange
* @param {boolean} overwrite
@@ -1209,19 +1268,17 @@ WebInspector.CSSProperty.prototype = {
*/
function callback(error, stylePayload)
{
- WebInspector.cssModel._pendingCommandsMajorState.pop();
+ this.ownerStyle._cssModel._pendingCommandsMajorState.pop();
if (!error) {
if (majorChange)
- WebInspector.domAgent.markUndoableState();
- this.text = propertyText;
- var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
+ this.ownerStyle._cssModel._domModel.markUndoableState();
+ var style = WebInspector.CSSStyleDeclaration.parsePayload(this.ownerStyle._cssModel, stylePayload);
var newProperty = style.allProperties[this.index];
if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
newProperty.setDisabled(false, enabledCallback);
return;
}
-
if (userCallback)
userCallback(style);
} else {
@@ -1233,12 +1290,14 @@ WebInspector.CSSProperty.prototype = {
if (!this.ownerStyle)
throw "No ownerStyle for property";
- if (!this.ownerStyle.id)
+ if (!this.ownerStyle.styleSheetId)
throw "No owner style id";
// An index past all the properties adds a new property to the style.
- WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
- CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this));
+ var cssModel = this.ownerStyle._cssModel;
+ cssModel._pendingCommandsMajorState.push(majorChange);
+ var range = /** @type {!WebInspector.TextRange} */ (this.range);
+ cssModel._agent.setPropertyText(this.ownerStyle.styleSheetId, overwrite ? range : range.collapseToStart(), propertyText, callback.bind(this));
},
/**
@@ -1249,7 +1308,7 @@ WebInspector.CSSProperty.prototype = {
*/
setValue: function(newValue, majorChange, overwrite, userCallback)
{
- var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";"
+ var text = this.name + ": " + newValue + (this.important ? " !important" : "") + ";"
this.setText(text, majorChange, overwrite, userCallback);
},
@@ -1261,33 +1320,15 @@ WebInspector.CSSProperty.prototype = {
{
if (!this.ownerStyle && userCallback)
userCallback(null);
- if (disabled === this.disabled && userCallback)
- userCallback(this.ownerStyle);
-
- /**
- * @param {?string} error
- * @param {!CSSAgent.CSSStyle} stylePayload
- */
- function callback(error, stylePayload)
- {
- WebInspector.cssModel._pendingCommandsMajorState.pop();
- if (error) {
- if (userCallback)
- userCallback(null);
- return;
- }
- WebInspector.domAgent.markUndoableState();
- if (userCallback) {
- var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
- userCallback(style);
- }
+ if (disabled === this.disabled) {
+ if (userCallback)
+ userCallback(this.ownerStyle);
+ return;
}
-
- if (!this.ownerStyle.id)
- throw "No owner style id";
-
- WebInspector.cssModel._pendingCommandsMajorState.push(false);
- CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this));
+ if (disabled)
+ this.setText("/* " + this.text + " */", true, true, userCallback);
+ else
+ this.setText(this.text.substring(2, this.text.length - 2).trim(), true, true, userCallback);
},
/**
@@ -1307,22 +1348,90 @@ WebInspector.CSSProperty.prototype = {
var line = forName ? range.startLine : range.endLine;
// End of range is exclusive, so subtract 1 from the end offset.
var column = forName ? range.startColumn : range.endColumn - (this.text && this.text.endsWith(";") ? 2 : 1);
- var rawLocation = new WebInspector.CSSLocation(url, line, column);
- return WebInspector.cssModel.rawLocationToUILocation(rawLocation);
+ var rawLocation = new WebInspector.CSSLocation(this.ownerStyle._cssModel.target(), url, line, column);
+ return rawLocation.toUILocation();
}
}
/**
* @constructor
+ * @param {!CSSAgent.MediaQueryExpression} payload
+ */
+WebInspector.CSSMediaQueryExpression = function(payload)
+{
+ this._value = payload.value;
+ this._unit = payload.unit;
+ this._feature = payload.feature;
+ this._computedLength = payload.computedLength || null;
+}
+
+/**
+ * @param {!CSSAgent.MediaQueryExpression} payload
+ */
+WebInspector.CSSMediaQueryExpression.parsePayload = function(payload)
+{
+ return new WebInspector.CSSMediaQueryExpression(payload);
+}
+
+WebInspector.CSSMediaQueryExpression.prototype = {
+ /**
+ * @return {number}
+ */
+ value: function()
+ {
+ return this._value;
+ },
+
+ /**
+ * @return {string}
+ */
+ unit: function()
+ {
+ return this._unit;
+ },
+
+ /**
+ * @return {string}
+ */
+ feature: function()
+ {
+ return this._feature;
+ },
+
+ /**
+ * @return {?number}
+ */
+ computedLength: function()
+ {
+ return this._computedLength;
+ }
+}
+
+
+/**
+ * @constructor
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSMedia} payload
*/
-WebInspector.CSSMedia = function(payload)
+WebInspector.CSSMedia = function(cssModel, payload)
{
+ this._cssModel = cssModel
this.text = payload.text;
this.source = payload.source;
this.sourceURL = payload.sourceURL || "";
this.range = payload.range ? WebInspector.TextRange.fromObject(payload.range) : null;
this.parentStyleSheetId = payload.parentStyleSheetId;
+ this.mediaList = null;
+ if (payload.mediaList) {
+ this.mediaList = [];
+ for (var i = 0; i < payload.mediaList.length; ++i) {
+ var mediaQueryPayload = payload.mediaList[i];
+ var mediaQueryExpressions = [];
+ for (var j = 0; j < mediaQueryPayload.length; ++j)
+ mediaQueryExpressions.push(WebInspector.CSSMediaQueryExpression.parsePayload(mediaQueryPayload[j]));
+ this.mediaList.push(mediaQueryExpressions);
+ }
+ }
}
WebInspector.CSSMedia.Source = {
@@ -1333,28 +1442,43 @@ WebInspector.CSSMedia.Source = {
};
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSMedia} payload
* @return {!WebInspector.CSSMedia}
*/
-WebInspector.CSSMedia.parsePayload = function(payload)
+WebInspector.CSSMedia.parsePayload = function(cssModel, payload)
{
- return new WebInspector.CSSMedia(payload);
+ return new WebInspector.CSSMedia(cssModel, payload);
}
/**
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!Array.<!CSSAgent.CSSMedia>} payload
* @return {!Array.<!WebInspector.CSSMedia>}
*/
-WebInspector.CSSMedia.parseMediaArrayPayload = function(payload)
+WebInspector.CSSMedia.parseMediaArrayPayload = function(cssModel, payload)
{
var result = [];
for (var i = 0; i < payload.length; ++i)
- result.push(WebInspector.CSSMedia.parsePayload(payload[i]));
+ result.push(WebInspector.CSSMedia.parsePayload(cssModel, payload[i]));
return result;
}
WebInspector.CSSMedia.prototype = {
/**
+ * @param {string} styleSheetId
+ * @param {!WebInspector.TextRange} oldRange
+ * @param {!WebInspector.TextRange} newRange
+ */
+ sourceStyleSheetEdited: function(styleSheetId, oldRange, newRange)
+ {
+ if (this.parentStyleSheetId !== styleSheetId)
+ return;
+ if (this.range)
+ this.range = this.range.rebaseAfterTextEdit(oldRange, newRange);
+ },
+
+ /**
* @return {number|undefined}
*/
lineNumberInSource: function()
@@ -1385,17 +1509,19 @@ WebInspector.CSSMedia.prototype = {
*/
header: function()
{
- return this.parentStyleSheetId ? WebInspector.cssModel.styleSheetHeaderForId(this.parentStyleSheetId) : null;
+ return this.parentStyleSheetId ? this._cssModel.styleSheetHeaderForId(this.parentStyleSheetId) : null;
}
}
/**
* @constructor
* @implements {WebInspector.ContentProvider}
+ * @param {!WebInspector.CSSStyleModel} cssModel
* @param {!CSSAgent.CSSStyleSheetHeader} payload
*/
-WebInspector.CSSStyleSheetHeader = function(payload)
+WebInspector.CSSStyleSheetHeader = function(cssModel, payload)
{
+ this._cssModel = cssModel;
this.id = payload.styleSheetId;
this.frameId = payload.frameId;
this.sourceURL = payload.sourceURL;
@@ -1419,7 +1545,7 @@ WebInspector.CSSStyleSheetHeader.prototype = {
*/
resourceURL: function()
{
- return this.origin === "inspector" ? this._viaInspectorResourceURL() : this.sourceURL;
+ return this.isViaInspector() ? this._viaInspectorResourceURL() : this.sourceURL;
},
/**
@@ -1433,7 +1559,7 @@ WebInspector.CSSStyleSheetHeader.prototype = {
updateLocations: function()
{
- var items = this._locations.items();
+ var items = this._locations.values();
for (var i = 0; i < items.length; ++i)
items[i].update();
},
@@ -1453,11 +1579,11 @@ WebInspector.CSSStyleSheetHeader.prototype = {
*/
rawLocationToUILocation: function(lineNumber, columnNumber)
{
- var uiLocation;
- var rawLocation = new WebInspector.CSSLocation(this.resourceURL(), lineNumber, columnNumber);
+ var uiLocation = null;
+ var rawLocation = new WebInspector.CSSLocation(this._cssModel.target(), this.resourceURL(), lineNumber, columnNumber);
for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
- return uiLocation ? uiLocation.uiSourceCode.overrideLocation(uiLocation) : null;
+ return uiLocation;
},
/**
@@ -1472,17 +1598,9 @@ WebInspector.CSSStyleSheetHeader.prototype = {
/**
* @return {string}
*/
- _key: function()
- {
- return this.frameId + ":" + this.resourceURL();
- },
-
- /**
- * @return {string}
- */
_viaInspectorResourceURL: function()
{
- var frame = WebInspector.resourceTreeModel.frameForId(this.frameId);
+ var frame = this._cssModel.target().resourceTreeModel.frameForId(this.frameId);
console.assert(frame);
var parsedURL = new WebInspector.ParsedURL(frame.url);
var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
@@ -1513,6 +1631,7 @@ WebInspector.CSSStyleSheetHeader.prototype = {
/**
* @override
+ * @return {string}
*/
contentURL: function()
{
@@ -1521,6 +1640,7 @@ WebInspector.CSSStyleSheetHeader.prototype = {
/**
* @override
+ * @return {!WebInspector.ResourceType}
*/
contentType: function()
{
@@ -1528,11 +1648,22 @@ WebInspector.CSSStyleSheetHeader.prototype = {
},
/**
+ * @param {string} text
+ * @return {string}
+ */
+ _trimSourceURL: function(text)
+ {
+ var sourceURLRegex = /\n[\040\t]*\/\*[#@][\040\t]sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/mg;
+ return text.replace(sourceURLRegex, "");
+ },
+
+ /**
* @override
+ * @param {function(?string)} callback
*/
requestContent: function(callback)
{
- CSSAgent.getStyleSheetText(this.id, textCallback.bind(this));
+ this._cssModel._agent.getStyleSheetText(this.id, textCallback.bind(this));
/**
* @this {WebInspector.CSSStyleSheetHeader}
@@ -1540,10 +1671,11 @@ WebInspector.CSSStyleSheetHeader.prototype = {
function textCallback(error, text)
{
if (error) {
- WebInspector.log("Failed to get text for stylesheet " + this.id + ": " + error);
+ WebInspector.messageSink.addErrorMessage("Failed to get text for stylesheet " + this.id + ": " + error);
text = "";
// Fall through.
}
+ text = this._trimSourceURL(text);
callback(text);
}
},
@@ -1560,80 +1692,28 @@ WebInspector.CSSStyleSheetHeader.prototype = {
// searchInContent should call back later.
this.requestContent(performSearch);
- }
-}
-
-/**
- * @constructor
- * @param {!CSSAgent.CSSStyleSheetBody} payload
- */
-WebInspector.CSSStyleSheet = function(payload)
-{
- this.id = payload.styleSheetId;
- this.rules = [];
- this.styles = {};
- for (var i = 0; i < payload.rules.length; ++i) {
- var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]);
- this.rules.push(rule);
- if (rule.style)
- this.styles[rule.style.id] = rule.style;
- }
- if ("text" in payload)
- this._text = payload.text;
-}
-
-/**
- * @param {!CSSAgent.StyleSheetId} styleSheetId
- * @param {function(?WebInspector.CSSStyleSheet)} userCallback
- */
-WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
-{
- /**
- * @param {?string} error
- * @param {!CSSAgent.CSSStyleSheetBody} styleSheetPayload
- */
- function callback(error, styleSheetPayload)
- {
- if (error)
- userCallback(null);
- else
- userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
- }
- CSSAgent.getStyleSheet(styleSheetId, callback);
-}
+ },
-WebInspector.CSSStyleSheet.prototype = {
/**
- * @return {string|undefined}
+ * @param {string} newText
+ * @param {function(?Protocol.Error)} callback
*/
- getText: function()
+ setContent: function(newText, callback)
{
- return this._text;
+ newText = this._trimSourceURL(newText);
+ if (this.hasSourceURL)
+ newText += "\n/*# sourceURL=" + this.sourceURL + " */";
+ this._cssModel._agent.setStyleSheetText(this.id, newText, callback);
},
/**
- * @param {string} newText
- * @param {boolean} majorChange
- * @param {function(?string)=} userCallback
+ * @return {boolean}
*/
- setText: function(newText, majorChange, userCallback)
+ isViaInspector: function()
{
- /**
- * @param {?string} error
- */
- function callback(error)
- {
- if (!error)
- WebInspector.domAgent.markUndoableState();
-
- WebInspector.cssModel._pendingCommandsMajorState.pop();
- if (userCallback)
- userCallback(error);
- }
+ return this.origin === "inspector";
+ },
- WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
- CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
- }
}
/**
@@ -1675,107 +1755,6 @@ WebInspector.CSSDispatcher.prototype = {
{
this._cssModel._styleSheetRemoved(id);
},
-
- /**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- namedFlowCreated: function(namedFlowPayload)
- {
- this._cssModel._namedFlowCreated(namedFlowPayload);
- },
-
- /**
- * @param {!DOMAgent.NodeId} documentNodeId
- * @param {string} flowName
- */
- namedFlowRemoved: function(documentNodeId, flowName)
- {
- this._cssModel._namedFlowRemoved(documentNodeId, flowName);
- },
-
- /**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- regionLayoutUpdated: function(namedFlowPayload)
- {
- this._cssModel._regionLayoutUpdated(namedFlowPayload);
- },
-
- /**
- * @param {!CSSAgent.NamedFlow} namedFlowPayload
- */
- regionOversetChanged: function(namedFlowPayload)
- {
- this._cssModel._regionOversetChanged(namedFlowPayload);
- }
-}
-
-/**
- * @constructor
- * @param {!CSSAgent.NamedFlow} payload
- */
-WebInspector.NamedFlow = function(payload)
-{
- this.documentNodeId = payload.documentNodeId;
- this.name = payload.name;
- this.overset = payload.overset;
- this.content = payload.content;
- this.regions = payload.regions;
-}
-
-/**
- * @param {!CSSAgent.NamedFlow} payload
- * @return {!WebInspector.NamedFlow}
- */
-WebInspector.NamedFlow.parsePayload = function(payload)
-{
- return new WebInspector.NamedFlow(payload);
-}
-
-/**
- * @constructor
- * @param {!Array.<!CSSAgent.NamedFlow>} payload
- */
-WebInspector.NamedFlowCollection = function(payload)
-{
- /** @type {!Object.<string, !WebInspector.NamedFlow>} */
- this.namedFlowMap = {};
-
- for (var i = 0; i < payload.length; ++i) {
- var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]);
- this.namedFlowMap[namedFlow.name] = namedFlow;
- }
-}
-
-WebInspector.NamedFlowCollection.prototype = {
- /**
- * @param {!WebInspector.NamedFlow} namedFlow
- */
- _appendNamedFlow: function(namedFlow)
- {
- this.namedFlowMap[namedFlow.name] = namedFlow;
- },
-
- /**
- * @param {string} flowName
- */
- _removeNamedFlow: function(flowName)
- {
- delete this.namedFlowMap[flowName];
- },
-
- /**
- * @param {string} flowName
- * @return {?WebInspector.NamedFlow}
- */
- flowByName: function(flowName)
- {
- var namedFlow = this.namedFlowMap[flowName];
-
- if (!namedFlow)
- return null;
- return namedFlow;
- }
}
/**
@@ -1790,16 +1769,6 @@ WebInspector.CSSStyleModel.ComputedStyleLoader = function(cssModel)
}
WebInspector.CSSStyleModel.ComputedStyleLoader.prototype = {
- reset: function()
- {
- for (var nodeId in this._nodeIdToCallbackData) {
- var callbacks = this._nodeIdToCallbackData[nodeId];
- for (var i = 0; i < callbacks.length; ++i)
- callbacks[i](null);
- }
- this._nodeIdToCallbackData = {};
- },
-
/**
* @param {!DOMAgent.NodeId} nodeId
* @param {function(?WebInspector.CSSStyleDeclaration)} userCallback
@@ -1813,7 +1782,7 @@ WebInspector.CSSStyleModel.ComputedStyleLoader.prototype = {
this._nodeIdToCallbackData[nodeId] = [userCallback];
- CSSAgent.getComputedStyleForNode(nodeId, resultCallback.bind(this, nodeId));
+ this._cssModel._agent.getComputedStyleForNode(nodeId, resultCallback.bind(this, nodeId));
/**
* @param {!DOMAgent.NodeId} nodeId
@@ -1823,7 +1792,7 @@ WebInspector.CSSStyleModel.ComputedStyleLoader.prototype = {
*/
function resultCallback(nodeId, error, computedPayload)
{
- var computedStyle = (error || !computedPayload) ? null : WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload);
+ var computedStyle = (error || !computedPayload) ? null : WebInspector.CSSStyleDeclaration.parseComputedStylePayload(this._cssModel, computedPayload);
var callbacks = this._nodeIdToCallbackData[nodeId];
// The loader has been reset.
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleSheetMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleSheetMapping.js
index 9137dff31b4..87d52199ea2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSStyleSheetMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CSSStyleSheetMapping.js
@@ -32,14 +32,14 @@
* @constructor
* @param {!WebInspector.CSSStyleModel} cssModel
* @param {!WebInspector.Workspace} workspace
- * @param {!WebInspector.SimpleWorkspaceProvider} networkWorkspaceProvider
+ * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
*/
-WebInspector.CSSStyleSheetMapping = function(cssModel, workspace, networkWorkspaceProvider)
+WebInspector.CSSStyleSheetMapping = function(cssModel, workspace, networkWorkspaceBinding)
{
this._cssModel = cssModel;
this._workspace = workspace;
this._stylesSourceMapping = new WebInspector.StylesSourceMapping(cssModel, workspace);
- this._sassSourceMapping = new WebInspector.SASSSourceMapping(cssModel, workspace, networkWorkspaceProvider);
+ this._sassSourceMapping = new WebInspector.SASSSourceMapping(cssModel, workspace, networkWorkspaceBinding);
cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetRemoved, this._styleSheetRemoved, this);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CompilerScriptMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CompilerScriptMapping.js
index f4b21081976..141cf63b90c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CompilerScriptMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CompilerScriptMapping.js
@@ -31,14 +31,17 @@
/**
* @constructor
* @implements {WebInspector.ScriptSourceMapping}
+ * @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
- * @param {!WebInspector.SimpleWorkspaceProvider} networkWorkspaceProvider
+ * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
*/
-WebInspector.CompilerScriptMapping = function(workspace, networkWorkspaceProvider)
+WebInspector.CompilerScriptMapping = function(debuggerModel, workspace, networkWorkspaceBinding)
{
+ this._target = debuggerModel.target();
+ this._debuggerModel = debuggerModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
- this._networkWorkspaceProvider = networkWorkspaceProvider;
+ this._networkWorkspaceBinding = networkWorkspaceBinding;
/** @type {!Object.<string, !WebInspector.SourceMap>} */
this._sourceMapForSourceMapURL = {};
/** @type {!Object.<string, !Array.<function(?WebInspector.SourceMap)>>} */
@@ -49,7 +52,7 @@ WebInspector.CompilerScriptMapping = function(workspace, networkWorkspaceProvide
this._scriptForSourceMap = new Map();
/** @type {!StringMap.<!WebInspector.SourceMap>} */
this._sourceMapForURL = new StringMap();
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}
WebInspector.CompilerScriptMapping.prototype = {
@@ -72,7 +75,7 @@ WebInspector.CompilerScriptMapping.prototype = {
var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
if (!uiSourceCode)
return null;
- return new WebInspector.UILocation(uiSourceCode, /** @type {number} */ (entry[3]), /** @type {number} */ (entry[4]));
+ return uiSourceCode.uiLocation(/** @type {number} */ (entry[3]), /** @type {number} */ (entry[4]));
},
/**
@@ -91,7 +94,7 @@ WebInspector.CompilerScriptMapping.prototype = {
var script = /** @type {!WebInspector.Script} */ (this._scriptForSourceMap.get(sourceMap));
console.assert(script);
var entry = sourceMap.findEntryReversed(uiSourceCode.url, lineNumber);
- return WebInspector.debuggerModel.createRawLocation(script, entry[0], entry[1]);
+ return this._debuggerModel.createRawLocation(script, /** @type {number} */ (entry[0]), /** @type {number} */ (entry[1]));
},
/**
@@ -128,26 +131,32 @@ WebInspector.CompilerScriptMapping.prototype = {
this._sourceMapForURL.put(sourceURL, sourceMap);
if (!this._workspace.hasMappingForURL(sourceURL) && !this._workspace.uiSourceCodeForURL(sourceURL)) {
var contentProvider = sourceMap.sourceContentProvider(sourceURL, WebInspector.resourceTypes.Script);
- this._networkWorkspaceProvider.addFileForURL(sourceURL, contentProvider, true);
+ this._networkWorkspaceBinding.addFileForURL(sourceURL, contentProvider, script.isContentScript());
}
var uiSourceCode = this._workspace.uiSourceCodeForURL(sourceURL);
- if (uiSourceCode) {
+ if (uiSourceCode)
this._bindUISourceCode(uiSourceCode);
- uiSourceCode.isContentScript = script.isContentScript;
- } else {
- WebInspector.showErrorMessage(WebInspector.UIString("Failed to locate workspace file mapped to URL %s from source map %s", sourceURL, sourceMap.url()));
- }
+ else
+ this._target.consoleModel.showErrorMessage(WebInspector.UIString("Failed to locate workspace file mapped to URL %s from source map %s", sourceURL, sourceMap.url()));
}
script.updateLocations();
}
},
/**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return false;
+ },
+
+ /**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
_bindUISourceCode: function(uiSourceCode)
{
- uiSourceCode.setSourceMapping(this);
+ uiSourceCode.setSourceMappingForTarget(this._target, this);
},
/**
@@ -155,7 +164,7 @@ WebInspector.CompilerScriptMapping.prototype = {
*/
_unbindUISourceCode: function(uiSourceCode)
{
- uiSourceCode.setSourceMapping(null);
+ uiSourceCode.setSourceMappingForTarget(this._target, null);
},
/**
@@ -181,7 +190,7 @@ WebInspector.CompilerScriptMapping.prototype = {
callback(null);
return;
}
- var scriptURL = WebInspector.ParsedURL.completeURL(WebInspector.inspectedPageURL, script.sourceURL);
+ var scriptURL = WebInspector.ParsedURL.completeURL(script.target().resourceTreeModel.inspectedPageURL(), script.sourceURL);
if (!scriptURL) {
callback(null);
return;
@@ -230,22 +239,18 @@ WebInspector.CompilerScriptMapping.prototype = {
_debuggerReset: function()
{
/**
- * @param {!WebInspector.SourceMap} sourceMap
+ * @param {string} sourceURL
* @this {WebInspector.CompilerScriptMapping}
*/
- function unbindUISourceCodesForSourceMap(sourceMap)
+ function unbindUISourceCodeForURL(sourceURL)
{
- var sourceURLs = sourceMap.sources();
- for (var i = 0; i < sourceURLs.length; ++i) {
- var sourceURL = sourceURLs[i];
- var uiSourceCode = this._workspace.uiSourceCodeForURL(sourceURL);
- if (!uiSourceCode)
- continue;
- this._unbindUISourceCode(uiSourceCode);
- }
+ var uiSourceCode = this._workspace.uiSourceCodeForURL(sourceURL);
+ if (!uiSourceCode)
+ return;
+ this._unbindUISourceCode(uiSourceCode);
}
- this._sourceMapForURL.values().forEach(unbindUISourceCodesForSourceMap.bind(this));
+ this._sourceMapForURL.keys().forEach(unbindUISourceCodeForURL.bind(this));
this._sourceMapForSourceMapURL = {};
this._pendingSourceMapLoadingCallbacks = {};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
new file mode 100644
index 00000000000..5466bf266ca
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.ConsoleModel = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+
+ /** @type {!Array.<!WebInspector.ConsoleMessage>} */
+ this.messages = [];
+ this.warnings = 0;
+ this.errors = 0;
+ this._consoleAgent = target.consoleAgent();
+ target.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
+ this._enableAgent();
+}
+
+WebInspector.ConsoleModel.Events = {
+ ConsoleCleared: "ConsoleCleared",
+ MessageAdded: "MessageAdded",
+ CommandEvaluated: "CommandEvaluated",
+}
+
+WebInspector.ConsoleModel.prototype = {
+ _enableAgent: function()
+ {
+ if (WebInspector.settings.monitoringXHREnabled.get())
+ this._consoleAgent.setMonitoringXHREnabled(true);
+
+ this._enablingConsole = true;
+
+ /**
+ * @this {WebInspector.ConsoleModel}
+ */
+ function callback()
+ {
+ delete this._enablingConsole;
+ }
+ this._consoleAgent.enable(callback.bind(this));
+ },
+
+ /**
+ * @return {boolean}
+ */
+ enablingConsole: function()
+ {
+ return !!this._enablingConsole;
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} msg
+ * @param {boolean=} isFromBackend
+ */
+ addMessage: function(msg, isFromBackend)
+ {
+ if (isFromBackend && WebInspector.NetworkManager.hasDevToolsRequestHeader(msg.request))
+ return;
+
+ msg.index = this.messages.length;
+ this.messages.push(msg);
+ this._incrementErrorWarningCount(msg);
+
+ this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
+ },
+
+ show: function()
+ {
+ WebInspector.Revealer.reveal(this);
+ },
+
+ /**
+ * @param {string} messageText
+ * @param {!WebInspector.ConsoleMessage.MessageLevel=} messageLevel
+ * @param {boolean=} showConsole
+ */
+ log: function(messageText, messageLevel, showConsole)
+ {
+ var message = new WebInspector.ConsoleMessage(
+ this.target(),
+ WebInspector.ConsoleMessage.MessageSource.Other,
+ messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
+ messageText);
+
+ this.addMessage(message);
+ if (showConsole)
+ this.show();
+ },
+
+ /**
+ * @param {string} error
+ */
+ showErrorMessage: function(error)
+ {
+ this.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} msg
+ */
+ _incrementErrorWarningCount: function(msg)
+ {
+ switch (msg.level) {
+ case WebInspector.ConsoleMessage.MessageLevel.Warning:
+ this.warnings++;
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.Error:
+ this.errors++;
+ break;
+ }
+ },
+
+ requestClearMessages: function()
+ {
+ this._consoleAgent.clearMessages();
+ this.clearMessages();
+ },
+
+ clearMessages: function()
+ {
+ this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
+
+ this.messages = [];
+ this.errors = 0;
+ this.warnings = 0;
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @param {!WebInspector.ExecutionContext} executionContext
+ * @param {string} text
+ * @param {boolean=} useCommandLineAPI
+ */
+WebInspector.ConsoleModel.evaluateCommandInConsole = function(executionContext, text, useCommandLineAPI)
+{
+ useCommandLineAPI = !!useCommandLineAPI;
+ var target = executionContext.target();
+
+ var commandMessage = new WebInspector.ConsoleMessage(target, WebInspector.ConsoleMessage.MessageSource.JS, null, text, WebInspector.ConsoleMessage.MessageType.Command);
+ target.consoleModel.addMessage(commandMessage);
+
+ /**
+ * @param {?WebInspector.RemoteObject} result
+ * @param {boolean} wasThrown
+ * @param {?RuntimeAgent.RemoteObject=} valueResult
+ * @this {WebInspector.ConsoleModel}
+ */
+ function printResult(result, wasThrown, valueResult)
+ {
+ if (!result)
+ return;
+
+ this.show();
+ this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, wasThrown: wasThrown, text: text, commandMessage: commandMessage});
+ }
+
+ executionContext.evaluate(text, "console", useCommandLineAPI, false, false, true, printResult.bind(target.consoleModel));
+
+ WebInspector.userMetrics.ConsoleEvaluated.record();
+}
+
+
+/**
+ * @constructor
+ * @param {?WebInspector.Target} target
+ * @param {string} source
+ * @param {?string} level
+ * @param {string} messageText
+ * @param {string=} type
+ * @param {?string=} url
+ * @param {number=} line
+ * @param {number=} column
+ * @param {!NetworkAgent.RequestId=} requestId
+ * @param {!Array.<!RuntimeAgent.RemoteObject>=} parameters
+ * @param {!Array.<!ConsoleAgent.CallFrame>=} stackTrace
+ * @param {number=} timestamp
+ * @param {boolean=} isOutdated
+ * @param {!RuntimeAgent.ExecutionContextId=} executionContextId
+ */
+WebInspector.ConsoleMessage = function(target, source, level, messageText, type, url, line, column, requestId, parameters, stackTrace, timestamp, isOutdated, executionContextId)
+{
+ this._target = target;
+ this.source = source;
+ this.level = level;
+ this.messageText = messageText;
+ this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
+ this.url = url || null;
+ this.line = line || 0;
+ this.column = column || 0;
+ this.parameters = parameters;
+ this.stackTrace = stackTrace;
+ this.timestamp = timestamp || Date.now();
+ this.isOutdated = isOutdated;
+ this.executionContextId = executionContextId || 0;
+
+ this.request = requestId ? target.networkLog.requestForId(requestId) : null;
+
+ if (this.request) {
+ this.stackTrace = this.request.initiator.stackTrace;
+ if (this.request.initiator && this.request.initiator.url) {
+ this.url = this.request.initiator.url;
+ this.line = this.request.initiator.lineNumber;
+ }
+ }
+}
+
+WebInspector.ConsoleMessage.prototype = {
+ /**
+ * @return {?WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} originatingMessage
+ */
+ setOriginatingMessage: function(originatingMessage)
+ {
+ this._originatingConsoleMessage = originatingMessage;
+ },
+
+ /**
+ * @return {?WebInspector.ConsoleMessage}
+ */
+ originatingMessage: function()
+ {
+ return this._originatingConsoleMessage;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isGroupMessage: function()
+ {
+ return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
+ this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed ||
+ this.type === WebInspector.ConsoleMessage.MessageType.EndGroup;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isGroupStartMessage: function()
+ {
+ return this.type === WebInspector.ConsoleMessage.MessageType.StartGroup ||
+ this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isErrorOrWarning: function()
+ {
+ return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
+ },
+
+ /**
+ * @return {!WebInspector.ConsoleMessage}
+ */
+ clone: function()
+ {
+ return new WebInspector.ConsoleMessage(
+ this.target(),
+ this.source,
+ this.level,
+ this.messageText,
+ this.type,
+ this.url,
+ this.line,
+ this.column,
+ this.request ? this.request.requestId : undefined,
+ this.parameters,
+ this.stackTrace,
+ this.timestamp,
+ this.isOutdated,
+ this.executionContextId);
+ },
+
+ /**
+ * @param {?WebInspector.ConsoleMessage} msg
+ * @return {boolean}
+ */
+ isEqual: function(msg)
+ {
+ if (!msg)
+ return false;
+
+ if (this.stackTrace) {
+ if (!msg.stackTrace || this.stackTrace.length !== msg.stackTrace.length)
+ return false;
+
+ for (var i = 0; i < msg.stackTrace.length; ++i) {
+ if (this.stackTrace[i].url !== msg.stackTrace[i].url ||
+ this.stackTrace[i].functionName !== msg.stackTrace[i].functionName ||
+ this.stackTrace[i].lineNumber !== msg.stackTrace[i].lineNumber ||
+ this.stackTrace[i].columnNumber !== msg.stackTrace[i].columnNumber)
+ return false;
+ }
+ }
+
+ if (this.parameters) {
+ if (!msg.parameters || this.parameters.length !== msg.parameters.length)
+ return false;
+
+ for (var i = 0; i < msg.parameters.length; ++i) {
+ // Never treat objects as equal - their properties might change over time.
+ if (this.parameters[i].type !== msg.parameters[i].type || msg.parameters[i].type === "object" || this.parameters[i].value !== msg.parameters[i].value)
+ return false;
+ }
+ }
+
+ return (this.target() === msg.target())
+ && (this.source === msg.source)
+ && (this.type === msg.type)
+ && (this.level === msg.level)
+ && (this.line === msg.line)
+ && (this.url === msg.url)
+ && (this.messageText === msg.messageText)
+ && (this.request === msg.request)
+ && (this.executionContextId === msg.executionContextId);
+ }
+}
+
+// Note: Keep these constants in sync with the ones in Console.h
+/**
+ * @enum {string}
+ */
+WebInspector.ConsoleMessage.MessageSource = {
+ XML: "xml",
+ JS: "javascript",
+ Network: "network",
+ ConsoleAPI: "console-api",
+ Storage: "storage",
+ AppCache: "appcache",
+ Rendering: "rendering",
+ CSS: "css",
+ Security: "security",
+ Other: "other",
+ Deprecation: "deprecation"
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.ConsoleMessage.MessageType = {
+ Log: "log",
+ Dir: "dir",
+ DirXML: "dirxml",
+ Table: "table",
+ Trace: "trace",
+ Clear: "clear",
+ StartGroup: "startGroup",
+ StartGroupCollapsed: "startGroupCollapsed",
+ EndGroup: "endGroup",
+ Assert: "assert",
+ Result: "result",
+ Profile: "profile",
+ ProfileEnd: "profileEnd",
+ Command: "command"
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.ConsoleMessage.MessageLevel = {
+ Log: "log",
+ Info: "info",
+ Warning: "warning",
+ Error: "error",
+ Debug: "debug"
+}
+
+/**
+ * @param {!WebInspector.ConsoleMessage} a
+ * @param {!WebInspector.ConsoleMessage} b
+ * @return {number}
+ */
+WebInspector.ConsoleMessage.timestampComparator = function (a, b)
+{
+ return a.timestamp - b.timestamp;
+}
+
+/**
+ * @constructor
+ * @implements {ConsoleAgent.Dispatcher}
+ * @param {!WebInspector.ConsoleModel} console
+ */
+WebInspector.ConsoleDispatcher = function(console)
+{
+ this._console = console;
+}
+
+WebInspector.ConsoleDispatcher.prototype = {
+ /**
+ * @param {!ConsoleAgent.ConsoleMessage} payload
+ */
+ messageAdded: function(payload)
+ {
+ var consoleMessage = new WebInspector.ConsoleMessage(
+ this._console.target(),
+ payload.source,
+ payload.level,
+ payload.text,
+ payload.type,
+ payload.url,
+ payload.line,
+ payload.column,
+ payload.networkRequestId,
+ payload.parameters,
+ payload.stackTrace,
+ payload.timestamp * 1000, // Convert to ms.
+ this._console._enablingConsole,
+ payload.executionContextId);
+ this._console.addMessage(consoleMessage, true);
+ },
+
+ /**
+ * @param {number} count
+ */
+ messageRepeatCountUpdated: function(count)
+ {
+ },
+
+ messagesCleared: function()
+ {
+ if (!WebInspector.settings.preserveConsoleLog.get())
+ this._console.clearMessages();
+ }
+}
+
+/**
+ * @type {!WebInspector.ConsoleModel}
+ */
+WebInspector.console;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProvider.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProvider.js
index 46274dc001b..70017102f37 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProvider.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProvider.js
@@ -79,15 +79,10 @@ WebInspector.ContentProvider.performSearchInContent = function(content, query, c
{
var regex = createSearchRegex(query, caseSensitive, isRegex);
+ var contentString = new String(content);
var result = [];
- var lineEndings = content.lineEndings();
- for (var i = 0; i < lineEndings.length; ++i) {
- var lineStart = i > 0 ? lineEndings[i - 1] + 1 : 0;
- var lineEnd = lineEndings[i];
- var lineContent = content.substring(lineStart, lineEnd);
- if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) === "\r")
- lineContent = lineContent.substring(0, lineContent.length - 1)
-
+ for (var i = 0; i < contentString.lineCount(); ++i) {
+ var lineContent = contentString.lineAt(i);
regex.lastIndex = 0;
if (regex.exec(lineContent))
result.push(new WebInspector.ContentProvider.SearchMatch(i, lineContent));
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProviderBasedProjectDelegate.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviderBasedProjectDelegate.js
index 4699f9f8029..528c31d8a6d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProviderBasedProjectDelegate.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviderBasedProjectDelegate.js
@@ -31,31 +31,24 @@
/**
* @constructor
* @implements {WebInspector.ProjectDelegate}
- * @extends {WebInspector.Object}
- * @param {string} type
+ * @param {!WebInspector.Workspace} workspace
+ * @param {string} id
+ * @param {!WebInspector.projectTypes} type
*/
-WebInspector.ContentProviderBasedProjectDelegate = function(type)
+WebInspector.ContentProviderBasedProjectDelegate = function(workspace, id, type)
{
this._type = type;
/** @type {!Object.<string, !WebInspector.ContentProvider>} */
this._contentProviders = {};
- /** @type {!Object.<string, boolean>} */
- this._isContentScriptMap = {};
+ this._workspace = workspace;
+ this._id = id;
+ this._projectStore = workspace.addProject(id, this);
}
WebInspector.ContentProviderBasedProjectDelegate.prototype = {
/**
* @return {string}
*/
- id: function()
- {
- // Overriddden by subclasses
- return "";
- },
-
- /**
- * @return {string}
- */
type: function()
{
return this._type;
@@ -220,14 +213,11 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
},
/**
- * @param {!Array.<string>} queries
- * @param {!Array.<string>} fileQueries
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
- findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback)
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback)
{
var result = [];
var paths = Object.keys(this._contentProviders);
@@ -238,39 +228,11 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
return;
}
- /**
- * @param {string} path
- * @this {WebInspector.ContentProviderBasedProjectDelegate}
- */
- function filterOutContentScripts(path)
- {
- return !this._isContentScriptMap[path];
- }
-
- if (!WebInspector.settings.searchInContentScripts.get())
- paths = paths.filter(filterOutContentScripts.bind(this));
-
- var fileRegexes = [];
- for (var i = 0; i < fileQueries.length; ++i)
- fileRegexes.push(new RegExp(fileQueries[i], caseSensitive ? "" : "i"));
-
- /**
- * @param {!string} file
- */
- function filterOutNonMatchingFiles(file)
- {
- for (var i = 0; i < fileRegexes.length; ++i) {
- if (!file.match(fileRegexes[i]))
- return false;
- }
- return true;
- }
-
- paths = paths.filter(filterOutNonMatchingFiles);
+ paths = paths.filter(searchConfig.filePathMatchesFileQuery.bind(searchConfig));
var barrier = new CallbackBarrier();
progress.setTotalWork(paths.length);
for (var i = 0; i < paths.length; ++i)
- searchInContent.call(this, paths[i], barrier.createCallback(searchInContentCallback.bind(this, paths[i])));
+ searchInContent.call(this, paths[i], barrier.createCallback(searchInContentCallback.bind(null, paths[i])));
barrier.callWhenDone(doneCallback);
/**
@@ -280,7 +242,7 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
*/
function searchInContent(path, callback)
{
- var queriesToRun = queries.slice();
+ var queriesToRun = searchConfig.queries().slice();
searchNextQuery.call(this);
/**
@@ -293,7 +255,7 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
return;
}
var query = queriesToRun.shift();
- this._contentProviders[path].searchInContent(query, caseSensitive, isRegex, contentCallback.bind(this));
+ this._contentProviders[path].searchInContent(query, !searchConfig.ignoreCase(), searchConfig.isRegex(), contentCallback.bind(this));
}
/**
@@ -330,17 +292,10 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
/**
* @param {!WebInspector.Progress} progress
- * @param {function()} callback
*/
- indexContent: function(progress, callback)
+ indexContent: function(progress)
{
- setTimeout(innerCallback, 0);
-
- function innerCallback()
- {
- progress.done();
- callback();
- }
+ setTimeout(progress.done.bind(progress), 0);
},
/**
@@ -348,17 +303,16 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
* @param {string} name
* @param {string} url
* @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean} isEditable
- * @param {boolean=} isContentScript
* @return {string}
*/
- addContentProvider: function(parentPath, name, url, contentProvider, isEditable, isContentScript)
+ addContentProvider: function(parentPath, name, url, contentProvider)
{
var path = parentPath ? parentPath + "/" + name : name;
- var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, url, url, contentProvider.contentType(), isEditable, isContentScript);
+ if (this._contentProviders[path])
+ return path;
+ var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, url, url, contentProvider.contentType());
this._contentProviders[path] = contentProvider;
- this._isContentScriptMap[path] = isContentScript || false;
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor);
+ this._projectStore.addFile(fileDescriptor);
return path;
},
@@ -368,8 +322,7 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
removeFile: function(path)
{
delete this._contentProviders[path];
- delete this._isContentScriptMap[path];
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
+ this._projectStore.removeFile(path);
},
/**
@@ -383,9 +336,7 @@ WebInspector.ContentProviderBasedProjectDelegate.prototype = {
reset: function()
{
this._contentProviders = {};
- this._isContentScriptMap = {};
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
- },
-
- __proto__: WebInspector.Object.prototype
+ this._workspace.removeProject(this._id);
+ this._projectStore = this._workspace.addProject(this._id, this);
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProviders.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviders.js
index c0a51bbea7c..6c44b9ca1ff 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ContentProviders.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ContentProviders.js
@@ -51,20 +51,20 @@ WebInspector.ConcatenatedScriptsContentProvider.prototype = {
return this._sortedScriptsArray;
this._sortedScriptsArray = [];
-
+
var scripts = this._scripts.slice();
scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });
-
+
var scriptOpenTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag.length;
var scriptCloseTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag.length;
-
+
this._sortedScriptsArray.push(scripts[0]);
for (var i = 1; i < scripts.length; ++i) {
var previousScript = this._sortedScriptsArray[this._sortedScriptsArray.length - 1];
-
+
var lineNumber = previousScript.endLine;
var columnNumber = previousScript.endColumn + scriptCloseTagLength + scriptOpenTagLength;
-
+
if (lineNumber < scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber <= scripts[i].columnOffset))
this._sortedScriptsArray.push(scripts[i]);
}
@@ -86,7 +86,7 @@ WebInspector.ConcatenatedScriptsContentProvider.prototype = {
{
return WebInspector.resourceTypes.Document;
},
-
+
/**
* @param {function(?string)} callback
*/
@@ -135,7 +135,6 @@ WebInspector.ConcatenatedScriptsContentProvider.prototype = {
/**
* @param {!WebInspector.Script} script
* @param {!Array.<!PageAgent.SearchMatch>} searchMatches
- * @this {WebInspector.ConcatenatedScriptsContentProvider}
*/
function searchCallback(script, searchMatches)
{
@@ -145,12 +144,12 @@ WebInspector.ConcatenatedScriptsContentProvider.prototype = {
results[script.scriptId].push(searchMatch);
}
scriptsLeft--;
- maybeCallback.call(this);
+ maybeCallback();
}
maybeCallback();
for (var i = 0; i < scripts.length; ++i)
- scripts[i].searchInContent(query, caseSensitive, isRegex, searchCallback.bind(this, scripts[i]));
+ scripts[i].searchInContent(query, caseSensitive, isRegex, searchCallback.bind(null, scripts[i]));
},
/**
@@ -182,16 +181,14 @@ WebInspector.ConcatenatedScriptsContentProvider.prototype = {
}
return content;
- },
-
- __proto__: WebInspector.ContentProvider.prototype
+ }
}
/**
* @constructor
+ * @implements {WebInspector.ContentProvider}
* @param {string} sourceURL
* @param {!WebInspector.ResourceType} contentType
- * @implements {WebInspector.ContentProvider}
*/
WebInspector.CompilerSourceMappingContentProvider = function(sourceURL, contentType)
{
@@ -215,7 +212,7 @@ WebInspector.CompilerSourceMappingContentProvider.prototype = {
{
return this._contentType;
},
-
+
/**
* @param {function(?string)} callback
*/
@@ -264,9 +261,7 @@ WebInspector.CompilerSourceMappingContentProvider.prototype = {
callback(WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
}
- },
-
- __proto__: WebInspector.ContentProvider.prototype
+ }
}
/**
@@ -324,7 +319,5 @@ WebInspector.StaticContentProvider.prototype = {
// searchInContent should call back later.
window.setTimeout(performSearch.bind(this), 0);
- },
-
- __proto__: WebInspector.ContentProvider.prototype
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CookieParser.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js
index b126113dfda..26110e4552d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CookieParser.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/CookieParser.js
@@ -343,8 +343,8 @@ WebInspector.Cookie.prototype = {
},
/**
- * @param {string} key
- * @param {string=} value
+ * @param {string} key
+ * @param {string=} value
*/
addAttribute: function(key, value)
{
@@ -376,7 +376,7 @@ WebInspector.Cookies = {}
WebInspector.Cookies.getCookiesAsync = function(callback)
{
/**
- * @param {?Protocol.Error} error
+ * @param {?Protocol.Error} error
* @param {!Array.<!PageAgent.Cookie>} cookies
*/
function mycallback(error, cookies)
@@ -412,6 +412,7 @@ WebInspector.Cookies.buildCookieProtocolObject = function(protocolCookie)
/**
* @param {!WebInspector.Cookie} cookie
* @param {string} resourceURL
+ * @return {boolean}
*/
WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
@@ -424,8 +425,9 @@ WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
}
/**
- * @param {string} cookieDomain
+ * @param {string} cookieDomain
* @param {string} resourceDomain
+ * @return {boolean}
*/
WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMAgent.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
index 09286b7ab17..f2fe1b05793 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMAgent.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMModel.js
@@ -31,24 +31,28 @@
/**
* @constructor
- * @param {!WebInspector.DOMAgent} domAgent
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.DOMModel} domModel
* @param {?WebInspector.DOMDocument} doc
* @param {boolean} isInShadowTree
* @param {!DOMAgent.Node} payload
*/
-WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
- this._domAgent = domAgent;
+WebInspector.DOMNode = function(domModel, doc, isInShadowTree, payload) {
+ WebInspector.TargetAware.call(this, domModel.target());
+ this._domModel = domModel;
+ this._agent = domModel._agent;
this.ownerDocument = doc;
this._isInShadowTree = isInShadowTree;
this.id = payload.nodeId;
- domAgent._idToDOMNode[this.id] = this;
+ domModel._idToDOMNode[this.id] = this;
this._nodeType = payload.nodeType;
this._nodeName = payload.nodeName;
this._localName = payload.localName;
this._nodeValue = payload.nodeValue;
this._pseudoType = payload.pseudoType;
this._shadowRootType = payload.shadowRootType;
+ this._frameId = payload.frameId || null;
this._shadowRoots = [];
@@ -72,24 +76,29 @@ WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
if (payload.shadowRoots) {
for (var i = 0; i < payload.shadowRoots.length; ++i) {
var root = payload.shadowRoots[i];
- var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, true, root);
+ var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, root);
this._shadowRoots.push(node);
node.parentNode = this;
}
}
if (payload.templateContent) {
- this._templateContent = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, true, payload.templateContent);
+ this._templateContent = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, payload.templateContent);
this._templateContent.parentNode = this;
}
+ if (payload.importedDocument) {
+ this._importedDocument = new WebInspector.DOMNode(this._domModel, this.ownerDocument, true, payload.importedDocument);
+ this._importedDocument.parentNode = this;
+ }
+
if (payload.children)
this._setChildrenPayload(payload.children);
this._setPseudoElements(payload.pseudoElements);
if (payload.contentDocument) {
- this._contentDocument = new WebInspector.DOMDocument(domAgent, payload.contentDocument);
+ this._contentDocument = new WebInspector.DOMDocument(domModel, payload.contentDocument);
this._children = [this._contentDocument];
this._renumber();
}
@@ -110,11 +119,17 @@ WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) {
}
}
+/**
+ * @enum {string}
+ */
WebInspector.DOMNode.PseudoElementNames = {
Before: "before",
After: "after"
}
+/**
+ * @enum {string}
+ */
WebInspector.DOMNode.ShadowRootTypes = {
UserAgent: "user-agent",
Author: "author"
@@ -122,6 +137,14 @@ WebInspector.DOMNode.ShadowRootTypes = {
WebInspector.DOMNode.prototype = {
/**
+ * @return {!WebInspector.DOMModel}
+ */
+ domModel: function()
+ {
+ return this._domModel;
+ },
+
+ /**
* @return {?Array.<!WebInspector.DOMNode>}
*/
children: function()
@@ -162,7 +185,7 @@ WebInspector.DOMNode.prototype = {
},
/**
- * @return {!WebInspector.DOMNode}
+ * @return {?WebInspector.DOMNode}
*/
templateContent: function()
{
@@ -170,6 +193,14 @@ WebInspector.DOMNode.prototype = {
},
/**
+ * @return {?WebInspector.DOMNode}
+ */
+ importedDocument: function()
+ {
+ return this._importedDocument;
+ },
+
+ /**
* @return {number}
*/
nodeType: function()
@@ -218,6 +249,28 @@ WebInspector.DOMNode.prototype = {
},
/**
+ * @return {?WebInspector.DOMNode}
+ */
+ ancestorUserAgentShadowRoot: function()
+ {
+ if (!this._isInShadowTree)
+ return null;
+
+ var current = this;
+ while (!current.isShadowRoot())
+ current = current.parentNode;
+ return current.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? current : null;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isShadowRoot: function()
+ {
+ return !!this._shadowRootType;
+ },
+
+ /**
* @return {?string}
*/
shadowRootType: function()
@@ -230,16 +283,19 @@ WebInspector.DOMNode.prototype = {
*/
nodeNameInCorrectCase: function()
{
+ var shadowRootType = this.shadowRootType();
+ if (shadowRootType)
+ return "#shadow-root" + (shadowRootType === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? " (user-agent)" : "");
return this.isXMLNode() ? this.nodeName() : this.nodeName().toLowerCase();
},
/**
* @param {string} name
- * @param {function(?Protocol.Error)=} callback
+ * @param {function(?Protocol.Error, number)=} callback
*/
setNodeName: function(name, callback)
{
- DOMAgent.setNodeName(this.id, name, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.setNodeName(this.id, name, this._domModel._markRevision(this, callback));
},
/**
@@ -264,7 +320,7 @@ WebInspector.DOMNode.prototype = {
*/
setNodeValue: function(value, callback)
{
- DOMAgent.setNodeValue(this.id, value, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.setNodeValue(this.id, value, this._domModel._markRevision(this, callback));
},
/**
@@ -284,7 +340,7 @@ WebInspector.DOMNode.prototype = {
*/
setAttribute: function(name, text, callback)
{
- DOMAgent.setAttributesAsText(this.id, text, name, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.setAttributesAsText(this.id, text, name, this._domModel._markRevision(this, callback));
},
/**
@@ -294,7 +350,7 @@ WebInspector.DOMNode.prototype = {
*/
setAttributeValue: function(name, value, callback)
{
- DOMAgent.setAttributeValue(this.id, name, value, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.setAttributeValue(this.id, name, value, this._domModel._markRevision(this, callback));
},
/**
@@ -327,9 +383,9 @@ WebInspector.DOMNode.prototype = {
}
}
- WebInspector.domAgent._markRevision(this, callback)(error);
+ this._domModel._markRevision(this, callback)(error);
}
- DOMAgent.removeAttribute(this.id, name, mycallback.bind(this));
+ this._agent.removeAttribute(this.id, name, mycallback.bind(this));
},
/**
@@ -353,7 +409,7 @@ WebInspector.DOMNode.prototype = {
callback(error ? null : this.children());
}
- DOMAgent.requestChildNodes(this.id, undefined, mycallback.bind(this));
+ this._agent.requestChildNodes(this.id, undefined, mycallback.bind(this));
},
/**
@@ -372,15 +428,15 @@ WebInspector.DOMNode.prototype = {
callback(error ? null : this._children);
}
- DOMAgent.requestChildNodes(this.id, depth, mycallback.bind(this));
+ this._agent.requestChildNodes(this.id, depth, mycallback.bind(this));
},
/**
- * @param {function(?Protocol.Error)=} callback
+ * @param {function(?Protocol.Error, string)=} callback
*/
getOuterHTML: function(callback)
{
- DOMAgent.getOuterHTML(this.id, callback);
+ this._agent.getOuterHTML(this.id, callback);
},
/**
@@ -389,7 +445,7 @@ WebInspector.DOMNode.prototype = {
*/
setOuterHTML: function(html, callback)
{
- DOMAgent.setOuterHTML(this.id, html, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.setOuterHTML(this.id, html, this._domModel._markRevision(this, callback));
},
/**
@@ -397,7 +453,7 @@ WebInspector.DOMNode.prototype = {
*/
removeNode: function(callback)
{
- DOMAgent.removeNode(this.id, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.removeNode(this.id, this._domModel._markRevision(this, callback));
},
copyNode: function()
@@ -407,16 +463,32 @@ WebInspector.DOMNode.prototype = {
if (!error)
InspectorFrontendHost.copyText(text);
}
- DOMAgent.getOuterHTML(this.id, copy);
+ this._agent.getOuterHTML(this.id, copy);
},
/**
* @param {string} objectGroupId
- * @param {function(?Protocol.Error)=} callback
+ * @param {function(?Array.<!WebInspector.DOMModel.EventListener>)} callback
*/
eventListeners: function(objectGroupId, callback)
{
- DOMAgent.getEventListenersForNode(this.id, objectGroupId, callback);
+ var target = this.target();
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!Array.<!DOMAgent.EventListener>} payloads
+ */
+ function mycallback(error, payloads)
+ {
+ if (error) {
+ callback(null);
+ return;
+ }
+ callback(payloads.map(function(payload) {
+ return new WebInspector.DOMModel.EventListener(target, payload);
+ }));
+ }
+ this._agent.getEventListenersForNode(this.id, objectGroupId, mycallback);
},
/**
@@ -424,10 +496,19 @@ WebInspector.DOMNode.prototype = {
*/
path: function()
{
+ /**
+ * @param {?WebInspector.DOMNode} node
+ */
+ function canPush(node)
+ {
+ return node && ("index" in node || (node.isShadowRoot() && node.parentNode)) && node._nodeName.length;
+ }
+
var path = [];
var node = this;
- while (node && "index" in node && node._nodeName.length) {
- path.push([node.index, node._nodeName]);
+ while (canPush(node)) {
+ var index = typeof node.index === "number" ? node.index : (node.shadowRootType() === WebInspector.DOMNode.ShadowRootTypes.UserAgent ? "u" : "a");
+ path.push([index, node._nodeName]);
node = node.parentNode;
}
path.reverse();
@@ -462,6 +543,17 @@ WebInspector.DOMNode.prototype = {
},
/**
+ * @return {?PageAgent.FrameId}
+ */
+ frameId: function()
+ {
+ var node = this;
+ while (!node._frameId && node.parentNode)
+ node = node.parentNode;
+ return node._frameId;
+ },
+
+ /**
* @param {!Array.<string>} attrs
* @return {boolean}
*/
@@ -494,7 +586,7 @@ WebInspector.DOMNode.prototype = {
*/
_insertChild: function(prev, payload)
{
- var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
+ var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
this._children.splice(this._children.indexOf(prev) + 1, 0, node);
this._renumber();
return node;
@@ -531,7 +623,7 @@ WebInspector.DOMNode.prototype = {
this._children = [];
for (var i = 0; i < payloads.length; ++i) {
var payload = payloads[i];
- var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payload);
+ var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payload);
this._children.push(node);
}
this._renumber();
@@ -547,7 +639,7 @@ WebInspector.DOMNode.prototype = {
return;
for (var i = 0; i < payloads.length; ++i) {
- var node = new WebInspector.DOMNode(this._domAgent, this.ownerDocument, this._isInShadowTree, payloads[i]);
+ var node = new WebInspector.DOMNode(this._domModel, this.ownerDocument, this._isInShadowTree, payloads[i]);
node.parentNode = this;
this._pseudoElements[node.pseudoType()] = node;
}
@@ -619,7 +711,7 @@ WebInspector.DOMNode.prototype = {
*/
moveTo: function(targetNode, anchorNode, callback)
{
- DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, WebInspector.domAgent._markRevision(this, callback));
+ this._agent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, this._domModel._markRevision(this, callback));
},
/**
@@ -683,11 +775,20 @@ WebInspector.DOMNode.prototype = {
this.parentNode._updateDescendantUserPropertyCount(name, -1);
},
+ /**
+ * @param {string} name
+ * @return {?T}
+ * @template T
+ */
getUserProperty: function(name)
{
- return this._userProperties ? this._userProperties[name] : null;
+ return (this._userProperties && this._userProperties[name]) || null;
},
+ /**
+ * @param {string} name
+ * @return {number}
+ */
descendantUserPropertyCount: function(name)
{
return this._descendantUserPropertyCounters && this._descendantUserPropertyCounters[name] ? this._descendantUserPropertyCounters[name] : 0;
@@ -706,18 +807,72 @@ WebInspector.DOMNode.prototype = {
return WebInspector.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
}
return null;
- }
+ },
+
+ /**
+ * @param {string=} mode
+ * @param {!RuntimeAgent.RemoteObjectId=} objectId
+ */
+ highlight: function(mode, objectId)
+ {
+ this._domModel.highlightDOMNode(this.id, mode, objectId);
+ },
+
+ highlightForTwoSeconds: function()
+ {
+ this._domModel.highlightDOMNodeForTwoSeconds(this.id);
+ },
+
+ reveal: function()
+ {
+ WebInspector.Revealer.reveal(this);
+ },
+
+ /**
+ * @param {string=} objectGroup
+ * @param {function(?WebInspector.RemoteObject)=} callback
+ */
+ resolveToObject: function(objectGroup, callback)
+ {
+ this._agent.resolveNode(this.id, objectGroup, mycallback.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!RuntimeAgent.RemoteObject} object
+ * @this {WebInspector.DOMNode}
+ */
+ function mycallback(error, object)
+ {
+ if (!callback)
+ return;
+
+ if (error || !object)
+ callback(null);
+ else
+ callback(this.target().runtimeModel.createRemoteObject(object));
+ }
+ },
+
+ /**
+ * @param {function(?DOMAgent.BoxModel)} callback
+ */
+ boxModel: function(callback)
+ {
+ this._agent.getBoxModel(this.id, this._domModel._wrapClientCallback(callback));
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
/**
* @extends {WebInspector.DOMNode}
* @constructor
- * @param {!WebInspector.DOMAgent} domAgent
+ * @param {!WebInspector.DOMModel} domModel
* @param {!DOMAgent.Node} payload
*/
-WebInspector.DOMDocument = function(domAgent, payload)
+WebInspector.DOMDocument = function(domModel, payload)
{
- WebInspector.DOMNode.call(this, domAgent, this, false, payload);
+ WebInspector.DOMNode.call(this, domModel, this, false, payload);
this.documentURL = payload.documentURL || "";
this.baseURL = payload.baseURL || "";
this.xmlVersion = payload.xmlVersion;
@@ -729,23 +884,29 @@ WebInspector.DOMDocument.prototype = {
}
/**
- * @extends {WebInspector.Object}
* @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.DOMAgent = function() {
+WebInspector.DOMModel = function(target) {
+ WebInspector.TargetAwareObject.call(this, target);
+
+ this._agent = target.domAgent();
+
/** @type {!Object.<number, !WebInspector.DOMNode>} */
this._idToDOMNode = {};
/** @type {?WebInspector.DOMDocument} */
this._document = null;
/** @type {!Object.<number, boolean>} */
this._attributeLoadNodeIds = {};
- InspectorBackend.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));
+ target.registerDOMDispatcher(new WebInspector.DOMDispatcher(this));
- this._defaultHighlighter = new WebInspector.DefaultDOMNodeHighlighter();
+ this._defaultHighlighter = new WebInspector.DefaultDOMNodeHighlighter(this._agent);
this._highlighter = this._defaultHighlighter;
+ this._agent.enable();
}
-WebInspector.DOMAgent.Events = {
+WebInspector.DOMModel.Events = {
AttrModified: "AttrModified",
AttrRemoved: "AttrRemoved",
CharacterDataModified: "CharacterDataModified",
@@ -755,10 +916,9 @@ WebInspector.DOMAgent.Events = {
ChildNodeCountUpdated: "ChildNodeCountUpdated",
UndoRedoRequested: "UndoRedoRequested",
UndoRedoCompleted: "UndoRedoCompleted",
- InspectNodeRequested: "InspectNodeRequested"
}
-WebInspector.DOMAgent.prototype = {
+WebInspector.DOMModel.prototype = {
/**
* @param {function(!WebInspector.DOMDocument)=} callback
*/
@@ -778,7 +938,7 @@ WebInspector.DOMAgent.prototype = {
this._pendingDocumentRequestCallbacks = [callback];
/**
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
* @param {?Protocol.Error} error
* @param {!DOMAgent.Node} root
*/
@@ -795,7 +955,7 @@ WebInspector.DOMAgent.prototype = {
delete this._pendingDocumentRequestCallbacks;
}
- DOMAgent.getDocument(onDocumentAvailable.bind(this));
+ this._agent.getDocument(onDocumentAvailable.bind(this));
},
/**
@@ -808,11 +968,19 @@ WebInspector.DOMAgent.prototype = {
/**
* @param {!RuntimeAgent.RemoteObjectId} objectId
- * @param {function(?DOMAgent.NodeId)=} callback
+ * @param {function(?WebInspector.DOMNode)=} callback
*/
pushNodeToFrontend: function(objectId, callback)
{
- this._dispatchWhenDocumentAvailable(DOMAgent.requestNode.bind(DOMAgent, objectId), callback);
+ /**
+ * @param {?DOMAgent.NodeId} nodeId
+ * @this {!WebInspector.DOMModel}
+ */
+ function mycallback(nodeId)
+ {
+ callback(nodeId ? this.nodeForId(nodeId) : null);
+ }
+ this._dispatchWhenDocumentAvailable(this._agent.requestNode.bind(this._agent, objectId), mycallback.bind(this));
},
/**
@@ -821,16 +989,16 @@ WebInspector.DOMAgent.prototype = {
*/
pushNodeByPathToFrontend: function(path, callback)
{
- this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByPathToFrontend.bind(DOMAgent, path), callback);
+ this._dispatchWhenDocumentAvailable(this._agent.pushNodeByPathToFrontend.bind(this._agent, path), callback);
},
/**
- * @param {number} backendNodeId
- * @param {function(?number)=} callback
+ * @param {!Array.<number>} backendNodeIds
+ * @param {function(?Array.<number>)=} callback
*/
- pushNodeByBackendIdToFrontend: function(backendNodeId, callback)
+ pushNodesByBackendIdsToFrontend: function(backendNodeIds, callback)
{
- this._dispatchWhenDocumentAvailable(DOMAgent.pushNodeByBackendIdToFrontend.bind(DOMAgent, backendNodeId), callback);
+ this._dispatchWhenDocumentAvailable(this._agent.pushNodesByBackendIdsToFrontend.bind(this._agent, backendNodeIds), callback);
},
/**
@@ -847,11 +1015,12 @@ WebInspector.DOMAgent.prototype = {
* @param {!T=} result
* @template T
*/
- return function(error, result)
+ var wrapper = function(error, result)
{
// Caller is responsible for handling the actual error.
callback(error ? null : result);
- }
+ };
+ return wrapper;
},
/**
@@ -864,7 +1033,7 @@ WebInspector.DOMAgent.prototype = {
var callbackWrapper = this._wrapClientCallback(callback);
/**
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function onDocumentAvailable()
{
@@ -890,7 +1059,7 @@ WebInspector.DOMAgent.prototype = {
return;
node._setAttribute(name, value);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: name });
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified, { node: node, name: name });
},
/**
@@ -903,7 +1072,7 @@ WebInspector.DOMAgent.prototype = {
if (!node)
return;
node._removeAttribute(name);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrRemoved, { node: node, name: name });
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrRemoved, { node: node, name: name });
},
/**
@@ -915,13 +1084,13 @@ WebInspector.DOMAgent.prototype = {
this._attributeLoadNodeIds[nodeIds[i]] = true;
if ("_loadNodeAttributesTimeout" in this)
return;
- this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 0);
+ this._loadNodeAttributesTimeout = setTimeout(this._loadNodeAttributes.bind(this), 20);
},
_loadNodeAttributes: function()
{
/**
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
* @param {!DOMAgent.NodeId} nodeId
* @param {?Protocol.Error} error
* @param {!Array.<string>} attributes
@@ -935,7 +1104,7 @@ WebInspector.DOMAgent.prototype = {
var node = this._idToDOMNode[nodeId];
if (node) {
if (node._setAttributesPayload(attributes))
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.AttrModified, { node: node, name: "style" });
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.AttrModified, { node: node, name: "style" });
}
}
@@ -943,7 +1112,7 @@ WebInspector.DOMAgent.prototype = {
for (var nodeId in this._attributeLoadNodeIds) {
var nodeIdAsNumber = parseInt(nodeId, 10);
- DOMAgent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsNumber));
+ this._agent.getAttributes(nodeIdAsNumber, callback.bind(this, nodeIdAsNumber));
}
this._attributeLoadNodeIds = {};
},
@@ -956,7 +1125,7 @@ WebInspector.DOMAgent.prototype = {
{
var node = this._idToDOMNode[nodeId];
node._nodeValue = newValue;
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.CharacterDataModified, node);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.CharacterDataModified, node);
},
/**
@@ -983,7 +1152,7 @@ WebInspector.DOMAgent.prototype = {
this._document = new WebInspector.DOMDocument(this, payload);
else
this._document = null;
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.DocumentUpdated, this._document);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.DocumentUpdated, this._document);
},
/**
@@ -1020,7 +1189,7 @@ WebInspector.DOMAgent.prototype = {
{
var node = this._idToDOMNode[nodeId];
node._childNodeCount = newValue;
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, node);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.ChildNodeCountUpdated, node);
},
/**
@@ -1034,7 +1203,7 @@ WebInspector.DOMAgent.prototype = {
var prev = this._idToDOMNode[prevId];
var node = parent._insertChild(prev, payload);
this._idToDOMNode[node.id] = node;
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
},
/**
@@ -1047,7 +1216,7 @@ WebInspector.DOMAgent.prototype = {
var node = this._idToDOMNode[nodeId];
parent._removeChild(node);
this._unbind(node);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: node, parent: parent});
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: node, parent: parent});
},
/**
@@ -1063,7 +1232,7 @@ WebInspector.DOMAgent.prototype = {
node.parentNode = host;
this._idToDOMNode[node.id] = node;
host._shadowRoots.push(node);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
},
/**
@@ -1080,7 +1249,7 @@ WebInspector.DOMAgent.prototype = {
return;
host._removeChild(root);
this._unbind(root);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: root, parent: host});
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: root, parent: host});
},
/**
@@ -1097,7 +1266,7 @@ WebInspector.DOMAgent.prototype = {
this._idToDOMNode[node.id] = node;
console.assert(!parent._pseudoElements[node.pseudoType()]);
parent._pseudoElements[node.pseudoType()] = node;
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeInserted, node);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeInserted, node);
},
/**
@@ -1114,7 +1283,7 @@ WebInspector.DOMAgent.prototype = {
return;
parent._removeChild(pseudoElement);
this._unbind(pseudoElement);
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node: pseudoElement, parent: parent});
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.NodeRemoved, {node: pseudoElement, parent: parent});
},
/**
@@ -1135,21 +1304,11 @@ WebInspector.DOMAgent.prototype = {
},
/**
- * @param {number} nodeId
- */
- inspectElement: function(nodeId)
- {
- var node = this._idToDOMNode[nodeId];
- if (node)
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectNodeRequested, nodeId);
- },
-
- /**
* @param {!DOMAgent.NodeId} nodeId
*/
_inspectNodeRequested: function(nodeId)
{
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.InspectNodeRequested, nodeId);
+ WebInspector.Revealer.reveal(this.nodeForId(nodeId))
},
/**
@@ -1164,14 +1323,14 @@ WebInspector.DOMAgent.prototype = {
* @param {?Protocol.Error} error
* @param {string} searchId
* @param {number} resultsCount
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function callback(error, searchId, resultsCount)
{
this._searchId = searchId;
searchCallback(resultsCount);
}
- DOMAgent.performSearch(query, callback.bind(this));
+ this._agent.performSearch(query, callback.bind(this));
},
/**
@@ -1181,14 +1340,14 @@ WebInspector.DOMAgent.prototype = {
searchResult: function(index, callback)
{
if (this._searchId)
- DOMAgent.getSearchResults(this._searchId, index, index + 1, searchResultsCallback.bind(this));
+ this._agent.getSearchResults(this._searchId, index, index + 1, searchResultsCallback.bind(this));
else
callback(null);
/**
* @param {?Protocol.Error} error
* @param {!Array.<number>} nodeIds
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function searchResultsCallback(error, nodeIds)
{
@@ -1207,7 +1366,7 @@ WebInspector.DOMAgent.prototype = {
cancelSearch: function()
{
if (this._searchId) {
- DOMAgent.discardSearchResults(this._searchId);
+ this._agent.discardSearchResults(this._searchId);
delete this._searchId;
}
},
@@ -1219,7 +1378,7 @@ WebInspector.DOMAgent.prototype = {
*/
querySelector: function(nodeId, selectors, callback)
{
- DOMAgent.querySelector(nodeId, selectors, this._wrapClientCallback(callback));
+ this._agent.querySelector(nodeId, selectors, this._wrapClientCallback(callback));
},
/**
@@ -1229,7 +1388,7 @@ WebInspector.DOMAgent.prototype = {
*/
querySelectorAll: function(nodeId, selectors, callback)
{
- DOMAgent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callback));
+ this._agent.querySelectorAll(nodeId, selectors, this._wrapClientCallback(callback));
},
/**
@@ -1239,11 +1398,25 @@ WebInspector.DOMAgent.prototype = {
*/
highlightDOMNode: function(nodeId, mode, objectId)
{
+ this.highlightDOMNodeWithConfig(nodeId, { mode: mode }, objectId);
+ },
+
+ /**
+ * @param {!DOMAgent.NodeId=} nodeId
+ * @param {!{mode: (string|undefined), showInfo: (boolean|undefined)}=} config
+ * @param {!RuntimeAgent.RemoteObjectId=} objectId
+ */
+ highlightDOMNodeWithConfig: function(nodeId, config, objectId)
+ {
+ config = config || { mode: "all", showInfo: undefined };
if (this._hideDOMNodeHighlightTimeout) {
clearTimeout(this._hideDOMNodeHighlightTimeout);
delete this._hideDOMNodeHighlightTimeout;
}
- this._highlighter.highlightDOMNode(nodeId || 0, this._buildHighlightConfig(mode), objectId);
+ var highlightConfig = this._buildHighlightConfig(config.mode);
+ if (typeof config.showInfo !== "undefined")
+ highlightConfig.showInfo = config.showInfo;
+ this._highlighter.highlightDOMNode(this.nodeForId(nodeId || 0), highlightConfig, objectId);
},
hideDOMNodeHighlight: function()
@@ -1262,17 +1435,17 @@ WebInspector.DOMAgent.prototype = {
/**
* @param {boolean} enabled
- * @param {boolean} inspectShadowDOM
+ * @param {boolean} inspectUAShadowDOM
* @param {function(?Protocol.Error)=} callback
*/
- setInspectModeEnabled: function(enabled, inspectShadowDOM, callback)
+ setInspectModeEnabled: function(enabled, inspectUAShadowDOM, callback)
{
/**
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function onDocumentAvailable()
{
- this._highlighter.setInspectModeEnabled(enabled, inspectShadowDOM, this._buildHighlightConfig(), callback);
+ this._highlighter.setInspectModeEnabled(enabled, inspectUAShadowDOM, this._buildHighlightConfig(), callback);
}
this.requestDocument(onDocumentAvailable.bind(this));
},
@@ -1284,7 +1457,8 @@ WebInspector.DOMAgent.prototype = {
_buildHighlightConfig: function(mode)
{
mode = mode || "all";
- var highlightConfig = { showInfo: mode === "all", showRulers: WebInspector.settings.showMetricsRulers.get() };
+ // FIXME: split show rulers and show extension lines.
+ var highlightConfig = { showInfo: mode === "all", showRulers: WebInspector.overridesSupport.showMetricsRulers() };
if (mode === "all" || mode === "content")
highlightConfig.contentColor = WebInspector.Color.PageHighlight.Content.toProtocolRGBA();
@@ -1305,15 +1479,15 @@ WebInspector.DOMAgent.prototype = {
/**
* @param {!WebInspector.DOMNode} node
- * @param {function(?Protocol.Error, !A=, !B=)=} callback
- * @return {function(?Protocol.Error, !A=, !B=)}
- * @template A,B
+ * @param {function(?Protocol.Error, ...)=} callback
+ * @return {function(...)}
+ * @template T
*/
_markRevision: function(node, callback)
{
/**
* @param {?Protocol.Error} error
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function wrapperFunction(error)
{
@@ -1355,7 +1529,7 @@ WebInspector.DOMAgent.prototype = {
/**
* @param {?Protocol.Error} error
* @param {string} scriptId
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function scriptAddedCallback(error, scriptId)
{
@@ -1370,7 +1544,7 @@ WebInspector.DOMAgent.prototype = {
markUndoableState: function()
{
- DOMAgent.markUndoableState();
+ this._agent.markUndoableState();
},
/**
@@ -1380,16 +1554,16 @@ WebInspector.DOMAgent.prototype = {
{
/**
* @param {?Protocol.Error} error
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function mycallback(error)
{
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);
callback(error);
}
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
- DOMAgent.undo(callback);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);
+ this._agent.undo(callback);
},
/**
@@ -1399,16 +1573,16 @@ WebInspector.DOMAgent.prototype = {
{
/**
* @param {?Protocol.Error} error
- * @this {WebInspector.DOMAgent}
+ * @this {WebInspector.DOMModel}
*/
function mycallback(error)
{
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoCompleted);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoCompleted);
callback(error);
}
- this.dispatchEventToListeners(WebInspector.DOMAgent.Events.UndoRedoRequested);
- DOMAgent.redo(callback);
+ this.dispatchEventToListeners(WebInspector.DOMModel.Events.UndoRedoRequested);
+ this._agent.redo(callback);
},
/**
@@ -1419,23 +1593,47 @@ WebInspector.DOMAgent.prototype = {
this._highlighter = highlighter || this._defaultHighlighter;
},
- __proto__: WebInspector.Object.prototype
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {function(?WebInspector.DOMNode)} callback
+ */
+ nodeForLocation: function(x, y, callback)
+ {
+ this._agent.getNodeForLocation(x, y, mycallback.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {number} nodeId
+ * @this {WebInspector.DOMModel}
+ */
+ function mycallback(error, nodeId)
+ {
+ if (error) {
+ callback(null);
+ return;
+ }
+ callback(this.nodeForId(nodeId));
+ }
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
* @constructor
* @implements {DOMAgent.Dispatcher}
- * @param {!WebInspector.DOMAgent} domAgent
+ * @param {!WebInspector.DOMModel} domModel
*/
-WebInspector.DOMDispatcher = function(domAgent)
+WebInspector.DOMDispatcher = function(domModel)
{
- this._domAgent = domAgent;
+ this._domModel = domModel;
}
WebInspector.DOMDispatcher.prototype = {
documentUpdated: function()
{
- this._domAgent._documentUpdated();
+ this._domModel._documentUpdated();
},
/**
@@ -1443,7 +1641,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
inspectNodeRequested: function(nodeId)
{
- this._domAgent._inspectNodeRequested(nodeId);
+ this._domModel._inspectNodeRequested(nodeId);
},
/**
@@ -1453,7 +1651,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
attributeModified: function(nodeId, name, value)
{
- this._domAgent._attributeModified(nodeId, name, value);
+ this._domModel._attributeModified(nodeId, name, value);
},
/**
@@ -1462,7 +1660,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
attributeRemoved: function(nodeId, name)
{
- this._domAgent._attributeRemoved(nodeId, name);
+ this._domModel._attributeRemoved(nodeId, name);
},
/**
@@ -1470,7 +1668,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
inlineStyleInvalidated: function(nodeIds)
{
- this._domAgent._inlineStyleInvalidated(nodeIds);
+ this._domModel._inlineStyleInvalidated(nodeIds);
},
/**
@@ -1479,7 +1677,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
characterDataModified: function(nodeId, characterData)
{
- this._domAgent._characterDataModified(nodeId, characterData);
+ this._domModel._characterDataModified(nodeId, characterData);
},
/**
@@ -1488,7 +1686,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
setChildNodes: function(parentId, payloads)
{
- this._domAgent._setChildNodes(parentId, payloads);
+ this._domModel._setChildNodes(parentId, payloads);
},
/**
@@ -1497,7 +1695,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
childNodeCountUpdated: function(nodeId, childNodeCount)
{
- this._domAgent._childNodeCountUpdated(nodeId, childNodeCount);
+ this._domModel._childNodeCountUpdated(nodeId, childNodeCount);
},
/**
@@ -1507,7 +1705,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
childNodeInserted: function(parentNodeId, previousNodeId, payload)
{
- this._domAgent._childNodeInserted(parentNodeId, previousNodeId, payload);
+ this._domModel._childNodeInserted(parentNodeId, previousNodeId, payload);
},
/**
@@ -1516,7 +1714,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
childNodeRemoved: function(parentNodeId, nodeId)
{
- this._domAgent._childNodeRemoved(parentNodeId, nodeId);
+ this._domModel._childNodeRemoved(parentNodeId, nodeId);
},
/**
@@ -1525,7 +1723,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
shadowRootPushed: function(hostId, root)
{
- this._domAgent._shadowRootPushed(hostId, root);
+ this._domModel._shadowRootPushed(hostId, root);
},
/**
@@ -1534,7 +1732,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
shadowRootPopped: function(hostId, rootId)
{
- this._domAgent._shadowRootPopped(hostId, rootId);
+ this._domModel._shadowRootPopped(hostId, rootId);
},
/**
@@ -1543,7 +1741,7 @@ WebInspector.DOMDispatcher.prototype = {
*/
pseudoElementAdded: function(parentId, pseudoElement)
{
- this._domAgent._pseudoElementAdded(parentId, pseudoElement);
+ this._domModel._pseudoElementAdded(parentId, pseudoElement);
},
/**
@@ -1552,11 +1750,59 @@ WebInspector.DOMDispatcher.prototype = {
*/
pseudoElementRemoved: function(parentId, pseudoElementId)
{
- this._domAgent._pseudoElementRemoved(parentId, pseudoElementId);
+ this._domModel._pseudoElementRemoved(parentId, pseudoElementId);
}
}
/**
+ * @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
+ * @param {!DOMAgent.EventListener} payload
+ */
+WebInspector.DOMModel.EventListener = function(target, payload)
+{
+ WebInspector.TargetAware.call(this, target);
+ this._payload = payload;
+}
+
+WebInspector.DOMModel.EventListener.prototype = {
+ /**
+ * @return {!DOMAgent.EventListener}
+ */
+ payload: function()
+ {
+ return this._payload;
+ },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ node: function()
+ {
+ return this.target().domModel.nodeForId(this._payload.nodeId);
+ },
+
+ /**
+ * @return {!WebInspector.DebuggerModel.Location}
+ */
+ location: function()
+ {
+ return WebInspector.DebuggerModel.Location.fromPayload(this.target(), this._payload.location);
+ },
+
+ /**
+ * @return {?WebInspector.RemoteObject}
+ */
+ handler: function()
+ {
+ return this._payload.handler ? this.target().runtimeModel.createRemoteObject(this._payload.handler) : null;
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
+}
+
+/**
* @interface
*/
WebInspector.DOMNodeHighlighter = function() {
@@ -1564,55 +1810,58 @@ WebInspector.DOMNodeHighlighter = function() {
WebInspector.DOMNodeHighlighter.prototype = {
/**
- * @param {!DOMAgent.NodeId} nodeId
+ * @param {?WebInspector.DOMNode} node
* @param {!DOMAgent.HighlightConfig} config
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
- highlightDOMNode: function(nodeId, config, objectId) {},
+ highlightDOMNode: function(node, config, objectId) {},
/**
* @param {boolean} enabled
- * @param {boolean} inspectShadowDOM
+ * @param {boolean} inspectUAShadowDOM
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
- setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback) {}
+ setInspectModeEnabled: function(enabled, inspectUAShadowDOM, config, callback) {}
}
/**
* @constructor
* @implements {WebInspector.DOMNodeHighlighter}
+ * @param {!Protocol.DOMAgent} agent
*/
-WebInspector.DefaultDOMNodeHighlighter = function() {
+WebInspector.DefaultDOMNodeHighlighter = function(agent)
+{
+ this._agent = agent;
}
WebInspector.DefaultDOMNodeHighlighter.prototype = {
/**
- * @param {!DOMAgent.NodeId} nodeId
+ * @param {?WebInspector.DOMNode} node
* @param {!DOMAgent.HighlightConfig} config
* @param {!RuntimeAgent.RemoteObjectId=} objectId
*/
- highlightDOMNode: function(nodeId, config, objectId)
+ highlightDOMNode: function(node, config, objectId)
{
- if (objectId || nodeId)
- DOMAgent.highlightNode(config, objectId ? undefined : nodeId, objectId);
+ if (objectId || node)
+ this._agent.highlightNode(config, objectId ? undefined : node.id, objectId);
else
- DOMAgent.hideHighlight();
+ this._agent.hideHighlight();
},
/**
* @param {boolean} enabled
- * @param {boolean} inspectShadowDOM
+ * @param {boolean} inspectUAShadowDOM
* @param {!DOMAgent.HighlightConfig} config
* @param {function(?Protocol.Error)=} callback
*/
- setInspectModeEnabled: function(enabled, inspectShadowDOM, config, callback)
+ setInspectModeEnabled: function(enabled, inspectUAShadowDOM, config, callback)
{
- DOMAgent.setInspectModeEnabled(enabled, inspectShadowDOM, config, callback);
+ this._agent.setInspectModeEnabled(enabled, inspectUAShadowDOM, config, callback);
}
}
/**
- * @type {!WebInspector.DOMAgent}
+ * @type {!WebInspector.DOMModel}
*/
-WebInspector.domAgent;
+WebInspector.domModel;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DOMStorage.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMStorage.js
index edce4b6764d..251fb9a832a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DOMStorage.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DOMStorage.js
@@ -30,11 +30,13 @@
/**
* @constructor
* @extends {WebInspector.Object}
+ * @param {!WebInspector.DOMStorageModel} model
* @param {string} securityOrigin
* @param {boolean} isLocalStorage
*/
-WebInspector.DOMStorage = function(securityOrigin, isLocalStorage)
+WebInspector.DOMStorage = function(model, securityOrigin, isLocalStorage)
{
+ this._model = model;
this._securityOrigin = securityOrigin;
this._isLocalStorage = isLocalStorage;
}
@@ -81,7 +83,7 @@ WebInspector.DOMStorage.prototype = {
*/
getItems: function(callback)
{
- DOMStorageAgent.getDOMStorageItems(this.id, callback);
+ this._model._agent.getDOMStorageItems(this.id, callback);
},
/**
@@ -90,7 +92,7 @@ WebInspector.DOMStorage.prototype = {
*/
setItem: function(key, value)
{
- DOMStorageAgent.setDOMStorageItem(this.id, key, value);
+ this._model._agent.setDOMStorageItem(this.id, key, value);
},
/**
@@ -98,7 +100,7 @@ WebInspector.DOMStorage.prototype = {
*/
removeItem: function(key)
{
- DOMStorageAgent.removeDOMStorageItem(this.id, key);
+ this._model._agent.removeDOMStorageItem(this.id, key);
},
__proto__: WebInspector.Object.prototype
@@ -106,16 +108,20 @@ WebInspector.DOMStorage.prototype = {
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.DOMStorageModel = function()
+WebInspector.DOMStorageModel = function(target)
{
+ WebInspector.TargetAwareObject.call(this, target);
+
/** @type {!Object.<string, !WebInspector.DOMStorage>} */
this._storages = {};
- InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
- DOMStorageAgent.enable();
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
+ target.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
+ this._agent = target.domstorageAgent();
+ this._agent.enable();
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
}
WebInspector.DOMStorageModel.Events = {
@@ -133,13 +139,13 @@ WebInspector.DOMStorageModel.prototype = {
var securityOrigin = /** @type {string} */ (event.data);
var localStorageKey = this._storageKey(securityOrigin, true);
console.assert(!this._storages[localStorageKey]);
- var localStorage = new WebInspector.DOMStorage(securityOrigin, true);
+ var localStorage = new WebInspector.DOMStorage(this, securityOrigin, true);
this._storages[localStorageKey] = localStorage;
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, localStorage);
var sessionStorageKey = this._storageKey(securityOrigin, false);
console.assert(!this._storages[sessionStorageKey]);
- var sessionStorage = new WebInspector.DOMStorage(securityOrigin, false);
+ var sessionStorage = new WebInspector.DOMStorage(this, securityOrigin, false);
this._storages[sessionStorageKey] = sessionStorage;
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, sessionStorage);
},
@@ -251,7 +257,7 @@ WebInspector.DOMStorageModel.prototype = {
return result;
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Database.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Database.js
index 933a70eca31..34364b1e511 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Database.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Database.js
@@ -29,6 +29,10 @@
/**
* @constructor
* @param {!WebInspector.DatabaseModel} model
+ * @param {string} id
+ * @param {string} domain
+ * @param {string} name
+ * @param {string} version
*/
WebInspector.Database = function(model, id, domain, name, version)
{
@@ -89,7 +93,7 @@ WebInspector.Database.prototype = {
if (!error)
callback(names.sort());
}
- DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback);
+ this._model._agent.getDatabaseTableNames(this._id, sortingCallback);
},
/**
@@ -124,19 +128,23 @@ WebInspector.Database.prototype = {
}
onSuccess(columnNames, values);
}
- DatabaseAgent.executeSQL(this._id, query, callback.bind(this));
+ this._model._agent.executeSQL(this._id, query, callback);
}
}
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.DatabaseModel = function()
+WebInspector.DatabaseModel = function(target)
{
+ WebInspector.TargetAwareObject.call(this, target);
+
this._databases = [];
- InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
- DatabaseAgent.enable();
+ target.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
+ this._agent = target.databaseAgent();
+ this._agent.enable();
}
WebInspector.DatabaseModel.Events = {
@@ -173,7 +181,7 @@ WebInspector.DatabaseModel.prototype = {
this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DebuggerModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index e6553de3774..c7033dccd77 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DebuggerModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -30,53 +30,52 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.DebuggerModel = function()
+WebInspector.DebuggerModel = function(target)
{
- InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));
+ WebInspector.TargetAwareObject.call(this, target);
+
+ target.registerDebuggerDispatcher(new WebInspector.DebuggerDispatcher(this));
+ this._agent = target.debuggerAgent();
/** @type {?WebInspector.DebuggerPausedDetails} */
this._debuggerPausedDetails = null;
/** @type {!Object.<string, !WebInspector.Script>} */
this._scripts = {};
- /** @type {!Object.<!string, !Array.<!WebInspector.Script>>} */
- this._scriptsBySourceURL = {};
+ /** @type {!StringMap.<!Array.<!WebInspector.Script>>} */
+ this._scriptsBySourceURL = new StringMap();
- this._canSetScriptSource = false;
this._breakpointsActive = true;
+ /** @type {!WebInspector.Object} */
+ this._breakpointResolvedEventTarget = new WebInspector.Object();
- WebInspector.settings.pauseOnExceptionStateString = WebInspector.settings.createSetting("pauseOnExceptionStateString", WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions);
- WebInspector.settings.pauseOnExceptionStateString.addChangeListener(this._pauseOnExceptionStateChanged, this);
+ this._isPausing = false;
+ WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._pauseOnExceptionStateChanged, this);
+ WebInspector.settings.pauseOnCaughtException.addChangeListener(this._pauseOnExceptionStateChanged, this);
WebInspector.settings.enableAsyncStackTraces.addChangeListener(this._asyncStackTracesStateChanged, this);
+ target.profilingLock.addEventListener(WebInspector.Lock.Events.StateChanged, this._profilingStateChanged, this);
this.enableDebugger();
- WebInspector.DebuggerModel.applySkipStackFrameSettings();
+ WebInspector.settings.skipStackFramesSwitch.addChangeListener(this._applySkipStackFrameSettings, this);
+ WebInspector.settings.skipStackFramesPattern.addChangeListener(this._applySkipStackFrameSettings, this);
+ this._applySkipStackFrameSettings();
}
-// Keep these in sync with WebCore::ScriptDebugServer
+/**
+ * Keep these in sync with WebCore::ScriptDebugServer
+ *
+ * @enum {string}
+ */
WebInspector.DebuggerModel.PauseOnExceptionsState = {
DontPauseOnExceptions : "none",
PauseOnAllExceptions : "all",
PauseOnUncaughtExceptions: "uncaught"
};
-/**
- * @constructor
- * @implements {WebInspector.RawLocation}
- * @param {string} scriptId
- * @param {number} lineNumber
- * @param {number} columnNumber
- */
-WebInspector.DebuggerModel.Location = function(scriptId, lineNumber, columnNumber)
-{
- this.scriptId = scriptId;
- this.lineNumber = lineNumber;
- this.columnNumber = columnNumber;
-}
-
WebInspector.DebuggerModel.Events = {
DebuggerWasEnabled: "DebuggerWasEnabled",
DebuggerWasDisabled: "DebuggerWasDisabled",
@@ -84,7 +83,6 @@ WebInspector.DebuggerModel.Events = {
DebuggerResumed: "DebuggerResumed",
ParsedScriptSource: "ParsedScriptSource",
FailedToParseScriptSource: "FailedToParseScriptSource",
- BreakpointResolved: "BreakpointResolved",
GlobalObjectCleared: "GlobalObjectCleared",
CallFrameSelected: "CallFrameSelected",
ConsoleCommandEvaluatedInSelectedCallFrame: "ConsoleCommandEvaluatedInSelectedCallFrame",
@@ -115,17 +113,7 @@ WebInspector.DebuggerModel.prototype = {
if (this._debuggerEnabled)
return;
- /**
- * @param {?Protocol.Error} error
- * @param {boolean} result
- * @this {WebInspector.DebuggerModel}
- */
- function callback(error, result)
- {
- this._canSetScriptSource = result;
- }
- DebuggerAgent.canSetScriptSource(callback.bind(this));
- DebuggerAgent.enable(this._debuggerWasEnabled.bind(this));
+ this._agent.enable(this._debuggerWasEnabled.bind(this));
},
disableDebugger: function()
@@ -133,7 +121,7 @@ WebInspector.DebuggerModel.prototype = {
if (!this._debuggerEnabled)
return;
- DebuggerAgent.disable(this._debuggerWasDisabled.bind(this));
+ this._agent.disable(this._debuggerWasDisabled.bind(this));
},
/**
@@ -146,7 +134,7 @@ WebInspector.DebuggerModel.prototype = {
clearTimeout(this._skipAllPausesTimeout);
delete this._skipAllPausesTimeout;
}
- DebuggerAgent.setSkipAllPauses(skip, untilReload);
+ this._agent.setSkipAllPauses(skip, untilReload);
},
/**
@@ -156,19 +144,11 @@ WebInspector.DebuggerModel.prototype = {
{
if (this._skipAllPausesTimeout)
clearTimeout(this._skipAllPausesTimeout);
- DebuggerAgent.setSkipAllPauses(true, true);
+ this._agent.setSkipAllPauses(true, true);
// If reload happens before the timeout, the flag will be already unset and the timeout callback won't change anything.
this._skipAllPausesTimeout = setTimeout(this.skipAllPauses.bind(this, false), timeout);
},
- /**
- * @return {boolean}
- */
- canSetScriptSource: function()
- {
- return this._canSetScriptSource;
- },
-
_debuggerWasEnabled: function()
{
this._debuggerEnabled = true;
@@ -179,83 +159,96 @@ WebInspector.DebuggerModel.prototype = {
_pauseOnExceptionStateChanged: function()
{
- DebuggerAgent.setPauseOnExceptions(WebInspector.settings.pauseOnExceptionStateString.get());
+ var state;
+ if (!WebInspector.settings.pauseOnExceptionEnabled.get()) {
+ state = WebInspector.DebuggerModel.PauseOnExceptionsState.DontPauseOnExceptions;
+ } else if (WebInspector.settings.pauseOnCaughtException.get()) {
+ state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnAllExceptions;
+ } else {
+ state = WebInspector.DebuggerModel.PauseOnExceptionsState.PauseOnUncaughtExceptions;
+ }
+ this._agent.setPauseOnExceptions(state);
+ },
+
+ _profilingStateChanged: function()
+ {
+ if (WebInspector.experimentsSettings.disableAgentsWhenProfile.isEnabled()) {
+ if (this.target().profilingLock.isAcquired())
+ this.disableDebugger();
+ else
+ this.enableDebugger();
+ }
+ this._asyncStackTracesStateChanged();
},
_asyncStackTracesStateChanged: function()
{
const maxAsyncStackChainDepth = 4;
- var enabled = WebInspector.settings.enableAsyncStackTraces.get() && WebInspector.experimentsSettings.asyncStackTraces.isEnabled();
- DebuggerAgent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0);
+ var enabled = WebInspector.settings.enableAsyncStackTraces.get() && !this.target().profilingLock.isAcquired();
+ this._agent.setAsyncCallStackDepth(enabled ? maxAsyncStackChainDepth : 0);
},
_debuggerWasDisabled: function()
{
this._debuggerEnabled = false;
+ this._isPausing = false;
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerWasDisabled);
},
- /**
- * @param {!WebInspector.DebuggerModel.Location} rawLocation
- */
- continueToLocation: function(rawLocation)
- {
- DebuggerAgent.continueToLocation(rawLocation);
- },
-
- /**
- * @param {!WebInspector.DebuggerModel.Location} rawLocation
- */
- stepIntoSelection: function(rawLocation)
+ stepInto: function()
{
/**
- * @param {!WebInspector.DebuggerModel.Location} requestedLocation
- * @param {?string} error
* @this {WebInspector.DebuggerModel}
*/
- function callback(requestedLocation, error)
- {
- if (error)
- return;
- this._pendingStepIntoLocation = requestedLocation;
- };
- DebuggerAgent.continueToLocation(rawLocation, true, callback.bind(this, rawLocation));
- },
-
- stepInto: function()
- {
function callback()
{
- DebuggerAgent.stepInto();
+ this._agent.stepInto();
}
- DebuggerAgent.setOverlayMessage(undefined, callback.bind(this));
+ this._agent.setOverlayMessage(undefined, callback.bind(this));
},
stepOver: function()
{
+ /**
+ * @this {WebInspector.DebuggerModel}
+ */
function callback()
{
- DebuggerAgent.stepOver();
+ this._agent.stepOver();
}
- DebuggerAgent.setOverlayMessage(undefined, callback.bind(this));
+ this._agent.setOverlayMessage(undefined, callback.bind(this));
},
stepOut: function()
{
+ /**
+ * @this {WebInspector.DebuggerModel}
+ */
function callback()
{
- DebuggerAgent.stepOut();
+ this._agent.stepOut();
}
- DebuggerAgent.setOverlayMessage(undefined, callback.bind(this));
+ this._agent.setOverlayMessage(undefined, callback.bind(this));
},
resume: function()
{
+ /**
+ * @this {WebInspector.DebuggerModel}
+ */
function callback()
{
- DebuggerAgent.resume();
+ this._agent.resume();
}
- DebuggerAgent.setOverlayMessage(undefined, callback.bind(this));
+ this._agent.setOverlayMessage(undefined, callback.bind(this));
+ this._isPausing = false;
+ },
+
+ pause: function()
+ {
+ this._isPausing = true;
+ this.skipAllPauses(false);
+ this._agent.pause();
},
/**
@@ -265,7 +258,7 @@ WebInspector.DebuggerModel.prototype = {
*/
setBreakpointByScriptLocation: function(rawLocation, condition, callback)
{
- var script = this.scriptForId(rawLocation.scriptId);
+ var script = rawLocation.script();
if (script.sourceURL)
this.setBreakpointByURL(script.sourceURL, rawLocation.lineNumber, rawLocation.columnNumber, condition, callback);
else
@@ -283,7 +276,7 @@ WebInspector.DebuggerModel.prototype = {
{
// Adjust column if needed.
var minColumnNumber = 0;
- var scripts = this._scriptsBySourceURL[url] || [];
+ var scripts = this._scriptsBySourceURL.get(url) || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (lineNumber === script.lineOffset)
@@ -291,8 +284,8 @@ WebInspector.DebuggerModel.prototype = {
}
columnNumber = Math.max(columnNumber, minColumnNumber);
+ var target = this.target();
/**
- * @this {WebInspector.DebuggerModel}
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!Array.<!DebuggerAgent.Location>} locations
@@ -300,11 +293,11 @@ WebInspector.DebuggerModel.prototype = {
function didSetBreakpoint(error, breakpointId, locations)
{
if (callback) {
- var rawLocations = /** @type {!Array.<!WebInspector.DebuggerModel.Location>} */ (locations);
+ var rawLocations = locations ? locations.map(WebInspector.DebuggerModel.Location.fromPayload.bind(WebInspector.DebuggerModel.Location, target)) : [];
callback(error ? null : breakpointId, rawLocations);
}
}
- DebuggerAgent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, undefined, didSetBreakpoint.bind(this));
+ this._agent.setBreakpointByUrl(lineNumber, url, undefined, columnNumber, condition, undefined, didSetBreakpoint);
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},
@@ -315,8 +308,9 @@ WebInspector.DebuggerModel.prototype = {
*/
setBreakpointBySourceId: function(rawLocation, condition, callback)
{
+ var target = this.target();
+
/**
- * @this {WebInspector.DebuggerModel}
* @param {?Protocol.Error} error
* @param {!DebuggerAgent.BreakpointId} breakpointId
* @param {!DebuggerAgent.Location} actualLocation
@@ -324,21 +318,32 @@ WebInspector.DebuggerModel.prototype = {
function didSetBreakpoint(error, breakpointId, actualLocation)
{
if (callback) {
- var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (actualLocation);
- callback(error ? null : breakpointId, [rawLocation]);
+ var location = WebInspector.DebuggerModel.Location.fromPayload(target, actualLocation);
+ callback(error ? null : breakpointId, [location]);
}
}
- DebuggerAgent.setBreakpoint(rawLocation, condition, didSetBreakpoint.bind(this));
+ this._agent.setBreakpoint(rawLocation.payload(), condition, didSetBreakpoint);
WebInspector.userMetrics.ScriptsBreakpointSet.record();
},
/**
* @param {!DebuggerAgent.BreakpointId} breakpointId
- * @param {function(?Protocol.Error)=} callback
+ * @param {function()=} callback
*/
removeBreakpoint: function(breakpointId, callback)
{
- DebuggerAgent.removeBreakpoint(breakpointId, callback);
+ this._agent.removeBreakpoint(breakpointId, innerCallback);
+
+ /**
+ * @param {?Protocol.Error} error
+ */
+ function innerCallback(error)
+ {
+ if (error)
+ console.error("Failed to remove breakpoint: " + error);
+ if (callback)
+ callback();
+ }
},
/**
@@ -347,7 +352,7 @@ WebInspector.DebuggerModel.prototype = {
*/
_breakpointResolved: function(breakpointId, location)
{
- this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, {breakpointId: breakpointId, location: location});
+ this._breakpointResolvedEventTarget.dispatchEventToListeners(breakpointId, WebInspector.DebuggerModel.Location.fromPayload(this.target(), location));
},
_globalObjectCleared: function()
@@ -360,7 +365,7 @@ WebInspector.DebuggerModel.prototype = {
_reset: function()
{
this._scripts = {};
- this._scriptsBySourceURL = {};
+ this._scriptsBySourceURL.clear();
},
/**
@@ -387,7 +392,7 @@ WebInspector.DebuggerModel.prototype = {
{
if (!sourceURL)
return [];
- return this._scriptsBySourceURL[sourceURL] || [];
+ return this._scriptsBySourceURL.get(sourceURL) || [];
},
/**
@@ -440,6 +445,7 @@ WebInspector.DebuggerModel.prototype = {
*/
_setDebuggerPausedDetails: function(debuggerPausedDetails)
{
+ this._isPausing = false;
if (this._debuggerPausedDetails)
this._debuggerPausedDetails.dispose();
this._debuggerPausedDetails = debuggerPausedDetails;
@@ -447,10 +453,10 @@ WebInspector.DebuggerModel.prototype = {
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
if (debuggerPausedDetails) {
this.setSelectedCallFrame(debuggerPausedDetails.callFrames[0]);
- DebuggerAgent.setOverlayMessage(WebInspector.UIString("Paused in debugger"));
+ this._agent.setOverlayMessage(WebInspector.UIString("Paused in debugger"));
} else {
this.setSelectedCallFrame(null);
- DebuggerAgent.setOverlayMessage();
+ this._agent.setOverlayMessage();
}
},
@@ -463,20 +469,7 @@ WebInspector.DebuggerModel.prototype = {
*/
_pausedScript: function(callFrames, reason, auxData, breakpointIds, asyncStackTrace)
{
- if (this._pendingStepIntoLocation) {
- var requestedLocation = this._pendingStepIntoLocation;
- delete this._pendingStepIntoLocation;
-
- if (callFrames.length > 0) {
- var topLocation = callFrames[0].location;
- if (topLocation.lineNumber == requestedLocation.lineNumber && topLocation.columnNumber == requestedLocation.columnNumber && topLocation.scriptId == requestedLocation.scriptId) {
- this.stepInto();
- return;
- }
- }
- }
-
- this._setDebuggerPausedDetails(new WebInspector.DebuggerPausedDetails(callFrames, reason, auxData, breakpointIds, asyncStackTrace));
+ this._setDebuggerPausedDetails(new WebInspector.DebuggerPausedDetails(this.target(), callFrames, reason, auxData, breakpointIds, asyncStackTrace));
},
_resumedScript: function()
@@ -498,7 +491,7 @@ WebInspector.DebuggerModel.prototype = {
*/
_parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
{
- var script = new WebInspector.Script(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL);
+ var script = new WebInspector.Script(this.target(), scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL);
this._registerScript(script);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script);
},
@@ -512,10 +505,10 @@ WebInspector.DebuggerModel.prototype = {
if (script.isAnonymousScript())
return;
- var scripts = this._scriptsBySourceURL[script.sourceURL];
+ var scripts = this._scriptsBySourceURL.get(script.sourceURL);
if (!scripts) {
scripts = [];
- this._scriptsBySourceURL[script.sourceURL] = scripts;
+ this._scriptsBySourceURL.put(script.sourceURL, scripts);
}
scripts.push(script);
},
@@ -530,7 +523,7 @@ WebInspector.DebuggerModel.prototype = {
{
if (script.sourceURL)
return this.createRawLocationByURL(script.sourceURL, lineNumber, columnNumber)
- return new WebInspector.DebuggerModel.Location(script.scriptId, lineNumber, columnNumber);
+ return new WebInspector.DebuggerModel.Location(this.target(), script.scriptId, lineNumber, columnNumber);
},
/**
@@ -542,7 +535,7 @@ WebInspector.DebuggerModel.prototype = {
createRawLocationByURL: function(sourceURL, lineNumber, columnNumber)
{
var closestScript = null;
- var scripts = this._scriptsBySourceURL[sourceURL] || [];
+ var scripts = this._scriptsBySourceURL.get(sourceURL) || [];
for (var i = 0, l = scripts.length; i < l; ++i) {
var script = scripts[i];
if (!closestScript)
@@ -554,7 +547,7 @@ WebInspector.DebuggerModel.prototype = {
closestScript = script;
break;
}
- return closestScript ? new WebInspector.DebuggerModel.Location(closestScript.scriptId, lineNumber, columnNumber) : null;
+ return closestScript ? new WebInspector.DebuggerModel.Location(this.target(), closestScript.scriptId, lineNumber, columnNumber) : null;
},
/**
@@ -566,6 +559,14 @@ WebInspector.DebuggerModel.prototype = {
},
/**
+ * @return {boolean}
+ */
+ isPausing: function()
+ {
+ return this._isPausing;
+ },
+
+ /**
* @param {?WebInspector.DebuggerModel.CallFrame} callFrame
*/
setSelectedCallFrame: function(callFrame)
@@ -586,15 +587,6 @@ WebInspector.DebuggerModel.prototype = {
},
/**
- * @return {!DebuggerAgent.CallFrameId|undefined}
- */
- _selectedCallFrameId: function()
- {
- var callFrame = this.selectedCallFrame();
- return callFrame ? callFrame.id : undefined;
- },
-
- /**
* @param {string} code
* @param {string} objectGroup
* @param {boolean} includeCommandLineAPI
@@ -617,7 +609,7 @@ WebInspector.DebuggerModel.prototype = {
else if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
- callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);
+ callback(this.target().runtimeModel.createRemoteObject(result), !!wasThrown);
if (objectGroup === "console")
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame);
@@ -649,7 +641,7 @@ WebInspector.DebuggerModel.prototype = {
for (var i = 0; i < selectedCallFrame.scopeChain.length; ++i) {
var scope = selectedCallFrame.scopeChain[i];
- var object = WebInspector.RemoteObject.fromPayload(scope.object);
+ var object = this.target().runtimeModel.createRemoteObject(scope.object);
pendingRequests++;
object.getAllProperties(false, propertiesCollected);
}
@@ -663,7 +655,7 @@ WebInspector.DebuggerModel.prototype = {
if (this._breakpointsActive === active)
return;
this._breakpointsActive = active;
- DebuggerAgent.setBreakpointsActive(active);
+ this._agent.setBreakpointsActive(active);
this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, active);
},
@@ -700,7 +692,6 @@ WebInspector.DebuggerModel.prototype = {
/**
* Handles notification from JavaScript VM about updated stack (liveedit or frame restart action).
- * @this {WebInspector.DebuggerModel}
* @param {!Array.<!DebuggerAgent.CallFrame>=} newCallFrames
* @param {!Object=} details
* @param {!DebuggerAgent.StackTrace=} asyncStackTrace
@@ -714,16 +705,59 @@ WebInspector.DebuggerModel.prototype = {
this._pausedScript(newCallFrames, this._debuggerPausedDetails.reason, this._debuggerPausedDetails.auxData, this._debuggerPausedDetails.breakpointIds, asyncStackTrace);
},
- __proto__: WebInspector.Object.prototype
-}
+ _applySkipStackFrameSettings: function()
+ {
+ if (!WebInspector.experimentsSettings.frameworksDebuggingSupport.isEnabled())
+ return;
+ var settings = WebInspector.settings;
+ var patternParameter = settings.skipStackFramesSwitch.get() ? settings.skipStackFramesPattern.get() : undefined;
+ this._agent.skipStackFrames(patternParameter);
+ },
-WebInspector.DebuggerModel.applySkipStackFrameSettings = function()
-{
- if (!WebInspector.experimentsSettings.frameworksDebuggingSupport.isEnabled())
- return;
- var settings = WebInspector.settings;
- var patternParameter = settings.skipStackFramesSwitch.get() ? settings.skipStackFramesPattern.get() : undefined;
- DebuggerAgent.skipStackFrames(patternParameter);
+ /**
+ * @param {!WebInspector.RemoteObject} remoteObject
+ * @param {function(?DebuggerAgent.FunctionDetails)} callback
+ */
+ functionDetails: function(remoteObject, callback)
+ {
+ this._agent.getFunctionDetails(remoteObject.objectId, didGetDetails);
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!DebuggerAgent.FunctionDetails} response
+ */
+ function didGetDetails(error, response)
+ {
+ if (error) {
+ console.error(error);
+ callback(null);
+ return;
+ }
+ callback(response);
+ }
+ },
+
+ /**
+ * @param {!DebuggerAgent.BreakpointId} breakpointId
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ addBreakpointListener: function(breakpointId, listener, thisObject)
+ {
+ this._breakpointResolvedEventTarget.addEventListener(breakpointId, listener, thisObject)
+ },
+
+ /**
+ * @param {!DebuggerAgent.BreakpointId} breakpointId
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ removeBreakpointListener: function(breakpointId, listener, thisObject)
+ {
+ this._breakpointResolvedEventTarget.removeEventListener(breakpointId, listener, thisObject);
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
}
WebInspector.DebuggerEventTypes = {
@@ -810,37 +844,122 @@ WebInspector.DebuggerDispatcher.prototype = {
/**
* @constructor
+ * @implements {WebInspector.RawLocation}
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
+ * @param {string} scriptId
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ */
+WebInspector.DebuggerModel.Location = function(target, scriptId, lineNumber, columnNumber)
+{
+ WebInspector.TargetAware.call(this, target);
+ this._debuggerModel = target.debuggerModel;
+ this.scriptId = scriptId;
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+}
+
+/**
+ * @param {!WebInspector.Target} target
+ * @param {!DebuggerAgent.Location} payload
+ * @return {!WebInspector.DebuggerModel.Location}
+ */
+WebInspector.DebuggerModel.Location.fromPayload = function(target, payload)
+{
+ return new WebInspector.DebuggerModel.Location(target, payload.scriptId, payload.lineNumber, payload.columnNumber);
+}
+
+WebInspector.DebuggerModel.Location.prototype = {
+ /**
+ * @return {!DebuggerAgent.Location}
+ */
+ payload: function()
+ {
+ return { scriptId: this.scriptId, lineNumber: this.lineNumber, columnNumber: this.columnNumber };
+ },
+
+ /**
+ * @return {!WebInspector.Script}
+ */
+ script: function()
+ {
+ return this._debuggerModel.scriptForId(this.scriptId);
+ },
+
+ /**
+ * @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegate
+ * @return {!WebInspector.Script.Location}
+ */
+ createLiveLocation: function(updateDelegate)
+ {
+ return this._debuggerModel.createLiveLocation(this, updateDelegate);
+ },
+
+ /**
+ * @return {?WebInspector.UILocation}
+ */
+ toUILocation: function()
+ {
+ return this._debuggerModel.rawLocationToUILocation(this);
+ },
+
+ continueToLocation: function()
+ {
+ this._debuggerModel._agent.continueToLocation(this.payload());
+ },
+
+ /**
+ * @return {string}
+ */
+ id: function()
+ {
+ return this.target().id() + ":" + this.scriptId + ":" + this.lineNumber + ":" + this.columnNumber
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.Script} script
* @param {!DebuggerAgent.CallFrame} payload
* @param {boolean=} isAsync
*/
-WebInspector.DebuggerModel.CallFrame = function(script, payload, isAsync)
+WebInspector.DebuggerModel.CallFrame = function(target, script, payload, isAsync)
{
+ WebInspector.TargetAware.call(this, target);
+ this._debuggerAgent = target.debuggerModel._agent;
this._script = script;
this._payload = payload;
/** @type {!Array.<!WebInspector.Script.Location>} */
- this._locations = [];
+ this._liveLocations = [];
this._isAsync = isAsync;
+ this._location = WebInspector.DebuggerModel.Location.fromPayload(target, payload.location);
}
/**
+ * @param {!WebInspector.Target} target
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @param {boolean=} isAsync
* @return {!Array.<!WebInspector.DebuggerModel.CallFrame>}
*/
-WebInspector.DebuggerModel.CallFrame.fromPayloadArray = function(callFrames, isAsync)
+WebInspector.DebuggerModel.CallFrame.fromPayloadArray = function(target, callFrames, isAsync)
{
var result = [];
for (var i = 0; i < callFrames.length; ++i) {
var callFrame = callFrames[i];
- var script = WebInspector.debuggerModel.scriptForId(callFrame.location.scriptId);
+ var script = target.debuggerModel.scriptForId(callFrame.location.scriptId);
if (script)
- result.push(new WebInspector.DebuggerModel.CallFrame(script, callFrame, isAsync));
+ result.push(new WebInspector.DebuggerModel.CallFrame(target, script, callFrame, isAsync));
}
return result;
}
WebInspector.DebuggerModel.CallFrame.prototype = {
+
/**
* @return {!WebInspector.Script}
*/
@@ -874,19 +993,19 @@ WebInspector.DebuggerModel.CallFrame.prototype = {
},
/**
- * @return {!RuntimeAgent.RemoteObject}
+ * @return {?WebInspector.RemoteObject}
*/
- get this()
+ thisObject: function()
{
- return this._payload.this;
+ return this._payload.this ? this.target().runtimeModel.createRemoteObject(this._payload.this) : null;
},
/**
- * @return {!RuntimeAgent.RemoteObject|undefined}
+ * @return {?WebInspector.RemoteObject}
*/
- get returnValue()
+ returnValue: function()
{
- return this._payload.returnValue;
+ return this._payload.returnValue ? this.target().runtimeModel.createRemoteObject(this._payload.returnValue) : null
},
/**
@@ -900,10 +1019,9 @@ WebInspector.DebuggerModel.CallFrame.prototype = {
/**
* @return {!WebInspector.DebuggerModel.Location}
*/
- get location()
+ location: function()
{
- var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (this._payload.location);
- return rawLocation;
+ return this._location;
},
/**
@@ -926,7 +1044,6 @@ WebInspector.DebuggerModel.CallFrame.prototype = {
evaluate: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{
/**
- * @this {WebInspector.DebuggerModel.CallFrame}
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
@@ -940,7 +1057,7 @@ WebInspector.DebuggerModel.CallFrame.prototype = {
}
callback(result, wasThrown);
}
- DebuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluateOnCallFrame.bind(this));
+ this._debuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluateOnCallFrame);
},
/**
@@ -949,62 +1066,41 @@ WebInspector.DebuggerModel.CallFrame.prototype = {
restart: function(callback)
{
/**
- * @this {WebInspector.DebuggerModel.CallFrame}
* @param {?Protocol.Error} error
* @param {!Array.<!DebuggerAgent.CallFrame>=} callFrames
* @param {!Object=} details
* @param {!DebuggerAgent.StackTrace=} asyncStackTrace
+ * @this {WebInspector.DebuggerModel.CallFrame}
*/
function protocolCallback(error, callFrames, details, asyncStackTrace)
{
if (!error)
- WebInspector.debuggerModel.callStackModified(callFrames, details, asyncStackTrace);
+ this.target().debuggerModel.callStackModified(callFrames, details, asyncStackTrace);
if (callback)
callback(error);
}
- DebuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback);
- },
-
- /**
- * @param {function(!Array.<!DebuggerAgent.Location>)} callback
- */
- getStepIntoLocations: function(callback)
- {
- if (this._stepInLocations) {
- callback(this._stepInLocations.slice(0));
- return;
- }
- /**
- * @param {?string} error
- * @param {!Array.<!DebuggerAgent.Location>=} stepInPositions
- * @this {WebInspector.DebuggerModel.CallFrame}
- */
- function getStepInPositionsCallback(error, stepInPositions)
- {
- if (error)
- return;
- this._stepInLocations = stepInPositions;
- callback(this._stepInLocations.slice(0));
- }
- DebuggerAgent.getStepInPositions(this.id, getStepInPositionsCallback.bind(this));
+ this._debuggerAgent.restartFrame(this._payload.callFrameId, protocolCallback.bind(this));
},
/**
* @param {function(!WebInspector.UILocation):(boolean|undefined)} updateDelegate
+ * @return {!WebInspector.LiveLocation}
*/
createLiveLocation: function(updateDelegate)
{
- var location = this._script.createLiveLocation(this.location, updateDelegate);
- this._locations.push(location);
- return location;
+ var liveLocation = this._location.createLiveLocation(updateDelegate);
+ this._liveLocations.push(liveLocation);
+ return liveLocation;
},
dispose: function()
{
- for (var i = 0; i < this._locations.length; ++i)
- this._locations[i].dispose();
- this._locations = [];
- }
+ for (var i = 0; i < this._liveLocations.length; ++i)
+ this._liveLocations[i].dispose();
+ this._liveLocations = [];
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
/**
@@ -1021,18 +1117,19 @@ WebInspector.DebuggerModel.StackTrace = function(callFrames, asyncStackTrace, de
}
/**
+ * @param {!WebInspector.Target} target
* @param {!DebuggerAgent.StackTrace=} payload
* @param {boolean=} isAsync
* @return {?WebInspector.DebuggerModel.StackTrace}
*/
-WebInspector.DebuggerModel.StackTrace.fromPayload = function(payload, isAsync)
+WebInspector.DebuggerModel.StackTrace.fromPayload = function(target, payload, isAsync)
{
if (!payload)
return null;
- var callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(payload.callFrames, isAsync);
+ var callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(target, payload.callFrames, isAsync);
if (!callFrames.length)
return null;
- var asyncStackTrace = WebInspector.DebuggerModel.StackTrace.fromPayload(payload.asyncStackTrace, true);
+ var asyncStackTrace = WebInspector.DebuggerModel.StackTrace.fromPayload(target, payload.asyncStackTrace, true);
return new WebInspector.DebuggerModel.StackTrace(callFrames, asyncStackTrace, payload.description);
}
@@ -1048,29 +1145,44 @@ WebInspector.DebuggerModel.StackTrace.prototype = {
/**
* @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
* @param {!Array.<!DebuggerAgent.CallFrame>} callFrames
* @param {string} reason
* @param {!Object|undefined} auxData
* @param {!Array.<string>} breakpointIds
* @param {!DebuggerAgent.StackTrace=} asyncStackTrace
*/
-WebInspector.DebuggerPausedDetails = function(callFrames, reason, auxData, breakpointIds, asyncStackTrace)
+WebInspector.DebuggerPausedDetails = function(target, callFrames, reason, auxData, breakpointIds, asyncStackTrace)
{
- this.callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(callFrames);
+ WebInspector.TargetAware.call(this, target);
+ this.callFrames = WebInspector.DebuggerModel.CallFrame.fromPayloadArray(target, callFrames);
this.reason = reason;
this.auxData = auxData;
this.breakpointIds = breakpointIds;
- this.asyncStackTrace = WebInspector.DebuggerModel.StackTrace.fromPayload(asyncStackTrace, true);
+ this.asyncStackTrace = WebInspector.DebuggerModel.StackTrace.fromPayload(target, asyncStackTrace, true);
}
WebInspector.DebuggerPausedDetails.prototype = {
+ /**
+ * @return {?WebInspector.RemoteObject}
+ */
+ exception: function()
+ {
+ if (this.reason !== WebInspector.DebuggerModel.BreakReason.Exception)
+ return null;
+ return this.target().runtimeModel.createRemoteObject(/** @type {!RuntimeAgent.RemoteObject} */(this.auxData));
+ },
+
dispose: function()
{
for (var i = 0; i < this.callFrames.length; ++i)
this.callFrames[i].dispose();
if (this.asyncStackTrace)
this.asyncStackTrace.dispose();
- }
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DebuggerScriptMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerScriptMapping.js
index 112def27726..b6c1a37d682 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DebuggerScriptMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerScriptMapping.js
@@ -30,18 +30,18 @@
/**
* @constructor
+ * @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
- * @param {!WebInspector.SimpleWorkspaceProvider} networkWorkspaceProvider
+ * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
*/
-WebInspector.DebuggerScriptMapping = function(workspace, networkWorkspaceProvider)
+WebInspector.DebuggerScriptMapping = function(debuggerModel, workspace, networkWorkspaceBinding)
{
- this._defaultMapping = new WebInspector.DefaultScriptMapping(workspace);
- this._resourceMapping = new WebInspector.ResourceScriptMapping(workspace);
- this._compilerMapping = new WebInspector.CompilerScriptMapping(workspace, networkWorkspaceProvider);
- this._snippetMapping = WebInspector.scriptSnippetModel.scriptMapping;
+ this._defaultMapping = new WebInspector.DefaultScriptMapping(debuggerModel, workspace);
+ this._resourceMapping = new WebInspector.ResourceScriptMapping(debuggerModel, workspace);
+ this._compilerMapping = new WebInspector.CompilerScriptMapping(debuggerModel, workspace, networkWorkspaceBinding);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
+ debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
}
WebInspector.DebuggerScriptMapping.prototype = {
@@ -54,7 +54,7 @@ WebInspector.DebuggerScriptMapping.prototype = {
this._defaultMapping.addScript(script);
if (script.isSnippet()) {
- this._snippetMapping.addScript(script);
+ WebInspector.scriptSnippetModel.addScript(script);
return;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DefaultScriptMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DefaultScriptMapping.js
index 28940266405..febc08ced7a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DefaultScriptMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/DefaultScriptMapping.js
@@ -31,14 +31,16 @@
/**
* @constructor
* @implements {WebInspector.ScriptSourceMapping}
+ * @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
*/
-WebInspector.DefaultScriptMapping = function(workspace)
+WebInspector.DefaultScriptMapping = function(debuggerModel, workspace)
{
- this._projectDelegate = new WebInspector.DebuggerProjectDelegate();
+ this._debuggerModel = debuggerModel;
this._workspace = workspace;
- this._workspace.addProject(this._projectDelegate);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ this._projectId = "debugger:" + debuggerModel.target().id();
+ this._projectDelegate = new WebInspector.DebuggerProjectDelegate(this._workspace, this._projectId, WebInspector.projectTypes.Debugger);
+ debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._debuggerReset();
}
@@ -50,11 +52,11 @@ WebInspector.DefaultScriptMapping.prototype = {
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
- var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
+ var script = debuggerModelLocation.script();
var uiSourceCode = this._uiSourceCodeForScriptId[script.scriptId];
var lineNumber = debuggerModelLocation.lineNumber;
var columnNumber = debuggerModelLocation.columnNumber || 0;
- return new WebInspector.UILocation(uiSourceCode, lineNumber, columnNumber);
+ return uiSourceCode.uiLocation(lineNumber, columnNumber);
},
/**
@@ -66,8 +68,8 @@ WebInspector.DefaultScriptMapping.prototype = {
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
var scriptId = this._scriptIdForUISourceCode.get(uiSourceCode);
- var script = WebInspector.debuggerModel.scriptForId(scriptId);
- return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
+ var script = this._debuggerModel.scriptForId(scriptId);
+ return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
/**
@@ -76,19 +78,27 @@ WebInspector.DefaultScriptMapping.prototype = {
addScript: function(script)
{
var path = this._projectDelegate.addScript(script);
- var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
+ var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path);
if (!uiSourceCode) {
console.assert(uiSourceCode);
return;
}
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
this._scriptIdForUISourceCode.put(uiSourceCode, script.scriptId);
- uiSourceCode.setSourceMapping(this);
+ uiSourceCode.setSourceMappingForTarget(this._debuggerModel.target(), this);
script.pushSourceMapping(this);
script.addEventListener(WebInspector.Script.Events.ScriptEdited, this._scriptEdited.bind(this, script.scriptId));
},
/**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return true;
+ },
+
+ /**
* @param {string} scriptId
* @param {!WebInspector.Event} event
*/
@@ -109,28 +119,23 @@ WebInspector.DefaultScriptMapping.prototype = {
/**
* @constructor
+ * @param {!WebInspector.Workspace} workspace
+ * @param {string} id
+ * @param {!WebInspector.projectTypes} type
* @extends {WebInspector.ContentProviderBasedProjectDelegate}
*/
-WebInspector.DebuggerProjectDelegate = function()
+WebInspector.DebuggerProjectDelegate = function(workspace, id, type)
{
- WebInspector.ContentProviderBasedProjectDelegate.call(this, WebInspector.projectTypes.Debugger);
+ WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, type);
}
WebInspector.DebuggerProjectDelegate.prototype = {
/**
* @return {string}
*/
- id: function()
- {
- return "debugger:";
- },
-
- /**
- * @return {string}
- */
displayName: function()
{
- return "debugger";
+ return "";
},
/**
@@ -143,8 +148,8 @@ WebInspector.DebuggerProjectDelegate.prototype = {
var splitURL = WebInspector.ParsedURL.splitURL(script.sourceURL);
var name = splitURL[splitURL.length - 1];
name = "VM" + script.scriptId + (name ? " " + name : "");
- return this.addContentProvider("", name, script.sourceURL, contentProvider, false, script.isContentScript);
+ return this.addContentProvider("", name, script.sourceURL, contentProvider);
},
-
+
__proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileManager.js
index 7dcc17e0eb2..08734ec8837 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileManager.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileManager.js
@@ -124,7 +124,7 @@ WebInspector.FileManager.prototype = {
*/
close: function(url)
{
- InspectorFrontendHost.close(url);
+ // Currently a no-op.
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemMapping.js
index 6ef139ed0b1..93743d77ca1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemMapping.js
@@ -72,7 +72,7 @@ WebInspector.FileSystemMapping = function()
else
defaultExcludedFolders = defaultExcludedFolders.concat(defaultLinuxExcludedFolders);
var defaultExcludedFoldersPattern = defaultExcludedFolders.join("|");
- WebInspector.settings.workspaceFolderExcludePattern = WebInspector.settings.createSetting("workspaceFolderExcludePattern", defaultExcludedFoldersPattern);
+ WebInspector.settings.workspaceFolderExcludePattern = WebInspector.settings.createRegExpSetting("workspaceFolderExcludePattern", defaultExcludedFoldersPattern, WebInspector.isWin() ? "i" : "");
/** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.Entry>>} */
this._fileSystemMappings = {};
/** @type {!Object.<string, !Array.<!WebInspector.FileSystemMapping.ExcludedFolderEntry>>} */
@@ -121,13 +121,6 @@ WebInspector.FileSystemMapping.prototype = {
}
}
- var workspaceFolderExcludePattern = WebInspector.settings.workspaceFolderExcludePattern.get()
- try {
- var flags = WebInspector.isWin() ? "i" : "";
- this._workspaceFolderExcludeRegex = workspaceFolderExcludePattern ? new RegExp(workspaceFolderExcludePattern, flags) : null;
- } catch (e) {
- }
-
this._rebuildIndexes();
},
@@ -329,7 +322,8 @@ WebInspector.FileSystemMapping.prototype = {
if (entry.path === folderPath)
return true;
}
- return this._workspaceFolderExcludeRegex && this._workspaceFolderExcludeRegex.test(folderPath);
+ var regex = WebInspector.settings.workspaceFolderExcludePattern.asRegExp();
+ return regex && regex.test(folderPath);
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemModel.js
index 161d6d4cdf1..15d4660f1b1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemModel.js
@@ -30,18 +30,19 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.FileSystemModel = function()
+WebInspector.FileSystemModel = function(target)
{
- WebInspector.Object.call(this);
+ WebInspector.TargetAwareObject.call(this, target);
this._fileSystemsForOrigin = {};
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
-
- FileSystemAgent.enable();
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
+ this._agent = target.fileSystemAgent();
+ this._agent.enable();
this._reset();
}
@@ -51,7 +52,7 @@ WebInspector.FileSystemModel.prototype = {
{
for (var securityOrigin in this._fileSystemsForOrigin)
this._removeOrigin(securityOrigin);
- var securityOrigins = WebInspector.resourceTreeModel.securityOrigins();
+ var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
},
@@ -117,11 +118,11 @@ WebInspector.FileSystemModel.prototype = {
callback(FileError.SECURITY_ERR);
return;
}
-
+
callback(errorCode, backendRootEntry);
}
- FileSystemAgent.requestFileSystemRoot(origin, type, innerCallback.bind(this));
+ this._agent.requestFileSystemRoot(origin, type, innerCallback);
},
/**
@@ -187,7 +188,7 @@ WebInspector.FileSystemModel.prototype = {
callback(FileError.SECURITY_ERR);
return;
}
-
+
if (errorCode !== 0) {
callback(errorCode);
return;
@@ -196,7 +197,7 @@ WebInspector.FileSystemModel.prototype = {
callback(errorCode, backendEntries);
}
- FileSystemAgent.requestDirectoryContent(url, innerCallback.bind(this));
+ this._agent.requestDirectoryContent(url, innerCallback);
},
/**
@@ -240,11 +241,11 @@ WebInspector.FileSystemModel.prototype = {
callback(FileError.SECURITY_ERR);
return;
}
-
+
callback(errorCode, metadata);
}
- FileSystemAgent.requestMetadata(entry.url, innerCallback.bind(this));
+ this._agent.requestMetadata(entry.url, innerCallback);
},
/**
@@ -283,12 +284,12 @@ WebInspector.FileSystemModel.prototype = {
callback(FileError.SECURITY_ERR);
return;
}
-
+
if (callback)
callback(errorCode, content, charset);
}
- FileSystemAgent.requestFileContent(url, readAsText, start, end, charset, innerCallback.bind(this));
+ this._agent.requestFileContent(url, readAsText, start, end, charset, innerCallback);
},
/**
* @param {!WebInspector.FileSystemModel.Entry} entry
@@ -327,12 +328,12 @@ WebInspector.FileSystemModel.prototype = {
callback(FileError.SECURITY_ERR);
return;
}
-
+
if (callback)
callback(errorCode);
}
- FileSystemAgent.deleteEntry(url, innerCallback.bind(this));
+ this._agent.deleteEntry(url, innerCallback);
},
/**
@@ -351,7 +352,7 @@ WebInspector.FileSystemModel.prototype = {
}
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemProjectDelegate.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemWorkspaceBinding.js
index db244f44f42..2808a8e4c28 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileSystemProjectDelegate.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileSystemWorkspaceBinding.js
@@ -30,48 +30,179 @@
/**
* @constructor
- * @implements {WebInspector.ProjectDelegate}
- * @extends {WebInspector.Object}
- * @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem
+ * @param {!WebInspector.IsolatedFileSystemManager} isolatedFileSystemManager
* @param {!WebInspector.Workspace} workspace
*/
-WebInspector.FileSystemProjectDelegate = function(isolatedFileSystem, workspace)
+WebInspector.FileSystemWorkspaceBinding = function(isolatedFileSystemManager, workspace)
{
- this._fileSystem = isolatedFileSystem;
- this._normalizedFileSystemPath = this._fileSystem.path();
- if (WebInspector.isWin())
- this._normalizedFileSystemPath = this._normalizedFileSystemPath.replace(/\\/g, "/");
- this._fileSystemURL = "file://" + this._normalizedFileSystemPath + "/";
+ this._isolatedFileSystemManager = isolatedFileSystemManager;
this._workspace = workspace;
+ this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
+ this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
+ /** @type {!StringMap.<!WebInspector.FileSystemWorkspaceBinding.FileSystem>} */
+ this._boundFileSystems = new StringMap();
+
/** @type {!Object.<number, function(!Array.<string>)>} */
- this._searchCallbacks = {};
- /** @type {!Object.<number, function()>} */
- this._indexingCallbacks = {};
+ this._callbacks = {};
/** @type {!Object.<number, !WebInspector.Progress>} */
- this._indexingProgresses = {};
+ this._progresses = {};
}
-WebInspector.FileSystemProjectDelegate._scriptExtensions = ["js", "java", "coffee", "ts", "dart"].keySet();
-WebInspector.FileSystemProjectDelegate._styleSheetExtensions = ["css", "scss", "sass", "less"].keySet();
-WebInspector.FileSystemProjectDelegate._documentExtensions = ["htm", "html", "asp", "aspx", "phtml", "jsp"].keySet();
+WebInspector.FileSystemWorkspaceBinding._scriptExtensions = ["js", "java", "coffee", "ts", "dart"].keySet();
+WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions = ["css", "scss", "sass", "less"].keySet();
+WebInspector.FileSystemWorkspaceBinding._documentExtensions = ["htm", "html", "asp", "aspx", "phtml", "jsp"].keySet();
+
+WebInspector.FileSystemWorkspaceBinding._lastRequestId = 0;
-WebInspector.FileSystemProjectDelegate.projectId = function(fileSystemPath)
+/**
+ * @param {string} fileSystemPath
+ * @return {string}
+ */
+WebInspector.FileSystemWorkspaceBinding.projectId = function(fileSystemPath)
{
return "filesystem:" + fileSystemPath;
}
-WebInspector.FileSystemProjectDelegate._lastRequestId = 0;
+WebInspector.FileSystemWorkspaceBinding.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _fileSystemAdded: function(event)
+ {
+ var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
+ var boundFileSystem = new WebInspector.FileSystemWorkspaceBinding.FileSystem(this, fileSystem, this._workspace);
+ this._boundFileSystems.put(fileSystem.normalizedPath(), boundFileSystem);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _fileSystemRemoved: function(event)
+ {
+ var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
+ var boundFileSystem = this._boundFileSystems.get(fileSystem.normalizedPath());
+ boundFileSystem.dispose();
+ this._boundFileSystems.remove(fileSystem.normalizedPath());
+ },
-WebInspector.FileSystemProjectDelegate.prototype = {
/**
+ * @param {string} projectId
* @return {string}
*/
- id: function()
+ fileSystemPath: function(projectId)
+ {
+ var fileSystemPath = projectId.substr("filesystem:".length);
+ var normalizedPath = WebInspector.IsolatedFileSystem.normalizePath(fileSystemPath);
+ var boundFileSystem = this._boundFileSystems.get(normalizedPath);
+ return projectId.substr("filesystem:".length);
+ },
+
+ /**
+ * @return {number}
+ */
+ _nextId: function()
+ {
+ return ++WebInspector.FileSystemWorkspaceBinding._lastRequestId;
+ },
+
+ /**
+ * @param {function(!Array.<string>)} callback
+ * @return {number}
+ */
+ registerCallback: function(callback)
+ {
+ var requestId = this._nextId();
+ this._callbacks[requestId] = callback;
+ return requestId;
+ },
+
+ /**
+ * @param {!WebInspector.Progress} progress
+ * @return {number}
+ */
+ registerProgress: function(progress)
+ {
+ var requestId = this._nextId();
+ this._progresses[requestId] = progress;
+ return requestId;
+ },
+
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {number} totalWork
+ */
+ indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork)
+ {
+ var progress = this._progresses[requestId];
+ if (!progress)
+ return;
+ progress.setTotalWork(totalWork);
+ },
+
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {number} worked
+ */
+ indexingWorked: function(requestId, fileSystemPath, worked)
+ {
+ var progress = this._progresses[requestId];
+ if (!progress)
+ return;
+ progress.worked(worked);
+ },
+
+ /**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ */
+ indexingDone: function(requestId, fileSystemPath)
{
- return WebInspector.FileSystemProjectDelegate.projectId(this._fileSystem.path());
+ var progress = this._progresses[requestId];
+ if (!progress)
+ return;
+ progress.done();
+ delete this._progresses[requestId];
},
/**
+ * @param {number} requestId
+ * @param {string} fileSystemPath
+ * @param {!Array.<string>} files
+ */
+ searchCompleted: function(requestId, fileSystemPath, files)
+ {
+ var callback = this._callbacks[requestId];
+ if (!callback)
+ return;
+ callback.call(null, files);
+ delete this._callbacks[requestId];
+ },
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ProjectDelegate}
+ * @param {!WebInspector.IsolatedFileSystem} isolatedFileSystem
+ * @param {!WebInspector.Workspace} workspace
+ * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
+ */
+WebInspector.FileSystemWorkspaceBinding.FileSystem = function(fileSystemWorkspaceBinding, isolatedFileSystem, workspace)
+{
+ this._fileSystemWorkspaceBinding = fileSystemWorkspaceBinding;
+ this._fileSystem = isolatedFileSystem;
+ this._fileSystemURL = "file://" + this._fileSystem.normalizedPath() + "/";
+ this._workspace = workspace;
+
+ this._projectId = WebInspector.FileSystemWorkspaceBinding.projectId(this._fileSystem.path());
+ console.assert(!this._workspace.project(this._projectId));
+ this._projectStore = this._workspace.addProject(this._projectId, this);
+ this.populate();
+}
+
+WebInspector.FileSystemWorkspaceBinding.FileSystem.prototype = {
+ /**
* @return {string}
*/
type: function()
@@ -92,7 +223,8 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
displayName: function()
{
- return this._normalizedFileSystemPath.substr(this._normalizedFileSystemPath.lastIndexOf("/") + 1);
+ var normalizedPath = this._fileSystem.normalizedPath();
+ return normalizedPath.substr(normalizedPath.lastIndexOf("/") + 1);
},
/**
@@ -164,7 +296,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
/**
* @param {boolean} success
* @param {string=} newName
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(success, newName)
{
@@ -195,7 +327,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
searchInFileContent: function(path, query, caseSensitive, isRegex, callback)
{
var filePath = this._filePathForPath(path);
- this._fileSystem.requestFileContent(filePath, contentCallback.bind(this));
+ this._fileSystem.requestFileContent(filePath, contentCallback);
/**
* @param {?string} content
@@ -210,38 +342,35 @@ WebInspector.FileSystemProjectDelegate.prototype = {
},
/**
- * @param {!Array.<string>} queries
- * @param {!Array.<string>} fileQueries
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
- findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback)
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback)
{
- var result = [];
- var queriesToRun = queries.slice();
+ var result = null;
+ var queriesToRun = searchConfig.queries().slice();
if (!queriesToRun.length)
queriesToRun.push("");
progress.setTotalWork(queriesToRun.length);
searchNextQuery.call(this);
/**
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function searchNextQuery()
{
if (!queriesToRun.length) {
- matchFileQueries.call(this, result);
+ matchFileQueries.call(null, result);
return;
}
var query = queriesToRun.shift();
- this._searchInPath(isRegex ? "" : query, progress, innerCallback.bind(this));
+ this._searchInPath(searchConfig.isRegex() ? "" : query, progress, innerCallback.bind(this));
}
/**
* @param {!Array.<string>} files
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(files)
{
@@ -259,23 +388,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
function matchFileQueries(files)
{
- var fileRegexes = [];
- for (var i = 0; i < fileQueries.length; ++i)
- fileRegexes.push(new RegExp(fileQueries[i], caseSensitive ? "" : "i"));
-
- /**
- * @param {!string} file
- */
- function filterOutNonMatchingFiles(file)
- {
- for (var i = 0; i < fileRegexes.length; ++i) {
- if (!file.match(fileRegexes[i]))
- return false;
- }
- return true;
- }
-
- files = files.filter(filterOutNonMatchingFiles);
+ files = files.filter(searchConfig.filePathMatchesFileQuery.bind(searchConfig));
progress.done();
callback(files);
}
@@ -288,19 +401,18 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
_searchInPath: function(query, progress, callback)
{
- var requestId = ++WebInspector.FileSystemProjectDelegate._lastRequestId;
- this._searchCallbacks[requestId] = innerCallback.bind(this);
+ var requestId = this._fileSystemWorkspaceBinding.registerCallback(innerCallback.bind(this));
InspectorFrontendHost.searchInPath(requestId, this._fileSystem.path(), query);
/**
* @param {!Array.<string>} files
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(files)
{
/**
* @param {string} fullPath
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function trimAndNormalizeFileSystemPath(fullPath)
{
@@ -317,28 +429,12 @@ WebInspector.FileSystemProjectDelegate.prototype = {
},
/**
- * @param {number} requestId
- * @param {!Array.<string>} files
- */
- searchCompleted: function(requestId, files)
- {
- if (!this._searchCallbacks[requestId])
- return;
- var callback = this._searchCallbacks[requestId];
- delete this._searchCallbacks[requestId];
- callback(files);
- },
-
- /**
* @param {!WebInspector.Progress} progress
- * @param {function()} callback
*/
- indexContent: function(progress, callback)
+ indexContent: function(progress)
{
- var requestId = ++WebInspector.FileSystemProjectDelegate._lastRequestId;
- this._indexingCallbacks[requestId] = callback;
- this._indexingProgresses[requestId] = progress;
progress.setTotalWork(1);
+ var requestId = this._fileSystemWorkspaceBinding.registerProgress(progress);
progress.addEventListener(WebInspector.Progress.Events.Canceled, this._indexingCanceled.bind(this, requestId));
InspectorFrontendHost.indexPath(requestId, this._fileSystem.path());
},
@@ -348,50 +444,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
_indexingCanceled: function(requestId)
{
- if (!this._indexingProgresses[requestId])
- return;
InspectorFrontendHost.stopIndexing(requestId);
- delete this._indexingProgresses[requestId];
- delete this._indexingCallbacks[requestId];
- },
-
- /**
- * @param {number} requestId
- * @param {number} totalWork
- */
- indexingTotalWorkCalculated: function(requestId, totalWork)
- {
- if (!this._indexingProgresses[requestId])
- return;
- var progress = this._indexingProgresses[requestId];
- progress.setTotalWork(totalWork);
- },
-
- /**
- * @param {number} requestId
- * @param {number} worked
- */
- indexingWorked: function(requestId, worked)
- {
- if (!this._indexingProgresses[requestId])
- return;
- var progress = this._indexingProgresses[requestId];
- progress.worked(worked);
- },
-
- /**
- * @param {number} requestId
- */
- indexingDone: function(requestId)
- {
- if (!this._indexingProgresses[requestId])
- return;
- var progress = this._indexingProgresses[requestId];
- var callback = this._indexingCallbacks[requestId];
- delete this._indexingProgresses[requestId];
- delete this._indexingCallbacks[requestId];
- progress.done();
- callback.call();
},
/**
@@ -412,11 +465,11 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
_contentTypeForExtension: function(extension)
{
- if (WebInspector.FileSystemProjectDelegate._scriptExtensions[extension])
+ if (WebInspector.FileSystemWorkspaceBinding._scriptExtensions[extension])
return WebInspector.resourceTypes.Script;
- if (WebInspector.FileSystemProjectDelegate._styleSheetExtensions[extension])
+ if (WebInspector.FileSystemWorkspaceBinding._styleSheetExtensions[extension])
return WebInspector.resourceTypes.Stylesheet;
- if (WebInspector.FileSystemProjectDelegate._documentExtensions[extension])
+ if (WebInspector.FileSystemWorkspaceBinding._documentExtensions[extension])
return WebInspector.resourceTypes.Document;
return WebInspector.resourceTypes.Other;
},
@@ -439,7 +492,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
excludeFolder: function(path)
{
- WebInspector.isolatedFileSystemManager.mapping().addExcludedFolder(this._fileSystem.path(), path);
+ this._fileSystemWorkspaceBinding._isolatedFileSystemManager.mapping().addExcludedFolder(this._fileSystem.path(), path);
},
/**
@@ -455,7 +508,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
/**
* @param {?string} filePath
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function innerCallback(filePath)
{
@@ -472,7 +525,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
}
/**
- * @this {WebInspector.FileSystemProjectDelegate}
+ * @this {WebInspector.FileSystemWorkspaceBinding.FileSystem}
*/
function contentSet()
{
@@ -492,7 +545,7 @@ WebInspector.FileSystemProjectDelegate.prototype = {
remove: function()
{
- WebInspector.isolatedFileSystemManager.removeFileSystem(this._fileSystem.path());
+ this._fileSystemWorkspaceBinding._isolatedFileSystemManager.removeFileSystem(this._fileSystem.path());
},
/**
@@ -511,8 +564,8 @@ WebInspector.FileSystemProjectDelegate.prototype = {
var extension = this._extensionForPath(name);
var contentType = this._contentTypeForExtension(extension);
- var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, this._fileSystemURL + filePath, url, contentType, true);
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileAdded, fileDescriptor);
+ var fileDescriptor = new WebInspector.FileDescriptor(parentPath, name, this._fileSystemURL + filePath, url, contentType);
+ this._projectStore.addFile(fileDescriptor);
},
/**
@@ -520,82 +573,16 @@ WebInspector.FileSystemProjectDelegate.prototype = {
*/
_removeFile: function(path)
{
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.FileRemoved, path);
- },
-
- reset: function()
- {
- this.dispatchEventToListeners(WebInspector.ProjectDelegate.Events.Reset, null);
+ this._projectStore.removeFile(path);
},
-
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @type {!WebInspector.FileSystemProjectDelegate}
- */
-WebInspector.fileSystemProjectDelegate;
-
-/**
- * @constructor
- * @param {!WebInspector.IsolatedFileSystemManager} isolatedFileSystemManager
- * @param {!WebInspector.Workspace} workspace
- */
-WebInspector.FileSystemWorkspaceProvider = function(isolatedFileSystemManager, workspace)
-{
- this._isolatedFileSystemManager = isolatedFileSystemManager;
- this._workspace = workspace;
- this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, this._fileSystemAdded, this);
- this._isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
- this._projectDelegates = {};
-}
-WebInspector.FileSystemWorkspaceProvider.prototype = {
- /**
- * @param {!WebInspector.Event} event
- */
- _fileSystemAdded: function(event)
- {
- var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
- var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystem.path());
- var projectDelegate = new WebInspector.FileSystemProjectDelegate(fileSystem, this._workspace)
- this._projectDelegates[projectDelegate.id()] = projectDelegate;
- console.assert(!this._workspace.project(projectDelegate.id()));
- this._workspace.addProject(projectDelegate);
- projectDelegate.populate();
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
- _fileSystemRemoved: function(event)
- {
- var fileSystem = /** @type {!WebInspector.IsolatedFileSystem} */ (event.data);
- var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystem.path());
- this._workspace.removeProject(projectId);
- delete this._projectDelegates[projectId];
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- fileSystemPath: function(uiSourceCode)
- {
- var projectDelegate = this._projectDelegates[uiSourceCode.project().id()];
- return projectDelegate.fileSystemPath();
- },
-
- /**
- * @param {!WebInspector.FileSystemProjectDelegate} fileSystemPath
- */
- delegate: function(fileSystemPath)
+ dispose: function()
{
- var projectId = WebInspector.FileSystemProjectDelegate.projectId(fileSystemPath);
- return this._projectDelegates[projectId];
+ this._workspace.removeProject(this._projectId);
}
}
/**
- * @type {!WebInspector.FileSystemWorkspaceProvider}
+ * @type {!WebInspector.FileSystemWorkspaceBinding}
*/
-WebInspector.fileSystemWorkspaceProvider;
+WebInspector.fileSystemWorkspaceBinding;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FileUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileUtils.js
index 2dd5a13c1a1..4f7a8d21209 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FileUtils.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/FileUtils.js
@@ -47,6 +47,7 @@ WebInspector.OutputStreamDelegate.prototype = {
/**
* @param {!WebInspector.ChunkedReader} reader
+ * @param {!Event} event
*/
onError: function(reader, event) { },
}
@@ -312,38 +313,6 @@ WebInspector.createFileSelectorElement = function(callback) {
}
/**
- * @param {string} source
- * @param {number=} startIndex
- * @param {number=} lastIndex
- */
-WebInspector.findBalancedCurlyBrackets = function(source, startIndex, lastIndex) {
- lastIndex = lastIndex || source.length;
- startIndex = startIndex || 0;
- var counter = 0;
- var inString = false;
-
- for (var index = startIndex; index < lastIndex; ++index) {
- var character = source[index];
- if (inString) {
- if (character === "\\")
- ++index;
- else if (character === "\"")
- inString = false;
- } else {
- if (character === "\"")
- inString = true;
- else if (character === "{")
- ++counter;
- else if (character === "}") {
- if (--counter === 0)
- return index + 1;
- }
- }
- }
- return -1;
-}
-
-/**
* @constructor
* @implements {WebInspector.OutputStream}
*/
@@ -395,7 +364,7 @@ WebInspector.FileOutputStream.prototype = {
},
/**
- * @param {?Event} event
+ * @param {!WebInspector.Event} event
*/
_onAppendDone: function(event)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js
index 6df7b0f6907..d79cfdc29f9 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/IndexedDBModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IndexedDBModel.js
@@ -30,14 +30,16 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
*/
-WebInspector.IndexedDBModel = function()
+WebInspector.IndexedDBModel = function(target)
{
- IndexedDBAgent.enable();
+ WebInspector.TargetAwareObject.call(this, target);
+ this._agent = target.indexedDBAgent();
+ this._agent.enable();
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, this._securityOriginAdded, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, this._securityOriginRemoved, this);
/** @type {!Map.<!WebInspector.IndexedDBModel.DatabaseId, !WebInspector.IndexedDBModel.Database>} */
this._databases = new Map();
@@ -59,6 +61,10 @@ WebInspector.IndexedDBModel.KeyPathTypes = {
ArrayType: "array"
};
+/**
+ * @param {*} idbKey
+ * @return {?Object}
+ */
WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
{
if (typeof(idbKey) === "undefined" || idbKey === null)
@@ -91,10 +97,13 @@ WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
return key;
}
+/**
+ * @param {?IDBKeyRange=} idbKeyRange
+ * @return {?{lower: ?Object, upper: ?Object, lowerOpen: *, upperOpen: *}}
+ */
WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
{
- var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
- if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null)
+ if (typeof idbKeyRange === "undefined" || idbKeyRange === null)
return null;
var keyRange = {};
@@ -107,6 +116,7 @@ WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
/**
* @param {!IndexedDBAgent.KeyPath} keyPath
+ * @return {?string|!Array.<string>|undefined}
*/
WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
{
@@ -125,6 +135,10 @@ WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
return idbKeyPath;
}
+/**
+ * @param {?string|!Array.<string>|undefined} idbKeyPath
+ * @return {?string}
+ */
WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
{
if (typeof idbKeyPath === "string")
@@ -145,7 +159,7 @@ WebInspector.IndexedDBModel.prototype = {
{
for (var securityOrigin in this._databaseNamesBySecurityOrigin)
this._removeOrigin(securityOrigin);
- var securityOrigins = WebInspector.resourceTreeModel.securityOrigins();
+ var securityOrigins = this.target().resourceTreeModel.securityOrigins();
for (var i = 0; i < securityOrigins.length; ++i)
this._addOrigin(securityOrigins[i]);
},
@@ -171,7 +185,7 @@ WebInspector.IndexedDBModel.prototype = {
*/
clearObjectStore: function(databaseId, objectStoreName, callback)
{
- IndexedDBAgent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName, callback);
+ this._agent.clearObjectStore(databaseId.securityOrigin, databaseId.name, objectStoreName, callback);
},
/**
@@ -280,7 +294,7 @@ WebInspector.IndexedDBModel.prototype = {
this._updateOriginDatabaseNames(securityOrigin, databaseNames);
}
- IndexedDBAgent.requestDatabaseNames(securityOrigin, callback.bind(this));
+ this._agent.requestDatabaseNames(securityOrigin, callback.bind(this));
},
/**
@@ -320,13 +334,13 @@ WebInspector.IndexedDBModel.prototype = {
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
}
- IndexedDBAgent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
+ this._agent.requestDatabase(databaseId.securityOrigin, databaseId.name, callback.bind(this));
},
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} objectStoreName
- * @param {webkitIDBKeyRange} idbKeyRange
+ * @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
@@ -340,7 +354,7 @@ WebInspector.IndexedDBModel.prototype = {
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} objectStoreName
* @param {string} indexName
- * @param {webkitIDBKeyRange} idbKeyRange
+ * @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
@@ -355,7 +369,7 @@ WebInspector.IndexedDBModel.prototype = {
* @param {string} databaseName
* @param {string} objectStoreName
* @param {string} indexName
- * @param {webkitIDBKeyRange} idbKeyRange
+ * @param {?IDBKeyRange} idbKeyRange
* @param {number} skipCount
* @param {number} pageSize
* @param {function(!Array.<!WebInspector.IndexedDBModel.Entry>, boolean)} callback
@@ -379,19 +393,19 @@ WebInspector.IndexedDBModel.prototype = {
return;
var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
- var key = WebInspector.RemoteObject.fromPayload(dataEntries[i].key);
- var primaryKey = WebInspector.RemoteObject.fromPayload(dataEntries[i].primaryKey);
- var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value);
+ var key = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].key));
+ var primaryKey = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].primaryKey));
+ var value = WebInspector.RemoteObject.fromLocalObject(JSON.parse(dataEntries[i].value));
entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
}
callback(entries, hasMore);
}
var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
- IndexedDBAgent.requestData(databaseId.securityOrigin, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
+ this._agent.requestData(databaseId.securityOrigin, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
@@ -421,6 +435,7 @@ WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
WebInspector.IndexedDBModel.DatabaseId.prototype = {
/**
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
+ * @return {boolean}
*/
equals: function(databaseId)
{
@@ -431,6 +446,7 @@ WebInspector.IndexedDBModel.DatabaseId.prototype = {
* @constructor
* @param {!WebInspector.IndexedDBModel.DatabaseId} databaseId
* @param {string} version
+ * @param {number} intVersion
*/
WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion)
{
@@ -444,6 +460,7 @@ WebInspector.IndexedDBModel.Database = function(databaseId, version, intVersion)
* @constructor
* @param {string} name
* @param {*} keyPath
+ * @param {boolean} autoIncrement
*/
WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
{
@@ -467,6 +484,8 @@ WebInspector.IndexedDBModel.ObjectStore.prototype = {
* @constructor
* @param {string} name
* @param {*} keyPath
+ * @param {boolean} unique
+ * @param {boolean} multiEntry
*/
WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js
new file mode 100644
index 00000000000..3c9f9558c31
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/InspectorBackend.js
@@ -0,0 +1,877 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ */
+function InspectorBackendClass()
+{
+ this._connection = null;
+ this._agentPrototypes = {};
+ this._dispatcherPrototypes = {};
+ this._initialized = false;
+ this._enums = {};
+ this._initProtocolAgentsConstructor();
+}
+
+InspectorBackendClass.prototype = {
+
+ _initProtocolAgentsConstructor: function()
+ {
+ window.Protocol = {};
+
+ /**
+ * @constructor
+ * @param {!Object.<string, !Object>} agentsMap
+ */
+ window.Protocol.Agents = function(agentsMap) {
+ this._agentsMap = agentsMap;
+ };
+ },
+
+ /**
+ * @param {string} domain
+ */
+ _addAgentGetterMethodToProtocolAgentsPrototype: function(domain)
+ {
+ var upperCaseLength = 0;
+ while (upperCaseLength < domain.length && domain[upperCaseLength].toLowerCase() !== domain[upperCaseLength])
+ ++upperCaseLength;
+
+ var methodName = domain.substr(0, upperCaseLength).toLowerCase() + domain.slice(upperCaseLength) + "Agent";
+
+ /**
+ * @this {Protocol.Agents}
+ */
+ function agentGetter()
+ {
+ return this._agentsMap[domain];
+ }
+
+ window.Protocol.Agents.prototype[methodName] = agentGetter;
+
+ /**
+ * @this {Protocol.Agents}
+ */
+ function registerDispatcher(dispatcher)
+ {
+ this.registerDispatcher(domain, dispatcher)
+ }
+
+ window.Protocol.Agents.prototype["register" + domain + "Dispatcher"] = registerDispatcher;
+ },
+
+ /**
+ * @return {!InspectorBackendClass.Connection}
+ */
+ connection: function()
+ {
+ if (!this._connection)
+ throw "Main connection was not initialized";
+ return this._connection;
+ },
+
+ /**
+ * @param {!InspectorBackendClass.MainConnection} connection
+ */
+ setConnection: function(connection)
+ {
+ this._connection = connection;
+
+ this._connection.registerAgentsOn(window);
+ for (var type in this._enums) {
+ var domainAndMethod = type.split(".");
+ window[domainAndMethod[0] + "Agent"][domainAndMethod[1]] = this._enums[type];
+ }
+ },
+
+ /**
+ * @param {string} domain
+ * @return {!InspectorBackendClass.AgentPrototype}
+ */
+ _agentPrototype: function(domain)
+ {
+ if (!this._agentPrototypes[domain]) {
+ this._agentPrototypes[domain] = new InspectorBackendClass.AgentPrototype(domain);
+ this._addAgentGetterMethodToProtocolAgentsPrototype(domain);
+ }
+
+ return this._agentPrototypes[domain];
+ },
+
+ /**
+ * @param {string} domain
+ * @return {!InspectorBackendClass.DispatcherPrototype}
+ */
+ _dispatcherPrototype: function(domain)
+ {
+ if (!this._dispatcherPrototypes[domain])
+ this._dispatcherPrototypes[domain] = new InspectorBackendClass.DispatcherPrototype();
+ return this._dispatcherPrototypes[domain];
+ },
+
+ /**
+ * @param {string} method
+ * @param {!Array.<!Object>} signature
+ * @param {!Array.<string>} replyArgs
+ * @param {boolean} hasErrorData
+ */
+ registerCommand: function(method, signature, replyArgs, hasErrorData)
+ {
+ var domainAndMethod = method.split(".");
+ this._agentPrototype(domainAndMethod[0]).registerCommand(domainAndMethod[1], signature, replyArgs, hasErrorData);
+ this._initialized = true;
+ },
+
+ /**
+ * @param {string} type
+ * @param {!Object} values
+ */
+ registerEnum: function(type, values)
+ {
+ this._enums[type] = values;
+ this._initialized = true;
+ },
+
+ /**
+ * @param {string} eventName
+ * @param {!Object} params
+ */
+ registerEvent: function(eventName, params)
+ {
+ var domain = eventName.split(".")[0];
+ this._dispatcherPrototype(domain).registerEvent(eventName, params);
+ this._initialized = true;
+ },
+
+ /**
+ * @param {string} domain
+ * @param {!Object} dispatcher
+ */
+ registerDomainDispatcher: function(domain, dispatcher)
+ {
+ this._connection.registerDispatcher(domain, dispatcher);
+ },
+
+ /**
+ * @param {string} jsonUrl
+ */
+ loadFromJSONIfNeeded: function(jsonUrl)
+ {
+ if (this._initialized)
+ return;
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", jsonUrl, false);
+ xhr.send(null);
+
+ var schema = JSON.parse(xhr.responseText);
+ var code = InspectorBackendClass._generateCommands(schema);
+ eval(code);
+ },
+
+ /**
+ * @param {function(T)} clientCallback
+ * @param {string} errorPrefix
+ * @param {function(new:T,S)=} constructor
+ * @param {T=} defaultValue
+ * @return {function(?string, S)}
+ * @template T,S
+ */
+ wrapClientCallback: function(clientCallback, errorPrefix, constructor, defaultValue)
+ {
+ /**
+ * @param {?string} error
+ * @param {S} value
+ * @template S
+ */
+ function callbackWrapper(error, value)
+ {
+ if (error) {
+ console.error(errorPrefix + error);
+ clientCallback(defaultValue);
+ return;
+ }
+ if (constructor)
+ clientCallback(new constructor(value));
+ else
+ clientCallback(value);
+ }
+ return callbackWrapper;
+ }
+}
+
+/**
+ * @param {*} schema
+ * @return {string}
+ */
+InspectorBackendClass._generateCommands = function(schema) {
+ var jsTypes = { integer: "number", array: "object" };
+ var rawTypes = {};
+ var result = [];
+
+ var domains = schema["domains"] || [];
+ for (var i = 0; i < domains.length; ++i) {
+ var domain = domains[i];
+ for (var j = 0; domain.types && j < domain.types.length; ++j) {
+ var type = domain.types[j];
+ rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
+ }
+ }
+
+ function toUpperCase(groupIndex, group0, group1)
+ {
+ return [group0, group1][groupIndex].toUpperCase();
+ }
+ function generateEnum(enumName, items)
+ {
+ var members = []
+ for (var m = 0; m < items.length; ++m) {
+ var value = items[m];
+ var name = value.replace(/-(\w)/g, toUpperCase.bind(null, 1)).toTitleCase();
+ name = name.replace(/HTML|XML|WML|API/ig, toUpperCase.bind(null, 0));
+ members.push(name + ": \"" + value +"\"");
+ }
+ return "InspectorBackend.registerEnum(\"" + enumName + "\", {" + members.join(", ") + "});";
+ }
+
+ for (var i = 0; i < domains.length; ++i) {
+ var domain = domains[i];
+
+ var types = domain["types"] || [];
+ for (var j = 0; j < types.length; ++j) {
+ var type = types[j];
+ if ((type["type"] === "string") && type["enum"])
+ result.push(generateEnum(domain.domain + "." + type.id, type["enum"]));
+ else if (type["type"] === "object") {
+ var properties = type["properties"] || [];
+ for (var k = 0; k < properties.length; ++k) {
+ var property = properties[k];
+ if ((property["type"] === "string") && property["enum"])
+ result.push(generateEnum(domain.domain + "." + type.id + property["name"].toTitleCase(), property["enum"]));
+ }
+ }
+ }
+
+ var commands = domain["commands"] || [];
+ for (var j = 0; j < commands.length; ++j) {
+ var command = commands[j];
+ var parameters = command["parameters"];
+ var paramsText = [];
+ for (var k = 0; parameters && k < parameters.length; ++k) {
+ var parameter = parameters[k];
+
+ var type;
+ if (parameter.type)
+ type = jsTypes[parameter.type] || parameter.type;
+ else {
+ var ref = parameter["$ref"];
+ if (ref.indexOf(".") !== -1)
+ type = rawTypes[ref];
+ else
+ type = rawTypes[domain.domain + "." + ref];
+ }
+
+ var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
+ paramsText.push(text);
+ }
+
+ var returnsText = [];
+ var returns = command["returns"] || [];
+ for (var k = 0; k < returns.length; ++k) {
+ var parameter = returns[k];
+ returnsText.push("\"" + parameter.name + "\"");
+ }
+ var hasErrorData = String(Boolean(command.error));
+ result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "], " + hasErrorData + ");");
+ }
+
+ for (var j = 0; domain.events && j < domain.events.length; ++j) {
+ var event = domain.events[j];
+ var paramsText = [];
+ for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
+ var parameter = event.parameters[k];
+ paramsText.push("\"" + parameter.name + "\"");
+ }
+ result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
+ }
+
+ result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
+ }
+ return result.join("\n");
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+InspectorBackendClass.Connection = function()
+{
+ this._lastMessageId = 1;
+ this._pendingResponsesCount = 0;
+ this._agents = {};
+ this._dispatchers = {};
+ this._callbacks = {};
+ this._initialize(InspectorBackend._agentPrototypes, InspectorBackend._dispatcherPrototypes);
+}
+
+InspectorBackendClass.Connection.Events = {
+ Disconnected: "Disconnected",
+}
+
+InspectorBackendClass.Connection.prototype = {
+
+ /**
+ * @param {!Object.<string, !InspectorBackendClass.AgentPrototype>} agentPrototypes
+ * @param {!Object.<string, !InspectorBackendClass.DispatcherPrototype>} dispatcherPrototypes
+ */
+ _initialize: function(agentPrototypes, dispatcherPrototypes)
+ {
+ for (var domain in agentPrototypes) {
+ this._agents[domain] = Object.create(agentPrototypes[domain]);
+ this._agents[domain].setConnection(this);
+ }
+
+ for (var domain in dispatcherPrototypes)
+ this._dispatchers[domain] = Object.create(dispatcherPrototypes[domain])
+
+ },
+
+ /**
+ * @param {!Object} object
+ */
+ registerAgentsOn: function(object)
+ {
+ for (var domain in this._agents)
+ object[domain + "Agent"] = this._agents[domain];
+ },
+
+ /**
+ * @return {number}
+ */
+ nextMessageId: function()
+ {
+ return this._lastMessageId++;
+ },
+
+ /**
+ * @param {string} domain
+ * @return {!InspectorBackendClass.AgentPrototype}
+ */
+ agent: function(domain)
+ {
+ return this._agents[domain];
+ },
+
+ /**
+ * @return {!Object.<string, !Object>}
+ */
+ agentsMap: function()
+ {
+ return this._agents;
+ },
+
+ /**
+ * @param {string} domain
+ * @param {string} method
+ * @param {?Object} params
+ * @param {?function(*)} callback
+ * @private
+ */
+ _wrapCallbackAndSendMessageObject: function(domain, method, params, callback)
+ {
+ var messageObject = {};
+
+ var messageId = this.nextMessageId();
+ messageObject.id = messageId;
+
+ messageObject.method = method;
+ if (params)
+ messageObject.params = params;
+
+ var wrappedCallback = this._wrap(callback, domain, method);
+
+ if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
+ this._dumpProtocolMessage("frontend: " + JSON.stringify(messageObject));
+
+ this.sendMessage(messageObject);
+ ++this._pendingResponsesCount;
+ this._callbacks[messageId] = wrappedCallback;
+ },
+
+ /**
+ * @param {?function(*)} callback
+ * @param {string} method
+ * @param {string} domain
+ * @return {!function(*)}
+ */
+ _wrap: function(callback, domain, method)
+ {
+ if (!callback)
+ callback = function() {};
+
+ callback.methodName = method;
+ callback.domain = domain;
+ if (InspectorBackendClass.Options.dumpInspectorTimeStats)
+ callback.sendRequestTime = Date.now();
+
+ return callback;
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ reportProtocolError: function(messageObject)
+ {
+ console.error("Protocol Error: the message with wrong id. Message = " + JSON.stringify(messageObject));
+ },
+
+ /**
+ * @param {!Object|string} message
+ */
+ dispatch: function(message)
+ {
+ if (InspectorBackendClass.Options.dumpInspectorProtocolMessages)
+ this._dumpProtocolMessage("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
+
+ var messageObject = /** @type {!Object} */ ((typeof message === "string") ? JSON.parse(message) : message);
+
+ if ("id" in messageObject) { // just a response for some request
+
+ var callback = this._callbacks[messageObject.id];
+ if (!callback) {
+ this.reportProtocolError(messageObject);
+ return;
+ }
+
+ var processingStartTime;
+ if (InspectorBackendClass.Options.dumpInspectorTimeStats)
+ processingStartTime = Date.now();
+
+ this.agent(callback.domain).dispatchResponse(messageObject.id, messageObject, callback.methodName, callback);
+ --this._pendingResponsesCount;
+ delete this._callbacks[messageObject.id];
+
+ if (InspectorBackendClass.Options.dumpInspectorTimeStats)
+ console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
+
+ if (this._scripts && !this._pendingResponsesCount)
+ this.runAfterPendingDispatches();
+ return;
+ } else {
+ var method = messageObject.method.split(".");
+ var domainName = method[0];
+ if (!(domainName in this._dispatchers)) {
+ console.error("Protocol Error: the message " + messageObject.method + " is for non-existing domain '" + domainName + "'");
+ return;
+ }
+
+ this._dispatchers[domainName].dispatch(method[1], messageObject);
+
+ }
+
+ },
+
+ /**
+ * @param {string} domain
+ * @param {!Object} dispatcher
+ */
+ registerDispatcher: function(domain, dispatcher)
+ {
+ if (!this._dispatchers[domain])
+ return;
+
+ this._dispatchers[domain].setDomainDispatcher(dispatcher);
+ },
+
+ /**
+ * @param {string=} script
+ */
+ runAfterPendingDispatches: function(script)
+ {
+ if (!this._scripts)
+ this._scripts = [];
+
+ if (script)
+ this._scripts.push(script);
+
+ if (!this._pendingResponsesCount) {
+ var scripts = this._scripts;
+ this._scripts = []
+ for (var id = 0; id < scripts.length; ++id)
+ scripts[id].call(this);
+ }
+ },
+
+ /**
+ * @param {string} reason
+ */
+ fireDisconnected: function(reason)
+ {
+ this.dispatchEventToListeners(InspectorBackendClass.Connection.Events.Disconnected, {reason: reason});
+ },
+
+ _dumpProtocolMessage: function(message)
+ {
+ console.log(message);
+ },
+
+ __proto__: WebInspector.Object.prototype
+
+}
+
+/**
+ * @constructor
+ * @extends {InspectorBackendClass.Connection}
+ * @param {!function(!InspectorBackendClass.Connection)} onConnectionReady
+ */
+InspectorBackendClass.MainConnection = function(onConnectionReady)
+{
+ InspectorBackendClass.Connection.call(this);
+ onConnectionReady(this);
+}
+
+InspectorBackendClass.MainConnection.prototype = {
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ var message = JSON.stringify(messageObject);
+ InspectorFrontendHost.sendMessageToBackend(message);
+ },
+
+ __proto__: InspectorBackendClass.Connection.prototype
+}
+
+/**
+ * @constructor
+ * @extends {InspectorBackendClass.Connection}
+ * @param {string} url
+ * @param {!function(!InspectorBackendClass.Connection)} onConnectionReady
+ */
+InspectorBackendClass.WebSocketConnection = function(url, onConnectionReady)
+{
+ InspectorBackendClass.Connection.call(this);
+ this._socket = new WebSocket(url);
+ this._socket.onmessage = this._onMessage.bind(this);
+ this._socket.onerror = this._onError.bind(this);
+ this._socket.onopen = onConnectionReady.bind(null, this);
+ this._socket.onclose = this.fireDisconnected.bind(this, "websocket_closed");
+}
+
+InspectorBackendClass.WebSocketConnection.prototype = {
+
+ /**
+ * @param {!MessageEvent} message
+ */
+ _onMessage: function(message)
+ {
+ var data = /** @type {string} */ (message.data)
+ this.dispatch(data);
+ },
+
+ /**
+ * @param {!Event} error
+ */
+ _onError: function(error)
+ {
+ console.error(error);
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ var message = JSON.stringify(messageObject);
+ this._socket.send(message);
+ },
+
+ __proto__: InspectorBackendClass.Connection.prototype
+}
+
+
+/**
+ * @constructor
+ * @extends {InspectorBackendClass.Connection}
+ * @param {!function(!InspectorBackendClass.Connection)} onConnectionReady
+ */
+InspectorBackendClass.StubConnection = function(onConnectionReady)
+{
+ InspectorBackendClass.Connection.call(this);
+ onConnectionReady(this);
+}
+
+InspectorBackendClass.StubConnection.prototype = {
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ var message = JSON.stringify(messageObject);
+ setTimeout(this._echoResponse.bind(this, messageObject), 0);
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ _echoResponse: function(messageObject)
+ {
+ this.dispatch(messageObject)
+ },
+
+ __proto__: InspectorBackendClass.Connection.prototype
+}
+
+/**
+ * @constructor
+ * @param {string} domain
+ */
+InspectorBackendClass.AgentPrototype = function(domain)
+{
+ this._replyArgs = {};
+ this._hasErrorData = {};
+ this._domain = domain;
+}
+
+InspectorBackendClass.AgentPrototype.prototype = {
+
+ /**
+ * @param {!InspectorBackendClass.Connection} connection
+ */
+ setConnection: function(connection)
+ {
+ this._connection = connection;
+ },
+
+ /**
+ * @param {string} methodName
+ * @param {!Array.<!Object>} signature
+ * @param {!Array.<string>} replyArgs
+ * @param {boolean} hasErrorData
+ */
+ registerCommand: function(methodName, signature, replyArgs, hasErrorData)
+ {
+ var domainAndMethod = this._domain + "." + methodName;
+
+ /**
+ * @this {InspectorBackendClass.AgentPrototype}
+ */
+ function sendMessage(vararg)
+ {
+ var params = [domainAndMethod, signature].concat(Array.prototype.slice.call(arguments));
+ InspectorBackendClass.AgentPrototype.prototype._sendMessageToBackend.apply(this, params);
+ }
+
+ this[methodName] = sendMessage;
+
+ /**
+ * @this {InspectorBackendClass.AgentPrototype}
+ */
+ function invoke(vararg)
+ {
+ var params = [domainAndMethod].concat(Array.prototype.slice.call(arguments));
+ InspectorBackendClass.AgentPrototype.prototype._invoke.apply(this, params);
+ }
+
+ this["invoke_" + methodName] = invoke;
+
+ this._replyArgs[domainAndMethod] = replyArgs;
+ if (hasErrorData)
+ this._hasErrorData[domainAndMethod] = true;
+
+ },
+
+ /**
+ * @param {string} method
+ * @param {!Array.<!Object>} signature
+ * @param {*} vararg
+ * @private
+ */
+ _sendMessageToBackend: function(method, signature, vararg)
+ {
+ var args = Array.prototype.slice.call(arguments, 2);
+ var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;
+
+ var params = {};
+ var hasParams = false;
+ for (var i = 0; i < signature.length; ++i) {
+ var param = signature[i];
+ var paramName = param["name"];
+ var typeName = param["type"];
+ var optionalFlag = param["optional"];
+
+ if (!args.length && !optionalFlag) {
+ console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
+ return;
+ }
+
+ var value = args.shift();
+ if (optionalFlag && typeof value === "undefined") {
+ continue;
+ }
+
+ if (typeof value !== typeName) {
+ console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
+ return;
+ }
+
+ params[paramName] = value;
+ hasParams = true;
+ }
+
+ if (args.length === 1 && !callback && (typeof args[0] !== "undefined")) {
+ console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
+ return;
+ }
+
+ this._connection._wrapCallbackAndSendMessageObject(this._domain, method, hasParams ? params : null, callback);
+ },
+
+ /**
+ * @param {string} method
+ * @param {?Object} args
+ * @param {?function(*)} callback
+ */
+ _invoke: function(method, args, callback)
+ {
+ this._connection._wrapCallbackAndSendMessageObject(this._domain, method, args, callback);
+ },
+
+ /**
+ * @param {number} messageId
+ * @param {!Object} messageObject
+ * @param {string} methodName
+ * @param {function(!Array.<*>)} callback
+ */
+ dispatchResponse: function(messageId, messageObject, methodName, callback)
+ {
+ if (messageObject.error && messageObject.error.code !== -32000)
+ console.error("Request with id = " + messageObject.id + " failed. " + JSON.stringify(messageObject.error));
+
+ var argumentsArray = [];
+ argumentsArray[0] = messageObject.error ? messageObject.error.message: null;
+
+ if (this._hasErrorData[methodName])
+ argumentsArray[1] = messageObject.error ? messageObject.error.data : null;
+
+ if (messageObject.result) {
+ var paramNames = this._replyArgs[methodName] || [];
+ for (var i = 0; i < paramNames.length; ++i)
+ argumentsArray.push(messageObject.result[paramNames[i]]);
+ }
+
+ callback.apply(null, argumentsArray);
+ }
+}
+
+/**
+ * @constructor
+ */
+InspectorBackendClass.DispatcherPrototype = function()
+{
+ this._eventArgs = {};
+ this._dispatcher = null;
+}
+
+InspectorBackendClass.DispatcherPrototype.prototype = {
+
+ /**
+ * @param {string} eventName
+ * @param {!Object} params
+ */
+ registerEvent: function(eventName, params)
+ {
+ this._eventArgs[eventName] = params
+ },
+
+ /**
+ * @param {!Object} dispatcher
+ */
+ setDomainDispatcher: function(dispatcher)
+ {
+ this._dispatcher = dispatcher;
+ },
+
+ /**
+ * @param {string} functionName
+ * @param {!Object} messageObject
+ */
+ dispatch: function(functionName, messageObject)
+ {
+ if (!this._dispatcher)
+ return;
+
+ if (!(functionName in this._dispatcher)) {
+ console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
+ return;
+ }
+
+ if (!this._eventArgs[messageObject.method]) {
+ console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
+ return;
+ }
+
+ var params = [];
+ if (messageObject.params) {
+ var paramNames = this._eventArgs[messageObject.method];
+ for (var i = 0; i < paramNames.length; ++i)
+ params.push(messageObject.params[paramNames[i]]);
+ }
+
+ var processingStartTime;
+ if (InspectorBackendClass.Options.dumpInspectorTimeStats)
+ processingStartTime = Date.now();
+
+ this._dispatcher[functionName].apply(this._dispatcher, params);
+
+ if (InspectorBackendClass.Options.dumpInspectorTimeStats)
+ console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
+ }
+
+}
+
+InspectorBackendClass.Options = {
+ dumpInspectorTimeStats: false,
+ dumpInspectorProtocolMessages: false
+}
+
+InspectorBackend = new InspectorBackendClass();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystem.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystem.js
index 7923e3e7436..d3a359cc5d0 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystem.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystem.js
@@ -32,6 +32,8 @@
* @constructor
* @param {!WebInspector.IsolatedFileSystemManager} manager
* @param {string} path
+ * @param {string} name
+ * @param {string} rootURL
*/
WebInspector.IsolatedFileSystem = function(manager, path, name, rootURL)
{
@@ -61,11 +63,22 @@ WebInspector.IsolatedFileSystem.errorMessage = function(error)
msg = "INVALID_STATE_ERR";
break;
default:
- msg = "Unknown Error";
+ msg = WebInspector.UIString("Unknown Error");
break;
};
- return "File system error: " + msg;
+ return WebInspector.UIString("File system error: %s", msg);
+}
+
+/**
+ * @param {string} fileSystemPath
+ * @return {string}
+ */
+WebInspector.IsolatedFileSystem.normalizePath = function(fileSystemPath)
+{
+ if (WebInspector.isWin())
+ return fileSystemPath.replace(/\\/g, "/");
+ return fileSystemPath;
}
WebInspector.IsolatedFileSystem.prototype = {
@@ -80,6 +93,17 @@ WebInspector.IsolatedFileSystem.prototype = {
/**
* @return {string}
*/
+ normalizedPath: function()
+ {
+ if (this._normalizedPath)
+ return this._normalizedPath;
+ this._normalizedPath = WebInspector.IsolatedFileSystem.normalizePath(this._path);
+ return this._normalizedPath;
+ },
+
+ /**
+ * @return {string}
+ */
name: function()
{
return this._name;
@@ -238,7 +262,7 @@ WebInspector.IsolatedFileSystem.prototype = {
*/
function fileEntryLoaded(fileEntry)
{
- fileEntry.remove(fileEntryRemoved.bind(this), errorHandler.bind(this));
+ fileEntry.remove(fileEntryRemoved, errorHandler.bind(this));
}
function fileEntryRemoved()
@@ -262,7 +286,7 @@ WebInspector.IsolatedFileSystem.prototype = {
*/
requestMetadata: function(path, callback)
{
- this._requestFileSystem(fileSystemLoaded.bind(this));
+ this._requestFileSystem(fileSystemLoaded);
/**
* @param {?DOMFileSystem} fs
@@ -315,7 +339,7 @@ WebInspector.IsolatedFileSystem.prototype = {
{
var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
console.assert(domFileSystem);
- domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler.bind(this));
+ domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), errorHandler.bind(this));
}
/**
@@ -368,7 +392,7 @@ WebInspector.IsolatedFileSystem.prototype = {
*/
setFileContent: function(path, content, callback)
{
- this._requestFileSystem(fileSystemLoaded);
+ this._requestFileSystem(fileSystemLoaded.bind(this));
/**
* @param {?DOMFileSystem} fs
@@ -378,7 +402,7 @@ WebInspector.IsolatedFileSystem.prototype = {
{
var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
console.assert(domFileSystem);
- domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded, errorHandler.bind(this));
+ domFileSystem.root.getFile(path, { create: true }, fileEntryLoaded.bind(this), errorHandler.bind(this));
}
/**
@@ -387,7 +411,7 @@ WebInspector.IsolatedFileSystem.prototype = {
*/
function fileEntryLoaded(entry)
{
- entry.createWriter(fileWriterCreated, errorHandler.bind(this));
+ entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this));
}
/**
@@ -439,7 +463,7 @@ WebInspector.IsolatedFileSystem.prototype = {
var fileEntry;
var dirEntry;
var newFileEntry;
- this._requestFileSystem(fileSystemLoaded);
+ this._requestFileSystem(fileSystemLoaded.bind(this));
/**
* @param {?DOMFileSystem} fs
@@ -449,7 +473,7 @@ WebInspector.IsolatedFileSystem.prototype = {
{
var domFileSystem = /** @type {!DOMFileSystem} */ (fs);
console.assert(domFileSystem);
- domFileSystem.root.getFile(path, null, fileEntryLoaded, errorHandler.bind(this));
+ domFileSystem.root.getFile(path, null, fileEntryLoaded.bind(this), errorHandler.bind(this));
}
/**
@@ -464,16 +488,17 @@ WebInspector.IsolatedFileSystem.prototype = {
}
fileEntry = entry;
- fileEntry.getParent(dirEntryLoaded, errorHandler.bind(this));
+ fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this));
}
/**
* @param {!Entry} entry
+ * @this {WebInspector.IsolatedFileSystem}
*/
function dirEntryLoaded(entry)
{
dirEntry = entry;
- dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorHandler);
+ dirEntry.getFile(newName, null, newFileEntryLoaded, newFileEntryLoadErrorHandler.bind(this));
}
/**
@@ -537,7 +562,7 @@ WebInspector.IsolatedFileSystem.prototype = {
function toArray(list)
{
return Array.prototype.slice.call(list || [], 0);
- }
+ }
dirReader.readEntries(innerCallback, errorHandler);
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystemManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystemManager.js
index 8220b175bf2..d8cdfc3d190 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/IsolatedFileSystemManager.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/IsolatedFileSystemManager.js
@@ -39,9 +39,7 @@ WebInspector.IsolatedFileSystemManager = function()
/** @type {!Object.<string, !Array.<function(?DOMFileSystem)>>} */
this._pendingFileSystemRequests = {};
this._fileSystemMapping = new WebInspector.FileSystemMapping();
-
- if (this.supportsFileSystems())
- this._requestFileSystems();
+ this._requestFileSystems();
}
/** @typedef {!{fileSystemName: string, rootURL: string, fileSystemPath: string}} */
@@ -61,14 +59,6 @@ WebInspector.IsolatedFileSystemManager.prototype = {
return this._fileSystemMapping;
},
- /**
- * @return {boolean}
- */
- supportsFileSystems: function()
- {
- return InspectorFrontendHost.supportsFileSystems();
- },
-
_requestFileSystems: function()
{
console.assert(!this._loaded);
@@ -121,14 +111,6 @@ WebInspector.IsolatedFileSystemManager.prototype = {
this.dispatchEventToListeners(WebInspector.IsolatedFileSystemManager.Events.FileSystemAdded, isolatedFileSystem);
},
- /**
- * @return {!Array.<string>}
- */
- _fileSystemPaths: function()
- {
- return Object.keys(this._fileSystems);
- },
-
_processPendingFileSystemRequests: function()
{
for (var fileSystemPath in this._pendingFileSystemRequests) {
@@ -146,9 +128,9 @@ WebInspector.IsolatedFileSystemManager.prototype = {
_fileSystemAdded: function(errorMessage, fileSystem)
{
var fileSystemPath;
- if (errorMessage)
- WebInspector.showErrorMessage(errorMessage)
- else if (fileSystem) {
+ if (errorMessage) {
+ WebInspector.messageSink.addErrorMessage(errorMessage, true);
+ } else {
this._innerAddFileSystem(fileSystem);
fileSystemPath = fileSystem.fileSystemPath;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/LayerTreeModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/LayerTreeModel.js
new file mode 100644
index 00000000000..44a863cc0ac
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/LayerTreeModel.js
@@ -0,0 +1,1187 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @typedef {!{
+ bounds: {height: number, width: number},
+ children: Array.<!WebInspector.TracingLayerPayload>,
+ layer_id: number,
+ position: Array.<number>,
+ scroll_offset: Array.<number>,
+ layer_quad: Array.<number>,
+ draws_content: number,
+ transform: Array.<number>,
+ owner_node: number
+ }}
+*/
+WebInspector.TracingLayerPayload;
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ */
+WebInspector.LayerTreeModel = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+ InspectorBackend.registerLayerTreeDispatcher(new WebInspector.LayerTreeDispatcher(this));
+ target.domModel.addEventListener(WebInspector.DOMModel.Events.DocumentUpdated, this._onDocumentUpdated, this);
+ /** @type {?WebInspector.LayerTreeBase} */
+ this._layerTree = null;
+}
+
+WebInspector.LayerTreeModel.Events = {
+ LayerTreeChanged: "LayerTreeChanged",
+ LayerPainted: "LayerPainted",
+}
+
+WebInspector.LayerTreeModel.ScrollRectType = {
+ NonFastScrollable: {name: "NonFastScrollable", description: "Non fast scrollable"},
+ TouchEventHandler: {name: "TouchEventHandler", description: "Touch event handler"},
+ WheelEventHandler: {name: "WheelEventHandler", description: "Wheel event handler"},
+ RepaintsOnScroll: {name: "RepaintsOnScroll", description: "Repaints on scroll"}
+}
+
+WebInspector.LayerTreeModel.prototype = {
+ disable: function()
+ {
+ if (!this._enabled)
+ return;
+ this._enabled = false;
+ this._layerTree = null;
+ LayerTreeAgent.disable();
+ },
+
+ enable: function()
+ {
+ if (this._enabled)
+ return;
+ this._enabled = true;
+ this._layerTree = new WebInspector.AgentLayerTree(this._target);
+ this._lastPaintRectByLayerId = {};
+ LayerTreeAgent.enable();
+ },
+
+ /**
+ * @param {!WebInspector.LayerTreeBase} layerTree
+ */
+ setLayerTree: function(layerTree)
+ {
+ this.disable();
+ this._layerTree = layerTree;
+ this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
+ },
+
+ /**
+ * @return {?WebInspector.LayerTreeBase}
+ */
+ layerTree: function()
+ {
+ return this._layerTree;
+ },
+
+ /**
+ * @param {?Array.<!LayerTreeAgent.Layer>} layers
+ */
+ _layerTreeChanged: function(layers)
+ {
+ if (!this._enabled)
+ return;
+ var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
+ layerTree.setLayers(layers, onLayersSet.bind(this));
+
+ /**
+ * @this {WebInspector.LayerTreeModel}
+ */
+ function onLayersSet()
+ {
+ for (var layerId in this._lastPaintRectByLayerId) {
+ var lastPaintRect = this._lastPaintRectByLayerId[layerId];
+ var layer = layerTree.layerById(layerId);
+ if (layer)
+ layer._lastPaintRect = lastPaintRect;
+ }
+ this._lastPaintRectByLayerId = {};
+
+ this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerTreeChanged);
+ }
+ },
+
+ /**
+ * @param {!LayerTreeAgent.LayerId} layerId
+ * @param {!DOMAgent.Rect} clipRect
+ */
+ _layerPainted: function(layerId, clipRect)
+ {
+ if (!this._enabled)
+ return;
+ var layerTree = /** @type {!WebInspector.AgentLayerTree} */ (this._layerTree);
+ var layer = layerTree.layerById(layerId);
+ if (!layer) {
+ this._lastPaintRectByLayerId[layerId] = clipRect;
+ return;
+ }
+ layer._didPaint(clipRect);
+ this.dispatchEventToListeners(WebInspector.LayerTreeModel.Events.LayerPainted, layer);
+ },
+
+ _onDocumentUpdated: function()
+ {
+ if (!this._enabled)
+ return;
+ this.disable();
+ this.enable();
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.LayerTreeBase = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+ this._layersById = {};
+ this._backendNodeIdToNodeId = {};
+ this._reset();
+}
+
+WebInspector.LayerTreeBase.prototype = {
+ _reset: function()
+ {
+ this._root = null;
+ this._contentRoot = null;
+ },
+
+ /**
+ * @return {?WebInspector.Layer}
+ */
+ root: function()
+ {
+ return this._root;
+ },
+
+ /**
+ * @return {?WebInspector.Layer}
+ */
+ contentRoot: function()
+ {
+ return this._contentRoot;
+ },
+
+ /**
+ * @param {function(!WebInspector.Layer)} callback
+ * @param {?WebInspector.Layer=} root
+ * @return {boolean}
+ */
+ forEachLayer: function(callback, root)
+ {
+ if (!root) {
+ root = this.root();
+ if (!root)
+ return false;
+ }
+ return callback(root) || root.children().some(this.forEachLayer.bind(this, callback));
+ },
+
+ /**
+ * @param {string} id
+ * @return {?WebInspector.Layer}
+ */
+ layerById: function(id)
+ {
+ return this._layersById[id] || null;
+ },
+
+ /**
+ * @param {!Array.<number>} requestedNodeIds
+ * @param {function()} callback
+ */
+ _resolveBackendNodeIds: function(requestedNodeIds, callback)
+ {
+ if (!requestedNodeIds.length) {
+ callback();
+ return;
+ }
+
+ this.target().domModel.pushNodesByBackendIdsToFrontend(requestedNodeIds, populateBackendNodeIdMap.bind(this));
+
+ /**
+ * @this {WebInspector.LayerTreeBase}
+ * @param {?Array.<number>} nodeIds
+ */
+ function populateBackendNodeIdMap(nodeIds)
+ {
+ if (nodeIds) {
+ for (var i = 0; i < requestedNodeIds.length; ++i) {
+ var nodeId = nodeIds[i];
+ if (nodeId)
+ this._backendNodeIdToNodeId[requestedNodeIds[i]] = nodeId;
+ }
+ }
+ callback();
+ }
+ },
+
+ /**
+ * @param {!Object} viewportSize
+ */
+ setViewportSize: function(viewportSize)
+ {
+ this._viewportSize = viewportSize;
+ },
+
+ /**
+ * @return {!Object | undefined}
+ */
+ viewportSize: function()
+ {
+ return this._viewportSize;
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.LayerTreeBase}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TracingLayerTree = function(target)
+{
+ WebInspector.LayerTreeBase.call(this, target);
+}
+
+WebInspector.TracingLayerTree.prototype = {
+ /**
+ * @param {!WebInspector.TracingLayerPayload} root
+ * @param {!function()} callback
+ */
+ setLayers: function(root, callback)
+ {
+ var idsToResolve = [];
+ this._extractNodeIdsToResolve(idsToResolve, {}, root);
+ this._resolveBackendNodeIds(idsToResolve, onBackendNodeIdsResolved.bind(this));
+
+ /**
+ * @this {WebInspector.TracingLayerTree}
+ */
+ function onBackendNodeIdsResolved()
+ {
+ var oldLayersById = this._layersById;
+ this._layersById = {};
+ this._contentRoot = null;
+ this._root = this._innerSetLayers(oldLayersById, root);
+ callback();
+ }
+ },
+
+ /**
+ * @param {!Object.<(string|number), !WebInspector.Layer>} oldLayersById
+ * @param {!WebInspector.TracingLayerPayload} payload
+ * @return {!WebInspector.TracingLayer}
+ */
+ _innerSetLayers: function(oldLayersById, payload)
+ {
+ var layer = /** @type {?WebInspector.TracingLayer} */ (oldLayersById[payload.layer_id]);
+ if (layer)
+ layer._reset(payload);
+ else
+ layer = new WebInspector.TracingLayer(payload);
+ this._layersById[payload.layer_id] = layer;
+ if (!this._contentRoot && payload.draws_content)
+ this._contentRoot = layer;
+
+ if (payload.owner_node && this._backendNodeIdToNodeId[payload.owner_node])
+ layer._setNode(this._target.domModel.nodeForId(this._backendNodeIdToNodeId[payload.owner_node]));
+
+ for (var i = 0; payload.children && i < payload.children.length; ++i)
+ layer.addChild(this._innerSetLayers(oldLayersById, payload.children[i]));
+ return layer;
+ },
+
+ /**
+ * @param {!Array.<number>} nodeIdsToResolve
+ * @param {!Object} seenNodeIds
+ * @param {!WebInspector.TracingLayerPayload} payload
+ */
+ _extractNodeIdsToResolve: function(nodeIdsToResolve, seenNodeIds, payload)
+ {
+ var backendNodeId = payload.owner_node;
+ if (backendNodeId && !seenNodeIds[backendNodeId] && !(this._backendNodeIdToNodeId[backendNodeId] && this.target().domModel.nodeForId(backendNodeId))) {
+ seenNodeIds[backendNodeId] = true;
+ nodeIdsToResolve.push(backendNodeId);
+ }
+ for (var i = 0; payload.children && i < payload.children.length; ++i)
+ this._extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload.children[i]);
+ },
+
+ __proto__: WebInspector.LayerTreeBase.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.LayerTreeBase}
+ */
+WebInspector.AgentLayerTree = function(target)
+{
+ WebInspector.LayerTreeBase.call(this, target);
+}
+
+WebInspector.AgentLayerTree.prototype = {
+ /**
+ * @param {?Array.<!LayerTreeAgent.Layer>} payload
+ * @param {function()} callback
+ */
+ setLayers: function(payload, callback)
+ {
+ if (!payload) {
+ onBackendNodeIdsResolved.call(this);
+ return;
+ }
+
+ var idsToResolve = {};
+ var requestedIds = [];
+ for (var i = 0; i < payload.length; ++i) {
+ var backendNodeId = payload[i].backendNodeId;
+ if (!backendNodeId || idsToResolve[backendNodeId] ||
+ (this._backendNodeIdToNodeId[backendNodeId] && this.target().domModel.nodeForId(this._backendNodeIdToNodeId[backendNodeId]))) {
+ continue;
+ }
+ idsToResolve[backendNodeId] = true;
+ requestedIds.push(backendNodeId);
+ }
+ this._resolveBackendNodeIds(requestedIds, onBackendNodeIdsResolved.bind(this));
+
+ /**
+ * @this {WebInspector.AgentLayerTree}
+ */
+ function onBackendNodeIdsResolved()
+ {
+ this._innerSetLayers(payload);
+ callback();
+ }
+ },
+
+ /**
+ * @param {?Array.<!LayerTreeAgent.Layer>} layers
+ */
+ _innerSetLayers: function(layers)
+ {
+ this._reset();
+ // Payload will be null when not in the composited mode.
+ if (!layers)
+ return;
+ var oldLayersById = this._layersById;
+ this._layersById = {};
+ for (var i = 0; i < layers.length; ++i) {
+ var layerId = layers[i].layerId;
+ var layer = oldLayersById[layerId];
+ if (layer)
+ layer._reset(layers[i]);
+ else
+ layer = new WebInspector.AgentLayer(layers[i]);
+ this._layersById[layerId] = layer;
+ if (layers[i].backendNodeId) {
+ layer._setNode(this._target.domModel.nodeForId(this._backendNodeIdToNodeId[layers[i].backendNodeId]));
+ if (!this._contentRoot)
+ this._contentRoot = layer;
+ }
+ var parentId = layer.parentId();
+ if (parentId) {
+ var parent = this._layersById[parentId];
+ if (!parent)
+ console.assert(parent, "missing parent " + parentId + " for layer " + layerId);
+ parent.addChild(layer);
+ } else {
+ if (this._root)
+ console.assert(false, "Multiple root layers");
+ this._root = layer;
+ }
+ }
+ if (this._root)
+ this._root._calculateQuad(new WebKitCSSMatrix());
+ },
+
+ __proto__: WebInspector.LayerTreeBase.prototype
+}
+
+/**
+ * @interface
+ */
+WebInspector.Layer = function()
+{
+}
+
+WebInspector.Layer.prototype = {
+ /**
+ * @return {string}
+ */
+ id: function() { },
+
+ /**
+ * @return {?string}
+ */
+ parentId: function() { },
+
+ /**
+ * @return {?WebInspector.Layer}
+ */
+ parent: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ isRoot: function() { },
+
+ /**
+ * @return {!Array.<!WebInspector.Layer>}
+ */
+ children: function() { },
+
+ /**
+ * @param {!WebInspector.Layer} child
+ */
+ addChild: function(child) { },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ node: function() { },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ nodeForSelfOrAncestor: function() { },
+
+ /**
+ * @return {number}
+ */
+ offsetX: function() { },
+
+ /**
+ * @return {number}
+ */
+ offsetY: function() { },
+
+ /**
+ * @return {number}
+ */
+ width: function() { },
+
+ /**
+ * @return {number}
+ */
+ height: function() { },
+
+ /**
+ * @return {?Array.<number>}
+ */
+ transform: function() { },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ quad: function() { },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ anchorPoint: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ invisible: function() { },
+
+ /**
+ * @return {number}
+ */
+ paintCount: function() { },
+
+ /**
+ * @return {?DOMAgent.Rect}
+ */
+ lastPaintRect: function() { },
+
+ /**
+ * @return {!Array.<!LayerTreeAgent.ScrollRect>}
+ */
+ scrollRects: function() { },
+
+ /**
+ * @param {function(!Array.<string>)} callback
+ */
+ requestCompositingReasons: function(callback) { },
+
+ /**
+ * @param {function(!WebInspector.PaintProfilerSnapshot=)} callback
+ */
+ requestSnapshot: function(callback) { },
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Layer}
+ * @param {!LayerTreeAgent.Layer} layerPayload
+ */
+WebInspector.AgentLayer = function(layerPayload)
+{
+ this._reset(layerPayload);
+}
+
+WebInspector.AgentLayer.prototype = {
+ /**
+ * @return {string}
+ */
+ id: function()
+ {
+ return this._layerPayload.layerId;
+ },
+
+ /**
+ * @return {?string}
+ */
+ parentId: function()
+ {
+ return this._layerPayload.parentLayerId;
+ },
+
+ /**
+ * @return {?WebInspector.Layer}
+ */
+ parent: function()
+ {
+ return this._parent;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isRoot: function()
+ {
+ return !this.parentId();
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.Layer>}
+ */
+ children: function()
+ {
+ return this._children;
+ },
+
+ /**
+ * @param {!WebInspector.Layer} child
+ */
+ addChild: function(child)
+ {
+ if (child._parent)
+ console.assert(false, "Child already has a parent");
+ this._children.push(child);
+ child._parent = this;
+ },
+
+ /**
+ * @param {?WebInspector.DOMNode} node
+ */
+ _setNode: function(node)
+ {
+ this._node = node;
+ },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ node: function()
+ {
+ return this._node;
+ },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ nodeForSelfOrAncestor: function()
+ {
+ for (var layer = this; layer; layer = layer._parent) {
+ if (layer._node)
+ return layer._node;
+ }
+ return null;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetX: function()
+ {
+ return this._layerPayload.offsetX;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetY: function()
+ {
+ return this._layerPayload.offsetY;
+ },
+
+ /**
+ * @return {number}
+ */
+ width: function()
+ {
+ return this._layerPayload.width;
+ },
+
+ /**
+ * @return {number}
+ */
+ height: function()
+ {
+ return this._layerPayload.height;
+ },
+
+ /**
+ * @return {?Array.<number>}
+ */
+ transform: function()
+ {
+ return this._layerPayload.transform;
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ quad: function()
+ {
+ return this._quad;
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ anchorPoint: function()
+ {
+ return [
+ this._layerPayload.anchorX || 0,
+ this._layerPayload.anchorY || 0,
+ this._layerPayload.anchorZ || 0,
+ ];
+ },
+
+ /**
+ * @return {boolean}
+ */
+ invisible: function()
+ {
+ return this._layerPayload.invisible;
+ },
+
+ /**
+ * @return {number}
+ */
+ paintCount: function()
+ {
+ return this._paintCount || this._layerPayload.paintCount;
+ },
+
+ /**
+ * @return {?DOMAgent.Rect}
+ */
+ lastPaintRect: function()
+ {
+ return this._lastPaintRect;
+ },
+
+ /**
+ * @return {!Array.<!LayerTreeAgent.ScrollRect>}
+ */
+ scrollRects: function()
+ {
+ return this._scrollRects;
+ },
+
+ /**
+ * @param {function(!Array.<string>)} callback
+ */
+ requestCompositingReasons: function(callback)
+ {
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.reasonsForCompositingLayer(): ", undefined, []);
+ LayerTreeAgent.compositingReasons(this.id(), wrappedCallback);
+ },
+
+ /**
+ * @param {function(!WebInspector.PaintProfilerSnapshot=)} callback
+ */
+ requestSnapshot: function(callback)
+ {
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.makeSnapshot(): ", WebInspector.PaintProfilerSnapshot);
+ LayerTreeAgent.makeSnapshot(this.id(), wrappedCallback);
+ },
+
+ /**
+ * @param {!DOMAgent.Rect} rect
+ */
+ _didPaint: function(rect)
+ {
+ this._lastPaintRect = rect;
+ this._paintCount = this.paintCount() + 1;
+ this._image = null;
+ },
+
+ /**
+ * @param {!LayerTreeAgent.Layer} layerPayload
+ */
+ _reset: function(layerPayload)
+ {
+ /** @type {?WebInspector.DOMNode} */
+ this._node = null;
+ this._children = [];
+ this._parent = null;
+ this._paintCount = 0;
+ this._layerPayload = layerPayload;
+ this._image = null;
+ this._scrollRects = this._layerPayload.scrollRects || [];
+ },
+
+ /**
+ * @param {!Array.<number>} a
+ * @return {!CSSMatrix}
+ */
+ _matrixFromArray: function(a)
+ {
+ function toFixed9(x) { return x.toFixed(9); }
+ return new WebKitCSSMatrix("matrix3d(" + a.map(toFixed9).join(",") + ")");
+ },
+
+ /**
+ * @param {!CSSMatrix} parentTransform
+ * @return {!CSSMatrix}
+ */
+ _calculateTransformToViewport: function(parentTransform)
+ {
+ var offsetMatrix = new WebKitCSSMatrix().translate(this._layerPayload.offsetX, this._layerPayload.offsetY);
+ var matrix = offsetMatrix;
+
+ if (this._layerPayload.transform) {
+ var transformMatrix = this._matrixFromArray(this._layerPayload.transform);
+ var anchorVector = new WebInspector.Geometry.Vector(this._layerPayload.width * this.anchorPoint()[0], this._layerPayload.height * this.anchorPoint()[1], this.anchorPoint()[2]);
+ var anchorPoint = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(anchorVector, matrix);
+ var anchorMatrix = new WebKitCSSMatrix().translate(-anchorPoint.x, -anchorPoint.y, -anchorPoint.z);
+ matrix = anchorMatrix.inverse().multiply(transformMatrix.multiply(anchorMatrix.multiply(matrix)));
+ }
+
+ matrix = parentTransform.multiply(matrix);
+ return matrix;
+ },
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @return {!Array.<number>}
+ */
+ _createVertexArrayForRect: function(width, height)
+ {
+ return [0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0];
+ },
+
+ /**
+ * @param {!CSSMatrix} parentTransform
+ */
+ _calculateQuad: function(parentTransform)
+ {
+ var matrix = this._calculateTransformToViewport(parentTransform);
+ this._quad = [];
+ var vertices = this._createVertexArrayForRect(this._layerPayload.width, this._layerPayload.height);
+ for (var i = 0; i < 4; ++i) {
+ var point = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
+ this._quad.push(point.x, point.y);
+ }
+
+ function calculateQuadForLayer(layer)
+ {
+ layer._calculateQuad(matrix);
+ }
+
+ this._children.forEach(calculateQuadForLayer);
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TracingLayerPayload} payload
+ * @implements {WebInspector.Layer}
+ */
+WebInspector.TracingLayer = function(payload)
+{
+ this._reset(payload);
+}
+
+WebInspector.TracingLayer.prototype = {
+ /**
+ * @param {!WebInspector.TracingLayerPayload} payload
+ */
+ _reset: function(payload)
+ {
+ /** @type {?WebInspector.DOMNode} */
+ this._node = null;
+ this._layerId = String(payload.layer_id);
+ this._offsetX = payload.position[0];
+ this._offsetY = payload.position[1];
+ this._width = payload.bounds.width;
+ this._height = payload.bounds.height;
+ this._children = [];
+ this._parentLayerId = null;
+ this._parent = null;
+ this._quad = payload.layer_quad || [];
+ this._createScrollRects(payload);
+ },
+
+ /**
+ * @return {string}
+ */
+ id: function()
+ {
+ return this._layerId;
+ },
+
+ /**
+ * @return {?string}
+ */
+ parentId: function()
+ {
+ return this._parentLayerId;
+ },
+
+ /**
+ * @return {?WebInspector.Layer}
+ */
+ parent: function()
+ {
+ return this._parent;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isRoot: function()
+ {
+ return !this.parentId();
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.Layer>}
+ */
+ children: function()
+ {
+ return this._children;
+ },
+
+ /**
+ * @param {!WebInspector.Layer} child
+ */
+ addChild: function(child)
+ {
+ if (child._parent)
+ console.assert(false, "Child already has a parent");
+ this._children.push(child);
+ child._parent = this;
+ child._parentLayerId = this._layerId;
+ },
+
+
+ /**
+ * @param {?WebInspector.DOMNode} node
+ */
+ _setNode: function(node)
+ {
+ this._node = node;
+ },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ node: function()
+ {
+ return this._node;
+ },
+
+ /**
+ * @return {?WebInspector.DOMNode}
+ */
+ nodeForSelfOrAncestor: function()
+ {
+ for (var layer = this; layer; layer = layer._parent) {
+ if (layer._node)
+ return layer._node;
+ }
+ return null;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetX: function()
+ {
+ return this._offsetX;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetY: function()
+ {
+ return this._offsetY;
+ },
+
+ /**
+ * @return {number}
+ */
+ width: function()
+ {
+ return this._width;
+ },
+
+ /**
+ * @return {number}
+ */
+ height: function()
+ {
+ return this._height;
+ },
+
+ /**
+ * @return {?Array.<number>}
+ */
+ transform: function()
+ {
+ return null;
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ quad: function()
+ {
+ return this._quad;
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ anchorPoint: function()
+ {
+ return [0.5, 0.5, 0];
+ },
+
+ /**
+ * @return {boolean}
+ */
+ invisible: function()
+ {
+ return false;
+ },
+
+ /**
+ * @return {number}
+ */
+ paintCount: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @return {?DOMAgent.Rect}
+ */
+ lastPaintRect: function()
+ {
+ return null;
+ },
+
+ /**
+ * @return {!Array.<!LayerTreeAgent.ScrollRect>}
+ */
+ scrollRects: function()
+ {
+ return this._scrollRects;
+ },
+
+ /**
+ * @param {!Array.<number>} params
+ * @param {string} type
+ * @return {!Object}
+ */
+ _scrollRectsFromParams: function(params, type)
+ {
+ return {rect: {x: params[0], y: params[1], width: params[2], height: params[3]}, type: type};
+ },
+
+ /**
+ * @param {!WebInspector.TracingLayerPayload} payload
+ */
+ _createScrollRects: function(payload)
+ {
+ this._scrollRects = [];
+ if (payload.non_fast_scrollable_region)
+ this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region, WebInspector.LayerTreeModel.ScrollRectType.NonFastScrollable.name));
+ if (payload.touch_event_handler_region)
+ this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.TouchEventHandler.name));
+ if (payload.wheel_event_handler_region)
+ this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.WheelEventHandler.name));
+ if (payload.scroll_event_handler_region)
+ this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region, WebInspector.LayerTreeModel.ScrollRectType.RepaintsOnScroll.name));
+ },
+
+ /**
+ * @param {function(!Array.<string>)} callback
+ */
+ requestCompositingReasons: function(callback)
+ {
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.reasonsForCompositingLayer(): ", undefined, []);
+ LayerTreeAgent.compositingReasons(this.id(), wrappedCallback);
+ },
+
+ /**
+ * @param {function(!WebInspector.PaintProfilerSnapshot=)} callback
+ */
+ requestSnapshot: function(callback)
+ {
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.makeSnapshot(): ", WebInspector.PaintProfilerSnapshot);
+ LayerTreeAgent.makeSnapshot(this.id(), wrappedCallback);
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.DeferredLayerTree = function(target)
+{
+ this._target = target;
+}
+
+WebInspector.DeferredLayerTree.prototype = {
+ /**
+ * @param {function(!WebInspector.LayerTreeBase)} callback
+ */
+ resolve: function(callback) { },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ }
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.DeferredLayerTree}
+ * @param {!WebInspector.Target} target
+ * @param {!Array.<!LayerTreeAgent.Layer>} layers
+ */
+WebInspector.DeferredAgentLayerTree = function(target, layers)
+{
+ WebInspector.DeferredLayerTree.call(this, target);
+ this._layers = layers;
+}
+
+WebInspector.DeferredAgentLayerTree.prototype = {
+ /**
+ * @param {function(!WebInspector.LayerTreeBase)} callback
+ */
+ resolve: function(callback)
+ {
+ var result = new WebInspector.AgentLayerTree(this._target);
+ result.setLayers(this._layers, callback.bind(null, result));
+ },
+
+ __proto__: WebInspector.DeferredLayerTree.prototype
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.DeferredLayerTree}
+ * @param {!WebInspector.Target} target
+ * @param {!WebInspector.TracingLayerPayload} root
+ * @param {!Object} viewportSize
+ */
+WebInspector.DeferredTracingLayerTree = function(target, root, viewportSize)
+{
+ WebInspector.DeferredLayerTree.call(this, target);
+ this._root = root;
+ this._viewportSize = viewportSize;
+}
+
+WebInspector.DeferredTracingLayerTree.prototype = {
+ /**
+ * @param {function(!WebInspector.LayerTreeBase)} callback
+ */
+ resolve: function(callback)
+ {
+ var result = new WebInspector.TracingLayerTree(this._target);
+ result.setViewportSize(this._viewportSize);
+ result.setLayers(this._root, callback.bind(null, result));
+ },
+
+ __proto__: WebInspector.DeferredLayerTree.prototype
+};
+
+/**
+ * @constructor
+ * @implements {LayerTreeAgent.Dispatcher}
+ * @param {!WebInspector.LayerTreeModel} layerTreeModel
+ */
+WebInspector.LayerTreeDispatcher = function(layerTreeModel)
+{
+ this._layerTreeModel = layerTreeModel;
+}
+
+WebInspector.LayerTreeDispatcher.prototype = {
+ /**
+ * @param {!Array.<!LayerTreeAgent.Layer>=} layers
+ */
+ layerTreeDidChange: function(layers)
+ {
+ this._layerTreeModel._layerTreeChanged(layers || null);
+ },
+
+ /**
+ * @param {!LayerTreeAgent.LayerId} layerId
+ * @param {!DOMAgent.Rect} clipRect
+ */
+ layerPainted: function(layerId, clipRect)
+ {
+ this._layerTreeModel._layerPainted(layerId, clipRect);
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Linkifier.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Linkifier.js
index 8e34d8ca6a2..93917642afb 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Linkifier.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Linkifier.js
@@ -53,17 +53,74 @@ WebInspector.Linkifier = function(formatter)
this._liveLocations = [];
}
+/**
+ * @param {!WebInspector.Linkifier.LinkHandler} handler
+ */
+WebInspector.Linkifier.setLinkHandler = function(handler)
+{
+ WebInspector.Linkifier._linkHandler = handler;
+}
+
+/**
+ * @param {string} url
+ * @param {number=} lineNumber
+ * @return {boolean}
+ */
+WebInspector.Linkifier.handleLink = function(url, lineNumber)
+{
+ if (!WebInspector.Linkifier._linkHandler)
+ return false;
+ return WebInspector.Linkifier._linkHandler.handleLink(url, lineNumber)
+}
+
+/**
+ * @param {!Object} revealable
+ * @param {string} text
+ * @param {string=} fallbackHref
+ * @param {number=} fallbackLineNumber
+ * @param {string=} title
+ * @param {string=} classes
+ * @return {!Element}
+ */
+WebInspector.Linkifier.linkifyUsingRevealer = function(revealable, text, fallbackHref, fallbackLineNumber, title, classes)
+{
+ var a = document.createElement("a");
+ a.className = (classes || "") + " webkit-html-resource-link";
+ a.textContent = text.trimMiddle(WebInspector.Linkifier.MaxLengthForDisplayedURLs);
+ a.title = title || text;
+ if (fallbackHref) {
+ a.href = fallbackHref;
+ a.lineNumber = fallbackLineNumber;
+ }
+ /**
+ * @param {?Event} event
+ * @this {Object}
+ */
+ function clickHandler(event)
+ {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+ if (fallbackHref && WebInspector.Linkifier.handleLink(fallbackHref, fallbackLineNumber))
+ return;
+
+ WebInspector.Revealer.reveal(this);
+ }
+ a.addEventListener("click", clickHandler.bind(revealable), false);
+ return a;
+}
+
WebInspector.Linkifier.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @param {string} sourceURL
* @param {number} lineNumber
* @param {number=} columnNumber
* @param {string=} classes
* @return {?Element}
*/
- linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
+ linkifyLocation: function(target, sourceURL, lineNumber, columnNumber, classes)
{
- var rawLocation = WebInspector.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
+ var rawLocation = target.debuggerModel.createRawLocationByURL(sourceURL, lineNumber, columnNumber || 0);
if (!rawLocation)
return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes);
return this.linkifyRawLocation(rawLocation, classes);
@@ -76,11 +133,12 @@ WebInspector.Linkifier.prototype = {
*/
linkifyRawLocation: function(rawLocation, classes)
{
- var script = WebInspector.debuggerModel.scriptForId(rawLocation.scriptId);
+ // FIXME: this check should not be here.
+ var script = rawLocation.target().debuggerModel.scriptForId(rawLocation.scriptId);
if (!script)
return null;
- var anchor = WebInspector.linkifyURLAsNode("", "", classes, false);
- var liveLocation = script.createLiveLocation(rawLocation, this._updateAnchor.bind(this, anchor));
+ var anchor = this._createAnchor(classes);
+ var liveLocation = rawLocation.createLiveLocation(this._updateAnchor.bind(this, anchor));
this._liveLocations.push(liveLocation);
return anchor;
},
@@ -93,14 +151,40 @@ WebInspector.Linkifier.prototype = {
*/
linkifyCSSLocation: function(styleSheetId, rawLocation, classes)
{
- var anchor = WebInspector.linkifyURLAsNode("", "", classes, false);
- var liveLocation = WebInspector.cssModel.createLiveLocation(styleSheetId, rawLocation, this._updateAnchor.bind(this, anchor));
+ var anchor = this._createAnchor(classes);
+ var liveLocation = rawLocation.createLiveLocation(styleSheetId, this._updateAnchor.bind(this, anchor));
if (!liveLocation)
return null;
this._liveLocations.push(liveLocation);
return anchor;
},
+ /**
+ * @param {string=} classes
+ * @return {!Element}
+ */
+ _createAnchor: function(classes)
+ {
+ var anchor = document.createElement("a");
+ anchor.className = (classes || "") + " webkit-html-resource-link";
+
+ /**
+ * @param {?Event} event
+ */
+ function clickHandler(event)
+ {
+ event.stopImmediatePropagation();
+ event.preventDefault();
+ if (!anchor.__uiLocation)
+ return;
+ if (WebInspector.Linkifier.handleLink(anchor.__uiLocation.uiSourceCode.url, anchor.__uiLocation.lineNumber))
+ return;
+ WebInspector.Revealer.reveal(anchor.__uiLocation);
+ }
+ anchor.addEventListener("click", clickHandler, false);
+ return anchor;
+ },
+
reset: function()
{
for (var i = 0; i < this._liveLocations.length; ++i)
@@ -114,11 +198,7 @@ WebInspector.Linkifier.prototype = {
*/
_updateAnchor: function(anchor, uiLocation)
{
- anchor.preferredPanel = "sources";
- anchor.href = sanitizeHref(uiLocation.uiSourceCode.originURL());
- anchor.uiSourceCode = uiLocation.uiSourceCode;
- anchor.lineNumber = uiLocation.lineNumber;
- anchor.columnNumber = uiLocation.columnNumber;
+ anchor.__uiLocation = uiLocation;
this._formatter.formatLiveAnchor(anchor, uiLocation);
}
}
@@ -149,9 +229,7 @@ WebInspector.Linkifier.DefaultFormatter.prototype = {
if (typeof uiLocation.lineNumber === "number")
titleText += ":" + (uiLocation.lineNumber + 1);
anchor.title = titleText;
- },
-
- __proto__: WebInspector.LinkifierFormatter.prototype
+ }
}
/**
@@ -186,3 +264,35 @@ WebInspector.Linkifier.DefaultCSSFormatter.prototype = {
* @type {number}
*/
WebInspector.Linkifier.MaxLengthForDisplayedURLs = 150;
+
+/**
+ * @interface
+ */
+WebInspector.Linkifier.LinkHandler = function()
+{
+}
+
+WebInspector.Linkifier.LinkHandler.prototype = {
+ /**
+ * @param {string} url
+ * @param {number=} lineNumber
+ * @return {boolean}
+ */
+ handleLink: function(url, lineNumber) {}
+}
+
+/**
+ * @param {!WebInspector.Target} target
+ * @param {string} scriptId
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ * @return {string}
+ */
+WebInspector.Linkifier.liveLocationText = function(target, scriptId, lineNumber, columnNumber)
+{
+ var script = target.debuggerModel.scriptForId(scriptId);
+ if (!script)
+ return "";
+ var uiLocation = script.rawLocationToUILocation(lineNumber, columnNumber);
+ return uiLocation.linkText();
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/LiveEditSupport.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/LiveEditSupport.js
index 570619b168a..1abd6c1e7d3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/LiveEditSupport.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/LiveEditSupport.js
@@ -34,7 +34,9 @@
*/
WebInspector.LiveEditSupport = function(workspace)
{
- this._workspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.LiveEdit);
+ this._workspace = workspace;
+ this._projectId = "liveedit:";
+ this._projectDelegate = new WebInspector.DebuggerProjectDelegate(workspace, this._projectId, WebInspector.projectTypes.LiveEdit);
WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
this._debuggerReset();
}
@@ -46,9 +48,9 @@ WebInspector.LiveEditSupport.prototype = {
*/
uiSourceCodeForLiveEdit: function(uiSourceCode)
{
- var rawLocation = uiSourceCode.uiLocationToRawLocation(0, 0);
+ var rawLocation = uiSourceCode.uiLocationToRawLocation(WebInspector.targetManager.targets()[0], 0, 0);
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
- var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
+ var script = debuggerModelLocation.script();
var uiLocation = script.rawLocationToUILocation(0, 0);
// FIXME: Support live editing of scripts mapped to some file.
@@ -58,9 +60,10 @@ WebInspector.LiveEditSupport.prototype = {
return this._uiSourceCodeForScriptId[script.scriptId];
console.assert(!script.isInlineScript());
- var liveEditUISourceCode = this._workspaceProvider.addUniqueFileForURL(script.sourceURL, script, true, script.isContentScript);
+ var path = this._projectDelegate.addScript(script);
+ var liveEditUISourceCode = this._workspace.uiSourceCode(this._projectId, path);
- liveEditUISourceCode.setScriptFile(new WebInspector.LiveEditScriptFile(uiSourceCode, liveEditUISourceCode, script.scriptId));
+ liveEditUISourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCodeForScriptId[script.scriptId] = liveEditUISourceCode;
this._scriptIdForUISourceCode.put(liveEditUISourceCode, script.scriptId);
return liveEditUISourceCode;
@@ -72,8 +75,32 @@ WebInspector.LiveEditSupport.prototype = {
this._uiSourceCodeForScriptId = {};
/** @type {!Map.<!WebInspector.UISourceCode, string>} */
this._scriptIdForUISourceCode = new Map();
- this._workspaceProvider.reset();
+ this._projectDelegate.reset();
},
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _workingCopyCommitted: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
+ var scriptId = /** @type {string} */ (this._scriptIdForUISourceCode.get(uiSourceCode));
+ WebInspector.debuggerModel.setScriptSource(scriptId, uiSourceCode.workingCopy(), innerCallback);
+
+ /**
+ * @param {?string} error
+ * @param {!DebuggerAgent.SetScriptSourceError=} errorData
+ */
+ function innerCallback(error, errorData)
+ {
+ if (error) {
+ var script = WebInspector.debuggerModel.scriptForId(scriptId);
+ WebInspector.LiveEditSupport.logDetailedError(error, errorData, script);
+ return;
+ }
+ WebInspector.LiveEditSupport.logSuccess();
+ }
+ }
}
/**
@@ -86,93 +113,22 @@ WebInspector.LiveEditSupport.logDetailedError = function(error, errorData, conte
var warningLevel = WebInspector.ConsoleMessage.MessageLevel.Warning;
if (!errorData) {
if (error)
- WebInspector.log(WebInspector.UIString("LiveEdit failed: %s", error), warningLevel, false);
+ WebInspector.messageSink.addMessage(WebInspector.UIString("LiveEdit failed: %s", error), warningLevel);
return;
}
var compileError = errorData.compileError;
if (compileError) {
- var message = "LiveEdit compile failed: " + compileError.message;
- if (contextScript)
- message += " at " + contextScript.sourceURL + ":" + compileError.lineNumber + ":" + compileError.columnNumber;
- WebInspector.log(message, WebInspector.ConsoleMessage.MessageLevel.Error, false);
+ var location = contextScript ? WebInspector.UIString(" at %s:%d:%d", contextScript.sourceURL, compileError.lineNumber, compileError.columnNumber) : "";
+ var message = WebInspector.UIString("LiveEdit compile failed: %s%s", compileError.message, location);
+ WebInspector.messageSink.addErrorMessage(message);
} else {
- WebInspector.log("Unknown LiveEdit error: " + JSON.stringify(errorData) + "; " + error, warningLevel, false);
+ WebInspector.messageSink.addMessage(WebInspector.UIString("Unknown LiveEdit error: %s; %s", JSON.stringify(errorData), error), warningLevel);
}
}
WebInspector.LiveEditSupport.logSuccess = function()
{
- WebInspector.log(WebInspector.UIString("Recompilation and update succeeded."), WebInspector.ConsoleMessage.MessageLevel.Debug, false);
-}
-
-/**
- * @constructor
- * @implements {WebInspector.ScriptFile}
- * @extends {WebInspector.Object}
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {!WebInspector.UISourceCode} liveEditUISourceCode
- * @param {string} scriptId
- */
-WebInspector.LiveEditScriptFile = function(uiSourceCode, liveEditUISourceCode, scriptId)
-{
- WebInspector.ScriptFile.call(this);
- this._uiSourceCode = uiSourceCode;
- this._liveEditUISourceCode = liveEditUISourceCode;
- this._scriptId = scriptId;
- this._liveEditUISourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
-}
-
-WebInspector.LiveEditScriptFile.prototype = {
- _workingCopyCommitted: function(event)
- {
- /**
- * @param {?string} error
- * @param {!DebuggerAgent.SetScriptSourceError=} errorData
- * @this {WebInspector.LiveEditScriptFile}
- */
- function innerCallback(error, errorData)
- {
- if (error) {
- var script = WebInspector.debuggerModel.scriptForId(this._scriptId);
- WebInspector.LiveEditSupport.logDetailedError(error, errorData, script);
- return;
- }
- WebInspector.LiveEditSupport.logSuccess();
- }
-
- var script = WebInspector.debuggerModel.scriptForId(this._scriptId);
- WebInspector.debuggerModel.setScriptSource(script.scriptId, this._liveEditUISourceCode.workingCopy(), innerCallback.bind(this));
- },
-
- /**
- * @return {boolean}
- */
- hasDivergedFromVM: function()
- {
- return true;
- },
-
- /**
- * @return {boolean}
- */
- isDivergingFromVM: function()
- {
- return false;
- },
-
- /**
- * @return {boolean}
- */
- isMergingToVM: function()
- {
- return false;
- },
-
- checkMapping: function()
- {
- },
-
- __proto__: WebInspector.Object.prototype
+ WebInspector.messageSink.addMessage(WebInspector.UIString("Recompilation and update succeeded."));
}
/** @type {!WebInspector.LiveEditSupport} */
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkLog.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkLog.js
index f856f5c4b14..c7a2eb82886 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkLog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkLog.js
@@ -30,15 +30,19 @@
/**
* @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.NetworkLog = function()
+WebInspector.NetworkLog = function(target)
{
+ WebInspector.TargetAware.call(this, target);
+
this._requests = [];
this._requestForId = {};
- WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._onLoad, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._onLoad, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
}
WebInspector.NetworkLog.prototype = {
@@ -130,7 +134,9 @@ WebInspector.NetworkLog.prototype = {
requestForId: function(requestId)
{
return this._requestForId[requestId];
- }
+ },
+
+ __proto__: WebInspector.TargetAware.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
index 90d461fedab..2cf6b83916a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkManager.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
@@ -30,16 +30,20 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.NetworkManager = function()
+WebInspector.NetworkManager = function(target)
{
- WebInspector.Object.call(this);
+ WebInspector.TargetAwareObject.call(this, target);
this._dispatcher = new WebInspector.NetworkDispatcher(this);
+ this._target = target;
+ this._networkAgent = target.networkAgent();
+ target.registerNetworkDispatcher(this._dispatcher);
if (WebInspector.settings.cacheDisabled.get())
- NetworkAgent.setCacheDisabled(true);
+ this._networkAgent.setCacheDisabled(true);
- NetworkAgent.enable();
+ this._networkAgent.enable();
WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
}
@@ -92,6 +96,19 @@ WebInspector.NetworkManager._MIMETypes = {
"text/javascript1.3": {"script": true},
"text/jscript": {"script": true},
"text/livescript": {"script": true},
+ "text/vtt": {"texttrack": true},
+}
+
+// Keep in sync with kDevToolsRequestInitiator defined in InspectorResourceAgent.cpp
+WebInspector.NetworkManager._devToolsRequestHeader = "X-DevTools-Request-Initiator";
+
+/**
+ * @param {?WebInspector.NetworkRequest} request
+ * @return {boolean}
+ */
+WebInspector.NetworkManager.hasDevToolsRequestHeader = function(request)
+{
+ return !!request && !!request.requestHeaderValue(WebInspector.NetworkManager._devToolsRequestHeader);
}
WebInspector.NetworkManager.prototype = {
@@ -110,10 +127,10 @@ WebInspector.NetworkManager.prototype = {
_cacheDisabledSettingChanged: function(event)
{
var enabled = /** @type {boolean} */ (event.data);
- NetworkAgent.setCacheDisabled(enabled);
+ this._networkAgent.setCacheDisabled(enabled);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
@@ -125,7 +142,6 @@ WebInspector.NetworkDispatcher = function(manager)
this._manager = manager;
this._inflightRequestsById = {};
this._inflightRequestsByURL = {};
- InspectorBackend.registerNetworkDispatcher(this);
}
WebInspector.NetworkDispatcher.prototype = {
@@ -161,15 +177,14 @@ WebInspector.NetworkDispatcher.prototype = {
*/
_updateNetworkRequestWithResponse: function(networkRequest, response)
{
- if (!response)
- return;
-
if (response.url && networkRequest.url !== response.url)
networkRequest.url = response.url;
networkRequest.mimeType = response.mimeType;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
+ if (response.encodedDataLength >= 0)
+ networkRequest.setTransferSize(response.encodedDataLength);
if (response.headersText)
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders) {
@@ -179,6 +194,8 @@ WebInspector.NetworkDispatcher.prototype = {
networkRequest.connectionReused = response.connectionReused;
networkRequest.connectionId = response.connectionId;
+ if (response.remoteIPAddress)
+ networkRequest.setRemoteAddress(response.remoteIPAddress, response.remotePort || -1);
if (response.fromDiskCache)
networkRequest.cached = true;
@@ -186,16 +203,14 @@ WebInspector.NetworkDispatcher.prototype = {
networkRequest.timing = response.timing;
if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
- WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
+ var consoleModel = this._manager._target.consoleModel;
+ consoleModel.addMessage(new WebInspector.ConsoleMessage(consoleModel.target(), WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Log,
WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
0,
- 1,
- [],
- undefined,
networkRequest.requestId));
}
},
@@ -217,6 +232,7 @@ WebInspector.NetworkDispatcher.prototype = {
if (typeof networkRequest.type === "undefined"
|| networkRequest.type === WebInspector.resourceTypes.Other
+ || networkRequest.type === WebInspector.resourceTypes.Media
|| networkRequest.type === WebInspector.resourceTypes.XHR
|| networkRequest.type === WebInspector.resourceTypes.WebSocket)
return true;
@@ -231,17 +247,6 @@ WebInspector.NetworkDispatcher.prototype = {
},
/**
- * @param {!NetworkAgent.Response} response
- * @return {boolean}
- */
- _isNull: function(response)
- {
- if (!response)
- return true;
- return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
- },
-
- /**
* @param {!NetworkAgent.RequestId} requestId
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
@@ -291,10 +296,6 @@ WebInspector.NetworkDispatcher.prototype = {
*/
responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
{
- // FIXME: move this check to the backend.
- if (this._isNull(response))
- return;
-
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) {
// We missed the requestWillBeSent.
@@ -339,31 +340,34 @@ WebInspector.NetworkDispatcher.prototype = {
/**
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} finishTime
+ * @param {number} encodedDataLength
*/
- loadingFinished: function(requestId, finishTime)
+ loadingFinished: function(requestId, finishTime, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
- this._finishNetworkRequest(networkRequest, finishTime);
+ this._finishNetworkRequest(networkRequest, finishTime, encodedDataLength);
},
/**
* @param {!NetworkAgent.RequestId} requestId
* @param {!NetworkAgent.Timestamp} time
+ * @param {!PageAgent.ResourceType} resourceType
* @param {string} localizedDescription
* @param {boolean=} canceled
*/
- loadingFailed: function(requestId, time, localizedDescription, canceled)
+ loadingFailed: function(requestId, time, resourceType, localizedDescription, canceled)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.failed = true;
+ networkRequest.type = WebInspector.resourceTypes[resourceType];
networkRequest.canceled = canceled;
networkRequest.localizedFailDescription = localizedDescription;
- this._finishNetworkRequest(networkRequest, time);
+ this._finishNetworkRequest(networkRequest, time, -1);
},
/**
@@ -372,7 +376,7 @@ WebInspector.NetworkDispatcher.prototype = {
*/
webSocketCreated: function(requestId, requestURL)
{
- var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
+ var networkRequest = new WebInspector.NetworkRequest(this._manager._target, requestId, requestURL, "", "", "");
networkRequest.type = WebInspector.resourceTypes.WebSocket;
this._startNetworkRequest(networkRequest);
},
@@ -409,6 +413,11 @@ WebInspector.NetworkDispatcher.prototype = {
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
+ networkRequest.responseHeadersText = response.headersText;
+ if (response.requestHeaders)
+ networkRequest.setRequestHeaders(this._headersMapToHeadersArray(response.requestHeaders));
+ if (response.requestHeadersText)
+ networkRequest.setRequestHeadersText(response.requestHeadersText);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
@@ -474,7 +483,7 @@ WebInspector.NetworkDispatcher.prototype = {
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
- this._finishNetworkRequest(networkRequest, time);
+ this._finishNetworkRequest(networkRequest, time, -1);
},
/**
@@ -491,7 +500,7 @@ WebInspector.NetworkDispatcher.prototype = {
delete originalNetworkRequest.redirects;
if (previousRedirects.length > 0)
originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
- this._finishNetworkRequest(originalNetworkRequest, time);
+ this._finishNetworkRequest(originalNetworkRequest, time, -1);
var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
@@ -519,11 +528,14 @@ WebInspector.NetworkDispatcher.prototype = {
/**
* @param {!WebInspector.NetworkRequest} networkRequest
* @param {!NetworkAgent.Timestamp} finishTime
+ * @param {number} encodedDataLength
*/
- _finishNetworkRequest: function(networkRequest, finishTime)
+ _finishNetworkRequest: function(networkRequest, finishTime, encodedDataLength)
{
networkRequest.endTime = finishTime;
networkRequest.finished = true;
+ if (encodedDataLength >= 0)
+ networkRequest.setTransferSize(encodedDataLength);
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
delete this._inflightRequestsById[networkRequest.requestId];
delete this._inflightRequestsByURL[networkRequest.url];
@@ -548,7 +560,7 @@ WebInspector.NetworkDispatcher.prototype = {
*/
_createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
{
- var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
+ var networkRequest = new WebInspector.NetworkRequest(this._manager._target, requestId, url, documentURL, frameId, loaderId);
networkRequest.initiator = initiator;
return networkRequest;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkRequest.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
index 3e120d79549..9275fd4c51c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkRequest.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
@@ -30,16 +30,19 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
* @implements {WebInspector.ContentProvider}
* @param {!NetworkAgent.RequestId} requestId
+ * @param {!WebInspector.Target} target
* @param {string} url
* @param {string} documentURL
* @param {!PageAgent.FrameId} frameId
* @param {!NetworkAgent.LoaderId} loaderId
*/
-WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId)
+WebInspector.NetworkRequest = function(target, requestId, url, documentURL, frameId, loaderId)
{
+ WebInspector.TargetAwareObject.call(this, target);
+
this._requestId = requestId;
this.url = url;
this._documentURL = documentURL;
@@ -59,11 +62,14 @@ WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loa
this._frames = [];
this._responseHeaderValues = {};
+
+ this._remoteAddress = "";
}
WebInspector.NetworkRequest.Events = {
FinishedLoading: "FinishedLoading",
TimingChanged: "TimingChanged",
+ RemoteAddressChanged: "RemoteAddressChanged",
RequestHeadersChanged: "RequestHeadersChanged",
ResponseHeadersChanged: "ResponseHeadersChanged",
}
@@ -144,6 +150,26 @@ WebInspector.NetworkRequest.prototype = {
},
/**
+ * @param {string} ip
+ * @param {number} port
+ */
+ setRemoteAddress: function(ip, port)
+ {
+ if (ip.indexOf(":") !== -1)
+ ip = "[" + ip + "]";
+ this._remoteAddress = ip + ":" + port;
+ this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RemoteAddressChanged, this);
+ },
+
+ /**
+ * @return {string}
+ */
+ remoteAddress: function()
+ {
+ return this._remoteAddress;
+ },
+
+ /**
* @return {number}
*/
get startTime()
@@ -188,6 +214,7 @@ WebInspector.NetworkRequest.prototype = {
if (this._responseReceivedTime > x)
this._responseReceivedTime = x;
}
+ this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
},
/**
@@ -228,24 +255,7 @@ WebInspector.NetworkRequest.prototype = {
*/
get transferSize()
{
- if (typeof this._transferSize === "number")
- return this._transferSize;
- if (this.statusCode === 304) // Not modified
- return this.responseHeadersSize;
- if (this._cached)
- return 0;
- // If we did not receive actual transfer size from network
- // stack, we prefer using Content-Length over resourceSize as
- // resourceSize may differ from actual transfer size if platform's
- // network stack performed decoding (e.g. gzip decompression).
- // The Content-Length, though, is expected to come from raw
- // response headers and will reflect actual transfer length.
- // This won't work for chunked content encoding, so fall back to
- // resourceSize when we don't have Content-Length. This still won't
- // work for chunks with non-trivial encodings. We need a way to
- // get actual transfer size from the network stack.
- var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
- return this.responseHeadersSize + bodySize;
+ return this._transferSize || 0;
},
/**
@@ -257,6 +267,14 @@ WebInspector.NetworkRequest.prototype = {
},
/**
+ * @param {number} x
+ */
+ setTransferSize: function(x)
+ {
+ this._transferSize = x;
+ },
+
+ /**
* @return {boolean}
*/
get finished()
@@ -361,6 +379,9 @@ WebInspector.NetworkRequest.prototype = {
return this._parsedURL.displayName;
},
+ /**
+ * @return {string}
+ */
name: function()
{
if (this._name)
@@ -369,6 +390,9 @@ WebInspector.NetworkRequest.prototype = {
return this._name;
},
+ /**
+ * @return {string}
+ */
path: function()
{
if (this._path)
@@ -387,7 +411,7 @@ WebInspector.NetworkRequest.prototype = {
this._path = "";
} else {
this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;
- this._path = this._path.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
+ this._path = this._path.trimURL(this.target().resourceTreeModel.inspectedPageDomain());
if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams)
this._name = this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? "?" + this._parsedURL.queryParams : "");
else if (this._parsedURL.folderPathComponents) {
@@ -534,8 +558,10 @@ WebInspector.NetworkRequest.prototype = {
requestHttpVersion: function()
{
var headersText = this.requestHeadersText();
- if (!headersText)
- return undefined;
+ if (!headersText) {
+ // SPDY header.
+ return this.requestHeaderValue(":version");
+ }
var firstLine = headersText.split(/\r\n/)[0];
var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
return match ? match[1] : undefined;
@@ -564,11 +590,6 @@ WebInspector.NetworkRequest.prototype = {
*/
get responseHeadersText()
{
- if (typeof this._responseHeadersText === "undefined") {
- this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
- for (var i = 0; i < this.responseHeaders.length; ++i)
- this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
- }
return this._responseHeadersText;
},
@@ -580,14 +601,6 @@ WebInspector.NetworkRequest.prototype = {
},
/**
- * @return {number}
- */
- get responseHeadersSize()
- {
- return this.responseHeadersText.length;
- },
-
- /**
* @return {!Array.<!WebInspector.NetworkRequest.NameValue>}
*/
get sortedResponseHeaders()
@@ -680,7 +693,12 @@ WebInspector.NetworkRequest.prototype = {
*/
get responseHttpVersion()
{
- var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/);
+ var headersText = this._responseHeadersText;
+ if (!headersText) {
+ // SPDY header.
+ return this.responseHeaderValue(":version");
+ }
+ var match = headersText.match(/^(HTTP\/\d+\.\d+)/);
return match ? match[1] : undefined;
},
@@ -729,6 +747,14 @@ WebInspector.NetworkRequest.prototype = {
},
/**
+ * @return {?Protocol.Error|undefined}
+ */
+ contentError: function()
+ {
+ return this._contentError;
+ },
+
+ /**
* @return {boolean}
*/
get contentEncoded()
@@ -859,6 +885,7 @@ WebInspector.NetworkRequest.prototype = {
function onResourceContent(error, content, contentEncoded)
{
this._content = error ? null : content;
+ this._contentError = error;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
@@ -870,7 +897,7 @@ WebInspector.NetworkRequest.prototype = {
},
/**
- * @return {!{type: !WebInspector.NetworkRequest.InitiatorType, url: string, source: string, lineNumber: number, columnNumber: number}}
+ * @return {!{type: !WebInspector.NetworkRequest.InitiatorType, url: string, lineNumber: number, columnNumber: number}}
*/
initiatorInfo: function()
{
@@ -901,7 +928,7 @@ WebInspector.NetworkRequest.prototype = {
}
}
- this._initiatorInfo = {type: type, url: url, source: WebInspector.displayNameForURL(url), lineNumber: lineNumber, columnNumber: columnNumber};
+ this._initiatorInfo = {type: type, url: url, lineNumber: lineNumber, columnNumber: columnNumber};
return this._initiatorInfo;
},
@@ -954,5 +981,5 @@ WebInspector.NetworkRequest.prototype = {
this._frames.push(frameOrError);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkUISourceCodeProvider.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkUISourceCodeProvider.js
new file mode 100644
index 00000000000..851cca6f04a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkUISourceCodeProvider.js
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @implements {WebInspector.TargetManager.Observer}
+ * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
+ * @param {!WebInspector.Workspace} workspace
+ */
+WebInspector.NetworkUISourceCodeProvider = function(networkWorkspaceBinding, workspace)
+{
+ this._networkWorkspaceBinding = networkWorkspaceBinding;
+ this._workspace = workspace;
+ WebInspector.targetManager.observeTargets(this);
+ this._processedURLs = {};
+}
+
+WebInspector.NetworkUISourceCodeProvider.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
+ target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ target.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ // FIXME: add workspace cleanup here.
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
+ target.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ target.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
+ },
+
+ _populate: function()
+ {
+ /**
+ * @param {!WebInspector.ResourceTreeFrame} frame
+ * @this {WebInspector.NetworkUISourceCodeProvider}
+ */
+ function populateFrame(frame)
+ {
+ for (var i = 0; i < frame.childFrames.length; ++i)
+ populateFrame.call(this, frame.childFrames[i]);
+
+ var resources = frame.resources();
+ for (var i = 0; i < resources.length; ++i)
+ this._resourceAdded({data:resources[i]});
+ }
+
+ populateFrame.call(this, WebInspector.resourceTreeModel.mainFrame);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _parsedScriptSource: function(event)
+ {
+ var script = /** @type {!WebInspector.Script} */ (event.data);
+ if (!script.sourceURL || script.isInlineScript() || script.isSnippet())
+ return;
+ // Filter out embedder injected content scripts.
+ if (script.isContentScript() && !script.hasSourceURL) {
+ var parsedURL = new WebInspector.ParsedURL(script.sourceURL);
+ if (!parsedURL.isValid)
+ return;
+ }
+ this._addFile(script.sourceURL, script, script.isContentScript());
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _styleSheetAdded: function(event)
+ {
+ var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
+ if ((!header.hasSourceURL || header.isInline) && header.origin !== "inspector")
+ return;
+
+ this._addFile(header.resourceURL(), header, false);
+ },
+
+ /**
+ * @param {!WebInspector.Event|!{data: !WebInspector.Resource}} event
+ */
+ _resourceAdded: function(event)
+ {
+ var resource = /** @type {!WebInspector.Resource} */ (event.data);
+ this._addFile(resource.url, new WebInspector.NetworkUISourceCodeProvider.FallbackResource(resource));
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _mainFrameNavigated: function(event)
+ {
+ this._reset();
+ },
+
+ /**
+ * @param {string} url
+ * @param {!WebInspector.ContentProvider} contentProvider
+ * @param {boolean=} isContentScript
+ */
+ _addFile: function(url, contentProvider, isContentScript)
+ {
+ if (this._workspace.hasMappingForURL(url))
+ return;
+
+ var type = contentProvider.contentType();
+ if (type !== WebInspector.resourceTypes.Stylesheet && type !== WebInspector.resourceTypes.Document && type !== WebInspector.resourceTypes.Script)
+ return;
+ if (this._processedURLs[url])
+ return;
+ this._processedURLs[url] = true;
+ this._networkWorkspaceBinding.addFileForURL(url, contentProvider, isContentScript);
+ },
+
+ _reset: function()
+ {
+ this._processedURLs = {};
+ this._networkWorkspaceBinding.reset();
+ this._populate();
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ContentProvider}
+ * @param {!WebInspector.Resource} resource
+ */
+WebInspector.NetworkUISourceCodeProvider.FallbackResource = function(resource)
+{
+ this._resource = resource;
+}
+
+WebInspector.NetworkUISourceCodeProvider.FallbackResource.prototype = {
+
+ /**
+ * @return {string}
+ */
+ contentURL: function()
+ {
+ return this._resource.contentURL();
+ },
+
+ /**
+ * @return {!WebInspector.ResourceType}
+ */
+ contentType: function()
+ {
+ return this._resource.contentType();
+ },
+
+ /**
+ * @param {function(?string)} callback
+ */
+ requestContent: function(callback)
+ {
+ /**
+ * @this {WebInspector.NetworkUISourceCodeProvider.FallbackResource}
+ */
+ function loadFallbackContent()
+ {
+ var scripts = WebInspector.debuggerModel.scriptsForSourceURL(this._resource.url);
+ if (!scripts.length) {
+ callback(null);
+ return;
+ }
+
+ var contentProvider;
+ if (this._resource.type === WebInspector.resourceTypes.Document)
+ contentProvider = new WebInspector.ConcatenatedScriptsContentProvider(scripts);
+ else if (this._resource.type === WebInspector.resourceTypes.Script)
+ contentProvider = scripts[0];
+
+ console.assert(contentProvider, "Resource content request failed. " + this._resource.url);
+
+ contentProvider.requestContent(callback);
+ }
+
+ /**
+ * @param {?string} content
+ * @this {WebInspector.NetworkUISourceCodeProvider.FallbackResource}
+ */
+ function requestContentLoaded(content)
+ {
+ if (content)
+ callback(content)
+ else
+ loadFallbackContent.call(this);
+ }
+
+ this._resource.requestContent(requestContentLoaded.bind(this));
+ },
+
+ /**
+ * @param {string} query
+ * @param {boolean} caseSensitive
+ * @param {boolean} isRegex
+ * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
+ */
+ searchInContent: function(query, caseSensitive, isRegex, callback)
+ {
+ /**
+ * @param {?string} content
+ */
+ function documentContentLoaded(content)
+ {
+ if (content === null) {
+ callback([]);
+ return;
+ }
+
+ var result = WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
+ callback(result);
+ }
+
+ if (this.contentType() === WebInspector.resourceTypes.Document) {
+ this.requestContent(documentContentLoaded);
+ return;
+ }
+
+ this._resource.searchInContent(query, caseSensitive, isRegex, callback);
+ }
+}
+
+/**
+ * @type {!WebInspector.NetworkWorkspaceBinding}
+ */
+WebInspector.networkWorkspaceBinding;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SimpleWorkspaceProvider.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkWorkspaceBinding.js
index 6b06d9c2479..eda7781e696 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SimpleWorkspaceProvider.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NetworkWorkspaceBinding.js
@@ -31,29 +31,26 @@
/**
* @constructor
* @extends {WebInspector.ContentProviderBasedProjectDelegate}
- * @param {string} name
- * @param {string} type
+ * @param {!WebInspector.Workspace} workspace
+ * @param {string} projectId
+ * @param {string} projectName
+ * @param {!WebInspector.projectTypes} projectType
*/
-WebInspector.SimpleProjectDelegate = function(name, type)
+WebInspector.NetworkProjectDelegate = function(workspace, projectId, projectName, projectType)
{
- WebInspector.ContentProviderBasedProjectDelegate.call(this, type);
- this._name = name;
+ this._name = projectName;
+ this._id = projectId;
+ WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, projectId, projectType);
this._lastUniqueSuffix = 0;
}
-WebInspector.SimpleProjectDelegate.projectId = function(name, type)
-{
- var typePrefix = type !== WebInspector.projectTypes.Network ? (type + ":") : "";
- return typePrefix + name;
-}
-
-WebInspector.SimpleProjectDelegate.prototype = {
+WebInspector.NetworkProjectDelegate.prototype = {
/**
* @return {string}
*/
id: function()
{
- return WebInspector.SimpleProjectDelegate.projectId(this._name, this.type());
+ return this._id;
},
/**
@@ -64,7 +61,7 @@ WebInspector.SimpleProjectDelegate.prototype = {
if (typeof this._displayName !== "undefined")
return this._displayName;
if (!this._name) {
- this._displayName = this.type() !== WebInspector.projectTypes.Snippets ? WebInspector.UIString("(no domain)") : "";
+ this._displayName = WebInspector.UIString("(no domain)");
return this._displayName;
}
var parsedURL = new WebInspector.ParsedURL(this._name);
@@ -83,33 +80,11 @@ WebInspector.SimpleProjectDelegate.prototype = {
* @param {string} name
* @param {string} url
* @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean} isEditable
- * @param {boolean=} isContentScript
* @return {string}
*/
- addFile: function(parentPath, name, forceUniquePath, url, contentProvider, isEditable, isContentScript)
+ addFile: function(parentPath, name, url, contentProvider)
{
- if (forceUniquePath)
- name = this._ensureUniqueName(parentPath, name);
- return this.addContentProvider(parentPath, name, url, contentProvider, isEditable, isContentScript);
- },
-
- /**
- * @param {string} parentPath
- * @param {string} name
- * @return {string}
- */
- _ensureUniqueName: function(parentPath, name)
- {
- var path = parentPath ? parentPath + "/" + name : name;
- var uniquePath = path;
- var suffix = "";
- var contentProviders = this.contentProviders();
- while (contentProviders[uniquePath]) {
- suffix = " (" + (++this._lastUniqueSuffix) + ")";
- uniquePath = path + suffix;
- }
- return name + suffix;
+ return this.addContentProvider(parentPath, name, url, contentProvider);
},
__proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
@@ -119,70 +94,45 @@ WebInspector.SimpleProjectDelegate.prototype = {
* @constructor
* @extends {WebInspector.Object}
* @param {!WebInspector.Workspace} workspace
- * @param {string} type
*/
-WebInspector.SimpleWorkspaceProvider = function(workspace, type)
+WebInspector.NetworkWorkspaceBinding = function(workspace)
{
this._workspace = workspace;
- this._type = type;
- this._simpleProjectDelegates = {};
+ this._projectDelegates = {};
}
-WebInspector.SimpleWorkspaceProvider.prototype = {
+WebInspector.NetworkWorkspaceBinding.prototype = {
/**
* @param {string} projectName
- * @return {!WebInspector.SimpleProjectDelegate}
- */
- _projectDelegate: function(projectName)
- {
- if (this._simpleProjectDelegates[projectName])
- return this._simpleProjectDelegates[projectName];
- var simpleProjectDelegate = new WebInspector.SimpleProjectDelegate(projectName, this._type);
- this._simpleProjectDelegates[projectName] = simpleProjectDelegate;
- this._workspace.addProject(simpleProjectDelegate);
- return simpleProjectDelegate;
- },
-
- /**
- * @param {string} url
- * @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean} isEditable
- * @param {boolean=} isContentScript
- * @return {!WebInspector.UISourceCode}
+ * @param {boolean} isContentScripts
+ * @return {!WebInspector.NetworkProjectDelegate}
*/
- addFileForURL: function(url, contentProvider, isEditable, isContentScript)
+ _projectDelegate: function(projectName, isContentScripts)
{
- return this._innerAddFileForURL(url, contentProvider, isEditable, false, isContentScript);
- },
+ var projectId = (isContentScripts ? "contentscripts:" : "") + projectName;
+ var projectType = isContentScripts ? WebInspector.projectTypes.ContentScripts : WebInspector.projectTypes.Network;
- /**
- * @param {string} url
- * @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean} isEditable
- * @param {boolean=} isContentScript
- * @return {!WebInspector.UISourceCode}
- */
- addUniqueFileForURL: function(url, contentProvider, isEditable, isContentScript)
- {
- return this._innerAddFileForURL(url, contentProvider, isEditable, true, isContentScript);
+ if (this._projectDelegates[projectId])
+ return this._projectDelegates[projectId];
+ var projectDelegate = new WebInspector.NetworkProjectDelegate(this._workspace, projectId, projectName, projectType);
+ this._projectDelegates[projectId] = projectDelegate;
+ return projectDelegate;
},
/**
* @param {string} url
* @param {!WebInspector.ContentProvider} contentProvider
- * @param {boolean} isEditable
- * @param {boolean} forceUnique
* @param {boolean=} isContentScript
* @return {!WebInspector.UISourceCode}
*/
- _innerAddFileForURL: function(url, contentProvider, isEditable, forceUnique, isContentScript)
+ addFileForURL: function(url, contentProvider, isContentScript)
{
var splitURL = WebInspector.ParsedURL.splitURL(url);
var projectName = splitURL[0];
var parentPath = splitURL.slice(1, splitURL.length - 1).join("/");
var name = splitURL[splitURL.length - 1];
- var projectDelegate = this._projectDelegate(projectName);
- var path = projectDelegate.addFile(parentPath, name, forceUnique, url, contentProvider, isEditable, isContentScript);
+ var projectDelegate = this._projectDelegate(projectName, isContentScript || false);
+ var path = projectDelegate.addFile(parentPath, name, url, contentProvider);
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (this._workspace.uiSourceCode(projectDelegate.id(), path));
console.assert(uiSourceCode);
return uiSourceCode;
@@ -190,10 +140,10 @@ WebInspector.SimpleWorkspaceProvider.prototype = {
reset: function()
{
- for (var projectName in this._simpleProjectDelegates)
- this._simpleProjectDelegates[projectName].reset();
- this._simpleProjectDelegates = {};
+ for (var projectId in this._projectDelegates)
+ this._projectDelegates[projectId].reset();
+ this._projectDelegates = {};
},
-
+
__proto__: WebInspector.Object.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NotificationService.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NotificationService.js
new file mode 100644
index 00000000000..197101e67c6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/NotificationService.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.NotificationService = function() { }
+
+WebInspector.NotificationService.prototype = {
+ __proto__: WebInspector.Object.prototype
+}
+
+WebInspector.NotificationService.Events = {
+ InspectorLoaded: "InspectorLoaded",
+ SelectedNodeChanged: "SelectedNodeChanged"
+}
+
+WebInspector.notifications = new WebInspector.NotificationService();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/OverridesSupport.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/OverridesSupport.js
new file mode 100644
index 00000000000..72d503204b5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/OverridesSupport.js
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @implements {WebInspector.TargetManager.Observer}
+ * @extends {WebInspector.Object}
+ * @param {boolean} responsiveDesignAvailable
+ */
+WebInspector.OverridesSupport = function(responsiveDesignAvailable)
+{
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated.bind(this), this);
+ this._emulateViewportEnabled = false;
+ this._userAgent = "";
+ this._pageResizer = null;
+ this._initialized = false;
+ this._deviceMetricsThrottler = new WebInspector.Throttler(0);
+ this._responsiveDesignAvailable = responsiveDesignAvailable;
+ WebInspector.targetManager.observeTargets(this);
+}
+
+WebInspector.OverridesSupport.Events = {
+ OverridesWarningUpdated: "OverridesWarningUpdated",
+ EmulationStateChanged: "EmulationStateChanged"
+}
+
+/**
+ * @interface
+ * @extends {WebInspector.EventTarget}
+ */
+WebInspector.OverridesSupport.PageResizer = function()
+{
+};
+
+WebInspector.OverridesSupport.PageResizer.Events = {
+ AvailableSizeChanged: "AvailableSizeChanged", // No data.
+ ResizeRequested: "ResizeRequested" // Data is of type {!Size}.
+};
+
+WebInspector.OverridesSupport.PageResizer.prototype = {
+ /**
+ * Zero width and height mean default size.
+ * Scale should be applied to page-scale-dependent UI bits. Zero means no scale.
+ * @param {number} dipWidth
+ * @param {number} dipHeight
+ * @param {number} scale
+ */
+ update: function(dipWidth, dipHeight, scale) { }
+};
+
+/**
+ * @param {string} description
+ * @param {string} userAgent
+ * @constructor
+ */
+WebInspector.OverridesSupport.Device = function(description, userAgent)
+{
+ this.width = 800;
+ this.height = 600;
+ this.deviceScaleFactor = 1;
+ this.textAutosizing = true;
+ this.userAgent = userAgent;
+ this.touch = true;
+ this.viewport = true;
+
+ var splitMetrics = description.split("x");
+ if (splitMetrics.length >= 3) {
+ this.width = parseInt(splitMetrics[0], 10);
+ this.height = parseInt(splitMetrics[1], 10);
+ this.deviceScaleFactor = parseFloat(splitMetrics[2]);
+ }
+ if (splitMetrics.length >= 4)
+ this.touch = splitMetrics[3] == 1;
+ if (splitMetrics.length >= 5)
+ this.viewport = splitMetrics[4] == 1;
+}
+
+/**
+ * @constructor
+ * @param {number} latitude
+ * @param {number} longitude
+ * @param {string} error
+ */
+WebInspector.OverridesSupport.GeolocationPosition = function(latitude, longitude, error)
+{
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.error = error;
+}
+
+WebInspector.OverridesSupport.GeolocationPosition.prototype = {
+ /**
+ * @return {string}
+ */
+ toSetting: function()
+ {
+ return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
+ }
+}
+
+/**
+ * @return {!WebInspector.OverridesSupport.GeolocationPosition}
+ */
+WebInspector.OverridesSupport.GeolocationPosition.parseSetting = function(value)
+{
+ if (value) {
+ var splitError = value.split(":");
+ if (splitError.length === 2) {
+ var splitPosition = splitError[0].split("@")
+ if (splitPosition.length === 2)
+ return new WebInspector.OverridesSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
+ }
+ }
+ return new WebInspector.OverridesSupport.GeolocationPosition(0, 0, "");
+}
+
+/**
+ * @return {?WebInspector.OverridesSupport.GeolocationPosition}
+ */
+WebInspector.OverridesSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
+{
+ function isUserInputValid(value)
+ {
+ if (!value)
+ return true;
+ return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
+ }
+
+ if (!latitudeString ^ !latitudeString)
+ return null;
+
+ var isLatitudeValid = isUserInputValid(latitudeString);
+ var isLongitudeValid = isUserInputValid(longitudeString);
+
+ if (!isLatitudeValid && !isLongitudeValid)
+ return null;
+
+ var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
+ var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
+
+ return new WebInspector.OverridesSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
+}
+
+WebInspector.OverridesSupport.GeolocationPosition.clearGeolocationOverride = function()
+{
+ GeolocationAgent.clearGeolocationOverride();
+}
+
+/**
+ * @constructor
+ * @param {number} alpha
+ * @param {number} beta
+ * @param {number} gamma
+ */
+WebInspector.OverridesSupport.DeviceOrientation = function(alpha, beta, gamma)
+{
+ this.alpha = alpha;
+ this.beta = beta;
+ this.gamma = gamma;
+}
+
+WebInspector.OverridesSupport.DeviceOrientation.prototype = {
+ /**
+ * @return {string}
+ */
+ toSetting: function()
+ {
+ return JSON.stringify(this);
+ }
+}
+
+/**
+ * @return {!WebInspector.OverridesSupport.DeviceOrientation}
+ */
+WebInspector.OverridesSupport.DeviceOrientation.parseSetting = function(value)
+{
+ if (value) {
+ var jsonObject = JSON.parse(value);
+ return new WebInspector.OverridesSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
+ }
+ return new WebInspector.OverridesSupport.DeviceOrientation(0, 0, 0);
+}
+
+/**
+ * @return {?WebInspector.OverridesSupport.DeviceOrientation}
+ */
+WebInspector.OverridesSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
+{
+ function isUserInputValid(value)
+ {
+ if (!value)
+ return true;
+ return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
+ }
+
+ if (!alphaString ^ !betaString ^ !gammaString)
+ return null;
+
+ var isAlphaValid = isUserInputValid(alphaString);
+ var isBetaValid = isUserInputValid(betaString);
+ var isGammaValid = isUserInputValid(gammaString);
+
+ if (!isAlphaValid && !isBetaValid && !isGammaValid)
+ return null;
+
+ var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
+ var beta = isBetaValid ? parseFloat(betaString) : -1;
+ var gamma = isGammaValid ? parseFloat(gammaString) : -1;
+
+ return new WebInspector.OverridesSupport.DeviceOrientation(alpha, beta, gamma);
+}
+
+WebInspector.OverridesSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
+{
+ PageAgent.clearDeviceOrientationOverride();
+}
+
+/**
+ * @param {string} value
+ * @return {string}
+ */
+WebInspector.OverridesSupport.deviceSizeValidator = function(value)
+{
+ if (!value || (/^[\d]+$/.test(value) && value >= 0 && value <= 10000))
+ return "";
+ return WebInspector.UIString("Value must be non-negative integer");
+}
+
+/**
+ * @param {string} value
+ * @return {string}
+ */
+WebInspector.OverridesSupport.deviceScaleFactorValidator = function(value)
+{
+ if (!value || (/^[\d]+(\.\d+)?|\.\d+$/.test(value) && value >= 0 && value <= 10))
+ return "";
+ return WebInspector.UIString("Value must be non-negative float");
+}
+
+// Second element is user agent value.
+// Third element lists device metrics separated by 'x':
+// - screen width,
+// - screen height,
+// - device scale factor,
+// - touch (true by default if not present),
+// - viewport (true by default if not present).
+WebInspector.OverridesSupport._phones = [
+ ["Apple iPhone 3GS",
+ "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
+ "320x480x1"],
+ ["Apple iPhone 4",
+ "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
+ "320x480x2"],
+ ["Apple iPhone 5",
+ "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
+ "320x568x2"],
+ ["BlackBerry Z10",
+ "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
+ "384x640x2"],
+ ["BlackBerry Z30",
+ "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+",
+ "360x640x2"],
+ ["Google Nexus 4",
+ "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
+ "384x640x2"],
+ ["Google Nexus 5",
+ "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
+ "360x640x3"],
+ ["Google Nexus S",
+ "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "320x533x1.5"],
+ ["HTC Evo, Touch HD, Desire HD, Desire",
+ "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "320x533x1.5"],
+ ["HTC One X, EVO LTE",
+ "Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19",
+ "360x640x2"],
+ ["HTC Sensation, Evo 3D",
+ "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "360x640x1.5"],
+ ["LG Optimus 2X, Optimus 3D, Optimus Black",
+ "Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2",
+ "320x533x1.5"],
+ ["LG Optimus G",
+ "Mozilla/5.0 (Linux; Android 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
+ "384x640x2"],
+ ["LG Optimus LTE, Optimus 4X HD",
+ "Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "424x753x1.7"],
+ ["LG Optimus One",
+ "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "213x320x1.5"],
+ ["Motorola Defy, Droid, Droid X, Milestone",
+ "Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
+ "320x569x1.5"],
+ ["Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2",
+ "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "540x960x1"],
+ ["Motorola Droid Razr HD",
+ "Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "720x1280x1"],
+ ["Nokia C5, C6, C7, N97, N8, X7",
+ "NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) BrowserNG/7.1.4",
+ "360x640x1"],
+ ["Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900",
+ "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)",
+ "320x533x1.5"],
+ ["Samsung Galaxy Note 3",
+ "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "540x960x2"],
+ ["Samsung Galaxy Note II",
+ "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "360x640x2"],
+ ["Samsung Galaxy Note",
+ "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "400x640x2"],
+ ["Samsung Galaxy S III, Galaxy Nexus",
+ "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "360x640x2"],
+ ["Samsung Galaxy S, S II, W",
+ "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
+ "320x533x1.5"],
+ ["Samsung Galaxy S4",
+ "Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36",
+ "360x640x3"],
+ ["Sony Xperia S, Ion",
+ "Mozilla/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "360x640x2"],
+ ["Sony Xperia Sola, U",
+ "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "480x854x1"],
+ ["Sony Xperia Z, Z1",
+ "Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
+ "360x640x3"],
+];
+
+WebInspector.OverridesSupport._tablets = [
+ ["Amazon Kindle Fire HDX 7\u2033",
+ "Mozilla/5.0 (Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
+ "1920x1200x2"],
+ ["Amazon Kindle Fire HDX 8.9\u2033",
+ "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
+ "2560x1600x2"],
+ ["Amazon Kindle Fire (First Generation)",
+ "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.0.141.16-Gen4_11004310) AppleWebkit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true",
+ "1024x600x1"],
+ ["Apple iPad 1 / 2 / iPad Mini",
+ "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5",
+ "1024x768x1"],
+ ["Apple iPad 3 / 4",
+ "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53",
+ "1024x768x2"],
+ ["BlackBerry PlayBook",
+ "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+",
+ "1024x600x1"],
+ ["Google Nexus 10",
+ "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
+ "1280x800x2"],
+ ["Google Nexus 7 2",
+ "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
+ "960x600x2"],
+ ["Google Nexus 7",
+ "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36",
+ "966x604x1.325"],
+ ["Motorola Xoom, Xyboard",
+ "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
+ "1280x800x1"],
+ ["Samsung Galaxy Tab 7.7, 8.9, 10.1",
+ "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "1280x800x1"],
+ ["Samsung Galaxy Tab",
+ "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
+ "1024x600x1"],
+];
+
+WebInspector.OverridesSupport._notebooks = [
+ ["Notebook with touch",
+ "",
+ "1280x950x1x1x0"],
+ ["Notebook with HiDPI screen",
+ "",
+ "1440x900x2x0x0"],
+ ["Generic notebook",
+ "",
+ "1280x800x1x0x0"],
+];
+
+WebInspector.OverridesSupport._networkThroughputUnlimitedValue = -1;
+WebInspector.OverridesSupport._networkThroughputPresets = [
+ ["Offline", 0],
+ ["5 Kbps", 5 * 1024 / 8],
+ ["10 Kbps (GSM)", 10 * 1024 / 8],
+ ["20 Kbps", 20 * 1024 / 8],
+ ["40 Kbps (GPRS)", 40 * 1024 / 8],
+ ["80 Kbps", 80 * 1024 / 8],
+ ["160 Kbps (EDGE)", 160 * 1024 / 8],
+ ["320 Kbps", 320 * 1024 / 8],
+ ["640 Kbps (3G)", 640 * 1024 / 8],
+ ["1 Mbps", 1024 * 1024 / 8],
+ ["2 Mbps (802.11b)", 2048 * 1024 / 8],
+ ["No throttling", WebInspector.OverridesSupport._networkThroughputUnlimitedValue]
+];
+
+WebInspector.OverridesSupport.prototype = {
+ /**
+ * @return {boolean}
+ */
+ canEmulate: function()
+ {
+ return !!this._target && !this._target.isMobile();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ emulationEnabled: function()
+ {
+ return this.canEmulate() && this.settings._emulationEnabled.get();
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEmulationEnabled: function(enabled)
+ {
+ if (this.canEmulate()) {
+ this.settings._emulationEnabled.set(enabled);
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.EmulationStateChanged);
+ }
+ },
+
+ /**
+ * @return {boolean}
+ */
+ responsiveDesignAvailable: function()
+ {
+ return this._responsiveDesignAvailable;
+ },
+
+ /**
+ * @param {?WebInspector.OverridesSupport.PageResizer} pageResizer
+ * @param {!Size} availableSize
+ */
+ setPageResizer: function(pageResizer, availableSize)
+ {
+ if (pageResizer === this._pageResizer)
+ return;
+
+ if (this._pageResizer) {
+ this._pageResizer.removeEventListener(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, this._onPageResizerAvailableSizeChanged, this);
+ this._pageResizer.removeEventListener(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, this._onPageResizerResizeRequested, this);
+ }
+ this._pageResizer = pageResizer;
+ this._pageResizerAvailableSize = availableSize;
+ if (this._pageResizer) {
+ this._pageResizer.addEventListener(WebInspector.OverridesSupport.PageResizer.Events.AvailableSizeChanged, this._onPageResizerAvailableSizeChanged, this);
+ this._pageResizer.addEventListener(WebInspector.OverridesSupport.PageResizer.Events.ResizeRequested, this._onPageResizerResizeRequested, this);
+ }
+ if (this._initialized)
+ this._deviceMetricsChanged();
+ },
+
+ /**
+ * @param {!WebInspector.OverridesSupport.Device} device
+ */
+ emulateDevice: function(device)
+ {
+ this._deviceMetricsChangedListenerMuted = true;
+ this._userAgentChangedListenerMuted = true;
+ this.settings.userAgent.set(device.userAgent);
+ this.settings.deviceWidth.set(device.width);
+ this.settings.deviceHeight.set(device.height);
+ this.settings.deviceScaleFactor.set(device.deviceScaleFactor);
+ this.settings.deviceTextAutosizing.set(device.textAutosizing);
+ this.settings.emulateTouch.set(device.touch);
+ this.settings.emulateViewport.set(device.viewport);
+ delete this._deviceMetricsChangedListenerMuted;
+ delete this._userAgentChangedListenerMuted;
+
+ if (this._initialized) {
+ this._deviceMetricsChanged();
+ this._userAgentChanged();
+ }
+ },
+
+ reset: function()
+ {
+ this._deviceMetricsChangedListenerMuted = true;
+ this._userAgentChangedListenerMuted = true;
+ this.settings.userAgent.set("");
+ this.settings.deviceWidth.set(0);
+ this.settings.deviceHeight.set(0);
+ this.settings.deviceScaleFactor.set(0);
+ this.settings.deviceTextAutosizing.set(false);
+ this.settings.emulateTouch.set(false);
+ this.settings.emulateViewport.set(false);
+ this.settings.overrideDeviceOrientation.set(false);
+ this.settings.overrideGeolocation.set(false);
+ this.settings.overrideCSSMedia.set(false);
+ this.settings.networkConditionsThroughput.set(WebInspector.OverridesSupport._networkThroughputUnlimitedValue);
+ delete this._deviceMetricsChangedListenerMuted;
+ delete this._userAgentChangedListenerMuted;
+
+ if (this._initialized) {
+ this._deviceMetricsChanged();
+ this._userAgentChanged();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.OverridesSupport.Device} device
+ * @return {boolean}
+ */
+ isEmulatingDevice: function(device)
+ {
+ return this.settings.userAgent.get() === device.userAgent
+ && this.settings.deviceWidth.get() === device.width
+ && this.settings.deviceHeight.get() === device.height
+ && this.settings.deviceScaleFactor.get() === device.deviceScaleFactor
+ && this.settings.deviceTextAutosizing.get() === device.textAutosizing
+ && this.settings.emulateTouch.get() === device.touch
+ && this.settings.emulateViewport.get() === device.viewport;
+ },
+
+ applyInitialOverrides: function()
+ {
+ if (!this._target) {
+ this._applyInitialOverridesOnTargetAdded = true;
+ return;
+ }
+
+ this._initialized = true;
+
+ this.settings._emulationEnabled.addChangeListener(this._userAgentChanged, this);
+ this.settings.userAgent.addChangeListener(this._userAgentChanged, this);
+
+ this.settings._emulationEnabled.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.deviceWidth.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.deviceHeight.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.deviceScaleFactor.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.deviceTextAutosizing.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.emulateViewport.addChangeListener(this._deviceMetricsChanged, this);
+ this.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
+
+ this.settings._emulationEnabled.addChangeListener(this._geolocationPositionChanged, this);
+ this.settings.overrideGeolocation.addChangeListener(this._geolocationPositionChanged, this);
+ this.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
+
+ this.settings._emulationEnabled.addChangeListener(this._deviceOrientationChanged, this);
+ this.settings.overrideDeviceOrientation.addChangeListener(this._deviceOrientationChanged, this);
+ this.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
+
+ this.settings._emulationEnabled.addChangeListener(this._emulateTouchEventsChanged, this);
+ this.settings.emulateTouch.addChangeListener(this._emulateTouchEventsChanged, this);
+
+ this.settings._emulationEnabled.addChangeListener(this._cssMediaChanged, this);
+ this.settings.overrideCSSMedia.addChangeListener(this._cssMediaChanged, this);
+ this.settings.emulatedCSSMedia.addChangeListener(this._cssMediaChanged, this);
+
+ if (WebInspector.experimentsSettings.networkConditions.isEnabled()) {
+ this.settings._emulationEnabled.addChangeListener(this._networkConditionsChanged, this);
+ this.settings.networkConditionsThroughput.addChangeListener(this._networkConditionsChanged, this);
+ }
+
+ WebInspector.settings.showMetricsRulers.addChangeListener(this._showRulersChanged, this);
+ this._showRulersChanged();
+
+ if (!this.emulationEnabled())
+ return;
+
+ if (this.settings.overrideDeviceOrientation.get())
+ this._deviceOrientationChanged();
+
+ if (this.settings.overrideGeolocation.get())
+ this._geolocationPositionChanged();
+
+ if (this.settings.emulateTouch.get())
+ this._emulateTouchEventsChanged();
+
+ if (this.settings.overrideCSSMedia.get())
+ this._cssMediaChanged();
+
+ this._deviceMetricsChanged();
+
+ this._userAgentChanged();
+
+ if (WebInspector.experimentsSettings.networkConditions.isEnabled() && this.networkThroughputIsLimited())
+ this._networkConditionsChanged();
+ },
+
+ _userAgentChanged: function()
+ {
+ if (this._userAgentChangedListenerMuted)
+ return;
+ var userAgent = this.emulationEnabled() ? this.settings.userAgent.get() : "";
+ NetworkAgent.setUserAgentOverride(userAgent);
+ if (this._userAgent !== userAgent)
+ this._updateUserAgentWarningMessage(WebInspector.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
+ this._userAgent = userAgent;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onPageResizerAvailableSizeChanged: function(event)
+ {
+ this._pageResizerAvailableSize = /** @type {!Size} */ (event.data);
+ if (this._initialized)
+ this._deviceMetricsChanged();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onPageResizerResizeRequested: function(event)
+ {
+ if (typeof event.data.width !== "undefined") {
+ var width = /** @type {number} */ (event.data.width);
+ if (width !== this.settings.deviceWidth.get())
+ this.settings.deviceWidth.set(width);
+ }
+ if (typeof event.data.height !== "undefined") {
+ var height = /** @type {number} */ (event.data.height);
+ if (height !== this.settings.deviceHeight.get())
+ this.settings.deviceHeight.set(height);
+ }
+ },
+
+ _deviceMetricsChanged: function()
+ {
+ this._showRulersChanged();
+
+ if (this._deviceMetricsChangedListenerMuted)
+ return;
+
+ if (!this.emulationEnabled()) {
+ this._deviceMetricsThrottler.schedule(clearDeviceMetricsOverride.bind(this));
+ if (this._pageResizer)
+ this._pageResizer.update(0, 0, 1);
+ return;
+ }
+
+ var dipWidth = this.settings.deviceWidth.get();
+ var dipHeight = this.settings.deviceHeight.get();
+
+ var overrideWidth = dipWidth;
+ var overrideHeight = dipHeight;
+ if (this._pageResizer) {
+ var available = this._pageResizerAvailableSize;
+ if (available.width >= dipWidth && available.height >= dipHeight) {
+ this._pageResizer.update(dipWidth, dipHeight, 0);
+ // When we have enough space, no page size override is required. This will speed things up and remove lag.
+ overrideWidth = 0;
+ overrideHeight = 0;
+ } else {
+ this._pageResizer.update(Math.min(dipWidth, available.width), Math.min(dipHeight, available.height), 0);
+ }
+ }
+
+ this._deviceMetricsThrottler.schedule(setDeviceMetricsOverride.bind(this));
+
+ /**
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
+ * @this {WebInspector.OverridesSupport}
+ */
+ function setDeviceMetricsOverride(finishCallback)
+ {
+ PageAgent.setDeviceMetricsOverride(
+ overrideWidth, overrideHeight, this.settings.deviceScaleFactor.get(),
+ this.settings.emulateViewport.get(), this._pageResizer ? false : this.settings.deviceFitWindow.get(),
+ this.settings.deviceTextAutosizing.get(), this._fontScaleFactor(overrideWidth || dipWidth, overrideHeight || dipHeight),
+ apiCallback.bind(this, finishCallback));
+ }
+
+ /**
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
+ * @this {WebInspector.OverridesSupport}
+ */
+ function clearDeviceMetricsOverride(finishCallback)
+ {
+ PageAgent.clearDeviceMetricsOverride(apiCallback.bind(this, finishCallback));
+ }
+
+ /**
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
+ * @param {?Protocol.Error} error
+ * @this {WebInspector.OverridesSupport}
+ */
+ function apiCallback(finishCallback, error)
+ {
+ if (error) {
+ this._updateDeviceMetricsWarningMessage(WebInspector.UIString("Screen emulation is not available on this page."));
+ this._deviceMetricsOverrideAppliedForTest();
+ finishCallback();
+ return;
+ }
+
+ var viewportEnabled = this.emulationEnabled() && this.settings.emulateViewport.get();
+ if (this._emulateViewportEnabled !== viewportEnabled)
+ this._updateDeviceMetricsWarningMessage(WebInspector.UIString("You might need to reload the page for proper user agent spoofing and viewport rendering."));
+ this._emulateViewportEnabled = viewportEnabled;
+ this._deviceMetricsOverrideAppliedForTest();
+ finishCallback();
+ }
+ },
+
+ _deviceMetricsOverrideAppliedForTest: function()
+ {
+ // Used for sniffing in tests.
+ },
+
+ _geolocationPositionChanged: function()
+ {
+ if (!this.emulationEnabled() || !this.settings.overrideGeolocation.get()) {
+ GeolocationAgent.clearGeolocationOverride();
+ return;
+ }
+ var geolocation = WebInspector.OverridesSupport.GeolocationPosition.parseSetting(this.settings.geolocationOverride.get());
+ if (geolocation.error)
+ GeolocationAgent.setGeolocationOverride();
+ else
+ GeolocationAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
+ },
+
+ _deviceOrientationChanged: function()
+ {
+ if (!this.emulationEnabled() || !this.settings.overrideDeviceOrientation.get()) {
+ PageAgent.clearDeviceOrientationOverride();
+ return;
+ }
+
+ var deviceOrientation = WebInspector.OverridesSupport.DeviceOrientation.parseSetting(this.settings.deviceOrientationOverride.get());
+ PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
+ },
+
+ _emulateTouchEventsChanged: function()
+ {
+ var emulateTouch = this.emulationEnabled() && this.settings.emulateTouch.get();
+ var targets = WebInspector.targetManager.targets();
+ for (var i = 0; i < targets.length; ++i)
+ targets[i].domModel.emulateTouchEventObjects(emulateTouch);
+ },
+
+ _cssMediaChanged: function()
+ {
+ var enabled = this.emulationEnabled() && this.settings.overrideCSSMedia.get();
+ PageAgent.setEmulatedMedia(enabled ? this.settings.emulatedCSSMedia.get() : "");
+ var targets = WebInspector.targetManager.targets();
+ for (var i = 0; i < targets.length; ++i)
+ targets[i].cssModel.mediaQueryResultChanged();
+ },
+
+ _networkConditionsChanged: function()
+ {
+ if (!this.emulationEnabled() || !this.networkThroughputIsLimited()) {
+ NetworkAgent.emulateNetworkConditions(false, 0, 0, 0);
+ } else {
+ var throughput = this.settings.networkConditionsThroughput.get();
+ var offline = !throughput;
+ NetworkAgent.emulateNetworkConditions(offline, 0, throughput, throughput);
+ }
+ },
+
+ /**
+ * @return {boolean}
+ */
+ showMetricsRulers: function()
+ {
+ var rulersInPageResizer = this._pageResizer && this.emulationEnabled();
+ return WebInspector.settings.showMetricsRulers.get() && !rulersInPageResizer;
+ },
+
+ _showRulersChanged: function()
+ {
+ if (WebInspector.experimentsSettings.responsiveDesign.isEnabled())
+ return;
+ PageAgent.setShowViewportSizeOnResize(true, this.showMetricsRulers());
+ },
+
+ _onMainFrameNavigated: function()
+ {
+ if (this._initialized)
+ this._deviceMetricsChanged();
+ this._updateUserAgentWarningMessage("");
+ this._updateDeviceMetricsWarningMessage("");
+ },
+
+ /**
+ * @param {string} warningMessage
+ */
+ _updateDeviceMetricsWarningMessage: function(warningMessage)
+ {
+ this._deviceMetricsWarningMessage = warningMessage;
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.OverridesWarningUpdated);
+ },
+
+ /**
+ * @param {string} warningMessage
+ */
+ _updateUserAgentWarningMessage: function(warningMessage)
+ {
+ this._userAgentWarningMessage = warningMessage;
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.OverridesWarningUpdated);
+ },
+
+ /**
+ * @return {string}
+ */
+ warningMessage: function()
+ {
+ return this._deviceMetricsWarningMessage || this._userAgentWarningMessage || "";
+ },
+
+ clearWarningMessage: function()
+ {
+ this._deviceMetricsWarningMessage = "";
+ this._userAgentWarningMessage = "";
+ this.dispatchEventToListeners(WebInspector.OverridesSupport.Events.OverridesWarningUpdated);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ // FIXME: adapt this to multiple targets.
+ if (this._target)
+ return;
+ this._target = target;
+
+ this.settings = {};
+ this.settings._emulationEnabled = WebInspector.settings.createSetting("emulationEnabled", false);
+
+ this.settings.userAgent = WebInspector.settings.createSetting("userAgent", "");
+
+ this.settings.deviceWidth = WebInspector.settings.createSetting("deviceWidth", 0);
+ this.settings.deviceHeight = WebInspector.settings.createSetting("deviceHeight", 0);
+ this.settings.deviceScaleFactor = WebInspector.settings.createSetting("deviceScaleFactor", 0);
+ this.settings.deviceTextAutosizing = WebInspector.settings.createSetting("deviceTextAutosizing", true);
+ this.settings.deviceFitWindow = WebInspector.settings.createSetting("deviceFitWindow", true);
+ // FIXME: rename viewport to mobile everywhere in the code.
+ this.settings.emulateViewport = WebInspector.settings.createSetting("emulateViewport", false);
+
+ this.settings.emulateTouch = WebInspector.settings.createSetting("emulateTouch", false);
+
+ this.settings.overrideGeolocation = WebInspector.settings.createSetting("overrideGeolocation", false);
+ this.settings.geolocationOverride = WebInspector.settings.createSetting("geolocationOverride", "");
+
+ this.settings.overrideDeviceOrientation = WebInspector.settings.createSetting("overrideDeviceOrientation", false);
+ this.settings.deviceOrientationOverride = WebInspector.settings.createSetting("deviceOrientationOverride", "");
+
+ this.settings.overrideCSSMedia = WebInspector.settings.createSetting("overrideCSSMedia", false);
+ this.settings.emulatedCSSMedia = WebInspector.settings.createSetting("emulatedCSSMedia", "print");
+
+ this.settings.networkConditionsThroughput = WebInspector.settings.createSetting("networkConditionsThroughput", WebInspector.OverridesSupport._networkThroughputUnlimitedValue);
+
+ if (this._applyInitialOverridesOnTargetAdded) {
+ delete this._applyInitialOverridesOnTargetAdded;
+ this.applyInitialOverrides();
+ }
+ },
+
+ swapDimensions: function()
+ {
+ var width = WebInspector.overridesSupport.settings.deviceWidth.get();
+ var height = WebInspector.overridesSupport.settings.deviceHeight.get();
+ WebInspector.overridesSupport.settings.deviceWidth.set(height);
+ WebInspector.overridesSupport.settings.deviceHeight.set(width);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ // FIXME: adapt this to multiple targets.
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasTouchInputs: function()
+ {
+ return !!this._target && this._target.hasTouchInputs;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ networkThroughputIsLimited: function()
+ {
+ return this.settings.networkConditionsThroughput.get() !== WebInspector.OverridesSupport._networkThroughputUnlimitedValue;
+ },
+
+ /**
+ * Compute the font scale factor.
+ *
+ * Chromium on Android uses a device scale adjustment for fonts used in text autosizing for
+ * improved legibility. This function computes this adjusted value for text autosizing.
+ *
+ * For a description of the Android device scale adjustment algorithm, see:
+ * chrome/browser/chrome_content_browser_client.cc, GetFontScaleMultiplier(...)
+ *
+ * @param {number} width
+ * @param {number} height
+ * @return {number} font scale factor.
+ */
+ _fontScaleFactor: function(width, height)
+ {
+ if (!this.emulationEnabled())
+ return 1;
+ var deviceScaleFactor = this.settings.deviceScaleFactor.get();
+
+ if (!width || !height || !deviceScaleFactor)
+ return 1;
+
+ var minWidth = Math.min(width, height) / deviceScaleFactor;
+
+ var kMinFSM = 1.05;
+ var kWidthForMinFSM = 320;
+ var kMaxFSM = 1.3;
+ var kWidthForMaxFSM = 800;
+
+ if (minWidth <= kWidthForMinFSM)
+ return kMinFSM;
+ if (minWidth >= kWidthForMaxFSM)
+ return kMaxFSM;
+
+ // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
+ var ratio = (minWidth - kWidthForMinFSM) / (kWidthForMaxFSM - kWidthForMinFSM);
+ return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
+ },
+
+ /**
+ * @param {!Document} document
+ * @return {!Element}
+ */
+ createDeviceSelect: function(document)
+ {
+ var deviceSelectElement = document.createElement("select");
+
+ var selectDeviceOption = new Option(WebInspector.UIString("<Select model>"), WebInspector.UIString("<Select model>"));
+ selectDeviceOption.device = new WebInspector.OverridesSupport.Device("", "");
+ deviceSelectElement.add(selectDeviceOption);
+
+ addGroup(WebInspector.UIString("Devices"), WebInspector.OverridesSupport._phones.concat(WebInspector.OverridesSupport._tablets));
+ addGroup(WebInspector.UIString("Notebooks"), WebInspector.OverridesSupport._notebooks);
+
+ /**
+ * @param {string} name
+ * @param {!Array.<!Array.<string>>} devices
+ */
+ function addGroup(name, devices)
+ {
+ devices = devices.slice();
+ devices.sort();
+ var groupElement = deviceSelectElement.createChild("optgroup");
+ groupElement.label = name;
+ for (var i = 0; i < devices.length; ++i) {
+ var device = devices[i];
+ var option = new Option(device[0], device[0]);
+ option.device = new WebInspector.OverridesSupport.Device(device[2], device[1]);
+ groupElement.appendChild(option);
+ }
+ }
+
+ deviceSelectElement.addEventListener("change", deviceSelected, false);
+
+ var emulatedSettingChangedMuted = false;
+ WebInspector.overridesSupport.settings.deviceWidth.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.deviceHeight.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.deviceScaleFactor.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.deviceTextAutosizing.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.emulateViewport.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.emulateTouch.addChangeListener(emulatedSettingChanged);
+ WebInspector.overridesSupport.settings.userAgent.addChangeListener(emulatedSettingChanged);
+ emulatedSettingChanged();
+
+ function deviceSelected()
+ {
+ if (deviceSelectElement.selectedIndex === 0)
+ return;
+
+ var option = deviceSelectElement.options[deviceSelectElement.selectedIndex];
+ emulatedSettingChangedMuted = true;
+ WebInspector.overridesSupport.emulateDevice(option.device);
+ emulatedSettingChangedMuted = false;
+ }
+
+ function emulatedSettingChanged()
+ {
+ if (emulatedSettingChangedMuted)
+ return;
+
+ var index = 0;
+ for (var i = 1; i < deviceSelectElement.options.length; ++i) {
+ var option = deviceSelectElement.options[i];
+ if (WebInspector.overridesSupport.isEmulatingDevice(option.device)) {
+ index = i;
+ break;
+ }
+ }
+ deviceSelectElement.selectedIndex = index;
+ }
+
+ return deviceSelectElement;
+ },
+
+ /**
+ * @param {!Document} document
+ * @return {!Element}
+ */
+ createNetworkThroughputSelect: function(document)
+ {
+ var throughputSetting = WebInspector.overridesSupport.settings.networkConditionsThroughput;
+ var throughputSelectElement = document.createElement("select");
+ var presets = WebInspector.OverridesSupport._networkThroughputPresets;
+ for (var i = 0; i < presets.length; ++i)
+ throughputSelectElement.add(new Option(presets[i][0], presets[i][1]));
+
+ settingChanged();
+ throughputSetting.addChangeListener(settingChanged);
+ throughputSelectElement.addEventListener("change", throughputSelected, false);
+
+ function throughputSelected()
+ {
+ var value = Number(throughputSelectElement.options[throughputSelectElement.selectedIndex].value);
+ throughputSetting.removeChangeListener(settingChanged);
+ throughputSetting.set(value);
+ throughputSetting.addChangeListener(settingChanged);
+ }
+
+ function settingChanged()
+ {
+ var value = String(throughputSetting.get());
+ var options = throughputSelectElement.options;
+ var selectionRestored = false;
+ for (var i = 0; i < options.length; ++i) {
+ if (options[i].value === value) {
+ throughputSelectElement.selectedIndex = i;
+ selectionRestored = true;
+ break;
+ }
+ }
+ if (!selectionRestored)
+ throughputSelectElement.selectedIndex = options.length - 1;
+ }
+
+ return throughputSelectElement;
+ },
+
+ reveal: function()
+ {
+ WebInspector.Revealer.reveal(this);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+
+/**
+ * @type {!WebInspector.OverridesSupport}
+ */
+WebInspector.overridesSupport;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PieChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PaintProfiler.js
index 036b4ce9e2a..573630b845e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PieChart.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PaintProfiler.js
@@ -30,45 +30,45 @@
/**
* @constructor
- * @param {number} totalValue
+ * @param {string} snapshotId
*/
-WebInspector.PieChart = function(totalValue)
+WebInspector.PaintProfilerSnapshot = function(snapshotId)
{
- this.element = document.createElement("div");
- this.element.className = "pie-chart";
- this.element.createChild("div", "pie-chart-background");
- var totalString = Number.secondsToString(totalValue, true);
- this.element.createChild("div", "pie-chart-foreground").textContent = totalString;
- this._totalValue = totalValue;
- this._lastAngle = 0;
+ this._id = snapshotId;
}
-WebInspector.PieChart.prototype = {
+WebInspector.PaintProfilerSnapshot.prototype = {
+ dispose: function()
+ {
+ LayerTreeAgent.releaseSnapshot(this._id);
+ },
+
/**
- * @param {number} value
- * @param {string} color
+ * @param {?number} firstStep
+ * @param {?number} lastStep
+ * @param {function(string=)} callback
*/
- addSlice: function(value, color)
+ requestImage: function(firstStep, lastStep, callback)
{
- var sliceAngle = value / this._totalValue * 360;
- if (sliceAngle > 180) {
- this._innerAddSlice(180, color);
- sliceAngle -= 180;
- }
- this._innerAddSlice(sliceAngle, color);
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.replaySnapshot(): ");
+ LayerTreeAgent.replaySnapshot(this._id, firstStep || undefined, lastStep || undefined, wrappedCallback);
},
/**
- * @param {number} sliceAngle
- * @param {string} color
+ * @param {function(!Array.<!LayerTreeAgent.PaintProfile>=)} callback
*/
- _innerAddSlice: function(sliceAngle, color)
+ profile: function(callback)
{
- var sliceElement = this.element.createChild("div", "pie-chart-slice");
- sliceElement.style.webkitTransform = "rotate(" + Number(this._lastAngle).toFixed(2) + "deg)"
- var innerSliceElement = sliceElement.createChild("div", "pie-chart-slice-inner");
- innerSliceElement.style.backgroundColor = color;
- innerSliceElement.style.webkitTransform = "rotate(" + Number(sliceAngle).toFixed(2) + "deg)";
- this._lastAngle += sliceAngle;
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.profileSnapshot(): ");
+ LayerTreeAgent.profileSnapshot(this._id, 5, 1, wrappedCallback);
+ },
+
+ /**
+ * @param {function(!Array.<!Object>=)} callback
+ */
+ commandLog: function(callback)
+ {
+ var wrappedCallback = InspectorBackend.wrapClientCallback(callback, "LayerTreeAgent.snapshotCommandLog(): ");
+ LayerTreeAgent.snapshotCommandLog(this._id, wrappedCallback);
}
-}
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PowerProfiler.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PowerProfiler.js
new file mode 100644
index 00000000000..63ff51e45c5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PowerProfiler.js
@@ -0,0 +1,55 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.PowerProfiler = function()
+{
+ WebInspector.Object.call(this);
+ this._dispatcher = new WebInspector.PowerDispatcher(this);
+}
+
+WebInspector.PowerProfiler.EventTypes = {
+ PowerEventRecorded: "PowerEventRecorded"
+}
+
+WebInspector.PowerProfiler.prototype = {
+
+ startProfile: function ()
+ {
+ PowerAgent.start();
+ },
+
+ stopProfile: function ()
+ {
+ PowerAgent.end();
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @implements {PowerAgent.Dispatcher}
+ */
+WebInspector.PowerDispatcher = function(profiler)
+{
+ this._profiler = profiler;
+ InspectorBackend.registerPowerDispatcher(this);
+}
+
+WebInspector.PowerDispatcher.prototype = {
+ dataAvailable: function(events)
+ {
+ for (var i = 0; i < events.length; ++i)
+ this._profiler.dispatchEventToListeners(WebInspector.PowerProfiler.EventTypes.PowerEventRecorded, events[i]);
+ }
+}
+
+/**
+ * @type {!WebInspector.PowerProfiler}
+ */
+WebInspector.powerProfiler;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/PresentationConsoleMessageHelper.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PresentationConsoleMessageHelper.js
index 06bfc09cc3d..5acc9e223fd 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/PresentationConsoleMessageHelper.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/PresentationConsoleMessageHelper.js
@@ -30,6 +30,7 @@
/**
* @constructor
+ * @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.PresentationConsoleMessageHelper = function(workspace)
@@ -41,17 +42,37 @@ WebInspector.PresentationConsoleMessageHelper = function(workspace)
this._presentationConsoleMessages = [];
this._workspace = workspace;
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
-
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ WebInspector.targetManager.observeTargets(this);
}
WebInspector.PresentationConsoleMessageHelper.prototype = {
/**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
+ target.consoleModel.removeEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ },
+
+ /**
* @param {!WebInspector.Event} event
*/
_consoleMessageAdded: function(event)
@@ -60,7 +81,7 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
if (!message.url || !message.isErrorOrWarning())
return;
- var rawLocation = message.location();
+ var rawLocation = this._rawLocation(message);
if (rawLocation)
this._addConsoleMessageToScript(message, rawLocation);
else
@@ -69,6 +90,18 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
/**
* @param {!WebInspector.ConsoleMessage} message
+ * @return {?WebInspector.DebuggerModel.Location}
+ */
+ _rawLocation: function(message)
+ {
+ // FIXME(62725): stack trace line/column numbers are one-based.
+ var lineNumber = message.stackTrace ? message.stackTrace[0].lineNumber - 1 : message.line - 1;
+ var columnNumber = message.stackTrace && message.stackTrace[0].columnNumber ? message.stackTrace[0].columnNumber - 1 : 0;
+ return message.target().debuggerModel.createRawLocationByURL(message.url || "", lineNumber, columnNumber);
+ },
+
+ /**
+ * @param {!WebInspector.ConsoleMessage} message
* @param {!WebInspector.DebuggerModel.Location} rawLocation
*/
_addConsoleMessageToScript: function(message, rawLocation)
@@ -102,7 +135,7 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
var pendingMessages = [];
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
- var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (message.location());
+ var rawLocation = this._rawLocation(message);
if (script.scriptId === rawLocation.scriptId)
this._addConsoleMessageToScript(message, rawLocation);
else
@@ -141,7 +174,7 @@ WebInspector.PresentationConsoleMessageHelper.prototype = {
WebInspector.PresentationConsoleMessage = function(message, rawLocation)
{
this.originalMessage = message;
- this._liveLocation = WebInspector.debuggerModel.createLiveLocation(rawLocation, this._updateLocation.bind(this));
+ this._liveLocation = rawLocation.createLiveLocation(this._updateLocation.bind(this));
}
WebInspector.PresentationConsoleMessage.prototype = {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RemoteObject.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
index faee423d8b4..16f63803174 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RemoteObject.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
@@ -29,84 +29,128 @@
*/
/**
+ * This may not be an interface due to "instanceof WebInspector.RemoteObject" checks in the code.
+ *
* @constructor
- * @param {string|undefined} objectId
- * @param {string} type
- * @param {string|undefined} subtype
- * @param {*} value
- * @param {string=} description
- * @param {!RuntimeAgent.ObjectPreview=} preview
*/
-WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
-{
- this._type = type;
- this._subtype = subtype;
- if (objectId) {
- // handle
- this._objectId = objectId;
- this._description = description;
- this._hasChildren = true;
- this._preview = preview;
- } else {
- // Primitive or null object.
- console.assert(type !== "object" || value === null);
- this._description = description || (value + "");
- this._hasChildren = false;
- this.value = value;
- }
-}
+WebInspector.RemoteObject = function() { }
-/**
- * @param {number|string|boolean} value
- * @return {!WebInspector.RemoteObject}
- */
-WebInspector.RemoteObject.fromPrimitiveValue = function(value)
-{
- return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
-}
+WebInspector.RemoteObject.prototype = {
+ /** @return {string} */
+ get type()
+ {
+ throw "Not implemented";
+ },
-/**
- * @param {*} value
- * @return {!WebInspector.RemoteObject}
- */
-WebInspector.RemoteObject.fromLocalObject = function(value)
-{
- return new WebInspector.LocalJSONObject(value);
-}
+ /** @return {string|undefined} */
+ get subtype()
+ {
+ throw "Not implemented";
+ },
+
+ /** @return {string|undefined} */
+ get description()
+ {
+ throw "Not implemented";
+ },
+
+ /** @return {boolean} */
+ get hasChildren()
+ {
+ throw "Not implemented";
+ },
-/**
- * @param {!WebInspector.DOMNode} node
- * @param {string} objectGroup
- * @param {function(?WebInspector.RemoteObject)} callback
- */
-WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
-{
/**
- * @param {?Protocol.Error} error
- * @param {!RuntimeAgent.RemoteObject} object
+ * @return {number}
*/
- function mycallback(error, object)
+ arrayLength: function()
{
- if (!callback)
- return;
+ throw "Not implemented";
+ },
- if (error || !object)
- callback(null);
- else
- callback(WebInspector.RemoteObject.fromPayload(object));
+ /**
+ * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
+ */
+ getOwnProperties: function(callback)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @param {boolean} accessorPropertiesOnly
+ * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
+ */
+ getAllProperties: function(accessorPropertiesOnly, callback)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @param {string} name
+ * @param {function(string=)} callback
+ */
+ deleteProperty: function(name, callback)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @param {function(this:Object, ...)} functionDeclaration
+ * @param {!Array.<!RuntimeAgent.CallArgument>=} args
+ * @param {function(?WebInspector.RemoteObject, boolean=)=} callback
+ */
+ callFunction: function(functionDeclaration, args, callback)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @param {function(this:Object)} functionDeclaration
+ * @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args
+ * @param {function(*)} callback
+ */
+ callFunctionJSON: function(functionDeclaration, args, callback)
+ {
+ throw "Not implemented";
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ throw new Error("Target-less object");
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isNode: function()
+ {
+ return false;
+ },
+
+ reveal: function()
+ {
+ WebInspector.Revealer.reveal(this);
+ },
+
+ /**
+ * @param {function(?DebuggerAgent.FunctionDetails)} callback
+ */
+ functionDetails: function(callback)
+ {
+ callback(null);
}
- DOMAgent.resolveNode(node.id, objectGroup, mycallback);
}
/**
- * @param {!RuntimeAgent.RemoteObject} payload
+ * @param {*} value
* @return {!WebInspector.RemoteObject}
*/
-WebInspector.RemoteObject.fromPayload = function(payload)
+WebInspector.RemoteObject.fromLocalObject = function(value)
{
- console.assert(typeof payload === "object", "Remote object payload should only be an object");
-
- return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
+ return new WebInspector.LocalJSONObject(value);
}
/**
@@ -125,7 +169,75 @@ WebInspector.RemoteObject.type = function(remoteObject)
return remoteObject.type;
}
-WebInspector.RemoteObject.prototype = {
+/**
+ * @param {!RuntimeAgent.RemoteObject|!WebInspector.RemoteObject} remoteObject
+ * @return {!RuntimeAgent.CallArgument}
+ */
+WebInspector.RemoteObject.toCallArgument = function(remoteObject)
+{
+ var type = /** @type {!RuntimeAgent.CallArgumentType.<string>} */ (remoteObject.type);
+ var value = remoteObject.value;
+
+ // Handle special numbers: NaN, Infinity, -Infinity, -0.
+ if (type === "number") {
+ switch (remoteObject.description) {
+ case "NaN":
+ case "Infinity":
+ case "-Infinity":
+ case "-0":
+ value = remoteObject.description;
+ break;
+ }
+ }
+
+ return {
+ value: value,
+ objectId: remoteObject.objectId,
+ type: type
+ };
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.RemoteObject}
+ * @param {!WebInspector.Target} target
+ * @param {string|undefined} objectId
+ * @param {string} type
+ * @param {string|undefined} subtype
+ * @param {*} value
+ * @param {string=} description
+ * @param {!RuntimeAgent.ObjectPreview=} preview
+ */
+WebInspector.RemoteObjectImpl = function(target, objectId, type, subtype, value, description, preview)
+{
+ WebInspector.RemoteObject.call(this);
+
+ this._target = target;
+ this._runtimeAgent = target.runtimeAgent();
+ this._domModel = target.domModel;
+
+ this._type = type;
+ this._subtype = subtype;
+ if (objectId) {
+ // handle
+ this._objectId = objectId;
+ this._description = description;
+ this._hasChildren = (type !== "symbol");
+ this._preview = preview;
+ } else {
+ // Primitive or null object.
+ console.assert(type !== "object" || value === null);
+ this._description = description || (value + "");
+ this._hasChildren = false;
+ // Handle special numbers: NaN, Infinity, -Infinity, -0.
+ if (type === "number" && typeof value !== "number")
+ this.value = Number(value);
+ else
+ this.value = value;
+ }
+}
+
+WebInspector.RemoteObjectImpl.prototype = {
/** @return {!RuntimeAgent.RemoteObjectId} */
get objectId()
{
@@ -187,6 +299,7 @@ WebInspector.RemoteObject.prototype = {
{
/**
* @param {string} arrayStr
+ * @suppressReceiverCheck
* @this {Object}
*/
function remoteFunction(arrayStr)
@@ -218,6 +331,7 @@ WebInspector.RemoteObject.prototype = {
* @param {?Protocol.Error} error
* @param {!Array.<!RuntimeAgent.PropertyDescriptor>} properties
* @param {!Array.<!RuntimeAgent.InternalPropertyDescriptor>=} internalProperties
+ * @this {WebInspector.RemoteObjectImpl}
*/
function remoteObjectBinder(error, properties, internalProperties)
{
@@ -228,7 +342,19 @@ WebInspector.RemoteObject.prototype = {
var result = [];
for (var i = 0; properties && i < properties.length; ++i) {
var property = properties[i];
- result.push(new WebInspector.RemoteObjectProperty(property.name, null, property));
+ var propertyValue = property.value ? this._target.runtimeModel.createRemoteObject(property.value) : null;
+ var propertySymbol = property.symbol ? this._target.runtimeModel.createRemoteObject(property.symbol) : null;
+ var remoteProperty = new WebInspector.RemoteObjectProperty(property.name, propertyValue,
+ !!property.enumerable, !!property.writable, !!property.isOwn, !!property.wasThrown, propertySymbol);
+
+ if (typeof property.value === "undefined") {
+ if (property.get && property.get.type !== "undefined")
+ remoteProperty.getter = this._target.runtimeModel.createRemoteObject(property.get);
+ if (property.set && property.set.type !== "undefined")
+ remoteProperty.setter = this._target.runtimeModel.createRemoteObject(property.set);
+ }
+
+ result.push(remoteProperty);
}
var internalPropertiesResult = null;
if (internalProperties) {
@@ -237,12 +363,13 @@ WebInspector.RemoteObject.prototype = {
var property = internalProperties[i];
if (!property.value)
continue;
- internalPropertiesResult.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value)));
+ var propertyValue = this._target.runtimeModel.createRemoteObject(property.value);
+ internalPropertiesResult.push(new WebInspector.RemoteObjectProperty(property.name, propertyValue, true, false));
}
}
callback(result, internalPropertiesResult);
}
- RuntimeAgent.getProperties(this._objectId, ownProperties, accessorPropertiesOnly, remoteObjectBinder);
+ this._runtimeAgent.getProperties(this._objectId, ownProperties, accessorPropertiesOnly, remoteObjectBinder.bind(this));
},
/**
@@ -257,7 +384,7 @@ WebInspector.RemoteObject.prototype = {
return;
}
- RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
+ this._runtimeAgent.invoke_evaluate({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
/**
* @param {?Protocol.Error} error
@@ -275,7 +402,7 @@ WebInspector.RemoteObject.prototype = {
this.doSetObjectPropertyValue(result, name, callback);
if (result.objectId)
- RuntimeAgent.releaseObject(result.objectId);
+ this._runtimeAgent.releaseObject(result.objectId);
}
},
@@ -292,12 +419,8 @@ WebInspector.RemoteObject.prototype = {
// where property was defined; so do we.
var setPropertyValueFunction = "function(a, b) { this[a] = b; }";
- // Special case for NaN, Infinity, -Infinity, -0.
- if (result.type === "number" && String(result.value) !== result.description)
- setPropertyValueFunction = "function(a) { this[a] = " + result.description + "; }";
-
- delete result.description; // Optimize on traffic.
- RuntimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, [{ value:name }, result], true, undefined, undefined, propertySetCallback.bind(this));
+ var argv = [{ value: name }, WebInspector.RemoteObject.toCallArgument(result)]
+ this._runtimeAgent.callFunctionOn(this._objectId, setPropertyValueFunction, argv, true, undefined, undefined, propertySetCallback);
/**
* @param {?Protocol.Error} error
@@ -315,24 +438,56 @@ WebInspector.RemoteObject.prototype = {
},
/**
- * @param {function(?DOMAgent.NodeId)} callback
+ * @param {string} name
+ * @param {function(string=)} callback
+ */
+ deleteProperty: function(name, callback)
+ {
+ if (!this._objectId) {
+ callback("Can't delete a property of non-object.");
+ return;
+ }
+
+ var deletePropertyFunction = "function(a) { delete this[a]; return !(a in this); }";
+ this._runtimeAgent.callFunctionOn(this._objectId, deletePropertyFunction, [{ value: name }], true, undefined, undefined, deletePropertyCallback);
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!RuntimeAgent.RemoteObject} result
+ * @param {boolean=} wasThrown
+ */
+ function deletePropertyCallback(error, result, wasThrown)
+ {
+ if (error || wasThrown) {
+ callback(error || result.description);
+ return;
+ }
+ if (!result.value)
+ callback("Failed to delete property.");
+ else
+ callback();
+ }
+ },
+
+ /**
+ * @param {function(?WebInspector.DOMNode)} callback
*/
pushNodeToFrontend: function(callback)
{
- if (this._objectId)
- WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback);
+ if (this.isNode())
+ this._domModel.pushNodeToFrontend(this._objectId, callback);
else
- callback(0);
+ callback(null);
},
highlightAsDOMNode: function()
{
- WebInspector.domAgent.highlightDOMNode(undefined, undefined, this._objectId);
+ this._domModel.highlightDOMNode(undefined, undefined, this._objectId);
},
hideDOMNodeHighlight: function()
{
- WebInspector.domAgent.hideDOMNodeHighlight();
+ this._domModel.hideDOMNodeHighlight();
},
/**
@@ -346,6 +501,7 @@ WebInspector.RemoteObject.prototype = {
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
+ * @this {WebInspector.RemoteObjectImpl}
*/
function mycallback(error, result, wasThrown)
{
@@ -354,10 +510,10 @@ WebInspector.RemoteObject.prototype = {
if (error)
callback(null, false);
else
- callback(WebInspector.RemoteObject.fromPayload(result), wasThrown);
+ callback(this.target().runtimeModel.createRemoteObject(result), wasThrown);
}
- RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, mycallback);
+ this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, mycallback.bind(this));
},
/**
@@ -377,14 +533,14 @@ WebInspector.RemoteObject.prototype = {
callback((error || wasThrown) ? null : result.value);
}
- RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, mycallback);
+ this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, mycallback);
},
release: function()
{
if (!this._objectId)
return;
- RuntimeAgent.releaseObject(this._objectId);
+ this._runtimeAgent.releaseObject(this._objectId);
},
/**
@@ -399,7 +555,33 @@ WebInspector.RemoteObject.prototype = {
if (!matches)
return 0;
return parseInt(matches[1], 10);
- }
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isNode: function()
+ {
+ return !!this._objectId && this.type === "object" && this.subtype === "node";
+ },
+
+ /**
+ * @param {function(?DebuggerAgent.FunctionDetails)} callback
+ */
+ functionDetails: function(callback)
+ {
+ this._target.debuggerModel.functionDetails(this, callback)
+ },
+
+ __proto__: WebInspector.RemoteObject.prototype
};
@@ -411,7 +593,7 @@ WebInspector.RemoteObject.prototype = {
WebInspector.RemoteObject.loadFromObject = function(object, flattenProtoChain, callback)
{
if (flattenProtoChain)
- object.getAllProperties(false, callback);
+ object.getAllProperties(false, callback);
else
WebInspector.RemoteObject.loadFromObjectPerProto(object, callback);
};
@@ -473,7 +655,8 @@ WebInspector.RemoteObject.loadFromObjectPerProto = function(object, callback)
/**
* @constructor
- * @extends {WebInspector.RemoteObject}
+ * @extends {WebInspector.RemoteObjectImpl}
+ * @param {!WebInspector.Target} target
* @param {string|undefined} objectId
* @param {!WebInspector.ScopeRef} scopeRef
* @param {string} type
@@ -482,26 +665,14 @@ WebInspector.RemoteObject.loadFromObjectPerProto = function(object, callback)
* @param {string=} description
* @param {!RuntimeAgent.ObjectPreview=} preview
*/
-WebInspector.ScopeRemoteObject = function(objectId, scopeRef, type, subtype, value, description, preview)
+WebInspector.ScopeRemoteObject = function(target, objectId, scopeRef, type, subtype, value, description, preview)
{
- WebInspector.RemoteObject.call(this, objectId, type, subtype, value, description, preview);
+ WebInspector.RemoteObjectImpl.call(this, target, objectId, type, subtype, value, description, preview);
this._scopeRef = scopeRef;
this._savedScopeProperties = undefined;
+ this._debuggerAgent = target.debuggerAgent();
};
-/**
- * @param {!RuntimeAgent.RemoteObject} payload
- * @param {!WebInspector.ScopeRef=} scopeRef
- * @return {!WebInspector.RemoteObject}
- */
-WebInspector.ScopeRemoteObject.fromPayload = function(payload, scopeRef)
-{
- if (scopeRef)
- return new WebInspector.ScopeRemoteObject(payload.objectId, scopeRef, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
- else
- return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
-}
-
WebInspector.ScopeRemoteObject.prototype = {
/**
* @param {boolean} ownProperties
@@ -535,7 +706,7 @@ WebInspector.ScopeRemoteObject.prototype = {
callback(properties, internalProperties);
}
- WebInspector.RemoteObject.prototype.doGetProperties.call(this, ownProperties, accessorPropertiesOnly, wrappedCallback.bind(this));
+ WebInspector.RemoteObjectImpl.prototype.doGetProperties.call(this, ownProperties, accessorPropertiesOnly, wrappedCallback.bind(this));
},
/**
@@ -546,21 +717,7 @@ WebInspector.ScopeRemoteObject.prototype = {
*/
doSetObjectPropertyValue: function(result, name, callback)
{
- var newValue;
-
- switch (result.type) {
- case "undefined":
- newValue = {};
- break;
- case "object":
- case "function":
- newValue = { objectId: result.objectId };
- break;
- default:
- newValue = { value: result.value };
- }
-
- DebuggerAgent.setVariableValue(this._scopeRef.number, name, newValue, this._scopeRef.callFrameId, this._scopeRef.functionId, setVariableValueCallback.bind(this));
+ this._debuggerAgent.setVariableValue(this._scopeRef.number, name, WebInspector.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId, this._scopeRef.functionId, setVariableValueCallback.bind(this));
/**
* @param {?Protocol.Error} error
@@ -575,14 +732,14 @@ WebInspector.ScopeRemoteObject.prototype = {
if (this._savedScopeProperties) {
for (var i = 0; i < this._savedScopeProperties.length; i++) {
if (this._savedScopeProperties[i].name === name)
- this._savedScopeProperties[i].value = WebInspector.RemoteObject.fromPayload(result);
+ this._savedScopeProperties[i].value = this._target.runtimeModel.createRemoteObject(result);
}
}
callback();
}
},
- __proto__: WebInspector.RemoteObject.prototype
+ __proto__: WebInspector.RemoteObjectImpl.prototype
};
/**
@@ -603,64 +760,39 @@ WebInspector.ScopeRef = function(number, callFrameId, functionId)
* @constructor
* @param {string} name
* @param {?WebInspector.RemoteObject} value
- * @param {!RuntimeAgent.PropertyDescriptor=} descriptor
+ * @param {boolean=} enumerable
+ * @param {boolean=} writable
+ * @param {boolean=} isOwn
+ * @param {boolean=} wasThrown
+ * @param {?WebInspector.RemoteObject=} symbol
*/
-WebInspector.RemoteObjectProperty = function(name, value, descriptor)
+WebInspector.RemoteObjectProperty = function(name, value, enumerable, writable, isOwn, wasThrown, symbol)
{
this.name = name;
- this.enumerable = descriptor ? !!descriptor.enumerable : true;
- this.writable = descriptor ? !!descriptor.writable : true;
-
- if (value === null && descriptor) {
- if (descriptor.value)
- this.value = WebInspector.RemoteObject.fromPayload(descriptor.value)
- if (descriptor.get && descriptor.get.type !== "undefined")
- this.getter = WebInspector.RemoteObject.fromPayload(descriptor.get);
- if (descriptor.set && descriptor.set.type !== "undefined")
- this.setter = WebInspector.RemoteObject.fromPayload(descriptor.set);
- } else {
- this.value = value;
- }
-
- if (descriptor) {
- this.isOwn = descriptor.isOwn;
- this.wasThrown = !!descriptor.wasThrown;
- }
+ if (value !== null)
+ this.value = value;
+ this.enumerable = typeof enumerable !== "undefined" ? enumerable : true;
+ this.writable = typeof writable !== "undefined" ? writable : true;
+ this.isOwn = !!isOwn;
+ this.wasThrown = !!wasThrown;
+ if (symbol)
+ this.symbol = symbol;
}
WebInspector.RemoteObjectProperty.prototype = {
+ /**
+ * @return {boolean}
+ */
isAccessorProperty: function()
{
- return this.getter || this.setter;
+ return !!(this.getter || this.setter);
}
};
-/**
- * @param {string} name
- * @param {string} value
- * @return {!WebInspector.RemoteObjectProperty}
- */
-WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
-{
- return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
-}
-
-/**
- * @param {string} name
- * @param {!WebInspector.RemoteObject} value
- * @return {!WebInspector.RemoteObjectProperty}
- */
-WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
-{
- var result = new WebInspector.RemoteObjectProperty(name, value);
- result.writable = false;
- return result;
-}
-
-// The below is a wrapper around a local object that provides an interface comaptible
-// with RemoteObject, to be used by the UI code (primarily ObjectPropertiesSection).
+// Below is a wrapper around a local object that implements the RemoteObject interface,
+// which can be used by the UI code (primarily ObjectPropertiesSection).
// Note that only JSON-compliant objects are currently supported, as there's no provision
-// for traversing prototypes, extracting class names via constuctor, handling properties
+// for traversing prototypes, extracting class names via constructor, handling properties
// or functions.
/**
@@ -670,6 +802,7 @@ WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
*/
WebInspector.LocalJSONObject = function(value)
{
+ WebInspector.RemoteObject.call(this);
this._value = value;
}
@@ -789,14 +922,14 @@ WebInspector.LocalJSONObject.prototype = {
/**
* @param {boolean} accessorPropertiesOnly
- * @param {function(!Array.<!WebInspector.RemoteObjectProperty>)} callback
+ * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebInspector.RemoteObjectProperty>)} callback
*/
getAllProperties: function(accessorPropertiesOnly, callback)
{
if (accessorPropertiesOnly)
- callback([]);
+ callback([], null);
else
- callback(this._children());
+ callback(this._children(), null);
},
/**
@@ -878,5 +1011,7 @@ WebInspector.LocalJSONObject.prototype = {
}
callback(result);
- }
+ },
+
+ __proto__: WebInspector.RemoteObject.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Resource.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Resource.js
index ecaf074d4c1..20c66ec49f3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Resource.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Resource.js
@@ -151,7 +151,7 @@ WebInspector.Resource.prototype = {
*/
addMessage: function(msg)
{
- if (!msg.isErrorOrWarning() || !msg.message)
+ if (!msg.isErrorOrWarning() || !msg.messageText)
return;
if (!this._messages)
@@ -241,6 +241,9 @@ WebInspector.Resource.prototype = {
this._innerRequestContent();
},
+ /**
+ * @return {string}
+ */
canonicalMimeType: function()
{
return this.type.canonicalMimeType() || this.mimeType;
@@ -264,24 +267,10 @@ WebInspector.Resource.prototype = {
}
if (this.type === WebInspector.resourceTypes.Document) {
- this.requestContent(documentContentLoaded);
+ callback([]);
return;
}
- /**
- * @param {?string} content
- */
- function documentContentLoaded(content)
- {
- if (content === null) {
- callback([]);
- return;
- }
-
- var result = WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
- callback(result);
- }
-
if (this.frameId)
PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
else
@@ -331,7 +320,7 @@ WebInspector.Resource.prototype = {
function contentLoaded(error, content, contentEncoded)
{
if (error || content === null) {
- loadFallbackContent.call(this, error);
+ replyWithContent.call(this, null, false);
return;
}
replyWithContent.call(this, content, contentEncoded);
@@ -363,43 +352,6 @@ WebInspector.Resource.prototype = {
{
contentLoaded.call(this, error, content, contentEncoded);
}
-
- /**
- * @param {?Protocol.Error} error
- * @this {WebInspector.Resource}
- */
- function loadFallbackContent(error)
- {
- var scripts = WebInspector.debuggerModel.scriptsForSourceURL(this.url);
- if (!scripts.length) {
- console.error("Resource content request failed: " + error);
- replyWithContent.call(this, null, false);
- return;
- }
-
- var contentProvider;
- if (this.type === WebInspector.resourceTypes.Document)
- contentProvider = new WebInspector.ConcatenatedScriptsContentProvider(scripts);
- else if (this.type === WebInspector.resourceTypes.Script)
- contentProvider = scripts[0];
-
- if (!contentProvider) {
- console.error("Resource content request failed: " + error);
- replyWithContent.call(this, null, false);
- return;
- }
-
- contentProvider.requestContent(fallbackContentLoaded.bind(this));
- }
-
- /**
- * @param {?string} content
- * @this {WebInspector.Resource}
- */
- function fallbackContentLoaded(content)
- {
- replyWithContent.call(this, content, false);
- }
if (this.request) {
this.request.requestContent(requestContentLoaded.bind(this));
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceScriptMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceScriptMapping.js
index e13283f568b..e44d0977072 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceScriptMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceScriptMapping.js
@@ -31,15 +31,18 @@
/**
* @constructor
* @implements {WebInspector.ScriptSourceMapping}
+ * @param {!WebInspector.DebuggerModel} debuggerModel
* @param {!WebInspector.Workspace} workspace
*/
-WebInspector.ResourceScriptMapping = function(workspace)
+WebInspector.ResourceScriptMapping = function(debuggerModel, workspace)
{
+ this._target = debuggerModel.target();
+ this._debuggerModel = debuggerModel;
this._workspace = workspace;
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
+ this._boundURLs = new StringSet();
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
- this._initialize();
+ debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
}
WebInspector.ResourceScriptMapping.prototype = {
@@ -50,14 +53,14 @@ WebInspector.ResourceScriptMapping.prototype = {
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
- var script = WebInspector.debuggerModel.scriptForId(debuggerModelLocation.scriptId);
+ var script = debuggerModelLocation.script();
var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return null;
- var scriptFile = uiSourceCode.scriptFile();
+ var scriptFile = uiSourceCode.scriptFileForTarget(this._target);
if (scriptFile && ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM()))
return null;
- return new WebInspector.UILocation(uiSourceCode, debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
+ return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
},
/**
@@ -70,7 +73,7 @@ WebInspector.ResourceScriptMapping.prototype = {
{
var scripts = this._scriptsForUISourceCode(uiSourceCode);
console.assert(scripts.length);
- return WebInspector.debuggerModel.createRawLocation(scripts[0], lineNumber, columnNumber);
+ return this._debuggerModel.createRawLocation(scripts[0], lineNumber, columnNumber);
},
/**
@@ -82,10 +85,6 @@ WebInspector.ResourceScriptMapping.prototype = {
return;
script.pushSourceMapping(this);
- var scriptsForSourceURL = script.isInlineScript() ? this._inlineScriptsForSourceURL : this._nonInlineScriptsForSourceURL;
- scriptsForSourceURL.put(script.sourceURL, scriptsForSourceURL.get(script.sourceURL) || []);
- scriptsForSourceURL.get(script.sourceURL).push(script);
-
var uiSourceCode = this._workspaceUISourceCodeForScript(script);
if (!uiSourceCode)
return;
@@ -93,9 +92,19 @@ WebInspector.ResourceScriptMapping.prototype = {
this._bindUISourceCodeToScripts(uiSourceCode, [script]);
},
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return true;
+ },
+
_uiSourceCodeAddedToWorkspace: function(event)
{
var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ if (uiSourceCode.project().isServiceProject())
+ return;
if (!uiSourceCode.url)
return;
@@ -147,21 +156,9 @@ WebInspector.ResourceScriptMapping.prototype = {
*/
_scriptsForUISourceCode: function(uiSourceCode)
{
- var isInlineScript;
- switch (uiSourceCode.contentType()) {
- case WebInspector.resourceTypes.Document:
- isInlineScript = true;
- break;
- case WebInspector.resourceTypes.Script:
- isInlineScript = false;
- break;
- default:
- return [];
- }
if (!uiSourceCode.url)
return [];
- var scriptsForSourceURL = isInlineScript ? this._inlineScriptsForSourceURL : this._nonInlineScriptsForSourceURL;
- return scriptsForSourceURL.get(uiSourceCode.url) || [];
+ return this._debuggerModel.scriptsForSourceURL(uiSourceCode.url);
},
/**
@@ -172,54 +169,37 @@ WebInspector.ResourceScriptMapping.prototype = {
{
console.assert(scripts.length);
var scriptFile = new WebInspector.ResourceScriptFile(this, uiSourceCode, scripts);
- uiSourceCode.setScriptFile(scriptFile);
+ uiSourceCode.setScriptFileForTarget(this._target, scriptFile);
for (var i = 0; i < scripts.length; ++i)
scripts[i].updateLocations();
- uiSourceCode.setSourceMapping(this);
+ uiSourceCode.setSourceMappingForTarget(this._target, this);
+ this._boundURLs.add(uiSourceCode.url);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {!Array.<!WebInspector.Script>} scripts
*/
- _unbindUISourceCodeFromScripts: function(uiSourceCode, scripts)
+ _unbindUISourceCode: function(uiSourceCode)
{
- console.assert(scripts.length);
- var scriptFile = /** @type {!WebInspector.ResourceScriptFile} */ (uiSourceCode.scriptFile());
+ var scriptFile = /** @type {!WebInspector.ResourceScriptFile} */ (uiSourceCode.scriptFileForTarget(this._target));
if (scriptFile) {
scriptFile.dispose();
- uiSourceCode.setScriptFile(null);
+ uiSourceCode.setScriptFileForTarget(this._target, null);
}
- uiSourceCode.setSourceMapping(null);
- },
-
- _initialize: function()
- {
- /** @type {!StringMap.<!Array.<!WebInspector.Script>>} */
- this._inlineScriptsForSourceURL = new StringMap();
- /** @type {!StringMap.<!Array.<!WebInspector.Script>>} */
- this._nonInlineScriptsForSourceURL = new StringMap();
+ uiSourceCode.setSourceMappingForTarget(this._target, null);
},
_debuggerReset: function()
{
- /**
- * @param {!Array.<!WebInspector.Script>} scripts
- * @this {WebInspector.ResourceScriptMapping}
- */
- function unbindUISourceCodesForScripts(scripts)
+ var boundURLs = this._boundURLs.values();
+ for (var i = 0; i < boundURLs.length; ++i)
{
- if (!scripts.length)
- return;
- var uiSourceCode = this._workspaceUISourceCodeForScript(scripts[0]);
+ var uiSourceCode = this._workspace.uiSourceCodeForURL(boundURLs[i]);
if (!uiSourceCode)
- return;
- this._unbindUISourceCodeFromScripts(uiSourceCode, scripts);
+ continue;
+ this._unbindUISourceCode(uiSourceCode);
}
-
- this._inlineScriptsForSourceURL.values().forEach(unbindUISourceCodesForScripts.bind(this));
- this._nonInlineScriptsForSourceURL.values().forEach(unbindUISourceCodesForScripts.bind(this));
- this._initialize();
+ this._boundURLs.clear();
},
}
@@ -253,6 +233,11 @@ WebInspector.ScriptFile.prototype = {
isMergingToVM: function() { return false; },
checkMapping: function() { },
+
+ /**
+ * @return {?WebInspector.Target}
+ */
+ target: function() { return null; },
}
/**
@@ -261,6 +246,7 @@ WebInspector.ScriptFile.prototype = {
* @extends {WebInspector.Object}
* @param {!WebInspector.ResourceScriptMapping} resourceScriptMapping
* @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {!Array.<!WebInspector.Script>} scripts
*/
WebInspector.ResourceScriptFile = function(resourceScriptMapping, uiSourceCode, scripts)
{
@@ -273,13 +259,15 @@ WebInspector.ResourceScriptFile = function(resourceScriptMapping, uiSourceCode,
if (this._uiSourceCode.contentType() === WebInspector.resourceTypes.Script)
this._script = scripts[0];
- this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._update();
}
WebInspector.ResourceScriptFile.prototype = {
- _workingCopyCommitted: function(event)
+ /**
+ * @param {function(boolean)=} callback
+ */
+ commitLiveEdit: function(callback)
{
/**
* @param {?string} error
@@ -291,19 +279,21 @@ WebInspector.ResourceScriptFile.prototype = {
if (error) {
this._update();
WebInspector.LiveEditSupport.logDetailedError(error, errorData, this._script);
+ if (callback)
+ callback(false);
return;
}
this._scriptSource = source;
this._update();
WebInspector.LiveEditSupport.logSuccess();
+ if (callback)
+ callback(true);
}
if (!this._script)
return;
var source = this._uiSourceCode.workingCopy();
- if (this._script.hasSourceURL && !this._sourceEndsWithSourceURL(source))
- source += "\n //# sourceURL=" + this._script.sourceURL;
- WebInspector.debuggerModel.setScriptSource(this._script.scriptId, source, innerCallback.bind(this));
+ this._resourceScriptMapping._debuggerModel.setScriptSource(this._script.scriptId, source, innerCallback.bind(this));
},
/**
@@ -311,37 +301,16 @@ WebInspector.ResourceScriptFile.prototype = {
*/
_isDiverged: function()
{
- if (this._uiSourceCode.formatted())
- return false;
if (this._uiSourceCode.isDirty())
return true;
if (!this._script)
return false;
if (typeof this._scriptSource === "undefined")
return false;
- return !this._sourceMatchesScriptSource(this._uiSourceCode.workingCopy(), this._scriptSource);
- },
-
- /**
- * @param {string} source
- * @param {string} scriptSource
- * @return {boolean}
- */
- _sourceMatchesScriptSource: function(source, scriptSource)
- {
- if (!scriptSource.startsWith(source))
- return false;
- var scriptSourceTail = scriptSource.substr(source.length).trim();
- return !scriptSourceTail || !!scriptSourceTail.match(/^\/\/[@#]\ssourceURL=\s*(\S*?)\s*$/m);
- },
-
- /**
- * @param {string} source
- * @return {boolean}
- */
- _sourceEndsWithSourceURL: function(source)
- {
- return !!source.match(/\/\/[@#]\ssourceURL=\s*(\S*?)\s*$/m);
+ if (!this._uiSourceCode.workingCopy().startsWith(this._scriptSource))
+ return true;
+ var suffix = this._uiSourceCode.workingCopy().substr(this._scriptSource.length);
+ return !!suffix.length && !suffix.match(WebInspector.Script.sourceURLRegex);
},
/**
@@ -421,9 +390,18 @@ WebInspector.ResourceScriptFile.prototype = {
}
},
+ /**
+ * @return {?WebInspector.Target}
+ */
+ target: function()
+ {
+ if (!this._script)
+ return null;
+ return this._script.target();
+ },
+
dispose: function()
{
- this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceTreeModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
index f4736626af5..dac1d11cd6d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceTreeModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -30,26 +30,29 @@
/**
* @constructor
- * @extends {WebInspector.Object}
- * @param {!WebInspector.NetworkManager} networkManager
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.ResourceTreeModel = function(networkManager)
+WebInspector.ResourceTreeModel = function(target)
{
- networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
- networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
+ WebInspector.TargetAwareObject.call(this, target);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
- WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
+ target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
- PageAgent.enable();
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
+ target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
+
+ this._agent = target.pageAgent();
+ this._agent.enable();
this._fetchResourceTree();
- InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this));
+ target.registerPageDispatcher(new WebInspector.PageDispatcher(this));
this._pendingConsoleMessages = {};
this._securityOriginFrameCount = {};
+ this._inspectedPageURL = "";
}
WebInspector.ResourceTreeModel.EventTypes = {
@@ -58,7 +61,6 @@ WebInspector.ResourceTreeModel.EventTypes = {
FrameDetached: "FrameDetached",
FrameResized: "FrameResized",
MainFrameNavigated: "MainFrameNavigated",
- MainFrameCreatedOrNavigated: "MainFrameCreatedOrNavigated",
ResourceAdded: "ResourceAdded",
WillLoadCachedResources: "WillLoadCachedResources",
CachedResourcesLoaded: "CachedResourcesLoaded",
@@ -78,7 +80,7 @@ WebInspector.ResourceTreeModel.prototype = {
/** @type {!Object.<string, !WebInspector.ResourceTreeFrame>} */
this._frames = {};
delete this._cachedResourcesProcessed;
- PageAgent.getResourceTree(this._processCachedResources.bind(this));
+ this._agent.getResourceTree(this._processCachedResources.bind(this));
},
_processCachedResources: function(error, mainFramePayload)
@@ -89,13 +91,33 @@ WebInspector.ResourceTreeModel.prototype = {
}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
- WebInspector.inspectedPageURL = mainFramePayload.frame.url;
+ this._inspectedPageURL = mainFramePayload.frame.url;
this._addFramesRecursively(null, mainFramePayload);
this._dispatchInspectedURLChanged();
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
this._cachedResourcesProcessed = true;
},
+ /**
+ * @return {string}
+ */
+ inspectedPageURL: function()
+ {
+ return this._inspectedPageURL;
+ },
+
+ /**
+ * @return {string}
+ */
+ inspectedPageDomain: function()
+ {
+ var parsedURL = this._inspectedPageURL ? this._inspectedPageURL.asParsedURL() : null;
+ return parsedURL ? parsedURL.host : "";
+ },
+
+ /**
+ * @return {boolean}
+ */
cachedResourcesLoaded: function()
{
return this._cachedResourcesProcessed;
@@ -103,8 +125,8 @@ WebInspector.ResourceTreeModel.prototype = {
_dispatchInspectedURLChanged: function()
{
- InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL);
- this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL);
+ InspectorFrontendHost.inspectedURLChanged(this._inspectedPageURL);
+ this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedPageURL);
},
/**
@@ -119,8 +141,6 @@ WebInspector.ResourceTreeModel.prototype = {
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
if (!aboutToNavigate)
this._addSecurityOrigin(frame.securityOrigin);
- if (frame.isMainFrame())
- this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, frame);
},
/**
@@ -222,13 +242,11 @@ WebInspector.ResourceTreeModel.prototype = {
var addedOrigin = frame.securityOrigin;
if (frame.isMainFrame())
- WebInspector.inspectedPageURL = frame.url;
+ this._inspectedPageURL = frame.url;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
- if (frame.isMainFrame()) {
+ if (frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
- this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, frame);
- }
if (addedOrigin)
this._addSecurityOrigin(addedOrigin);
@@ -375,10 +393,10 @@ WebInspector.ResourceTreeModel.prototype = {
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
- resource.warnings += msg.repeatDelta;
+ resource.warnings++;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
- resource.errors += msg.repeatDelta;
+ resource.errors++;
break;
}
resource.addMessage(msg);
@@ -397,7 +415,7 @@ WebInspector.ResourceTreeModel.prototype = {
/**
* @param {string} url
- * @return {!WebInspector.Resource}
+ * @return {?WebInspector.Resource}
*/
resourceForURL: function(url)
{
@@ -417,7 +435,7 @@ WebInspector.ResourceTreeModel.prototype = {
var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
if (frame.isMainFrame())
- WebInspector.inspectedPageURL = frameResource.url;
+ this._inspectedPageURL = frameResource.url;
frame.addResource(frameResource);
for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
@@ -450,10 +468,10 @@ WebInspector.ResourceTreeModel.prototype = {
reloadPage: function(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor)
{
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage);
- PageAgent.reload(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor);
+ this._agent.reload(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
@@ -494,6 +512,14 @@ WebInspector.ResourceTreeFrame = function(model, parentFrame, frameId, payload)
WebInspector.ResourceTreeFrame.prototype = {
/**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._model.target();
+ },
+
+ /**
* @return {string}
*/
get id()
@@ -663,7 +689,7 @@ WebInspector.ResourceTreeFrame.prototype = {
}
}
this._callForFrameResources(filter);
- return result;
+ return result || null;
},
/**
@@ -682,6 +708,22 @@ WebInspector.ResourceTreeFrame.prototype = {
return true;
}
return false;
+ },
+
+ /**
+ * @return {string}
+ */
+ displayName: function()
+ {
+ if (!this._parentFrame)
+ return WebInspector.UIString("<top frame>");
+ var subtitle = new WebInspector.ParsedURL(this._url).displayName;
+ if (subtitle) {
+ if (!this._name)
+ return subtitle;
+ return this._name + "( " + subtitle + " )";
+ }
+ return WebInspector.UIString("<iframe>");
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceType.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceType.js
index 2c206c7fd07..552f817cef4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceType.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceType.js
@@ -116,9 +116,11 @@ WebInspector.resourceTypes = {
Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true),
Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true),
Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false),
+ Media: new WebInspector.ResourceType("media", "Media", "Media", "rgb(164,60,255)", false), // FIXME: Decide the color.
Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true),
XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true),
Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false),
+ TextTrack: new WebInspector.ResourceType("texttrack", "TextTrack", "TextTracks", "rgb(164,60,255)", true), // FIXME: Decide the color.
WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color.
Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false)
}
@@ -176,5 +178,8 @@ WebInspector.ResourceType.mimeTypesForExtensions = {
"sh": "text/x-sh",
// SCSS
- "scss": "text/x-scss"
+ "scss": "text/x-scss",
+
+ // Video Text Tracks.
+ "vtt": "text/vtt"
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceUtils.js
index 11229be1beb..11c932cf6c1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceUtils.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ResourceUtils.js
@@ -62,14 +62,14 @@ WebInspector.displayNameForURL = function(url)
if (uiSourceCode)
return uiSourceCode.displayName();
- if (!WebInspector.inspectedPageURL)
+ if (!WebInspector.resourceTreeModel.inspectedPageURL())
return url.trimURL("");
- var parsedURL = WebInspector.inspectedPageURL.asParsedURL();
+ var parsedURL = WebInspector.resourceTreeModel.inspectedPageURL().asParsedURL();
var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
- var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent);
- if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) {
- var baseURL = WebInspector.inspectedPageURL.substring(0, index);
+ var index = WebInspector.resourceTreeModel.inspectedPageURL().indexOf(lastPathComponent);
+ if (index !== -1 && index + lastPathComponent.length === WebInspector.resourceTreeModel.inspectedPageURL().length) {
+ var baseURL = WebInspector.resourceTreeModel.inspectedPageURL().substring(0, index);
if (url.startsWith(baseURL))
return url.substring(index);
}
@@ -148,14 +148,13 @@ WebInspector.linkifyStringAsFragment = function(string)
var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
if (typeof lineNumber !== "undefined") {
urlNode.lineNumber = lineNumber;
- urlNode.preferredPanel = "sources";
if (typeof columnNumber !== "undefined")
urlNode.columnNumber = columnNumber;
}
-
- return urlNode;
+
+ return urlNode;
}
-
+
return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
}
@@ -175,7 +174,9 @@ WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, too
classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";
var a = document.createElement("a");
- a.href = sanitizeHref(url);
+ var href = sanitizeHref(url);
+ if (href !== null)
+ a.href = href;
a.className = classes;
if (typeof tooltipText === "undefined")
a.title = url;
@@ -223,8 +224,7 @@ WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipT
WebInspector.linkifyRequestAsNode = function(request)
{
var anchor = WebInspector.linkifyURLAsNode(request.url);
- anchor.preferredPanel = "network";
- anchor.requestId = request.requestId;
+ anchor.requestId = request.requestId;
return anchor;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RuntimeModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
index 3bcbbec10a1..adfe382e4e7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RuntimeModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
@@ -30,98 +30,172 @@
/**
* @constructor
- * @extends {WebInspector.Object}
- * @param {!WebInspector.ResourceTreeModel} resourceTreeModel
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.RuntimeModel = function(resourceTreeModel)
+WebInspector.RuntimeModel = function(target)
{
- resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameAdded, this);
- resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
- resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
- resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded, this._didLoadCachedResources, this);
- this._frameIdToContextList = {};
+ WebInspector.TargetAwareObject.call(this, target);
+
+ this._debuggerModel = target.debuggerModel;
+ this._agent = target.runtimeAgent();
+ this.target().registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));
+ this._agent.enable();
+ /**
+ * @type {!Object.<number, !WebInspector.ExecutionContext>}
+ */
+ this._executionContextById = {};
}
WebInspector.RuntimeModel.Events = {
- FrameExecutionContextListAdded: "FrameExecutionContextListAdded",
- FrameExecutionContextListRemoved: "FrameExecutionContextListRemoved",
+ ExecutionContextCreated: "ExecutionContextCreated",
+ ExecutionContextDestroyed: "ExecutionContextDestroyed",
}
WebInspector.RuntimeModel.prototype = {
+
/**
- * @param {?WebInspector.ExecutionContext} executionContext
+ * @return {!Array.<!WebInspector.ExecutionContext>}
*/
- setCurrentExecutionContext: function(executionContext)
+ executionContexts: function()
{
- this._currentExecutionContext = executionContext;
+ return Object.values(this._executionContextById);
},
/**
- * @return {?WebInspector.ExecutionContext}
+ * @param {!RuntimeAgent.ExecutionContextDescription} context
*/
- currentExecutionContext: function()
+ _executionContextCreated: function(context)
{
- return this._currentExecutionContext;
+ var executionContext = new WebInspector.ExecutionContext(this.target(), context.id, context.name, context.isPageContext, context.frameId);
+ this._executionContextById[executionContext.id] = executionContext;
+ this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextCreated, executionContext);
},
/**
- * @return {!Array.<!WebInspector.FrameExecutionContextList>}
+ * @param {number} executionContextId
*/
- contextLists: function()
+ _executionContextDestroyed: function(executionContextId)
{
- return Object.values(this._frameIdToContextList);
+ var executionContext = this._executionContextById[executionContextId];
+ delete this._executionContextById[executionContextId];
+ this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, executionContext);
+ },
+
+ _executionContextsCleared: function()
+ {
+ var contexts = this.executionContexts();
+ this._executionContextById = {};
+ for (var i = 0; i < contexts.length; ++i)
+ this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionContextDestroyed, contexts[i]);
},
/**
- * @param {!WebInspector.ResourceTreeFrame} frame
- * @return {!WebInspector.FrameExecutionContextList}
+ * @param {!RuntimeAgent.RemoteObject} payload
+ * @return {!WebInspector.RemoteObject}
*/
- contextListByFrame: function(frame)
+ createRemoteObject: function(payload)
{
- return this._frameIdToContextList[frame.id];
+ console.assert(typeof payload === "object", "Remote object payload should only be an object");
+ return new WebInspector.RemoteObjectImpl(this.target(), payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
},
- _frameAdded: function(event)
+ /**
+ * @param {!RuntimeAgent.RemoteObject} payload
+ * @param {!WebInspector.ScopeRef} scopeRef
+ * @return {!WebInspector.RemoteObject}
+ */
+ createScopeRemoteObject: function(payload, scopeRef)
{
- var frame = event.data;
- var context = new WebInspector.FrameExecutionContextList(frame);
- this._frameIdToContextList[frame.id] = context;
- this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, context);
+ return new WebInspector.ScopeRemoteObject(this.target(), payload.objectId, scopeRef, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
},
- _frameNavigated: function(event)
+ /**
+ * @param {number|string|boolean} value
+ * @return {!WebInspector.RemoteObject}
+ */
+ createRemoteObjectFromPrimitiveValue: function(value)
{
- var frame = event.data;
- var context = this._frameIdToContextList[frame.id];
- if (context)
- context._frameNavigated(frame);
+ return new WebInspector.RemoteObjectImpl(this.target(), undefined, typeof value, undefined, value);
},
- _frameDetached: function(event)
+ /**
+ * @param {string} name
+ * @param {number|string|boolean} value
+ * @return {!WebInspector.RemoteObjectProperty}
+ */
+ createRemotePropertyFromPrimitiveValue: function(name, value)
{
- var frame = event.data;
- var context = this._frameIdToContextList[frame.id];
- if (!context)
- return;
- this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, context);
- delete this._frameIdToContextList[frame.id];
+ return new WebInspector.RemoteObjectProperty(name, this.createRemoteObjectFromPrimitiveValue(value));
},
- _didLoadCachedResources: function()
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @constructor
+ * @implements {RuntimeAgent.Dispatcher}
+ * @param {!WebInspector.RuntimeModel} runtimeModel
+ */
+WebInspector.RuntimeDispatcher = function(runtimeModel)
+{
+ this._runtimeModel = runtimeModel;
+}
+
+WebInspector.RuntimeDispatcher.prototype = {
+ executionContextCreated: function(context)
{
- InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(this));
- RuntimeAgent.enable();
+ this._runtimeModel._executionContextCreated(context);
},
- _executionContextCreated: function(context)
+ executionContextDestroyed: function(executionContextId)
{
- var contextList = this._frameIdToContextList[context.frameId];
- // FIXME(85708): this should never happen
- if (!contextList)
- return;
- contextList._addExecutionContext(new WebInspector.ExecutionContext(context.id, context.name, context.isPageContext));
+ this._runtimeModel._executionContextDestroyed(executionContextId);
},
+ executionContextsCleared: function()
+ {
+ this._runtimeModel._executionContextsCleared();
+ }
+
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAware}
+ * @param {!WebInspector.Target} target
+ * @param {number|undefined} id
+ * @param {string} name
+ * @param {boolean} isPageContext
+ * @param {string=} frameId
+ */
+WebInspector.ExecutionContext = function(target, id, name, isPageContext, frameId)
+{
+ WebInspector.TargetAware.call(this, target);
+ this.id = id;
+ this.name = (isPageContext && !name) ? "<page context>" : name;
+ this.isMainWorldContext = isPageContext;
+ this._debuggerModel = target.debuggerModel;
+ this.frameId = frameId;
+}
+
+/**
+ * @param {!WebInspector.ExecutionContext} a
+ * @param {!WebInspector.ExecutionContext} b
+ * @return {number}
+ */
+WebInspector.ExecutionContext.comparator = function(a, b)
+{
+ // Main world context should always go first.
+ if (a.isMainWorldContext)
+ return -1;
+ if (b.isMainWorldContext)
+ return +1;
+ return a.name.localeCompare(b.name);
+}
+
+WebInspector.ExecutionContext.prototype = {
+
/**
* @param {string} expression
* @param {string} objectGroup
@@ -133,8 +207,9 @@ WebInspector.RuntimeModel.prototype = {
*/
evaluate: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback)
{
- if (WebInspector.debuggerModel.selectedCallFrame()) {
- WebInspector.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback);
+ //FIXME: It will be moved to separate ExecutionContext
+ if (this._debuggerModel.selectedCallFrame()) {
+ this._debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback);
return;
}
@@ -144,6 +219,7 @@ WebInspector.RuntimeModel.prototype = {
}
/**
+ * @this {WebInspector.ExecutionContext}
* @param {?Protocol.Error} error
* @param {!RuntimeAgent.RemoteObject} result
* @param {boolean=} wasThrown
@@ -158,24 +234,9 @@ WebInspector.RuntimeModel.prototype = {
if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
- callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);
+ callback(this.target().runtimeModel.createRemoteObject(result), !!wasThrown);
}
- RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, returnByValue, generatePreview, evalCallback);
- },
-
- /**
- * @param {!Element} proxyElement
- * @param {!Range} wordRange
- * @param {boolean} force
- * @param {function(!Array.<string>, number=)} completionsReadyCallback
- */
- completionsForTextPrompt: function(proxyElement, wordRange, force, completionsReadyCallback)
- {
- // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
- var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, " =:[({;,!+-*/&|^<>", proxyElement, "backward");
- var expressionString = expressionRange.toString();
- var prefix = wordRange.toString();
- this._completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
+ this.target().runtimeAgent().evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this.id, returnByValue, generatePreview, evalCallback.bind(this));
},
/**
@@ -184,7 +245,7 @@ WebInspector.RuntimeModel.prototype = {
* @param {boolean} force
* @param {function(!Array.<string>, number=)} completionsReadyCallback
*/
- _completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
+ completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
{
var lastIndex = expressionString.length - 1;
@@ -205,13 +266,13 @@ WebInspector.RuntimeModel.prototype = {
return;
}
- if (!expressionString && WebInspector.debuggerModel.selectedCallFrame())
- WebInspector.debuggerModel.getSelectedCallFrameVariables(receivedPropertyNames.bind(this));
+ if (!expressionString && this._debuggerModel.selectedCallFrame())
+ this._debuggerModel.getSelectedCallFrameVariables(receivedPropertyNames.bind(this));
else
this.evaluate(expressionString, "completion", true, true, false, false, evaluated.bind(this));
/**
- * @this {WebInspector.RuntimeModel}
+ * @this {WebInspector.ExecutionContext}
*/
function evaluated(result, wasThrown)
{
@@ -222,7 +283,8 @@ WebInspector.RuntimeModel.prototype = {
/**
* @param {string} primitiveType
- * @this {WebInspector.RuntimeModel}
+ * @suppressReceiverCheck
+ * @this {WebInspector.ExecutionContext}
*/
function getCompletions(primitiveType)
{
@@ -258,7 +320,7 @@ WebInspector.RuntimeModel.prototype = {
* @param {?WebInspector.RemoteObject} notRelevant
* @param {boolean} wasThrown
* @param {?RuntimeAgent.RemoteObject=} result
- * @this {WebInspector.RuntimeModel}
+ * @this {WebInspector.ExecutionContext}
*/
function receivedPropertyNamesFromEval(notRelevant, wasThrown, result)
{
@@ -269,11 +331,11 @@ WebInspector.RuntimeModel.prototype = {
}
/**
- * @this {WebInspector.RuntimeModel}
+ * @this {WebInspector.ExecutionContext}
*/
function receivedPropertyNames(propertyNames)
{
- RuntimeAgent.releaseObjectGroup("completion");
+ this.target().runtimeAgent().releaseObjectGroup("completion");
if (!propertyNames) {
completionsReadyCallback([]);
return;
@@ -338,136 +400,10 @@ WebInspector.RuntimeModel.prototype = {
completionsReadyCallback(results);
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAware.prototype
}
/**
* @type {!WebInspector.RuntimeModel}
*/
WebInspector.runtimeModel;
-
-/**
- * @constructor
- * @implements {RuntimeAgent.Dispatcher}
- * @param {!WebInspector.RuntimeModel} runtimeModel
- */
-WebInspector.RuntimeDispatcher = function(runtimeModel)
-{
- this._runtimeModel = runtimeModel;
-}
-
-WebInspector.RuntimeDispatcher.prototype = {
- executionContextCreated: function(context)
- {
- this._runtimeModel._executionContextCreated(context);
- }
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.ExecutionContext = function(id, name, isPageContext)
-{
- this.id = id;
- this.name = (isPageContext && !name) ? "<page context>" : name;
- this.isMainWorldContext = isPageContext;
-}
-
-/**
- * @param {!WebInspector.ExecutionContext} a
- * @param {!WebInspector.ExecutionContext} b
- * @return {number}
- */
-WebInspector.ExecutionContext.comparator = function(a, b)
-{
- // Main world context should always go first.
- if (a.isMainWorldContext)
- return -1;
- if (b.isMainWorldContext)
- return +1;
- return a.name.localeCompare(b.name);
-}
-
-/**
- * @constructor
- * @extends {WebInspector.Object}
- */
-WebInspector.FrameExecutionContextList = function(frame)
-{
- this._frame = frame;
- this._executionContexts = [];
-}
-
-WebInspector.FrameExecutionContextList.EventTypes = {
- ContextsUpdated: "ContextsUpdated",
- ContextAdded: "ContextAdded"
-}
-
-WebInspector.FrameExecutionContextList.prototype =
-{
- _frameNavigated: function(frame)
- {
- this._frame = frame;
- this._executionContexts = [];
- this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this);
- },
-
- /**
- * @param {!WebInspector.ExecutionContext} context
- */
- _addExecutionContext: function(context)
- {
- var insertAt = insertionIndexForObjectInListSortedByFunction(context, this._executionContexts, WebInspector.ExecutionContext.comparator);
- this._executionContexts.splice(insertAt, 0, context);
- this.dispatchEventToListeners(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this);
- },
-
- executionContexts: function()
- {
- return this._executionContexts;
- },
-
- mainWorldContext: function()
- {
- return this._executionContexts[0];
- },
-
- /**
- * @param {string} securityOrigin
- */
- contextBySecurityOrigin: function(securityOrigin)
- {
- for (var i = 0; i < this._executionContexts.length; ++i) {
- var context = this._executionContexts[i];
- if (!context.isMainWorldContext && context.name === securityOrigin)
- return context;
- }
- },
-
- get frameId()
- {
- return this._frame.id;
- },
-
- get url()
- {
- return this._frame.url;
- },
-
- get displayName()
- {
- if (!this._frame.parentFrame)
- return "<top frame>";
- var name = this._frame.name || "";
- var subtitle = new WebInspector.ParsedURL(this._frame.url).displayName;
- if (subtitle) {
- if (!name)
- return subtitle;
- return name + "( " + subtitle + " )";
- }
- return "<iframe>";
- },
-
- __proto__: WebInspector.Object.prototype
-}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SASSSourceMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SASSSourceMapping.js
index 467b77e858e..2b6d5247ee2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SASSSourceMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SASSSourceMapping.js
@@ -33,16 +33,16 @@
* @implements {WebInspector.SourceMapping}
* @param {!WebInspector.CSSStyleModel} cssModel
* @param {!WebInspector.Workspace} workspace
- * @param {!WebInspector.SimpleWorkspaceProvider} networkWorkspaceProvider
+ * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
*/
-WebInspector.SASSSourceMapping = function(cssModel, workspace, networkWorkspaceProvider)
+WebInspector.SASSSourceMapping = function(cssModel, workspace, networkWorkspaceBinding)
{
this.pollPeriodMs = 5000;
this.pollIntervalMs = 200;
this._cssModel = cssModel;
this._workspace = workspace;
- this._networkWorkspaceProvider = networkWorkspaceProvider;
+ this._networkWorkspaceBinding = networkWorkspaceBinding;
this._addingRevisionCounter = 0;
this._reset();
WebInspector.fileManager.addEventListener(WebInspector.FileManager.EventTypes.SavedURL, this._fileSaveFinished, this);
@@ -50,7 +50,7 @@ WebInspector.SASSSourceMapping = function(cssModel, workspace, networkWorkspaceP
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeContentCommitted, this._uiSourceCodeContentCommitted, this);
- this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._reset, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._reset, this);
}
WebInspector.SASSSourceMapping.prototype = {
@@ -141,7 +141,7 @@ WebInspector.SASSSourceMapping.prototype = {
var etagMessage = this._headerValue("etag", headers) ? ", \"ETag\" response header found instead" : "";
var message = String.sprintf("The \"Last-Modified\" response header is missing or invalid for %s%s. The CSS auto-reload functionality will not work correctly.", url, etagMessage);
- WebInspector.log(message);
+ this._cssModel.target().consoleModel.log(message);
return null;
},
@@ -242,7 +242,7 @@ WebInspector.SASSSourceMapping.prototype = {
{
var cssUISourceCode = this._workspace.uiSourceCodeForURL(cssURL);
if (!cssUISourceCode) {
- WebInspector.log(cssURL + " resource missing. Please reload the page.");
+ WebInspector.messageSink.addMessage(WebInspector.UIString("%s resource missing. Please reload the page.", cssURL));
callback(cssURL, sassURL, true);
return;
}
@@ -527,7 +527,7 @@ WebInspector.SASSSourceMapping.prototype = {
this._addCSSURLforSASSURL(rawURL, url);
if (!this._workspace.hasMappingForURL(url) && !this._workspace.uiSourceCodeForURL(url)) {
var contentProvider = sourceMap.sourceContentProvider(url, WebInspector.resourceTypes.Stylesheet);
- this._networkWorkspaceProvider.addFileForURL(url, contentProvider, true);
+ this._networkWorkspaceBinding.addFileForURL(url, contentProvider);
}
}
},
@@ -549,7 +549,7 @@ WebInspector.SASSSourceMapping.prototype = {
var uiSourceCode = this._workspace.uiSourceCodeForURL(entry[2]);
if (!uiSourceCode)
return null;
- return new WebInspector.UILocation(uiSourceCode, entry[3], entry[4]);
+ return uiSourceCode.uiLocation(entry[3], entry[4]);
},
/**
@@ -561,7 +561,23 @@ WebInspector.SASSSourceMapping.prototype = {
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
// FIXME: Implement this when ui -> raw mapping has clients.
- return new WebInspector.CSSLocation(uiSourceCode.url || "", lineNumber, columnNumber);
+ return new WebInspector.CSSLocation(this._cssModel.target(), uiSourceCode.url || "", lineNumber, columnNumber);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return false;
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._cssModel.target();
},
/**
@@ -600,7 +616,7 @@ WebInspector.SASSSourceMapping.prototype = {
this._cssURLsForSASSURL = {};
/** @type {!Object.<string, !Array.<function(?WebInspector.SourceMap)>>} */
this._pendingSourceMapLoadingCallbacks = {};
- /** @type {!Object.<string, {deadlineMs: number, dataByURL: !Object.<string, !{timer: number, previousPoll: number}>}>} */
+ /** @type {!Object.<string, !{deadlineMs: number, dataByURL: !Object.<string, !{timer: number, previousPoll: number}>}>} */
this._pollDataForSASSURL = {};
/** @type {!Object.<string, !WebInspector.SourceMap>} */
this._sourceMapByURL = {};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Script.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
index c5ae5bee8d1..2548326791b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Script.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
@@ -25,8 +25,9 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
* @implements {WebInspector.ContentProvider}
+ * @param {!WebInspector.Target} target
* @param {string} scriptId
* @param {string} sourceURL
* @param {number} startLine
@@ -37,15 +38,16 @@
* @param {string=} sourceMapURL
* @param {boolean=} hasSourceURL
*/
-WebInspector.Script = function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
+WebInspector.Script = function(target, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, isContentScript, sourceMapURL, hasSourceURL)
{
+ WebInspector.TargetAwareObject.call(this, target);
this.scriptId = scriptId;
this.sourceURL = sourceURL;
this.lineOffset = startLine;
this.columnOffset = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
- this.isContentScript = isContentScript;
+ this._isContentScript = isContentScript;
this.sourceMapURL = sourceMapURL;
this.hasSourceURL = hasSourceURL;
/** @type {!Set.<!WebInspector.Script.Location>} */
@@ -60,8 +62,28 @@ WebInspector.Script.Events = {
WebInspector.Script.snippetSourceURLPrefix = "snippets:///";
+WebInspector.Script.sourceURLRegex = /\n[\040\t]*\/\/[@#]\ssourceURL=\s*(\S*?)\s*$/mg;
+
+/**
+ * @param {string} source
+ * @return {string}
+ */
+WebInspector.Script._trimSourceURLComment = function(source)
+{
+ return source.replace(WebInspector.Script.sourceURLRegex, "");
+},
+
+
WebInspector.Script.prototype = {
/**
+ * @return {boolean}
+ */
+ isContentScript: function()
+ {
+ return this._isContentScript;
+ },
+
+ /**
* @return {string}
*/
contentURL: function()
@@ -94,12 +116,12 @@ WebInspector.Script.prototype = {
*/
function didGetScriptSource(error, source)
{
- this._source = error ? "" : source;
+ this._source = WebInspector.Script._trimSourceURLComment(error ? "" : source);
callback(this._source);
}
if (this.scriptId) {
// Script failed to parse.
- DebuggerAgent.getScriptSource(this.scriptId, didGetScriptSource.bind(this));
+ this.target().debuggerAgent().getScriptSource(this.scriptId, didGetScriptSource.bind(this));
} else
callback("");
},
@@ -113,7 +135,6 @@ WebInspector.Script.prototype = {
searchInContent: function(query, caseSensitive, isRegex, callback)
{
/**
- * @this {WebInspector.Script}
* @param {?Protocol.Error} error
* @param {!Array.<!PageAgent.SearchMatch>} searchMatches
*/
@@ -131,12 +152,23 @@ WebInspector.Script.prototype = {
if (this.scriptId) {
// Script failed to parse.
- DebuggerAgent.searchInContent(this.scriptId, query, caseSensitive, isRegex, innerCallback.bind(this));
+ this.target().debuggerAgent().searchInContent(this.scriptId, query, caseSensitive, isRegex, innerCallback);
} else
callback([]);
},
/**
+ * @param {string} source
+ * @return {string}
+ */
+ _appendSourceURLCommentIfNeeded: function(source)
+ {
+ if (!this.hasSourceURL)
+ return source;
+ return source + "\n //# sourceURL=" + this.sourceURL;
+ },
+
+ /**
* @param {string} newSource
* @param {function(?Protocol.Error, !DebuggerAgent.SetScriptSourceError=, !Array.<!DebuggerAgent.CallFrame>=, !DebuggerAgent.StackTrace=, boolean=)} callback
*/
@@ -161,8 +193,12 @@ WebInspector.Script.prototype = {
this.dispatchEventToListeners(WebInspector.Script.Events.ScriptEdited, newSource);
}
+ newSource = WebInspector.Script._trimSourceURLComment(newSource);
+ // We append correct sourceURL to script for consistency only. It's not actually needed for things to work correctly.
+ newSource = this._appendSourceURLCommentIfNeeded(newSource);
+
if (this.scriptId)
- DebuggerAgent.setScriptSource(this.scriptId, newSource, undefined, didEditScriptSource.bind(this));
+ this.target().debuggerAgent().setScriptSource(this.scriptId, newSource, undefined, didEditScriptSource.bind(this));
else
callback("Script failed to parse");
},
@@ -193,6 +229,19 @@ WebInspector.Script.prototype = {
},
/**
+ * @return {boolean}
+ */
+ isFramework: function()
+ {
+ if (!WebInspector.experimentsSettings.frameworksDebuggingSupport.isEnabled())
+ return false;
+ if (!WebInspector.settings.skipStackFramesSwitch.get())
+ return false;
+ var regex = WebInspector.settings.skipStackFramesPattern.asRegExp();
+ return regex ? regex.test(this.sourceURL) : false;
+ },
+
+ /**
* @param {number} lineNumber
* @param {number=} columnNumber
* @return {!WebInspector.UILocation}
@@ -200,11 +249,11 @@ WebInspector.Script.prototype = {
rawLocationToUILocation: function(lineNumber, columnNumber)
{
var uiLocation;
- var rawLocation = new WebInspector.DebuggerModel.Location(this.scriptId, lineNumber, columnNumber || 0);
+ var rawLocation = new WebInspector.DebuggerModel.Location(this.target(), this.scriptId, lineNumber, columnNumber || 0);
for (var i = this._sourceMappings.length - 1; !uiLocation && i >= 0; --i)
uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
console.assert(uiLocation, "Script raw location can not be mapped to any ui location.");
- return uiLocation.uiSourceCode.overrideLocation(uiLocation);
+ return /** @type {!WebInspector.UILocation} */ (uiLocation);
},
/**
@@ -216,9 +265,19 @@ WebInspector.Script.prototype = {
this.updateLocations();
},
+ /**
+ * @return {!WebInspector.SourceMapping}
+ */
+ popSourceMapping: function()
+ {
+ var sourceMapping = this._sourceMappings.pop();
+ this.updateLocations();
+ return sourceMapping;
+ },
+
updateLocations: function()
{
- var items = this._locations.items();
+ var items = this._locations.values();
for (var i = 0; i < items.length; ++i)
items[i].update();
},
@@ -237,7 +296,7 @@ WebInspector.Script.prototype = {
return location;
},
- __proto__: WebInspector.Object.prototype
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptSnippetModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ScriptSnippetModel.js
index c3195670d27..a7a75fd02f6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptSnippetModel.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/ScriptSnippetModel.js
@@ -31,36 +31,69 @@
/**
* @constructor
* @extends {WebInspector.Object}
+ * @implements {WebInspector.TargetManager.Observer}
* @param {!WebInspector.Workspace} workspace
*/
WebInspector.ScriptSnippetModel = function(workspace)
{
this._workspace = workspace;
/** @type {!Object.<string, !WebInspector.UISourceCode>} */
- this._uiSourceCodeForScriptId = {};
- /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Script>} */
- this._scriptForUISourceCode = new Map();
- /** @type {!Object.<string, !WebInspector.UISourceCode>} */
this._uiSourceCodeForSnippetId = {};
/** @type {!Map.<!WebInspector.UISourceCode, string>} */
this._snippetIdForUISourceCode = new Map();
-
+
+ /** @type {!Map.<!WebInspector.Target, !WebInspector.SnippetScriptMapping>} */
+ this._mappingForTarget = new Map();
this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
- this._snippetScriptMapping = new WebInspector.SnippetScriptMapping(this);
- this._projectDelegate = new WebInspector.SnippetsProjectDelegate(this);
- this._project = this._workspace.addProject(this._projectDelegate);
- this.reset();
- WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ this._projectId = WebInspector.projectTypes.Snippets + ":";
+ this._projectDelegate = new WebInspector.SnippetsProjectDelegate(workspace, this, this._projectId);
+ this._project = this._workspace.project(this._projectId);
+ this._loadSnippets();
+ WebInspector.targetManager.observeTargets(this);
}
WebInspector.ScriptSnippetModel.prototype = {
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ this._mappingForTarget.put(target, new WebInspector.SnippetScriptMapping(target, this));
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ this._mappingForTarget.remove(target);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ * @return {!WebInspector.SnippetScriptMapping|undefined}
+ */
+ snippetScriptMapping: function(target) {
+ return this._mappingForTarget.get(target);
+ },
+
/**
+ * @param {!WebInspector.Script} script
+ */
+ addScript: function(script)
+ {
+ this._mappingForTarget.get(script.target()).addScript(script);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
* @return {!WebInspector.SnippetScriptMapping}
*/
- get scriptMapping()
+ createSnippetScriptMapping: function(target)
{
- return this._snippetScriptMapping;
+ return new WebInspector.SnippetScriptMapping(target, this);
},
/**
@@ -96,25 +129,34 @@ WebInspector.ScriptSnippetModel.prototype = {
_addScriptSnippet: function(snippet)
{
var path = this._projectDelegate.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet));
- var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
+ var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path);
if (!uiSourceCode) {
console.assert(uiSourceCode);
return "";
}
- var scriptFile = new WebInspector.SnippetScriptFile(this, uiSourceCode);
- uiSourceCode.setScriptFile(scriptFile);
+ uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._snippetIdForUISourceCode.put(uiSourceCode, snippet.id);
- uiSourceCode.setSourceMapping(this._snippetScriptMapping);
+ var breakpointLocations = this._removeBreakpoints(uiSourceCode);
+ this._restoreBreakpoints(uiSourceCode, breakpointLocations);
this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
return path;
},
/**
+ * @param {!WebInspector.Event} event
+ */
+ _workingCopyChanged: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
+ this._scriptSnippetEdited(uiSourceCode);
+ },
+
+ /**
* @param {string} path
*/
deleteScriptSnippet: function(path)
{
- var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
+ var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path);
if (!uiSourceCode)
return;
var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
@@ -165,23 +207,16 @@ WebInspector.ScriptSnippetModel.prototype = {
*/
_scriptSnippetEdited: function(uiSourceCode)
{
- var script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return;
-
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- var scriptUISourceCode = script.rawLocationToUILocation(0, 0).uiSourceCode;
- if (scriptUISourceCode)
- this._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
+ this._mappingForTarget.values().forEach(function(mapping) {mapping._restoreBreakpoints(uiSourceCode, breakpointLocations)});
},
/**
- * @param {string} snippetId
* @return {number}
*/
- _nextEvaluationIndex: function(snippetId)
+ _nextEvaluationIndex: function()
{
var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
@@ -189,42 +224,34 @@ WebInspector.ScriptSnippetModel.prototype = {
},
/**
+ * @param {!WebInspector.ExecutionContext} executionContext
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
- evaluateScriptSnippet: function(uiSourceCode)
+ evaluateScriptSnippet: function(executionContext, uiSourceCode)
{
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._releaseSnippetScript(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
- var evaluationIndex = this._nextEvaluationIndex(snippetId);
- uiSourceCode._evaluationIndex = evaluationIndex;
- var evaluationUrl = this._evaluationSourceURL(uiSourceCode);
+ var target = executionContext.target();
+ var evaluationIndex = this._nextEvaluationIndex();
+ var mapping = this._mappingForTarget.get(target);
+ mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
+ var evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
var expression = uiSourceCode.workingCopy();
-
- // In order to stop on the breakpoints during the snippet evaluation we need to compile and run it separately.
- // If separate compilation and execution is not supported by the port we fall back to evaluation in console.
- // In case we don't need that since debugger is already paused.
- // We do the same when we are stopped on the call frame since debugger is already paused and can not stop on breakpoint anymore.
- if (WebInspector.debuggerModel.selectedCallFrame()) {
- expression = uiSourceCode.workingCopy() + "\n//# sourceURL=" + evaluationUrl + "\n";
- WebInspector.evaluateInConsole(expression, true);
- return;
- }
-
- WebInspector.showConsole();
- DebuggerAgent.compileScript(expression, evaluationUrl, compileCallback.bind(this));
+ target.consoleModel.show();
+ target.debuggerAgent().compileScript(expression, evaluationUrl, executionContext.id, compileCallback.bind(this, target));
/**
+ * @param {!WebInspector.Target} target
* @param {?string} error
- * @param {string=} scriptId
- * @param {string=} syntaxErrorMessage
+ * @param {!DebuggerAgent.ScriptId=} scriptId
+ * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.ScriptSnippetModel}
*/
- function compileCallback(error, scriptId, syntaxErrorMessage)
+ function compileCallback(target, error, scriptId, exceptionDetails)
{
- if (!uiSourceCode || uiSourceCode._evaluationIndex !== evaluationIndex)
+ if (!uiSourceCode || this._mappingForTarget.get(target).evaluationIndex(uiSourceCode) !== evaluationIndex)
return;
if (error) {
@@ -233,107 +260,95 @@ WebInspector.ScriptSnippetModel.prototype = {
}
if (!scriptId) {
- var consoleMessage = WebInspector.ConsoleMessage.create(
- WebInspector.ConsoleMessage.MessageSource.JS,
- WebInspector.ConsoleMessage.MessageLevel.Error,
- syntaxErrorMessage || "");
- WebInspector.console.addMessage(consoleMessage);
+ this._printRunOrCompileScriptResultFailure(target, exceptionDetails, evaluationUrl);
return;
}
var breakpointLocations = this._removeBreakpoints(uiSourceCode);
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
- this._runScript(scriptId);
+ this._runScript(scriptId, executionContext, evaluationUrl);
}
},
/**
* @param {!DebuggerAgent.ScriptId} scriptId
+ * @param {!WebInspector.ExecutionContext} executionContext
+ * @param {?string=} sourceURL
*/
- _runScript: function(scriptId)
+ _runScript: function(scriptId, executionContext, sourceURL)
{
- var currentExecutionContext = WebInspector.runtimeModel.currentExecutionContext();
- DebuggerAgent.runScript(scriptId, currentExecutionContext ? currentExecutionContext.id : undefined, "console", false, runCallback.bind(this));
+ var target = executionContext.target();
+ target.debuggerAgent().runScript(scriptId, executionContext.id, "console", false, runCallback.bind(this, target));
/**
+ * @param {!WebInspector.Target} target
* @param {?string} error
* @param {?RuntimeAgent.RemoteObject} result
- * @param {boolean=} wasThrown
+ * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
* @this {WebInspector.ScriptSnippetModel}
*/
- function runCallback(error, result, wasThrown)
+ function runCallback(target, error, result, exceptionDetails)
{
if (error) {
console.error(error);
return;
}
- this._printRunScriptResult(result, wasThrown);
+ if (!exceptionDetails)
+ this._printRunScriptResult(target, result, sourceURL);
+ else
+ this._printRunOrCompileScriptResultFailure(target, exceptionDetails, sourceURL);
}
},
/**
+ * @param {!WebInspector.Target} target
* @param {?RuntimeAgent.RemoteObject} result
- * @param {boolean=} wasThrown
- */
- _printRunScriptResult: function(result, wasThrown)
- {
- var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
- var message = WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.JS, level, "", undefined, undefined, undefined, undefined, undefined, [result]);
- WebInspector.console.addMessage(message)
- },
-
- /**
- * @param {!WebInspector.DebuggerModel.Location} rawLocation
- * @return {?WebInspector.UILocation}
+ * @param {?string=} sourceURL
*/
- _rawLocationToUILocation: function(rawLocation)
+ _printRunScriptResult: function(target, result, sourceURL)
{
- var uiSourceCode = this._uiSourceCodeForScriptId[rawLocation.scriptId];
- if (!uiSourceCode)
- return null;
- return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber || 0);
+ var consoleMessage = new WebInspector.ConsoleMessage(
+ target,
+ WebInspector.ConsoleMessage.MessageSource.JS,
+ WebInspector.ConsoleMessage.MessageLevel.Log,
+ "",
+ undefined,
+ sourceURL,
+ undefined,
+ undefined,
+ undefined,
+ [result],
+ undefined);
+ target.consoleModel.addMessage(consoleMessage);
},
/**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {number} lineNumber
- * @param {number} columnNumber
- * @return {?WebInspector.DebuggerModel.Location}
+ * @param {!WebInspector.Target} target
+ * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
+ * @param {?string=} sourceURL
*/
- _uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
+ _printRunOrCompileScriptResultFailure: function(target, exceptionDetails, sourceURL)
{
- var script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return null;
-
- return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
- },
-
- /**
- * @param {!WebInspector.Script} script
- */
- _addScript: function(script)
- {
- var snippetId = this._snippetIdForSourceURL(script.sourceURL);
- if (!snippetId)
- return;
- var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];
-
- if (!uiSourceCode || this._evaluationSourceURL(uiSourceCode) !== script.sourceURL)
- return;
-
- console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
- this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
- this._scriptForUISourceCode.put(uiSourceCode, script);
- uiSourceCode.scriptFile().setHasDivergedFromVM(false);
- script.pushSourceMapping(this._snippetScriptMapping);
+ var consoleMessage = new WebInspector.ConsoleMessage(
+ target,
+ exceptionDetails.source,
+ WebInspector.ConsoleMessage.MessageLevel.Error,
+ exceptionDetails.text,
+ undefined,
+ sourceURL,
+ exceptionDetails.line,
+ exceptionDetails.column,
+ undefined,
+ undefined,
+ exceptionDetails.stackTrace);
+ target.consoleModel.addMessage(consoleMessage);
},
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {!Array.<!Object>}
+ * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
*/
_removeBreakpoints: function(uiSourceCode)
{
@@ -345,14 +360,14 @@ WebInspector.ScriptSnippetModel.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {!Array.<!Object>} breakpointLocations
+ * @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
*/
_restoreBreakpoints: function(uiSourceCode, breakpointLocations)
{
for (var i = 0; i < breakpointLocations.length; ++i) {
var uiLocation = breakpointLocations[i].uiLocation;
var breakpoint = breakpointLocations[i].breakpoint;
- WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled());
+ WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
}
},
@@ -361,35 +376,7 @@ WebInspector.ScriptSnippetModel.prototype = {
*/
_releaseSnippetScript: function(uiSourceCode)
{
- var script = this._scriptForUISourceCode.get(uiSourceCode);
- if (!script)
- return null;
-
- uiSourceCode.scriptFile().setIsDivergingFromVM(true);
- uiSourceCode.scriptFile().setHasDivergedFromVM(true);
- delete this._uiSourceCodeForScriptId[script.scriptId];
- this._scriptForUISourceCode.remove(uiSourceCode);
- delete uiSourceCode._evaluationIndex;
- uiSourceCode.scriptFile().setIsDivergingFromVM(false);
- },
-
- _debuggerReset: function()
- {
- for (var snippetId in this._uiSourceCodeForSnippetId) {
- var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];
- this._releaseSnippetScript(uiSourceCode);
- }
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @return {string}
- */
- _evaluationSourceURL: function(uiSourceCode)
- {
- var evaluationSuffix = "_" + uiSourceCode._evaluationIndex;
- var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
- return WebInspector.Script.snippetSourceURLPrefix + snippetId + evaluationSuffix;
+ this._mappingForTarget.values().forEach(function(mapping) {mapping._releaseSnippetScript(uiSourceCode)});
},
/**
@@ -406,101 +393,79 @@ WebInspector.ScriptSnippetModel.prototype = {
return snippetId;
},
- reset: function()
- {
- /** @type {!Object.<string, !WebInspector.UISourceCode>} */
- this._uiSourceCodeForScriptId = {};
- this._scriptForUISourceCode = new Map();
- /** @type {!Object.<string, !WebInspector.UISourceCode>} */
- this._uiSourceCodeForSnippetId = {};
- this._snippetIdForUISourceCode = new Map();
- this._projectDelegate.reset();
- this._loadSnippets();
- },
-
__proto__: WebInspector.Object.prototype
}
/**
* @constructor
- * @implements {WebInspector.ScriptFile}
- * @extends {WebInspector.Object}
+ * @implements {WebInspector.ScriptSourceMapping}
+ * @param {!WebInspector.Target} target
* @param {!WebInspector.ScriptSnippetModel} scriptSnippetModel
- * @param {!WebInspector.UISourceCode} uiSourceCode
*/
-WebInspector.SnippetScriptFile = function(scriptSnippetModel, uiSourceCode)
+WebInspector.SnippetScriptMapping = function(target, scriptSnippetModel)
{
- WebInspector.ScriptFile.call(this);
+ this._target = target;
this._scriptSnippetModel = scriptSnippetModel;
- this._uiSourceCode = uiSourceCode;
- this._hasDivergedFromVM = true;
- this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
+ /** @type {!Object.<string, !WebInspector.UISourceCode>} */
+ this._uiSourceCodeForScriptId = {};
+ /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Script>} */
+ this._scriptForUISourceCode = new Map();
+ /** @type {!Map.<!WebInspector.UISourceCode, number>} */
+ this._evaluationIndexForUISourceCode = new Map();
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
}
-WebInspector.SnippetScriptFile.prototype = {
+WebInspector.SnippetScriptMapping.prototype = {
/**
- * @return {boolean}
+ * @param {!WebInspector.UISourceCode} uiSourceCode
*/
- hasDivergedFromVM: function()
+ _releaseSnippetScript: function(uiSourceCode)
{
- return this._hasDivergedFromVM;
- },
+ var script = this._scriptForUISourceCode.get(uiSourceCode);
+ if (!script)
+ return;
- /**
- * @param {boolean} hasDivergedFromVM
- */
- setHasDivergedFromVM: function(hasDivergedFromVM)
- {
- this._hasDivergedFromVM = hasDivergedFromVM;
+ delete this._uiSourceCodeForScriptId[script.scriptId];
+ this._scriptForUISourceCode.remove(uiSourceCode);
+ this._evaluationIndexForUISourceCode.remove(uiSourceCode);
},
/**
- * @return {boolean}
+ +* @param {number} evaluationIndex
+ * @param {!WebInspector.UISourceCode} uiSourceCode
*/
- isDivergingFromVM: function()
- {
- return this._isDivergingFromVM;
- },
-
- checkMapping: function()
+ _setEvaluationIndex: function(evaluationIndex, uiSourceCode)
{
+ this._evaluationIndexForUISourceCode.put(uiSourceCode, evaluationIndex);
},
/**
- * @return {boolean}
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {number|undefined}
*/
- isMergingToVM: function()
+ evaluationIndex: function(uiSourceCode)
{
- return false;
+ return this._evaluationIndexForUISourceCode.get(uiSourceCode);
},
/**
- * @param {boolean} isDivergingFromVM
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {string}
*/
- setIsDivergingFromVM: function(isDivergingFromVM)
+ _evaluationSourceURL: function(uiSourceCode)
{
- this._isDivergingFromVM = isDivergingFromVM;
+ var evaluationSuffix = "_" + this._evaluationIndexForUISourceCode.get(uiSourceCode);
+ var snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
+ return WebInspector.Script.snippetSourceURLPrefix + snippetId + evaluationSuffix;
},
- _workingCopyChanged: function()
+ _reset: function()
{
- this._scriptSnippetModel._scriptSnippetEdited(this._uiSourceCode);
+ this._uiSourceCodeForScriptId = {};
+ this._scriptForUISourceCode.clear();
+ this._evaluationIndexForUISourceCode.clear();
},
- __proto__: WebInspector.Object.prototype
-}
-
-/**
- * @constructor
- * @implements {WebInspector.ScriptSourceMapping}
- * @param {!WebInspector.ScriptSnippetModel} scriptSnippetModel
- */
-WebInspector.SnippetScriptMapping = function(scriptSnippetModel)
-{
- this._scriptSnippetModel = scriptSnippetModel;
-}
-
-WebInspector.SnippetScriptMapping.prototype = {
/**
* @param {!WebInspector.RawLocation} rawLocation
* @return {?WebInspector.UILocation}
@@ -508,7 +473,11 @@ WebInspector.SnippetScriptMapping.prototype = {
rawLocationToUILocation: function(rawLocation)
{
var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */(rawLocation);
- return this._scriptSnippetModel._rawLocationToUILocation(debuggerModelLocation);
+ var uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
+ if (!uiSourceCode)
+ return null;
+
+ return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
},
/**
@@ -519,7 +488,11 @@ WebInspector.SnippetScriptMapping.prototype = {
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
- return this._scriptSnippetModel._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
+ var script = this._scriptForUISourceCode.get(uiSourceCode);
+ if (!script)
+ return null;
+
+ return this._target.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
},
/**
@@ -536,7 +509,42 @@ WebInspector.SnippetScriptMapping.prototype = {
*/
addScript: function(script)
{
- this._scriptSnippetModel._addScript(script);
+ var snippetId = this.snippetIdForSourceURL(script.sourceURL);
+ if (!snippetId)
+ return;
+ var uiSourceCode = this._scriptSnippetModel._uiSourceCodeForSnippetId[snippetId];
+
+ if (!uiSourceCode || this._evaluationSourceURL(uiSourceCode) !== script.sourceURL)
+ return;
+
+ console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
+ uiSourceCode.setSourceMappingForTarget(this._target, this);
+ this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
+ this._scriptForUISourceCode.put(uiSourceCode, script);
+ script.pushSourceMapping(this);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
+ */
+ _restoreBreakpoints: function(uiSourceCode, breakpointLocations)
+ {
+ var script = this._scriptForUISourceCode.get(uiSourceCode);
+ if (!script)
+ return;
+
+ var scriptUISourceCode = script.rawLocationToUILocation(0, 0).uiSourceCode;
+ if (scriptUISourceCode)
+ this._scriptSnippetModel._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return false;
}
}
@@ -593,40 +601,31 @@ WebInspector.SnippetContentProvider.prototype = {
// searchInContent should call back later.
window.setTimeout(performSearch.bind(this), 0);
- },
-
- __proto__: WebInspector.ContentProvider.prototype
+ }
}
/**
* @constructor
* @extends {WebInspector.ContentProviderBasedProjectDelegate}
+ * @param {!WebInspector.Workspace} workspace
* @param {!WebInspector.ScriptSnippetModel} model
+ * @param {string} id
*/
-WebInspector.SnippetsProjectDelegate = function(model)
+WebInspector.SnippetsProjectDelegate = function(workspace, model, id)
{
- WebInspector.ContentProviderBasedProjectDelegate.call(this, WebInspector.projectTypes.Snippets);
+ WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, WebInspector.projectTypes.Snippets);
this._model = model;
}
WebInspector.SnippetsProjectDelegate.prototype = {
/**
- * @override
- * @return {string}
- */
- id: function()
- {
- return WebInspector.projectTypes.Snippets + ":";
- },
-
- /**
* @param {string} name
* @param {!WebInspector.ContentProvider} contentProvider
* @return {string}
*/
addSnippet: function(name, contentProvider)
{
- return this.addContentProvider("", name, name, contentProvider, true, false);
+ return this.addContentProvider("", name, name, contentProvider);
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SearchConfig.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SearchConfig.js
new file mode 100644
index 00000000000..26bd6ef69b4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SearchConfig.js
@@ -0,0 +1,180 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.ProjectSearchConfig}
+ * @param {string} query
+ * @param {boolean} ignoreCase
+ * @param {boolean} isRegex
+ */
+WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
+{
+ this._query = query;
+ this._ignoreCase = ignoreCase;
+ this._isRegex = isRegex;
+ this._parse();
+}
+
+/** @typedef {!{regex: !RegExp, isNegative: boolean}} */
+WebInspector.SearchConfig.RegexQuery;
+
+/**
+ * @param {{query: string, ignoreCase: boolean, isRegex: boolean}} object
+ * @return {!WebInspector.SearchConfig}
+ */
+WebInspector.SearchConfig.fromPlainObject = function(object)
+{
+ return new WebInspector.SearchConfig(object.query, object.ignoreCase, object.isRegex);
+}
+
+WebInspector.SearchConfig.prototype = {
+ /**
+ * @return {string}
+ */
+ query: function()
+ {
+ return this._query;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ ignoreCase: function()
+ {
+ return this._ignoreCase;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isRegex: function()
+ {
+ return this._isRegex;
+ },
+
+ /**
+ * @return {{query: string, ignoreCase: boolean, isRegex: boolean}}
+ */
+ toPlainObject: function()
+ {
+ return { query: this.query(), ignoreCase: this.ignoreCase(), isRegex: this.isRegex() };
+ },
+
+ _parse: function()
+ {
+ var filePattern = "(?:-)?file:(([^\\\\ ]|\\\\.)+)"; // After file: prefix: any symbol except space and backslash or any symbol escaped with a backslash.
+ var quotedPattern = "\"(([^\\\\\"]|\\\\.)+)\""; // Inside double quotes: any symbol except double quote and backslash or any symbol escaped with a backslash.
+ var unquotedPattern = "(([^\\\\ ]|\\\\.)+)"; // any symbol except space and backslash or any symbol escaped with a backslash.
+
+ var pattern = "(" + filePattern + ")|(" + quotedPattern + ")|(" + unquotedPattern + ")";
+ var regexp = new RegExp(pattern, "g");
+ var queryParts = this._query.match(regexp) || [];
+
+ /**
+ * @type {!Array.<!WebInspector.SearchConfig.QueryTerm>}
+ */
+ this._fileQueries = [];
+
+ /**
+ * @type {!Array.<string>}
+ */
+ this._queries = [];
+
+ for (var i = 0; i < queryParts.length; ++i) {
+ var queryPart = queryParts[i];
+ if (!queryPart)
+ continue;
+ var fileQuery = this._parseFileQuery(queryPart);
+ if (fileQuery) {
+ this._fileQueries.push(fileQuery);
+ /** @type {!Array.<!WebInspector.SearchConfig.RegexQuery>} */
+ this._fileRegexQueries = this._fileRegexQueries || [];
+ this._fileRegexQueries.push({ regex: new RegExp(fileQuery.text, this.ignoreCase ? "i" : ""), isNegative: fileQuery.isNegative });
+ continue;
+ }
+ if (queryPart.startsWith("\"")) {
+ if (!queryPart.endsWith("\""))
+ continue;
+ this._queries.push(this._parseQuotedQuery(queryPart));
+ continue;
+ }
+ this._queries.push(this._parseUnquotedQuery(queryPart));
+ }
+ },
+
+ /**
+ * @param {string} filePath
+ * @return {boolean}
+ */
+ filePathMatchesFileQuery: function(filePath)
+ {
+ if (!this._fileRegexQueries)
+ return true;
+ for (var i = 0; i < this._fileRegexQueries.length; ++i) {
+ if (!!filePath.match(this._fileRegexQueries[i].regex) === this._fileRegexQueries[i].isNegative)
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * @return {!Array.<string>}
+ */
+ queries: function()
+ {
+ return this._queries;
+ },
+
+ _parseUnquotedQuery: function(query)
+ {
+ return query.replace(/\\(.)/g, "$1");
+ },
+
+ _parseQuotedQuery: function(query)
+ {
+ return query.substring(1, query.length - 1).replace(/\\(.)/g, "$1");
+ },
+
+ /**
+ * @param {string} query
+ * @return {?WebInspector.SearchConfig.QueryTerm}
+ */
+ _parseFileQuery: function(query)
+ {
+ var match = query.match(/^(-)?file:/);
+ if (!match)
+ return null;
+ var isNegative = !!match[1];
+ query = query.substr(match[0].length);
+ var result = "";
+ for (var i = 0; i < query.length; ++i) {
+ var char = query[i];
+ if (char === "*") {
+ result += ".*";
+ } else if (char === "\\") {
+ ++i;
+ var nextChar = query[i];
+ if (nextChar === " ")
+ result += " ";
+ } else {
+ if (String.regexSpecialCharacters().indexOf(query.charAt(i)) !== -1)
+ result += "\\";
+ result += query.charAt(i);
+ }
+ }
+ return new WebInspector.SearchConfig.QueryTerm(result, isNegative);
+ }
+}
+
+/**
+ * @constructor
+ * @param {string} text
+ * @param {boolean} isNegative
+ */
+WebInspector.SearchConfig.QueryTerm = function(text, isNegative)
+{
+ this.text = text;
+ this.isNegative = isNegative;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SnippetStorage.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SnippetStorage.js
index 9df3f73dfef..93acff5ce90 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SnippetStorage.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SnippetStorage.js
@@ -127,13 +127,6 @@ WebInspector.SnippetStorage.prototype = {
{
this._snippets[snippet.id] = snippet;
},
-
- reset: function()
- {
- this._lastSnippetIdentifierSetting.set(0);
- this._snippetsSetting.set([]);
- this._snippets = {};
- },
__proto__: WebInspector.Object.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourceMap.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js
index 3216cb0de4c..4ccd5e4df2c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourceMap.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMap.js
@@ -29,6 +29,37 @@
*/
/**
+ * @constructor
+ */
+function SourceMapV3()
+{
+ /** @type {number} */ this.version;
+ /** @type {string|undefined} */ this.file;
+ /** @type {!Array.<string>} */ this.sources;
+ /** @type {!Array.<!SourceMapV3.Section>|undefined} */ this.sections;
+ /** @type {string} */ this.mappings;
+ /** @type {string|undefined} */ this.sourceRoot;
+}
+
+/**
+ * @constructor
+ */
+SourceMapV3.Section = function()
+{
+ /** @type {!SourceMapV3} */ this.map;
+ /** @type {!SourceMapV3.Offset} */ this.offset;
+}
+
+/**
+ * @constructor
+ */
+SourceMapV3.Offset = function()
+{
+ /** @type {number} */ this.line;
+ /** @type {number} */ this.column;
+}
+
+/**
* Implements Source Map V3 model. See http://code.google.com/p/closure-compiler/wiki/SourceMaps
* for format description.
* @constructor
@@ -52,14 +83,6 @@ WebInspector.SourceMap = function(sourceMappingURL, payload)
this._parseMappingPayload(payload);
}
-WebInspector.SourceMap._sourceMapRequestHeaderName = "X-Source-Map-Request-From";
-WebInspector.SourceMap._sourceMapRequestHeaderValue = "inspector";
-
-WebInspector.SourceMap.hasSourceMapRequestHeader = function(request)
-{
- return request && request.requestHeaderValue(WebInspector.SourceMap._sourceMapRequestHeaderName) === WebInspector.SourceMap._sourceMapRequestHeaderValue;
-}
-
/**
* @param {string} sourceMapURL
* @param {string} compiledURL
@@ -69,8 +92,7 @@ WebInspector.SourceMap.hasSourceMapRequestHeader = function(request)
WebInspector.SourceMap.load = function(sourceMapURL, compiledURL, callback)
{
var headers = {};
- headers[WebInspector.SourceMap._sourceMapRequestHeaderName] = WebInspector.SourceMap._sourceMapRequestHeaderValue;
- NetworkAgent.loadResourceForFrontend(WebInspector.resourceTreeModel.mainFrame.id, sourceMapURL, headers, contentLoaded.bind(this));
+ NetworkAgent.loadResourceForFrontend(WebInspector.resourceTreeModel.mainFrame.id, sourceMapURL, headers, contentLoaded);
/**
* @param {?Protocol.Error} error
@@ -162,7 +184,7 @@ WebInspector.SourceMap.prototype = {
/**
* @param {number} lineNumber in compiled resource
* @param {number} columnNumber in compiled resource
- * @return {?Array.<*>}
+ * @return {?Array.<number|string>}
*/
findEntry: function(lineNumber, columnNumber)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourceMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMapping.js
index cc2812f95a3..791a540c00f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourceMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/SourceMapping.js
@@ -48,7 +48,12 @@ WebInspector.SourceMapping.prototype = {
* @param {number} columnNumber
* @return {?WebInspector.RawLocation}
*/
- uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { }
+ uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber) { },
+
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function() { }
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/StylesSourceMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/StylesSourceMapping.js
index 42393143336..950e0e2e61c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/StylesSourceMapping.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/StylesSourceMapping.js
@@ -38,11 +38,11 @@ WebInspector.StylesSourceMapping = function(cssModel, workspace)
{
this._cssModel = cssModel;
this._workspace = workspace;
- this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this);
this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameCreatedOrNavigated, this._mainFrameCreatedOrNavigated, this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
this._initialize();
@@ -61,7 +61,7 @@ WebInspector.StylesSourceMapping.prototype = {
var uiSourceCode = this._workspace.uiSourceCodeForURL(location.url);
if (!uiSourceCode)
return null;
- return new WebInspector.UILocation(uiSourceCode, location.lineNumber, location.columnNumber);
+ return uiSourceCode.uiLocation(location.lineNumber, location.columnNumber);
},
/**
@@ -72,7 +72,23 @@ WebInspector.StylesSourceMapping.prototype = {
*/
uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
{
- return new WebInspector.CSSLocation(uiSourceCode.url || "", lineNumber, columnNumber);
+ return new WebInspector.CSSLocation(this._cssModel.target(), uiSourceCode.url || "", lineNumber, columnNumber);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return true;
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._cssModel.target();
},
/**
@@ -167,7 +183,7 @@ WebInspector.StylesSourceMapping.prototype = {
/**
* @param {!WebInspector.Event} event
*/
- _projectWillReset: function(event)
+ _projectRemoved: function(event)
{
var project = /** @type {!WebInspector.Project} */ (event.data);
var uiSourceCodes = project.uiSourceCodes();
@@ -195,7 +211,7 @@ WebInspector.StylesSourceMapping.prototype = {
/**
* @param {!WebInspector.Event} event
*/
- _mainFrameCreatedOrNavigated: function(event)
+ _mainFrameNavigated: function(event)
{
for (var url in this._urlToHeadersByFrameId) {
var uiSourceCode = this._workspace.uiSourceCodeForURL(url);
@@ -271,40 +287,28 @@ WebInspector.StylesSourceMapping.prototype = {
delete this._updateStyleSheetTextTimer;
}
- CSSAgent.getStyleSheetText(styleSheetId, callback.bind(this));
-
- /**
- * @param {?string} error
- * @param {string} content
- * @this {WebInspector.StylesSourceMapping}
- */
- function callback(error, content)
- {
- if (!error)
- this._innerStyleSheetChanged(styleSheetId, content);
- }
- },
-
- /**
- * @param {!CSSAgent.StyleSheetId} styleSheetId
- * @param {string} content
- */
- _innerStyleSheetChanged: function(styleSheetId, content)
- {
var header = this._cssModel.styleSheetHeaderForId(styleSheetId);
if (!header)
return;
var styleSheetURL = header.resourceURL();
if (!styleSheetURL)
return;
-
var uiSourceCode = this._workspace.uiSourceCodeForURL(styleSheetURL)
if (!uiSourceCode)
return;
+ header.requestContent(callback.bind(this, uiSourceCode));
- var styleFile = this._styleFiles.get(uiSourceCode);
- if (styleFile)
- styleFile.addRevision(content);
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {?string} content
+ * @this {WebInspector.StylesSourceMapping}
+ */
+ function callback(uiSourceCode, content)
+ {
+ var styleFile = this._styleFiles.get(uiSourceCode);
+ if (styleFile)
+ styleFile.addRevision(content || "");
+ }
}
}
@@ -319,57 +323,53 @@ WebInspector.StyleFile = function(uiSourceCode, mapping)
this._mapping = mapping;
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
+ this._commitThrottler = new WebInspector.Throttler(WebInspector.StyleFile.updateTimeout);
}
WebInspector.StyleFile.updateTimeout = 200;
-WebInspector.StyleFile.sourceURLRegex = /\n[\040\t]*\/\*#[\040\t]sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/m;
-
WebInspector.StyleFile.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
_workingCopyCommitted: function(event)
{
if (this._isAddingRevision)
return;
- this._commitIncrementalEdit(true);
+ this._isMajorChangePending = true;
+ this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), true);
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
_workingCopyChanged: function(event)
{
if (this._isAddingRevision)
return;
- // FIXME: Extensions tests override updateTimeout because extensions don't have any control over applying changes to domain specific bindings.
- if (WebInspector.StyleFile.updateTimeout >= 0) {
- this._incrementalUpdateTimer = setTimeout(this._commitIncrementalEdit.bind(this, false), WebInspector.StyleFile.updateTimeout)
- } else
- this._commitIncrementalEdit(false);
+ this._commitThrottler.schedule(this._commitIncrementalEdit.bind(this), false);
},
/**
- * @param {boolean} majorChange
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
*/
- _commitIncrementalEdit: function(majorChange)
+ _commitIncrementalEdit: function(finishCallback)
{
- this._clearIncrementalUpdateTimer();
- this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.workingCopy(), majorChange, this._styleContentSet.bind(this));
+ this._mapping._setStyleContent(this._uiSourceCode, this._uiSourceCode.workingCopy(), this._isMajorChangePending, this._styleContentSet.bind(this, finishCallback));
+ this._isMajorChangePending = false;
},
/**
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback
* @param {?string} error
*/
- _styleContentSet: function(error)
+ _styleContentSet: function(finishCallback, error)
{
if (error)
- WebInspector.showErrorMessage(error);
- },
-
- _clearIncrementalUpdateTimer: function()
- {
- if (!this._incrementalUpdateTimer)
- return;
- clearTimeout(this._incrementalUpdateTimer);
- delete this._incrementalUpdateTimer;
+ this._mapping._cssModel.target().consoleModel.showErrorMessage(error);
+ finishCallback();
},
/**
@@ -378,8 +378,6 @@ WebInspector.StyleFile.prototype = {
addRevision: function(content)
{
this._isAddingRevision = true;
- if (this._uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem)
- content = content.replace(WebInspector.StyleFile.sourceURLRegex, "");
this._uiSourceCode.addRevision(content);
delete this._isAddingRevision;
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Target.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
new file mode 100644
index 00000000000..d257fda6d76
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {Protocol.Agents}
+ * @param {string} name
+ * @param {!InspectorBackendClass.Connection} connection
+ * @param {function(!WebInspector.Target)=} callback
+ */
+WebInspector.Target = function(name, connection, callback)
+{
+ Protocol.Agents.call(this, connection.agentsMap());
+ this._name = name;
+ this._connection = connection;
+ /** @type {boolean} */
+ this.isMainFrontend = false;
+ this._id = WebInspector.Target._nextId++;
+ /** @type {boolean} */
+ this.canScreencast = false;
+ this.pageAgent().canScreencast(this._initializeCapability.bind(this, "canScreencast", null));
+
+ /** @type {boolean} */
+ this.hasTouchInputs = false;
+ this.pageAgent().hasTouchInputs(this._initializeCapability.bind(this, "hasTouchInputs", null));
+
+ if (WebInspector.experimentsSettings.timelinePowerProfiler.isEnabled())
+ this.powerAgent().canProfilePower(this._initializeCapability.bind(this, "canProfilePower", null));
+
+ this.workerAgent().canInspectWorkers(this._initializeCapability.bind(this, "isMainFrontend", this._loadedWithCapabilities.bind(this, callback)));
+
+ /** @type {!WebInspector.Lock} */
+ this.profilingLock = new WebInspector.Lock();
+}
+
+WebInspector.Target._nextId = 1;
+
+WebInspector.Target.prototype = {
+
+ /**
+ * @return {number}
+ */
+ id: function()
+ {
+ return this._id;
+ },
+
+ /**
+ *
+ * @return {string}
+ */
+ name: function()
+ {
+ return this._name;
+ },
+
+ /**
+ * @param {string} name
+ * @param {function()|null} callback
+ * @param {?Protocol.Error} error
+ * @param {*} result
+ */
+ _initializeCapability: function(name, callback, error, result)
+ {
+ this[name] = result;
+ if (!Capabilities[name])
+ Capabilities[name] = result;
+ if (callback)
+ callback();
+ },
+
+ /**
+ * @param {function(!WebInspector.Target)=} callback
+ */
+ _loadedWithCapabilities: function(callback)
+ {
+ /** @type {!WebInspector.ConsoleModel} */
+ this.consoleModel = new WebInspector.ConsoleModel(this);
+ // This and similar lines are needed for compatibility.
+ if (!WebInspector.console)
+ WebInspector.console = this.consoleModel;
+
+ /** @type {!WebInspector.NetworkManager} */
+ this.networkManager = new WebInspector.NetworkManager(this);
+ if (!WebInspector.networkManager)
+ WebInspector.networkManager = this.networkManager;
+
+ /** @type {!WebInspector.ResourceTreeModel} */
+ this.resourceTreeModel = new WebInspector.ResourceTreeModel(this);
+ if (!WebInspector.resourceTreeModel)
+ WebInspector.resourceTreeModel = this.resourceTreeModel;
+
+ /** @type {!WebInspector.NetworkLog} */
+ this.networkLog = new WebInspector.NetworkLog(this);
+ if (!WebInspector.networkLog)
+ WebInspector.networkLog = this.networkLog;
+
+ /** @type {!WebInspector.DebuggerModel} */
+ this.debuggerModel = new WebInspector.DebuggerModel(this);
+ if (!WebInspector.debuggerModel)
+ WebInspector.debuggerModel = this.debuggerModel;
+
+ /** @type {!WebInspector.RuntimeModel} */
+ this.runtimeModel = new WebInspector.RuntimeModel(this);
+ if (!WebInspector.runtimeModel)
+ WebInspector.runtimeModel = this.runtimeModel;
+
+ /** @type {!WebInspector.DOMModel} */
+ this.domModel = new WebInspector.DOMModel(this);
+ if (!WebInspector.domModel)
+ WebInspector.domModel = this.domModel;
+
+ /** @type {!WebInspector.CSSStyleModel} */
+ this.cssModel = new WebInspector.CSSStyleModel(this);
+ if (!WebInspector.cssModel)
+ WebInspector.cssModel = this.cssModel;
+
+ /** @type {!WebInspector.WorkerManager} */
+ this.workerManager = new WebInspector.WorkerManager(this, this.isMainFrontend);
+ if (!WebInspector.workerManager)
+ WebInspector.workerManager = this.workerManager;
+
+ if (this.canProfilePower)
+ WebInspector.powerProfiler = new WebInspector.PowerProfiler();
+
+ /** @type {!WebInspector.TimelineManager} */
+ this.timelineManager = new WebInspector.TimelineManager(this);
+ if (!WebInspector.timelineManager)
+ WebInspector.timelineManager = this.timelineManager;
+
+ /** @type {!WebInspector.DatabaseModel} */
+ this.databaseModel = new WebInspector.DatabaseModel(this);
+ if (!WebInspector.databaseModel)
+ WebInspector.databaseModel = this.databaseModel;
+
+ /** @type {!WebInspector.DOMStorageModel} */
+ this.domStorageModel = new WebInspector.DOMStorageModel(this);
+ if (!WebInspector.domStorageModel)
+ WebInspector.domStorageModel = this.domStorageModel;
+
+ /** @type {!WebInspector.CPUProfilerModel} */
+ this.cpuProfilerModel = new WebInspector.CPUProfilerModel(this);
+ if (!WebInspector.cpuProfilerModel)
+ WebInspector.cpuProfilerModel = this.cpuProfilerModel;
+
+ new WebInspector.DebuggerScriptMapping(this.debuggerModel, WebInspector.workspace, WebInspector.networkWorkspaceBinding);
+
+ if (callback)
+ callback(this);
+ },
+
+ /**
+ * @override
+ * @param {string} domain
+ * @param {!Object} dispatcher
+ */
+ registerDispatcher: function(domain, dispatcher)
+ {
+ this._connection.registerDispatcher(domain, dispatcher);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isWorkerTarget: function()
+ {
+ return !this.isMainFrontend;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isMobile: function()
+ {
+ // FIXME: either add a separate capability or rename canScreencast to isMobile.
+ return this.canScreencast;
+ },
+
+ __proto__: Protocol.Agents.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TargetAware = function(target)
+{
+ this._target = target;
+}
+
+WebInspector.TargetAware.prototype = {
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TargetAwareObject = function(target)
+{
+ WebInspector.Object.call(this);
+ this._target = target;
+}
+
+WebInspector.TargetAwareObject.prototype = {
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._target;
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TargetManager = function()
+{
+ /** @type {!Array.<!WebInspector.Target>} */
+ this._targets = [];
+ /** @type {!Array.<!WebInspector.TargetManager.Observer>} */
+ this._observers = [];
+}
+
+WebInspector.TargetManager.prototype = {
+
+ /**
+ * @param {!WebInspector.TargetManager.Observer} targetObserver
+ */
+ observeTargets: function(targetObserver)
+ {
+ this.targets().forEach(targetObserver.targetAdded.bind(targetObserver));
+ this._observers.push(targetObserver);
+ },
+
+ /**
+ * @param {!WebInspector.TargetManager.Observer} targetObserver
+ */
+ unobserveTargets: function(targetObserver)
+ {
+ this._observers.remove(targetObserver);
+ },
+
+ /**
+ * @param {string} name
+ * @param {!InspectorBackendClass.Connection} connection
+ * @param {function(!WebInspector.Target)=} callback
+ */
+ createTarget: function(name, connection, callback)
+ {
+ var target = new WebInspector.Target(name, connection, callbackWrapper.bind(this));
+
+ /**
+ * @this {WebInspector.TargetManager}
+ * @param {!WebInspector.Target} newTarget
+ */
+ function callbackWrapper(newTarget)
+ {
+ this.addTarget(newTarget);
+ if (callback)
+ callback(newTarget);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Target} newTarget
+ */
+ addTarget: function(newTarget)
+ {
+ this._targets.push(newTarget);
+ var copy = this._observers;
+ for (var i = 0; i < copy.length; ++i)
+ copy[i].targetAdded(newTarget);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ removeTarget: function(target)
+ {
+ this._targets.remove(target);
+ var copy = this._observers;
+ for (var i = 0; i < copy.length; ++i)
+ copy[i].targetRemoved(target);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.Target>}
+ */
+ targets: function()
+ {
+ return this._targets;
+ },
+
+ /**
+ * @return {?WebInspector.Target}
+ */
+ activeTarget: function()
+ {
+ return this._targets[0];
+ }
+}
+
+/**
+ * @interface
+ */
+WebInspector.TargetManager.Observer = function()
+{
+}
+
+WebInspector.TargetManager.Observer.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target) { },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target) { },
+}
+
+/**
+ * @type {!WebInspector.TargetManager}
+ */
+WebInspector.targetManager;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/TempFile.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/TempFile.js
new file mode 100644
index 00000000000..f2519eceec9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/TempFile.js
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
+
+/**
+ * @constructor
+ * @param {!string} dirPath
+ * @param {!string} name
+ * @param {!function(?WebInspector.TempFile)} callback
+ */
+WebInspector.TempFile = function(dirPath, name, callback)
+{
+ this._fileEntry = null;
+ this._writer = null;
+
+ /**
+ * @param {!FileSystem} fs
+ * @this {WebInspector.TempFile}
+ */
+ function didInitFs(fs)
+ {
+ fs.root.getDirectory(dirPath, { create: true }, didGetDir.bind(this), errorHandler);
+ }
+
+ /**
+ * @param {!DirectoryEntry} dir
+ * @this {WebInspector.TempFile}
+ */
+ function didGetDir(dir)
+ {
+ dir.getFile(name, { create: true }, didCreateFile.bind(this), errorHandler);
+ }
+
+ /**
+ * @param {!FileEntry} fileEntry
+ * @this {WebInspector.TempFile}
+ */
+ function didCreateFile(fileEntry)
+ {
+ this._fileEntry = fileEntry;
+ fileEntry.createWriter(didCreateWriter.bind(this), errorHandler);
+ }
+
+ /**
+ * @param {!FileWriter} writer
+ * @this {WebInspector.TempFile}
+ */
+ function didCreateWriter(writer)
+ {
+ /**
+ * @this {WebInspector.TempFile}
+ */
+ function didTruncate(e)
+ {
+ this._writer = writer;
+ writer.onwrite = null;
+ writer.onerror = null;
+ callback(this);
+ }
+
+ function onTruncateError(e)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to truncate temp file " + e.code + " : " + e.message);
+ callback(null);
+ }
+
+ if (writer.length) {
+ writer.onwrite = didTruncate.bind(this);
+ writer.onerror = onTruncateError;
+ writer.truncate(0);
+ } else {
+ this._writer = writer;
+ callback(this);
+ }
+ }
+
+ function errorHandler(e)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to create temp file " + e.code + " : " + e.message);
+ callback(null);
+ }
+
+ /**
+ * @this {WebInspector.TempFile}
+ */
+ function didClearTempStorage()
+ {
+ window.requestFileSystem(window.TEMPORARY, 10, didInitFs.bind(this), errorHandler);
+ }
+ WebInspector.TempFile._ensureTempStorageCleared(didClearTempStorage.bind(this));
+}
+
+WebInspector.TempFile.prototype = {
+ /**
+ * @param {!string} data
+ * @param {!function(boolean)} callback
+ */
+ write: function(data, callback)
+ {
+ var blob = new Blob([data], {type: 'text/plain'});
+ this._writer.onerror = function(e)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to write into a temp file: " + e.message);
+ callback(false);
+ }
+ this._writer.onwrite = function(e)
+ {
+ callback(true);
+ }
+ this._writer.write(blob);
+ },
+
+ finishWriting: function()
+ {
+ this._writer = null;
+ },
+
+ /**
+ * @param {function(?string)} callback
+ */
+ read: function(callback)
+ {
+ /**
+ * @param {!File} file
+ */
+ function didGetFile(file)
+ {
+ var reader = new FileReader();
+
+ /**
+ * @this {FileReader}
+ */
+ reader.onloadend = function(e)
+ {
+ callback(/** @type {?string} */ (this.result));
+ }
+ reader.onerror = function(error)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to read from temp file: " + error.message);
+ }
+ reader.readAsText(file);
+ }
+ function didFailToGetFile(error)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to load temp file: " + error.message);
+ callback(null);
+ }
+ this._fileEntry.file(didGetFile, didFailToGetFile);
+ },
+
+ /**
+ * @param {!WebInspector.OutputStream} outputStream
+ * @param {!WebInspector.OutputStreamDelegate} delegate
+ */
+ writeToOutputSteam: function(outputStream, delegate)
+ {
+ /**
+ * @param {!File} file
+ */
+ function didGetFile(file)
+ {
+ var reader = new WebInspector.ChunkedFileReader(file, 10*1000*1000, delegate);
+ reader.start(outputStream);
+ }
+
+ function didFailToGetFile(error)
+ {
+ WebInspector.messageSink.addErrorMessage("Failed to load temp file: " + error.message);
+ outputStream.close();
+ }
+
+ this._fileEntry.file(didGetFile, didFailToGetFile);
+ },
+
+ remove: function()
+ {
+ if (this._fileEntry)
+ this._fileEntry.remove(function() {});
+ }
+}
+
+/**
+ * @constructor
+ * @param {!string} dirPath
+ * @param {!string} name
+ */
+WebInspector.BufferedTempFileWriter = function(dirPath, name)
+{
+ this._chunks = [];
+ this._tempFile = null;
+ this._isWriting = false;
+ this._finishCallback = null;
+ this._isFinished = false;
+ new WebInspector.TempFile(dirPath, name, this._didCreateTempFile.bind(this));
+}
+
+WebInspector.BufferedTempFileWriter.prototype = {
+ /**
+ * @param {!string} data
+ */
+ write: function(data)
+ {
+ if (!this._chunks)
+ return;
+ if (this._finishCallback)
+ throw new Error("No writes are allowed after close.");
+ this._chunks.push(data);
+ if (this._tempFile && !this._isWriting)
+ this._writeNextChunk();
+ },
+
+ /**
+ * @param {!function(?WebInspector.TempFile)} callback
+ */
+ close: function(callback)
+ {
+ this._finishCallback = callback;
+ if (this._isFinished)
+ callback(this._tempFile);
+ else if (!this._isWriting && !this._chunks.length)
+ this._notifyFinished();
+ },
+
+ _didCreateTempFile: function(tempFile)
+ {
+ this._tempFile = tempFile;
+ if (!tempFile) {
+ this._chunks = null;
+ this._notifyFinished();
+ return;
+ }
+ if (this._chunks.length)
+ this._writeNextChunk();
+ },
+
+ _writeNextChunk: function()
+ {
+ var chunkSize = 0;
+ var endIndex = 0;
+ for (; endIndex < this._chunks.length; endIndex++) {
+ chunkSize += this._chunks[endIndex].length;
+ if (chunkSize > 10 * 1000 * 1000)
+ break;
+ }
+ var chunk = this._chunks.slice(0, endIndex + 1).join("");
+ this._chunks.splice(0, endIndex + 1);
+ this._isWriting = true;
+ this._tempFile.write(chunk, this._didWriteChunk.bind(this));
+ },
+
+ _didWriteChunk: function(success)
+ {
+ this._isWriting = false;
+ if (!success) {
+ this._tempFile = null;
+ this._chunks = null;
+ this._notifyFinished();
+ return;
+ }
+ if (this._chunks.length)
+ this._writeNextChunk();
+ else if (this._finishCallback)
+ this._notifyFinished();
+ },
+
+ _notifyFinished: function()
+ {
+ this._isFinished = true;
+ if (this._tempFile)
+ this._tempFile.finishWriting();
+ if (this._finishCallback)
+ this._finishCallback(this._tempFile);
+ }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TempStorageCleaner = function()
+{
+ this._worker = new SharedWorker("temp_storage_shared_worker/TempStorageSharedWorker.js", "TempStorage");
+ this._callbacks = [];
+ this._worker.port.onmessage = this._handleMessage.bind(this);
+ this._worker.port.onerror = this._handleError.bind(this);
+}
+
+WebInspector.TempStorageCleaner.prototype = {
+ /**
+ * @param {!function()} callback
+ */
+ ensureStorageCleared: function(callback)
+ {
+ if (this._callbacks)
+ this._callbacks.push(callback);
+ else
+ callback();
+ },
+
+ _handleMessage: function(event)
+ {
+ if (event.data.type === "tempStorageCleared") {
+ if (event.data.error)
+ WebInspector.messageSink.addErrorMessage(event.data.error);
+ this._notifyCallbacks();
+ }
+ },
+
+ _handleError: function(event)
+ {
+ WebInspector.messageSink.addErrorMessage(WebInspector.UIString("Failed to clear temp storage: %s", event.data));
+ this._notifyCallbacks();
+ },
+
+ _notifyCallbacks: function()
+ {
+ var callbacks = this._callbacks;
+ this._callbacks = null;
+ for (var i = 0; i < callbacks.length; i++)
+ callbacks[i]();
+ }
+}
+
+/**
+ * @param {!function()} callback
+ */
+WebInspector.TempFile._ensureTempStorageCleared = function(callback)
+{
+ if (!WebInspector.TempFile._storageCleaner)
+ WebInspector.TempFile._storageCleaner = new WebInspector.TempStorageCleaner();
+ WebInspector.TempFile._storageCleaner.ensureStorageCleared(callback);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/TimelineManager.js
index af394961ffb..73f767cd668 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineManager.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/TimelineManager.js
@@ -30,20 +30,23 @@
/**
* @constructor
- * @extends {WebInspector.Object}
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
*/
-WebInspector.TimelineManager = function()
+WebInspector.TimelineManager = function(target)
{
- WebInspector.Object.call(this);
+ WebInspector.TargetAwareObject.call(this, target);
this._dispatcher = new WebInspector.TimelineDispatcher(this);
this._enablementCount = 0;
+ this._jsProfilerStarted = false;
TimelineAgent.enable();
}
WebInspector.TimelineManager.EventTypes = {
TimelineStarted: "TimelineStarted",
TimelineStopped: "TimelineStopped",
- TimelineEventRecorded: "TimelineEventRecorded"
+ TimelineEventRecorded: "TimelineEventRecorded",
+ TimelineProgress: "TimelineProgress"
}
WebInspector.TimelineManager.prototype = {
@@ -57,21 +60,29 @@ WebInspector.TimelineManager.prototype = {
/**
* @param {number=} maxCallStackDepth
- * @param {boolean=} includeDomCounters
+ * @param {boolean=} bufferEvents
+ * @param {string=} liveEvents
+ * @param {boolean=} includeCounters
* @param {boolean=} includeGPUEvents
* @param {function(?Protocol.Error)=} callback
*/
- start: function(maxCallStackDepth, includeDomCounters, includeGPUEvents, callback)
+ start: function(maxCallStackDepth, bufferEvents, liveEvents, includeCounters, includeGPUEvents, callback)
{
this._enablementCount++;
+ this.target().profilingLock.acquire();
+ if (WebInspector.experimentsSettings.timelineJSCPUProfile.isEnabled() && maxCallStackDepth) {
+ this._configureCpuProfilerSamplingInterval();
+ this._jsProfilerStarted = true;
+ ProfilerAgent.start();
+ }
if (this._enablementCount === 1)
- TimelineAgent.start(maxCallStackDepth, /* bufferEvents */false, includeDomCounters, includeGPUEvents, callback);
+ TimelineAgent.start(maxCallStackDepth, bufferEvents, liveEvents, includeCounters, includeGPUEvents, callback);
else if (callback)
callback(null);
},
/**
- * @param {function(?Protocol.Error)=} callback
+ * @param {function(?Protocol.Error,?ProfilerAgent.CPUProfile)} callback
*/
stop: function(callback)
{
@@ -80,13 +91,79 @@ WebInspector.TimelineManager.prototype = {
console.error("WebInspector.TimelineManager start/stop calls are unbalanced " + new Error().stack);
return;
}
+
+ var masterError = null;
+ var masterProfile = null;
+ var callbackBarrier = new CallbackBarrier();
+
+ if (this._jsProfilerStarted) {
+ ProfilerAgent.stop(callbackBarrier.createCallback(profilerCallback));
+ this._jsProfilerStarted = false;
+ }
if (!this._enablementCount)
- TimelineAgent.stop(callback);
- else if (callback)
- callback(null);
+ TimelineAgent.stop(callbackBarrier.createCallback(this._processBufferedEvents.bind(this, timelineCallback)));
+
+ callbackBarrier.callWhenDone(allDoneCallback.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ */
+ function timelineCallback(error)
+ {
+ masterError = masterError || error;
+ }
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!ProfilerAgent.CPUProfile} profile
+ */
+ function profilerCallback(error, profile)
+ {
+ masterError = masterError || error;
+ masterProfile = profile;
+ }
+
+ /**
+ * @this {WebInspector.TimelineManager}
+ */
+ function allDoneCallback()
+ {
+ this.target().profilingLock.release();
+ callback(masterError, masterProfile);
+ }
+ },
+
+ /**
+ * @param {function(?Protocol.Error)|undefined} callback
+ * @param {?Protocol.Error} error
+ * @param {!Array.<!TimelineAgent.TimelineEvent>=} events
+ */
+ _processBufferedEvents: function(callback, error, events)
+ {
+ if (events) {
+ for (var i = 0; i < events.length; ++i)
+ this._dispatcher.eventRecorded(events[i]);
+ }
+ if (callback)
+ callback(error);
},
- __proto__: WebInspector.Object.prototype
+ _configureCpuProfilerSamplingInterval: function()
+ {
+ var intervalUs = WebInspector.settings.highResolutionCpuProfiling.get() ? 100 : 1000;
+ ProfilerAgent.setSamplingInterval(intervalUs, didChangeInterval.bind(this));
+
+ /**
+ * @this {WebInspector.TimelineManager}
+ */
+ function didChangeInterval(error)
+ {
+ if (error)
+ this.target().consoleModel.showErrorMessage(error);
+ }
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
}
/**
@@ -123,7 +200,7 @@ WebInspector.TimelineDispatcher.prototype = {
{
if (consoleTimeline) {
// Wake up timeline panel module.
- WebInspector.panel("timeline");
+ WebInspector.moduleManager.loadModule("timeline");
}
this._started = true;
this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted, consoleTimeline);
@@ -136,6 +213,14 @@ WebInspector.TimelineDispatcher.prototype = {
{
this._started = false;
this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped, consoleTimeline);
+ },
+
+ /**
+ * @param {number} count
+ */
+ progress: function(count)
+ {
+ this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineProgress, count);
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/UISourceCode.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/UISourceCode.js
index 75db8468d17..157e8917c90 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/UISourceCode.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/UISourceCode.js
@@ -36,11 +36,11 @@
* @param {!WebInspector.Project} project
* @param {string} parentPath
* @param {string} name
+ * @param {string} originURL
* @param {string} url
* @param {!WebInspector.ResourceType} contentType
- * @param {boolean} isEditable
*/
-WebInspector.UISourceCode = function(project, parentPath, name, originURL, url, contentType, isEditable)
+WebInspector.UISourceCode = function(project, parentPath, name, originURL, url, contentType)
{
this._project = project;
this._parentPath = parentPath;
@@ -48,23 +48,28 @@ WebInspector.UISourceCode = function(project, parentPath, name, originURL, url,
this._originURL = originURL;
this._url = url;
this._contentType = contentType;
- this._isEditable = isEditable;
/** @type {!Array.<function(?string)>} */
this._requestContentCallbacks = [];
- /** @type {!Set.<!WebInspector.LiveLocation>} */
- this._liveLocations = new Set();
/** @type {!Array.<!WebInspector.PresentationConsoleMessage>} */
this._consoleMessages = [];
-
+
+ /**
+ * @type {!Map.<!WebInspector.Target, !WebInspector.SourceMapping>}
+ */
+ this._sourceMappingForTarget = new Map();
+
+ /**
+ * @type {!Map.<!WebInspector.Target, !WebInspector.ScriptFile>}
+ */
+ this._scriptFileForTarget = new Map();
+
/** @type {!Array.<!WebInspector.Revision>} */
this.history = [];
- if (this.isEditable() && this._url)
+ if (!this._project.isServiceProject() && this._url)
this._restoreRevisionHistory();
- this._formatterMapping = new WebInspector.IdentityFormatterSourceMapping();
}
WebInspector.UISourceCode.Events = {
- FormattedChanged: "FormattedChanged",
WorkingCopyChanged: "WorkingCopyChanged",
WorkingCopyCommitted: "WorkingCopyCommitted",
TitleChanged: "TitleChanged",
@@ -179,6 +184,11 @@ WebInspector.UISourceCode.prototype = {
}
},
+ remove: function()
+ {
+ this._project.deleteFile(this.path());
+ },
+
/**
* @param {string} name
* @param {string} url
@@ -215,19 +225,24 @@ WebInspector.UISourceCode.prototype = {
},
/**
+ * @param {!WebInspector.Target} target
* @return {?WebInspector.ScriptFile}
*/
- scriptFile: function()
+ scriptFileForTarget: function(target)
{
- return this._scriptFile;
+ return this._scriptFileForTarget.get(target) || null;
},
/**
+ * @param {!WebInspector.Target} target
* @param {?WebInspector.ScriptFile} scriptFile
*/
- setScriptFile: function(scriptFile)
+ setScriptFileForTarget: function(target, scriptFile)
{
- this._scriptFile = scriptFile;
+ if (scriptFile)
+ this._scriptFileForTarget.put(target, scriptFile);
+ else
+ this._scriptFileForTarget.remove(target);
},
/**
@@ -261,14 +276,39 @@ WebInspector.UISourceCode.prototype = {
},
/**
+ * @param {function()} callback
+ */
+ _pushCheckContentUpdatedCallback: function(callback)
+ {
+ if (!this._checkContentUpdatedCallbacks)
+ this._checkContentUpdatedCallbacks = [];
+ this._checkContentUpdatedCallbacks.push(callback);
+ },
+
+ _terminateContentCheck: function()
+ {
+ delete this._checkingContent;
+ if (this._checkContentUpdatedCallbacks) {
+ this._checkContentUpdatedCallbacks.forEach(function(callback) { callback(); });
+ delete this._checkContentUpdatedCallbacks;
+ }
+ },
+
+ /**
* @param {function()=} callback
*/
checkContentUpdated: function(callback)
{
- if (!this._project.canSetFileContent())
+ callback = callback || function() {};
+ if (!this._project.canSetFileContent()) {
+ callback();
return;
- if (this._checkingContent)
+ }
+ this._pushCheckContentUpdatedCallback(callback);
+
+ if (this._checkingContent) {
return;
+ }
this._checkingContent = true;
this._project.requestFileContent(this, contentLoaded.bind(this));
@@ -282,30 +322,22 @@ WebInspector.UISourceCode.prototype = {
var workingCopy = this.workingCopy();
this._commitContent("", false);
this.setWorkingCopy(workingCopy);
- delete this._checkingContent;
- if (callback)
- callback();
+ this._terminateContentCheck();
return;
}
if (typeof this._lastAcceptedContent === "string" && this._lastAcceptedContent === updatedContent) {
- delete this._checkingContent;
- if (callback)
- callback();
+ this._terminateContentCheck();
return;
}
if (this._content === updatedContent) {
delete this._lastAcceptedContent;
- delete this._checkingContent;
- if (callback)
- callback();
+ this._terminateContentCheck();
return;
}
if (!this.isDirty()) {
this._commitContent(updatedContent, false);
- delete this._checkingContent;
- if (callback)
- callback();
+ this._terminateContentCheck();
return;
}
@@ -314,9 +346,7 @@ WebInspector.UISourceCode.prototype = {
this._commitContent(updatedContent, false);
else
this._lastAcceptedContent = updatedContent;
- delete this._checkingContent;
- if (callback)
- callback();
+ this._terminateContentCheck();
}
},
@@ -360,7 +390,7 @@ WebInspector.UISourceCode.prototype = {
*/
_saveURLWithFileManager: function(forceSaveAs, content)
{
- WebInspector.fileManager.save(this._url, content, forceSaveAs, callback.bind(this));
+ WebInspector.fileManager.save(this._url, /** @type {string} */ (content), forceSaveAs, callback.bind(this));
WebInspector.fileManager.close(this._url);
/**
@@ -394,9 +424,9 @@ WebInspector.UISourceCode.prototype = {
*/
hasUnsavedCommittedChanges: function()
{
- if (this._savedWithFileManager || this.project().canSetFileContent() || !this._isEditable)
+ if (this._savedWithFileManager || this.project().canSetFileContent() || this._project.isServiceProject())
return false;
- if (WebInspector.extensionServer.hasSubscribers(WebInspector.extensionAPI.Events.ResourceContentCommitted))
+ if (this._project.workspace().hasResourceContentTrackingExtensions())
return false;
return !!this._hasCommittedChanges;
},
@@ -422,7 +452,7 @@ WebInspector.UISourceCode.prototype = {
function filterOutStale(historyItem)
{
// FIXME: Main frame might not have been loaded yet when uiSourceCodes for snippets are created.
- if (!WebInspector.resourceTreeModel.mainFrame)
+ if (!WebInspector.resourceTreeModel || !WebInspector.resourceTreeModel.mainFrame)
return false;
return historyItem.loaderId === WebInspector.resourceTreeModel.mainFrame.loaderId;
}
@@ -454,7 +484,7 @@ WebInspector.UISourceCode.prototype = {
delete registry[this.url];
window.localStorage["revision-history"] = JSON.stringify(registry);
},
-
+
revertToOriginal: function()
{
/**
@@ -506,14 +536,6 @@ WebInspector.UISourceCode.prototype = {
},
/**
- * @return {boolean}
- */
- isEditable: function()
- {
- return this._isEditable;
- },
-
- /**
* @return {string}
*/
workingCopy: function()
@@ -593,14 +615,6 @@ WebInspector.UISourceCode.prototype = {
/**
* @return {string}
*/
- _mimeType: function()
- {
- return this.contentType().canonicalMimeType();
- },
-
- /**
- * @return {string}
- */
highlighterType: function()
{
var lastIndexOfDot = this._name.lastIndexOf(".");
@@ -650,11 +664,6 @@ WebInspector.UISourceCode.prototype = {
this._requestContentCallbacks = [];
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](content);
-
- if (this._formatOnLoad) {
- delete this._formatOnLoad;
- this.setFormatted(true);
- }
},
/**
@@ -666,50 +675,34 @@ WebInspector.UISourceCode.prototype = {
},
/**
+ * @param {!WebInspector.Target} target
* @param {number} lineNumber
* @param {number} columnNumber
* @return {?WebInspector.RawLocation}
*/
- uiLocationToRawLocation: function(lineNumber, columnNumber)
+ uiLocationToRawLocation: function(target, lineNumber, columnNumber)
{
- if (!this._sourceMapping)
+ var sourceMapping = this._sourceMappingForTarget.get(target);
+ if (!sourceMapping)
return null;
- var location = this._formatterMapping.formattedToOriginal(lineNumber, columnNumber);
- return this._sourceMapping.uiLocationToRawLocation(this, location[0], location[1]);
+ return sourceMapping.uiLocationToRawLocation(this, lineNumber, columnNumber);
},
/**
- * @param {!WebInspector.LiveLocation} liveLocation
- */
- addLiveLocation: function(liveLocation)
- {
- this._liveLocations.add(liveLocation);
- },
-
- /**
- * @param {!WebInspector.LiveLocation} liveLocation
- */
- removeLiveLocation: function(liveLocation)
- {
- this._liveLocations.remove(liveLocation);
- },
-
- updateLiveLocations: function()
- {
- var items = this._liveLocations.items();
- for (var i = 0; i < items.length; ++i)
- items[i].update();
- },
-
- /**
- * @param {!WebInspector.UILocation} uiLocation
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {!Array.<!WebInspector.RawLocation>}
*/
- overrideLocation: function(uiLocation)
- {
- var location = this._formatterMapping.originalToFormatted(uiLocation.lineNumber, uiLocation.columnNumber);
- uiLocation.lineNumber = location[0];
- uiLocation.columnNumber = location[1];
- return uiLocation;
+ uiLocationToRawLocations: function(lineNumber, columnNumber)
+ {
+ var result = [];
+ var sourceMappings = this._sourceMappingForTarget.values();
+ for (var i = 0; i < sourceMappings.length; ++i) {
+ var rawLocation = sourceMappings[i].uiLocationToRawLocation(this, lineNumber, columnNumber);
+ if (rawLocation)
+ result.push(rawLocation);
+ }
+ return result;
},
/**
@@ -747,94 +740,38 @@ WebInspector.UISourceCode.prototype = {
/**
* @return {boolean}
*/
- formatted: function()
+ hasSourceMapping: function()
{
- return !!this._formatted;
+ return !!this._sourceMappingForTarget.size();
},
/**
- * @param {boolean} formatted
+ * @param {!WebInspector.Target} target
+ * @param {?WebInspector.SourceMapping} sourceMapping
*/
- setFormatted: function(formatted)
+ setSourceMappingForTarget: function(target, sourceMapping)
{
- if (!this.contentLoaded()) {
- this._formatOnLoad = formatted;
+ if (this._sourceMappingForTarget.get(target) === sourceMapping)
return;
- }
- if (this._formatted === formatted)
- return;
-
- if (this.isDirty())
- return;
-
- this._formatted = formatted;
-
- // Re-request content
- this._contentLoaded = false;
- this._content = false;
- this.requestContent(didGetContent.bind(this));
-
- /**
- * @this {WebInspector.UISourceCode}
- * @param {?string} content
- */
- function didGetContent(content)
- {
- var formatter;
- if (!formatted)
- formatter = new WebInspector.IdentityFormatter();
- else
- formatter = WebInspector.Formatter.createFormatter(this.contentType());
- formatter.formatContent(this.highlighterType(), content || "", formattedChanged.bind(this));
-
- /**
- * @this {WebInspector.UISourceCode}
- * @param {string} content
- * @param {!WebInspector.FormatterSourceMapping} formatterMapping
- */
- function formattedChanged(content, formatterMapping)
- {
- this._content = content;
- this._innerResetWorkingCopy();
- var oldFormatter = this._formatterMapping;
- this._formatterMapping = formatterMapping;
- this.dispatchEventToListeners(WebInspector.UISourceCode.Events.FormattedChanged, {
- content: content,
- oldFormatter: oldFormatter,
- newFormatter: this._formatterMapping,
- });
- this.updateLiveLocations();
- }
- }
- },
+ if (sourceMapping)
+ this._sourceMappingForTarget.put(target, sourceMapping);
+ else
+ this._sourceMappingForTarget.remove(target);
- /**
- * @return {?WebInspector.Formatter} formatter
- */
- createFormatter: function()
- {
- // overridden by subclasses.
- return null;
+ this.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged, {target: target, isIdentity: sourceMapping ? sourceMapping.isIdentity() : false});
},
/**
- * @return {boolean}
- */
- hasSourceMapping: function()
- {
- return !!this._sourceMapping;
- },
-
- /**
- * @param {?WebInspector.SourceMapping} sourceMapping
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ * @return {!WebInspector.UILocation}
*/
- setSourceMapping: function(sourceMapping)
+ uiLocation: function(lineNumber, columnNumber)
{
- if (this._sourceMapping === sourceMapping)
- return;
- this._sourceMapping = sourceMapping;
- this.dispatchEventToListeners(WebInspector.UISourceCode.Events.SourceMappingChanged);
+ if (typeof columnNumber === "undefined")
+ columnNumber = 0;
+ return new WebInspector.UILocation(this, lineNumber, columnNumber);
},
__proto__: WebInspector.Object.prototype
@@ -855,19 +792,20 @@ WebInspector.UILocation = function(uiSourceCode, lineNumber, columnNumber)
WebInspector.UILocation.prototype = {
/**
+ * @param {!WebInspector.Target} target
* @return {?WebInspector.RawLocation}
*/
- uiLocationToRawLocation: function()
+ uiLocationToRawLocation: function(target)
{
- return this.uiSourceCode.uiLocationToRawLocation(this.lineNumber, this.columnNumber);
+ return this.uiSourceCode.uiLocationToRawLocation(target, this.lineNumber, this.columnNumber);
},
/**
- * @return {?string}
+ * @return {!Array.<!WebInspector.RawLocation>}
*/
- url: function()
+ uiLocationToRawLocations: function()
{
- return this.uiSourceCode.contentURL();
+ return this.uiSourceCode.uiLocationToRawLocations(this.lineNumber, this.columnNumber);
},
/**
@@ -879,7 +817,15 @@ WebInspector.UILocation.prototype = {
if (typeof this.lineNumber === "number")
linkText += ":" + (this.lineNumber + 1);
return linkText;
- }
+ },
+
+ /**
+ * @return {string}
+ */
+ id: function()
+ {
+ return this.uiSourceCode.uri() + ":" + this.lineNumber + ":" + this.columnNumber;
+ },
}
/**
@@ -889,6 +835,13 @@ WebInspector.RawLocation = function()
{
}
+WebInspector.RawLocation.prototype = {
+ /**
+ * @return {?WebInspector.UILocation}
+ */
+ toUILocation: function() { }
+}
+
/**
* @constructor
* @param {!WebInspector.RawLocation} rawLocation
@@ -898,23 +851,16 @@ WebInspector.LiveLocation = function(rawLocation, updateDelegate)
{
this._rawLocation = rawLocation;
this._updateDelegate = updateDelegate;
- this._uiSourceCodes = [];
}
WebInspector.LiveLocation.prototype = {
update: function()
{
var uiLocation = this.uiLocation();
- if (uiLocation) {
- var uiSourceCode = uiLocation.uiSourceCode;
- if (this._uiSourceCodes.indexOf(uiSourceCode) === -1) {
- uiSourceCode.addLiveLocation(this);
- this._uiSourceCodes.push(uiSourceCode);
- }
- var oneTime = this._updateDelegate(uiLocation);
- if (oneTime)
- this.dispose();
- }
+ if (!uiLocation)
+ return;
+ if (this._updateDelegate(uiLocation))
+ this.dispose();
},
/**
@@ -930,14 +876,12 @@ WebInspector.LiveLocation.prototype = {
*/
uiLocation: function()
{
- // Should be overridden by subclasses.
+ throw "Not implemented";
},
dispose: function()
{
- for (var i = 0; i < this._uiSourceCodes.length; ++i)
- this._uiSourceCodes[i].removeLiveLocation(this);
- this._uiSourceCodes = [];
+ // Overridden by subclasses.
}
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerManager.js
new file mode 100644
index 00000000000..81841987e9c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerManager.js
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.Target} target
+ * @param {boolean} isMainFrontend
+ */
+WebInspector.WorkerManager = function(target, isMainFrontend)
+{
+ this._reset();
+ target.registerWorkerDispatcher(new WebInspector.WorkerDispatcher(this));
+ if (isMainFrontend) {
+ WorkerAgent.enable();
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
+ }
+}
+
+WebInspector.WorkerManager.Events = {
+ WorkerAdded: "WorkerAdded",
+ WorkerRemoved: "WorkerRemoved",
+ WorkersCleared: "WorkersCleared",
+ WorkerSelectionChanged: "WorkerSelectionChanged",
+ WorkerDisconnected: "WorkerDisconnected",
+ MessageFromWorker: "MessageFromWorker",
+}
+
+WebInspector.WorkerManager.MainThreadId = 0;
+
+WebInspector.WorkerManager.prototype = {
+
+ _reset: function()
+ {
+ /** @type {!Object.<number, string>} */
+ this._threadUrlByThreadId = {};
+ this._threadUrlByThreadId[WebInspector.WorkerManager.MainThreadId] = WebInspector.UIString("Thread: Main");
+ this._threadsList = [WebInspector.WorkerManager.MainThreadId];
+ this._selectedThreadId = WebInspector.WorkerManager.MainThreadId;
+ },
+
+ _workerCreated: function(workerId, url, inspectorConnected)
+ {
+ this._threadsList.push(workerId);
+ this._threadUrlByThreadId[workerId] = url;
+ this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerAdded, {workerId: workerId, url: url, inspectorConnected: inspectorConnected});
+ },
+
+ _workerTerminated: function(workerId)
+ {
+ this._threadsList.remove(workerId);
+ delete this._threadUrlByThreadId[workerId];
+ this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerRemoved, workerId);
+ },
+
+ _dispatchMessageFromWorker: function(workerId, message)
+ {
+ this.dispatchEventToListeners(WebInspector.WorkerManager.Events.MessageFromWorker, {workerId: workerId, message: message})
+ },
+
+ _disconnectedFromWorker: function()
+ {
+ this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkerDisconnected)
+ },
+
+ _mainFrameNavigated: function(event)
+ {
+ this._reset();
+ this.dispatchEventToListeners(WebInspector.WorkerManager.Events.WorkersCleared);
+ },
+
+ /**
+ * @return {!Array.<number>}
+ */
+ threadsList: function()
+ {
+ return this._threadsList;
+ },
+
+ /**
+ * @param {number} threadId
+ * @return {string}
+ */
+ threadUrl: function(threadId)
+ {
+ return this._threadUrlByThreadId[threadId];
+ },
+
+ /**
+ * @param {number} threadId
+ */
+ setSelectedThreadId: function(threadId)
+ {
+ this._selectedThreadId = threadId;
+ },
+
+ /**
+ * @return {number}
+ */
+ selectedThreadId: function()
+ {
+ return this._selectedThreadId;
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WorkerAgent.Dispatcher}
+ */
+WebInspector.WorkerDispatcher = function(workerManager)
+{
+ this._workerManager = workerManager;
+}
+
+WebInspector.WorkerDispatcher.prototype = {
+
+ workerCreated: function(workerId, url, inspectorConnected)
+ {
+ this._workerManager._workerCreated(workerId, url, inspectorConnected);
+ },
+
+ workerTerminated: function(workerId)
+ {
+ this._workerManager._workerTerminated(workerId);
+ },
+
+ dispatchMessageFromWorker: function(workerId, message)
+ {
+ this._workerManager._dispatchMessageFromWorker(workerId, message);
+ },
+
+ disconnectedFromWorker: function()
+ {
+ this._workerManager._disconnectedFromWorker();
+ }
+}
+
+/**
+ * @type {!WebInspector.WorkerManager}
+ */
+WebInspector.workerManager;
+
+/**
+ * @constructor
+ * @extends {InspectorBackendClass.Connection}
+ * @param {string} workerId
+ * @param {function(!InspectorBackendClass.Connection)} onConnectionReady
+ */
+WebInspector.ExternalWorkerConnection = function(workerId, onConnectionReady)
+{
+ InspectorBackendClass.Connection.call(this);
+ this._workerId = workerId;
+ window.addEventListener("message", this._processMessage.bind(this), true);
+ onConnectionReady(this);
+}
+
+WebInspector.ExternalWorkerConnection.prototype = {
+
+ /**
+ * @param {?Event} event
+ */
+ _processMessage: function(event)
+ {
+ if (!event)
+ return;
+
+ var message = event.data;
+ this.dispatch(message);
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ window.opener.postMessage({workerId: this._workerId, command: "sendMessageToBackend", message: messageObject}, "*");
+ },
+
+ __proto__: InspectorBackendClass.Connection.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerTargetManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerTargetManager.js
new file mode 100644
index 00000000000..073c9a0bc4e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkerTargetManager.js
@@ -0,0 +1,77 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/**
+ * @constructor
+ * @param {!WebInspector.Target} mainTarget
+ * @param {!WebInspector.TargetManager} targetManager
+ */
+WebInspector.WorkerTargetManager = function(mainTarget, targetManager)
+{
+ this._mainTarget = mainTarget;
+ this._targetManager = targetManager;
+ mainTarget.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerAdded, this._onWorkerAdded, this);
+}
+
+WebInspector.WorkerTargetManager.prototype = {
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onWorkerAdded: function(event)
+ {
+ var data = /** @type {{workerId: number, url: string}} */ (event.data);
+ new WebInspector.WorkerConnection(this._mainTarget, data.workerId, onConnectionReady.bind(this));
+
+ /**
+ * @this {WebInspector.WorkerTargetManager}
+ * @param {!InspectorBackendClass.Connection} connection
+ */
+ function onConnectionReady(connection)
+ {
+ this._targetManager.createTarget(event.data.url, connection)
+ }
+ }
+
+}
+
+/**
+ * @constructor
+ * @extends {InspectorBackendClass.Connection}
+ * @param {!WebInspector.Target} target
+ * @param {number} workerId
+ * @param {!function(!InspectorBackendClass.Connection)} onConnectionReady
+ */
+WebInspector.WorkerConnection = function(target, workerId, onConnectionReady)
+{
+ InspectorBackendClass.Connection.call(this);
+ this._workerId = workerId;
+ this._workerAgent = target.workerAgent();
+ this._workerAgent.connectToWorker(workerId, onConnectionReady.bind(null, this));
+ target.workerManager.addEventListener(WebInspector.WorkerManager.Events.MessageFromWorker, this._dispatchMessageFromWorker, this);
+}
+
+WebInspector.WorkerConnection.prototype = {
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _dispatchMessageFromWorker: function(event)
+ {
+ var data = /** @type {{workerId: number, command: string, message: !Object}} */ (event.data);
+ if (data.workerId === this._workerId)
+ this.dispatch(data.message);
+ },
+
+ /**
+ * @param {!Object} messageObject
+ */
+ sendMessage: function(messageObject)
+ {
+ this._workerAgent.sendMessageToWorker(this._workerId, messageObject);
+ },
+
+ __proto__: InspectorBackendClass.Connection.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Workspace.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js
index aa3bb58934f..4670b5e9e04 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Workspace.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/Workspace.js
@@ -35,47 +35,31 @@
* @param {string} originURL
* @param {string} url
* @param {!WebInspector.ResourceType} contentType
- * @param {boolean} isEditable
- * @param {boolean=} isContentScript
*/
-WebInspector.FileDescriptor = function(parentPath, name, originURL, url, contentType, isEditable, isContentScript)
+WebInspector.FileDescriptor = function(parentPath, name, originURL, url, contentType)
{
this.parentPath = parentPath;
this.name = name;
this.originURL = originURL;
this.url = url;
this.contentType = contentType;
- this.isEditable = isEditable;
- this.isContentScript = isContentScript || false;
}
/**
* @interface
- * @extends {WebInspector.EventTarget}
*/
WebInspector.ProjectDelegate = function() { }
-WebInspector.ProjectDelegate.Events = {
- FileAdded: "FileAdded",
- FileRemoved: "FileRemoved",
- Reset: "Reset",
-}
-
WebInspector.ProjectDelegate.prototype = {
/**
* @return {string}
*/
- id: function() { },
-
- /**
- * @return {string}
- */
type: function() { },
/**
* @return {string}
*/
- displayName: function() { },
+ displayName: function() { },
/**
* @param {string} path
@@ -148,39 +132,102 @@ WebInspector.ProjectDelegate.prototype = {
searchInFileContent: function(path, query, caseSensitive, isRegex, callback) { },
/**
- * @param {!Array.<string>} queries
- * @param {!Array.<string>} fileQueries
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
- findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback) { },
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback) { },
/**
* @param {!WebInspector.Progress} progress
- * @param {function()} callback
*/
- indexContent: function(progress, callback) { }
+ indexContent: function(progress) { }
+}
+
+/**
+ * @interface
+ */
+WebInspector.ProjectSearchConfig = function() {}
+
+WebInspector.ProjectSearchConfig.prototype = {
+ /**
+ * @return {string}
+ */
+ query: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ ignoreCase: function() { },
+
+ /**
+ * @return {boolean}
+ */
+ isRegex: function() { },
+
+ /**
+ * @return {!Array.<string>}
+ */
+ queries: function() { },
+
+ /**
+ * @param {string} filePath
+ * @return {boolean}
+ */
+ filePathMatchesFileQuery: function(filePath) { }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Project} project
+ */
+WebInspector.ProjectStore = function(project)
+{
+ this._project = project;
+}
+
+WebInspector.ProjectStore.prototype = {
+ /**
+ * @param {!WebInspector.FileDescriptor} fileDescriptor
+ */
+ addFile: function(fileDescriptor)
+ {
+ this._project._addFile(fileDescriptor);
+ },
+
+ /**
+ * @param {string} path
+ */
+ removeFile: function(path)
+ {
+ this._project._removeFile(path);
+ },
+
+ /**
+ * @return {!WebInspector.Project}
+ */
+ project: function()
+ {
+ return this._project;
+ }
}
/**
* @param {!WebInspector.Workspace} workspace
+ * @param {string} projectId
* @param {!WebInspector.ProjectDelegate} projectDelegate
* @constructor
*/
-WebInspector.Project = function(workspace, projectDelegate)
+WebInspector.Project = function(workspace, projectId, projectDelegate)
{
- /** @type {!Object.<string, {uiSourceCode: !WebInspector.UISourceCode, index: number}>} */
+ /** @type {!Object.<string, !{uiSourceCode: !WebInspector.UISourceCode, index: number}>} */
this._uiSourceCodesMap = {};
/** @type {!Array.<!WebInspector.UISourceCode>} */
this._uiSourceCodesList = [];
this._workspace = workspace;
+ this._projectId = projectId;
this._projectDelegate = projectDelegate;
this._displayName = this._projectDelegate.displayName();
- this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileAdded, this._fileAdded, this);
- this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.FileRemoved, this._fileRemoved, this);
- this._projectDelegate.addEventListener(WebInspector.ProjectDelegate.Events.Reset, this._reset, this);
}
WebInspector.Project.prototype = {
@@ -189,7 +236,7 @@ WebInspector.Project.prototype = {
*/
id: function()
{
- return this._projectDelegate.id();
+ return this._projectId;
},
/**
@@ -197,13 +244,13 @@ WebInspector.Project.prototype = {
*/
type: function()
{
- return this._projectDelegate.type();
+ return this._projectDelegate.type();
},
/**
* @return {string}
*/
- displayName: function()
+ displayName: function()
{
return this._displayName;
},
@@ -213,31 +260,26 @@ WebInspector.Project.prototype = {
*/
isServiceProject: function()
{
- return this._projectDelegate.type() === WebInspector.projectTypes.Debugger || this._projectDelegate.type() === WebInspector.projectTypes.LiveEdit;
+ return this._projectDelegate.type() === WebInspector.projectTypes.Debugger || this._projectDelegate.type() === WebInspector.projectTypes.Formatter || this._projectDelegate.type() === WebInspector.projectTypes.LiveEdit;
},
- _fileAdded: function(event)
+ /**
+ * @param {!WebInspector.FileDescriptor} fileDescriptor
+ */
+ _addFile: function(fileDescriptor)
{
- var fileDescriptor = /** @type {!WebInspector.FileDescriptor} */ (event.data);
var path = fileDescriptor.parentPath ? fileDescriptor.parentPath + "/" + fileDescriptor.name : fileDescriptor.name;
var uiSourceCode = this.uiSourceCode(path);
if (uiSourceCode)
return;
- uiSourceCode = new WebInspector.UISourceCode(this, fileDescriptor.parentPath, fileDescriptor.name, fileDescriptor.originURL, fileDescriptor.url, fileDescriptor.contentType, fileDescriptor.isEditable);
- uiSourceCode.isContentScript = fileDescriptor.isContentScript;
+ uiSourceCode = new WebInspector.UISourceCode(this, fileDescriptor.parentPath, fileDescriptor.name, fileDescriptor.originURL, fileDescriptor.url, fileDescriptor.contentType);
this._uiSourceCodesMap[path] = {uiSourceCode: uiSourceCode, index: this._uiSourceCodesList.length};
this._uiSourceCodesList.push(uiSourceCode);
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeAdded, uiSourceCode);
},
- _fileRemoved: function(event)
- {
- var path = /** @type {string} */ (event.data);
- this._removeFile(path);
- },
-
/**
* @param {string} path
*/
@@ -257,14 +299,22 @@ WebInspector.Project.prototype = {
this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.UISourceCodeRemoved, entry.uiSourceCode);
},
- _reset: function()
+ _remove: function()
{
- this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectWillReset, this);
+ this._workspace.dispatchEventToListeners(WebInspector.Workspace.Events.ProjectRemoved, this);
this._uiSourceCodesMap = {};
this._uiSourceCodesList = [];
},
/**
+ * @return {!WebInspector.Workspace}
+ */
+ workspace: function()
+ {
+ return this._workspace;
+ },
+
+ /**
* @param {string} path
* @return {?WebInspector.UISourceCode}
*/
@@ -450,39 +500,35 @@ WebInspector.Project.prototype = {
},
/**
- * @param {!Array.<string>} queries
- * @param {!Array.<string>} fileQueries
- * @param {boolean} caseSensitive
- * @param {boolean} isRegex
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
* @param {function(!Array.<string>)} callback
*/
- findFilesMatchingSearchRequest: function(queries, fileQueries, caseSensitive, isRegex, progress, callback)
+ findFilesMatchingSearchRequest: function(searchConfig, progress, callback)
{
- this._projectDelegate.findFilesMatchingSearchRequest(queries, fileQueries, caseSensitive, isRegex, progress, callback);
+ this._projectDelegate.findFilesMatchingSearchRequest(searchConfig, progress, callback);
},
/**
* @param {!WebInspector.Progress} progress
- * @param {function()} callback
*/
- indexContent: function(progress, callback)
- {
- this._projectDelegate.indexContent(progress, callback);
- },
-
- dispose: function()
+ indexContent: function(progress)
{
- this._projectDelegate.reset();
+ this._projectDelegate.indexContent(progress);
}
}
+/**
+ * @enum {string}
+ */
WebInspector.projectTypes = {
Debugger: "debugger",
+ Formatter: "formatter",
LiveEdit: "liveedit",
Network: "network",
Snippets: "snippets",
- FileSystem: "filesystem"
+ FileSystem: "filesystem",
+ ContentScripts: "contentscripts"
}
/**
@@ -495,13 +541,14 @@ WebInspector.Workspace = function(fileSystemMapping)
this._fileSystemMapping = fileSystemMapping;
/** @type {!Object.<string, !WebInspector.Project>} */
this._projects = {};
+ this._hasResourceContentTrackingExtensions = false;
}
WebInspector.Workspace.Events = {
UISourceCodeAdded: "UISourceCodeAdded",
UISourceCodeRemoved: "UISourceCodeRemoved",
UISourceCodeContentCommitted: "UISourceCodeContentCommitted",
- ProjectWillReset: "ProjectWillReset"
+ ProjectRemoved: "ProjectRemoved"
}
WebInspector.Workspace.prototype = {
@@ -534,9 +581,10 @@ WebInspector.Workspace.prototype = {
*/
uiSourceCodeForOriginURL: function(originURL)
{
- var networkProjects = this.projectsForType(WebInspector.projectTypes.Network)
- for (var i = 0; i < networkProjects.length; ++i) {
- var project = networkProjects[i];
+ var projects = this.projectsForType(WebInspector.projectTypes.Network);
+ projects = projects.concat(this.projectsForType(WebInspector.projectTypes.ContentScripts));
+ for (var i = 0; i < projects.length; ++i) {
+ var project = projects[i];
var uiSourceCode = project.uiSourceCodeForOriginURL(originURL);
if (uiSourceCode)
return uiSourceCode;
@@ -560,14 +608,16 @@ WebInspector.Workspace.prototype = {
},
/**
+ * @param {string} projectId
* @param {!WebInspector.ProjectDelegate} projectDelegate
- * @return {!WebInspector.Project}
+ * @return {!WebInspector.ProjectStore}
*/
- addProject: function(projectDelegate)
+ addProject: function(projectId, projectDelegate)
{
- var projectId = projectDelegate.id();
- this._projects[projectId] = new WebInspector.Project(this, projectDelegate);
- return this._projects[projectId];
+ var project = new WebInspector.Project(this, projectId, projectDelegate);
+ this._projects[projectId] = project;
+ var projectStore = new WebInspector.ProjectStore(project);
+ return projectStore;
},
/**
@@ -578,8 +628,8 @@ WebInspector.Workspace.prototype = {
var project = this._projects[projectId];
if (!project)
return;
- project.dispose();
delete this._projects[projectId];
+ project._remove();
},
/**
@@ -631,8 +681,6 @@ WebInspector.Workspace.prototype = {
*/
hasMappingForURL: function(url)
{
- if (!InspectorFrontendHost.supportsFileSystems())
- return false;
return this._fileSystemMapping.hasMappingForURL(url);
},
@@ -643,7 +691,19 @@ WebInspector.Workspace.prototype = {
_networkUISourceCodeForURL: function(url)
{
var splitURL = WebInspector.ParsedURL.splitURL(url);
- var projectId = WebInspector.SimpleProjectDelegate.projectId(splitURL[0], WebInspector.projectTypes.Network);
+ var projectId = splitURL[0];
+ var project = this.project(projectId);
+ return project ? project.uiSourceCode(splitURL.slice(1).join("/")) : null;
+ },
+
+ /**
+ * @param {string} url
+ * @return {?WebInspector.UISourceCode}
+ */
+ _contentScriptUISourceCodeForURL: function(url)
+ {
+ var splitURL = WebInspector.ParsedURL.splitURL(url);
+ var projectId = "contentscripts:" + splitURL[0];
var project = this.project(projectId);
return project ? project.uiSourceCode(splitURL.slice(1).join("/")) : null;
},
@@ -654,13 +714,11 @@ WebInspector.Workspace.prototype = {
*/
uiSourceCodeForURL: function(url)
{
- if (!InspectorFrontendHost.supportsFileSystems())
- return this._networkUISourceCodeForURL(url);
var file = this._fileSystemMapping.fileForURL(url);
if (!file)
- return this._networkUISourceCodeForURL(url);
+ return this._networkUISourceCodeForURL(url) || this._contentScriptUISourceCodeForURL(url);
- var projectId = WebInspector.FileSystemProjectDelegate.projectId(file.fileSystemPath);
+ var projectId = WebInspector.FileSystemWorkspaceBinding.projectId(file.fileSystemPath);
var project = this.project(projectId);
return project ? project.uiSourceCode(file.filePath) : null;
},
@@ -678,15 +736,14 @@ WebInspector.Workspace.prototype = {
/**
* @param {!WebInspector.UISourceCode} networkUISourceCode
* @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {!WebInspector.FileSystemWorkspaceProvider} fileSystemWorkspaceProvider
+ * @param {!WebInspector.FileSystemWorkspaceBinding} fileSystemWorkspaceBinding
*/
- addMapping: function(networkUISourceCode, uiSourceCode, fileSystemWorkspaceProvider)
+ addMapping: function(networkUISourceCode, uiSourceCode, fileSystemWorkspaceBinding)
{
var url = networkUISourceCode.url;
var path = uiSourceCode.path();
- var fileSystemPath = fileSystemWorkspaceProvider.fileSystemPath(uiSourceCode);
+ var fileSystemPath = fileSystemWorkspaceBinding.fileSystemPath(uiSourceCode.project().id());
this._fileSystemMapping.addMappingForResource(url, fileSystemPath, path);
- WebInspector.suggestReload();
},
/**
@@ -695,7 +752,22 @@ WebInspector.Workspace.prototype = {
removeMapping: function(uiSourceCode)
{
this._fileSystemMapping.removeMappingForURL(uiSourceCode.url);
- WebInspector.suggestReload();
+ },
+
+ /**
+ * @param {boolean} hasExtensions
+ */
+ setHasResourceContentTrackingExtensions: function(hasExtensions)
+ {
+ this._hasResourceContentTrackingExtensions = hasExtensions;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasResourceContentTrackingExtensions: function()
+ {
+ return this._hasResourceContentTrackingExtensions;
},
__proto__: WebInspector.Object.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/WorkspaceController.js b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkspaceController.js
index f5913614047..9ae5d89996e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/WorkspaceController.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sdk/WorkspaceController.js
@@ -56,6 +56,9 @@ WebInspector.WorkspaceController.prototype = {
return;
this._fileSystemRefreshTimeout = setTimeout(refreshFileSystems.bind(this), 1000);
+ /**
+ * @this {WebInspector.WorkspaceController}
+ */
function refreshFileSystems()
{
delete this._fileSystemRefreshTimeout;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/search/AdvancedSearchView.js b/chromium/third_party/WebKit/Source/devtools/front_end/search/AdvancedSearchView.js
new file mode 100644
index 00000000000..4a78f8ab332
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/search/AdvancedSearchView.js
@@ -0,0 +1,442 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.AdvancedSearchView = function()
+{
+ WebInspector.VBox.call(this);
+
+ this._searchId = 0;
+
+ this.element.classList.add("search-view");
+
+ this._searchPanelElement = this.element.createChild("div", "search-drawer-header");
+ this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
+
+ this._searchResultsElement = this.element.createChild("div");
+ this._searchResultsElement.className = "search-results";
+
+ this._search = this._searchPanelElement.createChild("input");
+ this._search.placeholder = WebInspector.UIString("Search sources");
+ this._search.setAttribute("type", "text");
+ this._search.classList.add("search-config-search");
+ this._search.setAttribute("results", "0");
+ this._search.setAttribute("size", 30);
+
+ this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
+ this._ignoreCaseLabel.classList.add("search-config-label");
+ this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
+ this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
+ this._ignoreCaseCheckbox.classList.add("search-config-checkbox");
+ this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));
+
+ this._regexLabel = this._searchPanelElement.createChild("label");
+ this._regexLabel.classList.add("search-config-label");
+ this._regexCheckbox = this._regexLabel.createChild("input");
+ this._regexCheckbox.setAttribute("type", "checkbox");
+ this._regexCheckbox.classList.add("search-config-checkbox");
+ this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));
+
+ this._searchStatusBarElement = this.element.createChild("div", "search-status-bar-summary");
+ this._searchMessageElement = this._searchStatusBarElement.createChild("span");
+ this._searchResultsMessageElement = document.createElement("span");
+
+ WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false).toPlainObject());
+ this._load();
+}
+
+WebInspector.AdvancedSearchView.prototype = {
+ /**
+ * @return {!WebInspector.SearchConfig}
+ */
+ _buildSearchConfig: function()
+ {
+ return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
+ },
+
+ toggle: function()
+ {
+ var selection = window.getSelection();
+ var queryCandidate;
+ if (selection.rangeCount)
+ queryCandidate = selection.toString().replace(/\r?\n.*/, "");
+
+ if (!this.isShowing())
+ WebInspector.inspectorView.showViewInDrawer("search");
+ if (queryCandidate)
+ this._search.value = queryCandidate;
+ this.focus();
+
+ this._startIndexing();
+ },
+
+ /**
+ * @param {boolean} finished
+ */
+ _onIndexingFinished: function(finished)
+ {
+ delete this._isIndexing;
+ this._indexingFinished(finished);
+ if (!finished)
+ delete this._pendingSearchConfig;
+ if (!this._pendingSearchConfig)
+ return;
+ var searchConfig = this._pendingSearchConfig
+ delete this._pendingSearchConfig;
+ this._innerStartSearch(searchConfig);
+ },
+
+ _startIndexing: function()
+ {
+ this._isIndexing = true;
+ // FIXME: this._currentSearchScope should be initialized based on searchConfig
+ this._currentSearchScope = this._searchScopes()[0];
+ if (this._progressIndicator)
+ this._progressIndicator.done();
+ this._progressIndicator = new WebInspector.ProgressIndicator();
+ this._indexingStarted(this._progressIndicator);
+ this._currentSearchScope.performIndexing(this._progressIndicator, this._onIndexingFinished.bind(this));
+ },
+
+ /**
+ * @param {number} searchId
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+ _onSearchResult: function(searchId, searchResult)
+ {
+ if (searchId !== this._searchId)
+ return;
+ this._addSearchResult(searchResult);
+ if (!searchResult.searchMatches.length)
+ return;
+ if (!this._searchResultsPane)
+ this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);
+ this._resetResults();
+ this._searchResultsElement.appendChild(this._searchResultsPane.element);
+ this._searchResultsPane.addSearchResult(searchResult);
+ },
+
+ /**
+ * @param {number} searchId
+ * @param {boolean} finished
+ */
+ _onSearchFinished: function(searchId, finished)
+ {
+ if (searchId !== this._searchId)
+ return;
+ if (!this._searchResultsPane)
+ this._nothingFound();
+ this._searchFinished(finished);
+ delete this._searchConfig;
+ },
+
+ /**
+ * @param {!WebInspector.SearchConfig} searchConfig
+ */
+ _startSearch: function(searchConfig)
+ {
+ this._resetSearch();
+ ++this._searchId;
+ if (!this._isIndexing)
+ this._startIndexing();
+ this._pendingSearchConfig = searchConfig;
+ },
+
+ /**
+ * @param {!WebInspector.SearchConfig} searchConfig
+ */
+ _innerStartSearch: function(searchConfig)
+ {
+ this._searchConfig = searchConfig;
+ // FIXME: this._currentSearchScope should be initialized based on searchConfig
+ this._currentSearchScope = this._searchScopes()[0];
+
+ if (this._progressIndicator)
+ this._progressIndicator.done();
+ this._progressIndicator = new WebInspector.ProgressIndicator();
+ this._searchStarted(this._progressIndicator);
+ this._currentSearchScope.performSearch(searchConfig, this._progressIndicator, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
+ },
+
+ _resetSearch: function()
+ {
+ this._stopSearch();
+
+ if (this._searchResultsPane) {
+ this._resetResults();
+ delete this._searchResultsPane;
+ }
+ },
+
+ _stopSearch: function()
+ {
+ if (this._progressIndicator)
+ this._progressIndicator.cancel();
+ if (this._currentSearchScope)
+ this._currentSearchScope.stopSearch();
+ delete this._searchConfig;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.SearchScope>}
+ */
+ _searchScopes: function()
+ {
+ // FIXME: implement multiple search scopes.
+ return /** @type {!Array.<!WebInspector.SearchScope>} */ (WebInspector.moduleManager.instances(WebInspector.SearchScope));
+ },
+
+ /**
+ * @param {!WebInspector.ProgressIndicator} progressIndicator
+ */
+ _searchStarted: function(progressIndicator)
+ {
+ this._resetResults();
+ this._resetCounters();
+
+ this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
+ progressIndicator.show(this._searchStatusBarElement);
+ this._updateSearchResultsMessage();
+
+ if (!this._searchingView)
+ this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
+ this._searchingView.show(this._searchResultsElement);
+ },
+
+ /**
+ * @param {!WebInspector.ProgressIndicator} progressIndicator
+ */
+ _indexingStarted: function(progressIndicator)
+ {
+ this._searchMessageElement.textContent = WebInspector.UIString("Indexing...");
+ progressIndicator.show(this._searchStatusBarElement);
+ },
+
+ /**
+ * @param {boolean} finished
+ */
+ _indexingFinished: function(finished)
+ {
+ this._searchMessageElement.textContent = finished ? "" : WebInspector.UIString("Indexing interrupted.");
+ },
+
+ _updateSearchResultsMessage: function()
+ {
+ if (this._searchMatchesCount && this._searchResultsCount)
+ this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
+ else
+ this._searchResultsMessageElement.textContent = "";
+ },
+
+ _resetResults: function()
+ {
+ if (this._searchingView)
+ this._searchingView.detach();
+ if (this._notFoundView)
+ this._notFoundView.detach();
+ this._searchResultsElement.removeChildren();
+ },
+
+ _resetCounters: function()
+ {
+ this._searchMatchesCount = 0;
+ this._searchResultsCount = 0;
+ this._nonEmptySearchResultsCount = 0;
+ },
+
+ _nothingFound: function()
+ {
+ this._resetResults();
+
+ if (!this._notFoundView)
+ this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
+ this._notFoundView.show(this._searchResultsElement);
+ this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
+ },
+
+ /**
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+ _addSearchResult: function(searchResult)
+ {
+ this._searchMatchesCount += searchResult.searchMatches.length;
+ this._searchResultsCount++;
+ if (searchResult.searchMatches.length)
+ this._nonEmptySearchResultsCount++;
+ this._updateSearchResultsMessage();
+ },
+
+ /**
+ * @param {boolean} finished
+ */
+ _searchFinished: function(finished)
+ {
+ this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
+ },
+
+ focus: function()
+ {
+ WebInspector.setCurrentFocusElement(this._search);
+ this._search.select();
+ },
+
+ willHide: function()
+ {
+ this._stopSearch();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onKeyDown: function(event)
+ {
+ switch (event.keyCode) {
+ case WebInspector.KeyboardShortcut.Keys.Enter.code:
+ this._onAction();
+ break;
+ }
+ },
+
+ _save: function()
+ {
+ WebInspector.settings.advancedSearchConfig.set(this._buildSearchConfig().toPlainObject());
+ },
+
+ _load: function()
+ {
+ var searchConfig = WebInspector.SearchConfig.fromPlainObject(WebInspector.settings.advancedSearchConfig.get());
+ this._search.value = searchConfig.query();
+ this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase();
+ this._regexCheckbox.checked = searchConfig.isRegex();
+ },
+
+ _onAction: function()
+ {
+ var searchConfig = this._buildSearchConfig();
+ if (!searchConfig.query() || !searchConfig.query().length)
+ return;
+
+ this._save();
+ this._startSearch(searchConfig);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ */
+WebInspector.SearchResultsPane = function(searchConfig)
+{
+ this._searchConfig = searchConfig;
+ this.element = document.createElement("div");
+}
+
+WebInspector.SearchResultsPane.prototype = {
+ /**
+ * @return {!WebInspector.ProjectSearchConfig}
+ */
+ get searchConfig()
+ {
+ return this._searchConfig;
+ },
+
+ /**
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+ addSearchResult: function(searchResult) { }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.AdvancedSearchView.ToggleDrawerViewActionDelegate = function()
+{
+}
+
+WebInspector.AdvancedSearchView.ToggleDrawerViewActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ var searchView = this._searchView();
+ if (!searchView)
+ return false;
+ if (!searchView.isShowing() || searchView._search !== document.activeElement) {
+ WebInspector.inspectorView.showPanel("sources");
+ searchView.toggle();
+ } else {
+ WebInspector.inspectorView.closeDrawer();
+ }
+ return true;
+ },
+
+ /**
+ * @return {?WebInspector.AdvancedSearchView}
+ */
+ _searchView: function()
+ {
+ if (!this._view) {
+ var extensions = WebInspector.moduleManager.extensions("drawer-view");
+ for (var i = 0; i < extensions.length; ++i) {
+ if (extensions[i].descriptor()["name"] === "search") {
+ this._view = extensions[i].instance();
+ break;
+ }
+ }
+ }
+ return this._view;
+ }
+}
+
+
+/**
+ * @constructor
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {!Array.<!Object>} searchMatches
+ */
+WebInspector.FileBasedSearchResult = function(uiSourceCode, searchMatches) {
+ this.uiSourceCode = uiSourceCode;
+ this.searchMatches = searchMatches;
+}
+
+/**
+ * @interface
+ */
+WebInspector.SearchScope = function()
+{
+}
+
+WebInspector.SearchScope.prototype = {
+ /**
+ * @param {!WebInspector.SearchConfig} searchConfig
+ * @param {!WebInspector.Progress} progress
+ * @param {function(!WebInspector.FileBasedSearchResult)} searchResultCallback
+ * @param {function(boolean)} searchFinishedCallback
+ */
+ performSearch: function(searchConfig, progress, searchResultCallback, searchFinishedCallback) { },
+
+ /**
+ * @param {!WebInspector.Progress} progress
+ * @param {function(boolean)} callback
+ */
+ performIndexing: function(progress, callback) { },
+
+ stopSearch: function() { },
+
+ /**
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ * @return {!WebInspector.SearchResultsPane}
+ */
+ createSearchResultsPane: function(searchConfig) { }
+}
+
+importScript("FileBasedSearchResultsPane.js");
+importScript("SourcesSearchScope.js");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/search/FileBasedSearchResultsPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/search/FileBasedSearchResultsPane.js
new file mode 100644
index 00000000000..6c6cd9035e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/search/FileBasedSearchResultsPane.js
@@ -0,0 +1,231 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.SearchResultsPane}
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ */
+WebInspector.FileBasedSearchResultsPane = function(searchConfig)
+{
+ WebInspector.SearchResultsPane.call(this, searchConfig);
+
+ this._searchResults = [];
+
+ this.element.id = "search-results-pane-file-based";
+
+ this._treeOutlineElement = document.createElement("ol");
+ this._treeOutlineElement.className = "search-results-outline-disclosure";
+ this.element.appendChild(this._treeOutlineElement);
+ this._treeOutline = new TreeOutline(this._treeOutlineElement);
+
+ this._matchesExpandedCount = 0;
+}
+
+WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
+WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;
+
+WebInspector.FileBasedSearchResultsPane.prototype = {
+ /**
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+ addSearchResult: function(searchResult)
+ {
+ this._searchResults.push(searchResult);
+ var uiSourceCode = searchResult.uiSourceCode;
+ if (!uiSourceCode)
+ return;
+ this._addFileTreeElement(searchResult);
+ },
+
+ /**
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+ _addFileTreeElement: function(searchResult)
+ {
+ var fileTreeElement = new WebInspector.FileBasedSearchResultsPane.FileTreeElement(this._searchConfig, searchResult);
+ this._treeOutline.appendChild(fileTreeElement);
+ // Expand until at least a certain number of matches is expanded.
+ if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
+ fileTreeElement.expand();
+ this._matchesExpandedCount += searchResult.searchMatches.length;
+ },
+
+ __proto__: WebInspector.SearchResultsPane.prototype
+}
+
+/**
+ * @constructor
+ * @extends {TreeElement}
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ * @param {!WebInspector.FileBasedSearchResult} searchResult
+ */
+WebInspector.FileBasedSearchResultsPane.FileTreeElement = function(searchConfig, searchResult)
+{
+ TreeElement.call(this, "", null, true);
+ this._searchConfig = searchConfig;
+ this._searchResult = searchResult;
+
+ this.toggleOnClick = true;
+ this.selectable = false;
+}
+
+WebInspector.FileBasedSearchResultsPane.FileTreeElement.prototype = {
+ onexpand: function()
+ {
+ if (this._initialized)
+ return;
+
+ this._updateMatchesUI();
+ this._initialized = true;
+ },
+
+ _updateMatchesUI: function()
+ {
+ this.removeChildren();
+ var toIndex = Math.min(this._searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
+ if (toIndex < this._searchResult.searchMatches.length) {
+ this._appendSearchMatches(0, toIndex - 1);
+ this._appendShowMoreMatchesElement(toIndex - 1);
+ } else {
+ this._appendSearchMatches(0, toIndex);
+ }
+ },
+
+ onattach: function()
+ {
+ this._updateSearchMatches();
+ },
+
+ _updateSearchMatches: function()
+ {
+ this.listItemElement.classList.add("search-result");
+
+ var fileNameSpan = document.createElement("span");
+ fileNameSpan.className = "search-result-file-name";
+ fileNameSpan.textContent = this._searchResult.uiSourceCode.fullDisplayName();
+ this.listItemElement.appendChild(fileNameSpan);
+
+ var matchesCountSpan = document.createElement("span");
+ matchesCountSpan.className = "search-result-matches-count";
+
+ var searchMatchesCount = this._searchResult.searchMatches.length;
+ if (searchMatchesCount === 1)
+ matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
+ else
+ matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
+
+ this.listItemElement.appendChild(matchesCountSpan);
+ if (this.expanded)
+ this._updateMatchesUI();
+ },
+
+ /**
+ * @param {number} fromIndex
+ * @param {number} toIndex
+ */
+ _appendSearchMatches: function(fromIndex, toIndex)
+ {
+ var searchResult = this._searchResult;
+ var uiSourceCode = searchResult.uiSourceCode;
+ var searchMatches = searchResult.searchMatches;
+
+ var queries = this._searchConfig.queries();
+ var regexes = [];
+ for (var i = 0; i < queries.length; ++i)
+ regexes.push(createSearchRegex(queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex()));
+
+ for (var i = fromIndex; i < toIndex; ++i) {
+ var lineNumber = searchMatches[i].lineNumber;
+ var lineContent = searchMatches[i].lineContent;
+ var matchRanges = [];
+ for (var j = 0; j < regexes.length; ++j)
+ matchRanges = matchRanges.concat(this._regexMatchRanges(lineContent, regexes[j]));
+
+ var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);
+
+ var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
+ var lineNumberSpan = document.createElement("span");
+ lineNumberSpan.classList.add("search-match-line-number");
+ lineNumberSpan.textContent = numberString;
+ anchor.appendChild(lineNumberSpan);
+
+ var contentSpan = this._createContentSpan(lineContent, matchRanges);
+ anchor.appendChild(contentSpan);
+
+ var searchMatchElement = new TreeElement("");
+ searchMatchElement.selectable = false;
+ this.appendChild(searchMatchElement);
+ searchMatchElement.listItemElement.className = "search-match source-code";
+ searchMatchElement.listItemElement.appendChild(anchor);
+ }
+ },
+
+ /**
+ * @param {number} startMatchIndex
+ */
+ _appendShowMoreMatchesElement: function(startMatchIndex)
+ {
+ var matchesLeftCount = this._searchResult.searchMatches.length - startMatchIndex;
+ var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
+ this._showMoreMatchesTreeElement = new TreeElement(showMoreMatchesText);
+ this.appendChild(this._showMoreMatchesTreeElement);
+ this._showMoreMatchesTreeElement.listItemElement.classList.add("show-more-matches");
+ this._showMoreMatchesTreeElement.onselect = this._showMoreMatchesElementSelected.bind(this, startMatchIndex);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {!Element}
+ */
+ _createAnchor: function(uiSourceCode, lineNumber, columnNumber)
+ {
+ return WebInspector.Linkifier.linkifyUsingRevealer(uiSourceCode.uiLocation(lineNumber, columnNumber), "", uiSourceCode.url, lineNumber);
+ },
+
+ /**
+ * @param {string} lineContent
+ * @param {!Array.<!WebInspector.SourceRange>} matchRanges
+ */
+ _createContentSpan: function(lineContent, matchRanges)
+ {
+ var contentSpan = document.createElement("span");
+ contentSpan.className = "search-match-content";
+ contentSpan.textContent = lineContent;
+ WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
+ return contentSpan;
+ },
+
+ /**
+ * @param {string} lineContent
+ * @param {!RegExp} regex
+ * @return {!Array.<!WebInspector.SourceRange>}
+ */
+ _regexMatchRanges: function(lineContent, regex)
+ {
+ regex.lastIndex = 0;
+ var match;
+ var offset = 0;
+ var matchRanges = [];
+ while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
+ matchRanges.push(new WebInspector.SourceRange(match.index, match[0].length));
+
+ return matchRanges;
+ },
+
+ /**
+ * @param {number} startMatchIndex
+ * @return {boolean}
+ */
+ _showMoreMatchesElementSelected: function(startMatchIndex)
+ {
+ this.removeChild(this._showMoreMatchesTreeElement);
+ this._appendSearchMatches(startMatchIndex, this._searchResult.searchMatches.length);
+ return false;
+ },
+
+ __proto__: TreeElement.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesSearchScope.js b/chromium/third_party/WebKit/Source/devtools/front_end/search/SourcesSearchScope.js
index af5a2b92065..a8f01f1ef21 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourcesSearchScope.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/search/SourcesSearchScope.js
@@ -29,14 +29,12 @@
/**
* @constructor
* @implements {WebInspector.SearchScope}
- * @param {!WebInspector.Workspace} workspace
*/
-WebInspector.SourcesSearchScope = function(workspace)
+WebInspector.SourcesSearchScope = function()
{
// FIXME: Add title once it is used by search controller.
- WebInspector.SearchScope.call(this)
this._searchId = 0;
- this._workspace = workspace;
+ this._workspace = WebInspector.workspace;
}
WebInspector.SourcesSearchScope.prototype = {
@@ -48,21 +46,15 @@ WebInspector.SourcesSearchScope.prototype = {
{
this.stopSearch();
- function filterOutServiceProjects(project)
- {
- return !project.isServiceProject();
- }
-
- var projects = this._workspace.projects().filter(filterOutServiceProjects);
- var barrier = new CallbackBarrier();
+ var projects = this._projects();
var compositeProgress = new WebInspector.CompositeProgress(progress);
- progress.addEventListener(WebInspector.Progress.Events.Canceled, indexingCanceled.bind(this));
+ progress.addEventListener(WebInspector.Progress.Events.Canceled, indexingCanceled);
for (var i = 0; i < projects.length; ++i) {
var project = projects[i];
var projectProgress = compositeProgress.createSubProgress(project.uiSourceCodes().length);
- project.indexContent(projectProgress, barrier.createCallback());
+ project.indexContent(projectProgress);
}
- barrier.callWhenDone(indexingFinishedCallback.bind(this, true));
+ compositeProgress.addEventListener(WebInspector.Progress.Events.Done, indexingFinishedCallback.bind(this, true));
function indexingCanceled()
{
@@ -72,9 +64,35 @@ WebInspector.SourcesSearchScope.prototype = {
},
/**
- * @param {!WebInspector.SearchConfig} searchConfig
+ * @return {!Array.<!WebInspector.Project>}
+ */
+ _projects: function()
+ {
+ /**
+ * @param {!WebInspector.Project} project
+ * @return {boolean}
+ */
+ function filterOutServiceProjects(project)
+ {
+ return !project.isServiceProject() || project.type() === WebInspector.projectTypes.Formatter;
+ }
+
+ /**
+ * @param {!WebInspector.Project} project
+ * @return {boolean}
+ */
+ function filterOutContentScriptsIfNeeded(project)
+ {
+ return WebInspector.settings.searchInContentScripts.get() || project.type() !== WebInspector.projectTypes.ContentScripts;
+ }
+
+ return this._workspace.projects().filter(filterOutServiceProjects).filter(filterOutContentScriptsIfNeeded);
+ },
+
+ /**
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
* @param {!WebInspector.Progress} progress
- * @param {function(!WebInspector.FileBasedSearchResultsPane.SearchResult)} searchResultCallback
+ * @param {function(!WebInspector.FileBasedSearchResult)} searchResultCallback
* @param {function(boolean)} searchFinishedCallback
*/
performSearch: function(searchConfig, progress, searchResultCallback, searchFinishedCallback)
@@ -84,15 +102,7 @@ WebInspector.SourcesSearchScope.prototype = {
this._searchFinishedCallback = searchFinishedCallback;
this._searchConfig = searchConfig;
- /**
- * @param {!WebInspector.Project} project
- */
- function filterOutServiceProjects(project)
- {
- return !project.isServiceProject();
- }
-
- var projects = this._workspace.projects().filter(filterOutServiceProjects);
+ var projects = this._projects();
var barrier = new CallbackBarrier();
var compositeProgress = new WebInspector.CompositeProgress(progress);
for (var i = 0; i < projects.length; ++i) {
@@ -103,7 +113,7 @@ WebInspector.SourcesSearchScope.prototype = {
var searchContentProgress = projectProgress.createSubProgress();
var barrierCallback = barrier.createCallback();
var callback = this._processMatchingFilesForProject.bind(this, this._searchId, project, searchContentProgress, barrierCallback);
- project.findFilesMatchingSearchRequest(searchConfig.queries(), searchConfig.fileQueries(), !searchConfig.ignoreCase, searchConfig.isRegex, findMatchingFilesProgress, callback);
+ project.findFilesMatchingSearchRequest(searchConfig, findMatchingFilesProgress, callback);
}
barrier.callWhenDone(this._searchFinishedCallback.bind(this, true));
},
@@ -122,6 +132,8 @@ WebInspector.SourcesSearchScope.prototype = {
return;
}
+ addDirtyFiles.call(this);
+
if (!files.length) {
progress.done();
callback();
@@ -138,7 +150,23 @@ WebInspector.SourcesSearchScope.prototype = {
scheduleSearchInNextFileOrFinish.call(this);
/**
- * @param {!string} path
+ * @this {WebInspector.SourcesSearchScope}
+ */
+ function addDirtyFiles()
+ {
+ var matchingFiles = StringSet.fromArray(files);
+ var uiSourceCodes = project.uiSourceCodes();
+ for (var i = 0; i < uiSourceCodes.length; ++i) {
+ if (!uiSourceCodes[i].isDirty())
+ continue;
+ var path = uiSourceCodes[i].path();
+ if (!matchingFiles.contains(path) && this._searchConfig.filePathMatchesFileQuery(path))
+ files.push(path);
+ }
+ }
+
+ /**
+ * @param {string} path
* @this {WebInspector.SourcesSearchScope}
*/
function searchInNextFile(path)
@@ -150,7 +178,19 @@ WebInspector.SourcesSearchScope.prototype = {
scheduleSearchInNextFileOrFinish.call(this);
return;
}
- uiSourceCode.requestContent(contentLoaded.bind(this, path));
+ if (uiSourceCode.isDirty())
+ contentLoaded.call(this, uiSourceCode.path(), uiSourceCode.workingCopy());
+ else
+ uiSourceCode.checkContentUpdated(contentUpdated.bind(this, uiSourceCode));
+ }
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @this {WebInspector.SourcesSearchScope}
+ */
+ function contentUpdated(uiSourceCode)
+ {
+ uiSourceCode.requestContent(contentLoaded.bind(this, uiSourceCode.path()));
}
/**
@@ -173,7 +213,7 @@ WebInspector.SourcesSearchScope.prototype = {
}
/**
- * @param {!string} path
+ * @param {string} path
* @param {?string} content
* @this {WebInspector.SourcesSearchScope}
*/
@@ -193,13 +233,13 @@ WebInspector.SourcesSearchScope.prototype = {
var queries = this._searchConfig.queries();
if (content !== null) {
for (var i = 0; i < queries.length; ++i) {
- var nextMatches = WebInspector.ContentProvider.performSearchInContent(content, queries[i], !this._searchConfig.ignoreCase, this._searchConfig.isRegex)
+ var nextMatches = WebInspector.ContentProvider.performSearchInContent(content, queries[i], !this._searchConfig.ignoreCase(), this._searchConfig.isRegex())
matches = matches.mergeOrdered(nextMatches, matchesComparator);
}
}
var uiSourceCode = project.uiSourceCode(path);
if (matches && uiSourceCode) {
- var searchResult = new WebInspector.FileBasedSearchResultsPane.SearchResult(uiSourceCode, matches);
+ var searchResult = new WebInspector.FileBasedSearchResult(uiSourceCode, matches);
this._searchResultCallback(searchResult);
}
@@ -214,12 +254,11 @@ WebInspector.SourcesSearchScope.prototype = {
},
/**
- * @param {!WebInspector.SearchConfig} searchConfig
+ * @param {!WebInspector.ProjectSearchConfig} searchConfig
+ * @return {!WebInspector.FileBasedSearchResultsPane}
*/
createSearchResultsPane: function(searchConfig)
{
return new WebInspector.FileBasedSearchResultsPane(searchConfig);
- },
-
- __proto__: WebInspector.SearchScope.prototype
+ }
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/search/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/search/module.json
new file mode 100644
index 00000000000..0d40ffac010
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/search/module.json
@@ -0,0 +1,27 @@
+{
+ "extensions": [
+ {
+ "type": "drawer-view",
+ "name": "search",
+ "title": "Search",
+ "order": "1",
+ "className": "WebInspector.AdvancedSearchView"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "search.toggle",
+ "className": "WebInspector.AdvancedSearchView.ToggleDrawerViewActionDelegate",
+ "bindings": [
+ {
+ "platform": "mac",
+ "shortcut": "Meta+Alt+F"
+ },
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+Shift+F"
+ }
+ ]
+ }
+ ],
+ "scripts": [ "AdvancedSearchView.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/EditFileSystemDialog.js b/chromium/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js
index b687996b1b0..bb2667fb760 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/EditFileSystemDialog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/settings/EditFileSystemDialog.js
@@ -43,7 +43,7 @@ WebInspector.EditFileSystemDialog = function(fileSystemPath)
var header = this.element.createChild("div", "header");
var headerText = header.createChild("span");
- headerText.textContent = "Edit file system";
+ headerText.textContent = WebInspector.UIString("Edit file system");
var closeButton = header.createChild("div", "close-button-gray done-button");
closeButton.addEventListener("click", this._onDoneClick.bind(this), false);
@@ -56,8 +56,8 @@ WebInspector.EditFileSystemDialog = function(fileSystemPath)
WebInspector.isolatedFileSystemManager.mapping().addEventListener(WebInspector.FileSystemMapping.Events.ExcludedFolderRemoved, this._excludedFolderRemoved, this);
var blockHeader = contents.createChild("div", "block-header");
- blockHeader.textContent = "Mappings";
- this._fileMappingsSection = contents.createChild("div", "file-mappings-section");
+ blockHeader.textContent = WebInspector.UIString("Mappings");
+ this._fileMappingsSection = contents.createChild("div", "section file-mappings-section");
this._fileMappingsListContainer = this._fileMappingsSection.createChild("div", "settings-list-container");
var entries = WebInspector.isolatedFileSystemManager.mapping().mappingEntries(this._fileSystemPath);
@@ -72,8 +72,8 @@ WebInspector.EditFileSystemDialog = function(fileSystemPath)
this._addMappingRow(entries[i]);
blockHeader = contents.createChild("div", "block-header");
- blockHeader.textContent = "Excluded folders";
- this._excludedFolderListSection = contents.createChild("div", "excluded-folders-section");
+ blockHeader.textContent = WebInspector.UIString("Excluded folders");
+ this._excludedFolderListSection = contents.createChild("div", "section excluded-folders-section");
this._excludedFolderListContainer = this._excludedFolderListSection.createChild("div", "settings-list-container");
var excludedFolderEntries = WebInspector.isolatedFileSystemManager.mapping().excludedFolders(fileSystemPath);
@@ -110,15 +110,19 @@ WebInspector.EditFileSystemDialog.prototype = {
_resize: function()
{
- if (!this._dialogElement)
+ if (!this._dialogElement || !this._relativeToElement)
return;
- const width = 540;
+ const minWidth = 200;
const minHeight = 150;
- var maxHeight = document.body.offsetHeight - 10;
+ var maxHeight = this._relativeToElement.offsetHeight - 10;
maxHeight = Math.max(minHeight, maxHeight);
+ var maxWidth = Math.min(540, this._relativeToElement.offsetWidth - 10);
+ maxWidth = Math.max(minWidth, maxWidth);
this._dialogElement.style.maxHeight = maxHeight + "px";
- this._dialogElement.style.width = width + "px";
+ this._dialogElement.style.width = maxWidth + "px";
+
+ WebInspector.DialogDelegate.prototype.position(this._dialogElement, this._relativeToElement);
},
/**
@@ -127,6 +131,7 @@ WebInspector.EditFileSystemDialog.prototype = {
*/
position: function(element, relativeToElement)
{
+ this._relativeToElement = relativeToElement;
this._resize();
},
@@ -151,6 +156,11 @@ WebInspector.EditFileSystemDialog.prototype = {
this._resize();
},
+ /**
+ * @param {string} itemId
+ * @param {string} columnId
+ * @return {string}
+ */
_fileMappingValuesProvider: function(itemId, columnId)
{
if (!itemId)
@@ -275,6 +285,11 @@ WebInspector.EditFileSystemDialog.prototype = {
this._excludedFolderList.removeItem(entry.path);
},
+ /**
+ * @param {string} itemId
+ * @param {string} columnId
+ * @return {string}
+ */
_excludedFolderValueProvider: function(itemId, columnId)
{
return itemId;
@@ -338,6 +353,7 @@ WebInspector.EditFileSystemDialog.prototype = {
var path = entry.path;
this._excludedFolderEntries.put(path, entry);
this._excludedFolderList.addItem(path, null);
+ this._resize();
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SettingsScreen.js b/chromium/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
index ebec7c60361..7beb3b8eb9f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SettingsScreen.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
@@ -28,6 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+importScript("EditFileSystemDialog.js");
+
/**
* @constructor
* @param {!function()} onHide
@@ -59,20 +61,8 @@ WebInspector.SettingsScreen = function(onHide)
this._lastSelectedTabSetting = WebInspector.settings.createSetting("lastSelectedSettingsTab", WebInspector.SettingsScreen.Tabs.General);
this.selectTab(this._lastSelectedTabSetting.get());
this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
-}
-
-/**
- * @param {string} text
- * @return {?string}
- */
-WebInspector.SettingsScreen.regexValidator = function(text)
-{
- var regex;
- try {
- regex = new RegExp(text);
- } catch (e) {
- }
- return regex ? null : "Invalid pattern";
+ this.element.addEventListener("keydown", this._keyDown.bind(this), false);
+ this._developerModeCounter = 0;
}
/**
@@ -85,9 +75,9 @@ WebInspector.SettingsScreen.integerValidator = function(min, max, text)
{
var value = Number(text);
if (isNaN(value))
- return "Invalid number format";
+ return WebInspector.UIString("Invalid number format");
if (value < min || value > max)
- return "Value is out of range [" + min + ", " + max + "]";
+ return WebInspector.UIString("Value is out of range [%d, %d]", min, max);
return null;
}
@@ -127,6 +117,7 @@ WebInspector.SettingsScreen.prototype = {
/**
* @override
+ * @return {boolean}
*/
isClosingKey: function(keyCode)
{
@@ -145,19 +136,29 @@ WebInspector.SettingsScreen.prototype = {
WebInspector.HelpScreen.prototype.willHide.call(this);
},
+ /**
+ * @param {?Event} event
+ */
+ _keyDown: function(event)
+ {
+ var shiftKeyCode = 16;
+ if (event.keyCode === shiftKeyCode && ++this._developerModeCounter > 5)
+ this.element.classList.add("settings-developer-mode");
+ },
+
__proto__: WebInspector.HelpScreen.prototype
}
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {string} name
* @param {string=} id
*/
WebInspector.SettingsTab = function(name, id)
{
- WebInspector.View.call(this);
- this.element.className = "settings-tab-container";
+ WebInspector.VBox.call(this);
+ this.element.classList.add("settings-tab-container");
if (id)
this.element.id = id;
var header = this.element.createChild("header");
@@ -165,72 +166,6 @@ WebInspector.SettingsTab = function(name, id)
this.containerElement = this.element.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
}
-/**
- * @param {string} name
- * @param {function(): *} getter
- * @param {function(*)} setter
- * @param {boolean=} omitParagraphElement
- * @param {!Element=} inputElement
- * @param {string=} tooltip
- * @return {!Element}
- */
-WebInspector.SettingsTab.createCheckbox = function(name, getter, setter, omitParagraphElement, inputElement, tooltip)
-{
- var input = inputElement || document.createElement("input");
- input.type = "checkbox";
- input.name = name;
- input.checked = getter();
-
- function listener()
- {
- setter(input.checked);
- }
- input.addEventListener("click", listener, false);
-
- var label = document.createElement("label");
- label.appendChild(input);
- label.appendChild(document.createTextNode(name));
- if (tooltip)
- label.title = tooltip;
-
- if (omitParagraphElement)
- return label;
-
- var p = document.createElement("p");
- p.appendChild(label);
- return p;
-}
-
-/**
- * @param {string} name
- * @param {!WebInspector.Setting} setting
- * @param {boolean=} omitParagraphElement
- * @param {!Element=} inputElement
- * @param {string=} tooltip
- * @return {!Element}
- */
-WebInspector.SettingsTab.createSettingCheckbox = function(name, setting, omitParagraphElement, inputElement, tooltip)
-{
- return WebInspector.SettingsTab.createCheckbox(name, setting.get.bind(setting), setting.set.bind(setting), omitParagraphElement, inputElement, tooltip);
-}
-
-/**
- * @param {!WebInspector.Setting} setting
- * @return {!Element}
- */
-WebInspector.SettingsTab.createSettingFieldset = function(setting)
-{
- var fieldset = document.createElement("fieldset");
- fieldset.disabled = !setting.get();
- setting.addChangeListener(settingChanged);
- return fieldset;
-
- function settingChanged()
- {
- fieldset.disabled = !setting.get();
- }
-}
-
WebInspector.SettingsTab.prototype = {
/**
* @param {string=} name
@@ -270,61 +205,7 @@ WebInspector.SettingsTab.prototype = {
return p;
},
- /**
- * @param {string} label
- * @param {!WebInspector.Setting} setting
- * @param {boolean} numeric
- * @param {number=} maxLength
- * @param {string=} width
- * @param {function(string):?string=} validatorCallback
- */
- _createInputSetting: function(label, setting, numeric, maxLength, width, validatorCallback)
- {
- var p = document.createElement("p");
- var labelElement = p.createChild("label");
- labelElement.textContent = label;
- var inputElement = p.createChild("input");
- inputElement.value = setting.get();
- inputElement.type = "text";
- if (numeric)
- inputElement.className = "numeric";
- if (maxLength)
- inputElement.maxLength = maxLength;
- if (width)
- inputElement.style.width = width;
- if (validatorCallback) {
- var errorMessageLabel = p.createChild("div");
- errorMessageLabel.classList.add("field-error-message");
- errorMessageLabel.style.color = "DarkRed";
- inputElement.oninput = function()
- {
- var error = validatorCallback(inputElement.value);
- if (!error)
- error = "";
- errorMessageLabel.textContent = error;
- };
- }
-
- function onBlur()
- {
- setting.set(numeric ? Number(inputElement.value) : inputElement.value);
- }
- inputElement.addEventListener("blur", onBlur, false);
-
- return p;
- },
-
- _createCustomSetting: function(name, element)
- {
- var p = document.createElement("p");
- var fieldsetElement = document.createElement("fieldset");
- fieldsetElement.createChild("label").textContent = name;
- fieldsetElement.appendChild(element);
- p.appendChild(fieldsetElement);
- return p;
- },
-
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
@@ -335,124 +216,134 @@ WebInspector.GenericSettingsTab = function()
{
WebInspector.SettingsTab.call(this, WebInspector.UIString("General"), "general-tab-content");
- var p = this._appendSection();
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Disable cache (while DevTools is open)"), WebInspector.settings.cacheDisabled));
- var disableJSElement = WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled);
- p.appendChild(disableJSElement);
- WebInspector.settings.javaScriptDisabled.addChangeListener(this._javaScriptDisabledChanged, this);
- this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0];
- this._updateScriptDisabledCheckbox();
-
- p = this._appendSection(WebInspector.UIString("Appearance"));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show 'Emulation' view in console drawer."), WebInspector.settings.showEmulationViewInDrawer));
- this._appendDrawerNote(p.lastElementChild);
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show 'Rendering' view in console drawer."), WebInspector.settings.showRenderingViewInDrawer));
- this._appendDrawerNote(p.lastElementChild);
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Split panels vertically when docked to right"), WebInspector.settings.splitVerticallyWhenDockedToRight));
-
- p = this._appendSection(WebInspector.UIString("Elements"));
- var colorFormatElement = this._createSelectSetting(WebInspector.UIString("Color format"), [
- [ WebInspector.UIString("As authored"), WebInspector.Color.Format.Original ],
- [ "HEX: #DAC0DE", WebInspector.Color.Format.HEX ],
- [ "RGB: rgb(128, 255, 255)", WebInspector.Color.Format.RGB ],
- [ "HSL: hsl(300, 80%, 90%)", WebInspector.Color.Format.HSL ]
- ], WebInspector.settings.colorFormat);
- p.appendChild(colorFormatElement);
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show user agent styles"), WebInspector.settings.showUserAgentStyles));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Word wrap"), WebInspector.settings.domWordWrap));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show Shadow DOM"), WebInspector.settings.showShadowDOM));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show rulers"), WebInspector.settings.showMetricsRulers));
-
- p = this._appendSection(WebInspector.UIString("Sources"));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Search in content scripts"), WebInspector.settings.searchInContentScripts));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Enable JS source maps"), WebInspector.settings.jsSourceMapsEnabled));
-
- var checkbox = WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Enable CSS source maps"), WebInspector.settings.cssSourceMapsEnabled);
- p.appendChild(checkbox);
- var fieldset = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.cssSourceMapsEnabled);
- var autoReloadCSSCheckbox = fieldset.createChild("input");
- fieldset.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Auto-reload generated CSS"), WebInspector.settings.cssReloadEnabled, false, autoReloadCSSCheckbox));
- checkbox.appendChild(fieldset);
-
- var indentationElement = this._createSelectSetting(WebInspector.UIString("Default indentation"), [
- [ WebInspector.UIString("2 spaces"), WebInspector.TextUtils.Indent.TwoSpaces ],
- [ WebInspector.UIString("4 spaces"), WebInspector.TextUtils.Indent.FourSpaces ],
- [ WebInspector.UIString("8 spaces"), WebInspector.TextUtils.Indent.EightSpaces ],
- [ WebInspector.UIString("Tab character"), WebInspector.TextUtils.Indent.TabCharacter ]
- ], WebInspector.settings.textEditorIndent);
- p.appendChild(indentationElement);
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Detect indentation"), WebInspector.settings.textEditorAutoDetectIndent));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Autocompletion"), WebInspector.settings.textEditorAutocompletion));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Bracket matching"), WebInspector.settings.textEditorBracketMatching));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show whitespace characters"), WebInspector.settings.showWhitespacesInEditor));
- if (WebInspector.experimentsSettings.frameworksDebuggingSupport.isEnabled()) {
- checkbox = WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Skip stepping through sources with particular names"), WebInspector.settings.skipStackFramesSwitch);
- fieldset = WebInspector.SettingsTab.createSettingFieldset(WebInspector.settings.skipStackFramesSwitch);
- fieldset.appendChild(this._createInputSetting(WebInspector.UIString("Pattern"), WebInspector.settings.skipStackFramesPattern, false, 1000, "100px", WebInspector.SettingsScreen.regexValidator));
- checkbox.appendChild(fieldset);
- p.appendChild(checkbox);
- }
- WebInspector.settings.skipStackFramesSwitch.addChangeListener(this._skipStackFramesSwitchOrPatternChanged, this);
- WebInspector.settings.skipStackFramesPattern.addChangeListener(this._skipStackFramesSwitchOrPatternChanged, this);
-
- p = this._appendSection(WebInspector.UIString("Profiler"));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Show advanced heap snapshot properties"), WebInspector.settings.showAdvancedHeapSnapshotProperties));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("High resolution CPU profiling"), WebInspector.settings.highResolutionCpuProfiling));
+ this._populateSectionsFromExtensions();
- p = this._appendSection(WebInspector.UIString("Console"));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Log XMLHttpRequests"), WebInspector.settings.monitoringXHREnabled));
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Preserve log upon navigation"), WebInspector.settings.preserveConsoleLog));
+ var restoreDefaults = this._appendSection().createChild("input", "settings-tab-text-button");
+ restoreDefaults.type = "button";
+ restoreDefaults.value = WebInspector.UIString("Restore defaults and reload");
+ restoreDefaults.addEventListener("click", restoreAndReload, false);
- if (WebInspector.extensionServer.hasExtensions()) {
- var handlerSelector = new WebInspector.HandlerSelector(WebInspector.openAnchorLocationRegistry);
- p = this._appendSection(WebInspector.UIString("Extensions"));
- p.appendChild(this._createCustomSetting(WebInspector.UIString("Open links in"), handlerSelector.element));
+ function restoreAndReload()
+ {
+ if (window.localStorage)
+ window.localStorage.clear();
+ WebInspector.reload();
}
-
- p = this._appendSection();
- var panelShortcutTitle = WebInspector.UIString("Enable %s + 1-9 shortcut to switch panels", WebInspector.isMac() ? "Cmd" : "Ctrl");
- p.appendChild(WebInspector.SettingsTab.createSettingCheckbox(panelShortcutTitle, WebInspector.settings.shortcutPanelSwitch));
}
WebInspector.GenericSettingsTab.prototype = {
- _updateScriptDisabledCheckbox: function()
+ _populateSectionsFromExtensions: function()
+ {
+ /** @const */
+ var explicitSectionOrder = ["", "Appearance", "Elements", "Sources", "Profiler", "Console", "Extensions"];
+
+ var allExtensions = WebInspector.moduleManager.extensions("ui-setting");
+
+ /** @type {!StringMultimap.<!WebInspector.ModuleManager.Extension>} */
+ var extensionsBySectionId = new StringMultimap();
+ /** @type {!StringMultimap.<!WebInspector.ModuleManager.Extension>} */
+ var childSettingExtensionsByParentName = new StringMultimap();
+
+ allExtensions.forEach(function(extension) {
+ var descriptor = extension.descriptor();
+ var sectionName = descriptor["section"] || "";
+ if (!sectionName && descriptor["parentSettingName"]) {
+ childSettingExtensionsByParentName.put(descriptor["parentSettingName"], extension);
+ return;
+ }
+ extensionsBySectionId.put(sectionName, extension);
+ });
+
+ var sectionIds = extensionsBySectionId.keys();
+ var explicitlyOrderedSections = {};
+ for (var i = 0; i < explicitSectionOrder.length; ++i) {
+ explicitlyOrderedSections[explicitSectionOrder[i]] = true;
+ var extensions = extensionsBySectionId.get(explicitSectionOrder[i]);
+ if (!extensions.size())
+ continue;
+ this._addSectionWithExtensionProvidedSettings(explicitSectionOrder[i], extensions.values(), childSettingExtensionsByParentName);
+ }
+ for (var i = 0; i < sectionIds.length; ++i) {
+ if (explicitlyOrderedSections[sectionIds[i]])
+ continue;
+ this._addSectionWithExtensionProvidedSettings(sectionIds[i], extensionsBySectionId.get(sectionIds[i]).values(), childSettingExtensionsByParentName);
+ }
+ },
+
+ /**
+ * @param {string} sectionName
+ * @param {!Array.<!WebInspector.ModuleManager.Extension>} extensions
+ * @param {!StringMultimap.<!WebInspector.ModuleManager.Extension>} childSettingExtensionsByParentName
+ */
+ _addSectionWithExtensionProvidedSettings: function(sectionName, extensions, childSettingExtensionsByParentName)
{
+ var uiSectionName = sectionName && WebInspector.UIString(sectionName);
+ var sectionElement = this._appendSection(uiSectionName);
+ extensions.forEach(processSetting.bind(this, null));
+
/**
- * @param {?Protocol.Error} error
- * @param {string} status
+ * @param {?Element} parentFieldset
+ * @param {!WebInspector.ModuleManager.Extension} extension
* @this {WebInspector.GenericSettingsTab}
*/
- function executionStatusCallback(error, status)
+ function processSetting(parentFieldset, extension)
{
- if (error || !status)
+ var descriptor = extension.descriptor();
+ var experimentName = descriptor["experiment"];
+ if (experimentName && (!WebInspector.experimentsSettings[experimentName] || !WebInspector.experimentsSettings[experimentName].isEnabled()))
return;
- switch (status) {
- case "forbidden":
- this._disableJSCheckbox.checked = true;
- this._disableJSCheckbox.disabled = true;
- break;
- case "disabled":
- this._disableJSCheckbox.checked = true;
- break;
- default:
- this._disableJSCheckbox.checked = false;
- break;
+ var settingName = descriptor["settingName"];
+ var setting = WebInspector.settings[settingName];
+ var instance = extension.instance();
+ var settingControl;
+ if (instance && descriptor["settingType"] === "custom") {
+ settingControl = instance.settingElement();
+ if (!settingControl)
+ return;
+ }
+ if (!settingControl) {
+ var uiTitle = WebInspector.UIString(descriptor["title"]);
+ settingControl = createSettingControl.call(this, uiTitle, setting, descriptor, instance);
+ }
+ if (settingName) {
+ var childSettings = childSettingExtensionsByParentName.get(settingName);
+ if (childSettings.size()) {
+ var fieldSet = WebInspector.SettingsUI.createSettingFieldset(setting);
+ settingControl.appendChild(fieldSet);
+ childSettings.values().forEach(function(item) { processSetting.call(this, fieldSet, item); }, this);
+ }
}
+ var containerElement = parentFieldset || sectionElement;
+ containerElement.appendChild(settingControl);
}
- PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
- },
-
- _javaScriptDisabledChanged: function()
- {
- // We need to manually update the checkbox state, since enabling JavaScript in the page can actually uncover the "forbidden" state.
- PageAgent.setScriptExecutionDisabled(WebInspector.settings.javaScriptDisabled.get(), this._updateScriptDisabledCheckbox.bind(this));
- },
-
- _skipStackFramesSwitchOrPatternChanged: function()
- {
- WebInspector.DebuggerModel.applySkipStackFrameSettings();
+ /**
+ * @param {string} uiTitle
+ * @param {!WebInspector.Setting} setting
+ * @param {!Object} descriptor
+ * @param {?Object} instance
+ * @return {!Element}
+ * @this {WebInspector.GenericSettingsTab}
+ */
+ function createSettingControl(uiTitle, setting, descriptor, instance)
+ {
+ switch (descriptor["settingType"]) {
+ case "checkbox":
+ return WebInspector.SettingsUI.createSettingCheckbox(uiTitle, setting);
+ case "select":
+ var descriptorOptions = descriptor["options"]
+ var options = new Array(descriptorOptions.length);
+ for (var i = 0; i < options.length; ++i) {
+ // The third array item flags that the option name is "raw" (non-i18n-izable).
+ var optionName = descriptorOptions[i][2] ? descriptorOptions[i][0] : WebInspector.UIString(descriptorOptions[i][0]);
+ options[i] = [WebInspector.UIString(descriptorOptions[i][0]), descriptorOptions[i][1]];
+ }
+ return this._createSelectSetting(uiTitle, options, setting);
+ default:
+ throw "Invalid setting type: " + descriptor["settingType"];
+ }
+ }
},
/**
@@ -482,7 +373,7 @@ WebInspector.WorkspaceSettingsTab = function()
WebInspector.isolatedFileSystemManager.addEventListener(WebInspector.IsolatedFileSystemManager.Events.FileSystemRemoved, this._fileSystemRemoved, this);
this._commonSection = this._appendSection(WebInspector.UIString("Common"));
- var folderExcludePatternInput = this._createInputSetting(WebInspector.UIString("Folder exclude pattern"), WebInspector.settings.workspaceFolderExcludePattern, false, 0, "270px", WebInspector.SettingsScreen.regexValidator);
+ var folderExcludePatternInput = WebInspector.SettingsUI.createSettingInputField(WebInspector.UIString("Folder exclude pattern"), WebInspector.settings.workspaceFolderExcludePattern, false, 0, "270px", WebInspector.SettingsUI.regexValidator);
this._commonSection.appendChild(folderExcludePatternInput);
this._fileSystemsSection = this._appendSection(WebInspector.UIString("Folders"));
@@ -492,12 +383,12 @@ WebInspector.WorkspaceSettingsTab = function()
var addFileSystemButton = this._addFileSystemRowElement.createChild("input", "settings-tab-text-button");
addFileSystemButton.type = "button";
addFileSystemButton.value = WebInspector.UIString("Add folder\u2026");
- addFileSystemButton.addEventListener("click", this._addFileSystemClicked.bind(this));
+ addFileSystemButton.addEventListener("click", this._addFileSystemClicked.bind(this), false);
this._editFileSystemButton = this._addFileSystemRowElement.createChild("input", "settings-tab-text-button");
this._editFileSystemButton.type = "button";
this._editFileSystemButton.value = WebInspector.UIString("Edit\u2026");
- this._editFileSystemButton.addEventListener("click", this._editFileSystemClicked.bind(this));
+ this._editFileSystemButton.addEventListener("click", this._editFileSystemClicked.bind(this), false);
this._updateEditFileSystemButtonState();
this._reset();
@@ -560,10 +451,7 @@ WebInspector.WorkspaceSettingsTab.prototype = {
this._editFileSystem(id);
},
- /**
- * @param {!WebInspector.Event=} event
- */
- _editFileSystemClicked: function(event)
+ _editFileSystemClicked: function()
{
this._editFileSystem(this._selectedFileSystemPath());
},
@@ -573,7 +461,7 @@ WebInspector.WorkspaceSettingsTab.prototype = {
*/
_editFileSystem: function(id)
{
- WebInspector.EditFileSystemDialog.show(document.body, id);
+ WebInspector.EditFileSystemDialog.show(WebInspector.inspectorView.element, id);
},
/**
@@ -713,7 +601,8 @@ WebInspector.ExperimentsSettingsTab.prototype = {
input.addEventListener("click", listener, false);
var p = document.createElement("p");
- var label = document.createElement("label");
+ p.className = experiment.hidden && !experiment.isEnabled() ? "settings-experiment-hidden" : "";
+ var label = p.createChild("label");
label.appendChild(input);
label.appendChild(document.createTextNode(WebInspector.UIString(experiment.title)));
p.appendChild(label);
@@ -728,28 +617,14 @@ WebInspector.ExperimentsSettingsTab.prototype = {
*/
WebInspector.SettingsController = function()
{
- this._statusBarButton = new WebInspector.StatusBarButton(WebInspector.UIString("Settings"), "settings-status-bar-item");
- this._statusBarButton.element.addEventListener("mouseup", this._mouseUp.bind(this), false);
-
/** @type {?WebInspector.SettingsScreen} */
this._settingsScreen;
+
+ window.addEventListener("resize", this._resize.bind(this), true);
}
WebInspector.SettingsController.prototype =
{
- /**
- * @return {!Element}
- */
- get statusBarItem()
- {
- return this._statusBarButton.element;
- },
-
- _mouseUp: function()
- {
- this.showSettingsScreen();
- },
-
_onHideSettingsScreen: function()
{
delete this._settingsScreenVisible;
@@ -770,13 +645,7 @@ WebInspector.SettingsController.prototype =
this._settingsScreenVisible = true;
},
- _hideSettingsScreen: function()
- {
- if (this._settingsScreen)
- this._settingsScreen.hide();
- },
-
- resize: function()
+ _resize: function()
{
if (this._settingsScreen && this._settingsScreen.isShowing())
this._settingsScreen.doResize();
@@ -785,7 +654,25 @@ WebInspector.SettingsController.prototype =
/**
* @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.SettingsController.SettingsScreenActionDelegate = function() { }
+
+WebInspector.SettingsController.SettingsScreenActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ WebInspector._settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.General);
+ return true;
+ }
+}
+
+/**
+ * @constructor
* @extends {WebInspector.Object}
+ * @param {!Array.<string>} columns
* @param {function(!Element, string, ?string)} itemRenderer
*/
WebInspector.SettingsList = function(columns, itemRenderer)
@@ -915,7 +802,7 @@ WebInspector.SettingsList.prototype = {
/**
* @param {?string} id
- * @param {!Event=} event
+ * @param {?Event=} event
*/
_onDoubleClick: function(id, event)
{
@@ -924,7 +811,7 @@ WebInspector.SettingsList.prototype = {
/**
* @param {?string} id
- * @param {!Event=} event
+ * @param {?Event=} event
*/
selectItem: function(id, event)
{
@@ -960,6 +847,8 @@ WebInspector.SettingsList.prototype = {
/**
* @constructor
* @extends {WebInspector.SettingsList}
+ * @param {!Array.<string>} columns
+ * @param {function(string, string):string} valuesProvider
* @param {function(?string, !Object)} validateHandler
* @param {function(?string, !Object)} editHandler
*/
@@ -1004,10 +893,10 @@ WebInspector.EditableSettingsList.prototype = {
columnElement.classList.add("settings-list-column-" + columnId);
var placeholder = (columnId === "url") ? WebInspector.UIString("URL prefix") : WebInspector.UIString("Folder path");
if (itemId === null) {
- var inputElement = columnElement.createChild("input", "list-column-editor");
+ var inputElement = /** @type {!HTMLInputElement} */ (columnElement.createChild("input", "list-column-editor"));
inputElement.placeholder = placeholder;
- inputElement.addEventListener("blur", this._onAddMappingInputBlur.bind(this));
- inputElement.addEventListener("input", this._validateEdit.bind(this, itemId));
+ inputElement.addEventListener("blur", this._onAddMappingInputBlur.bind(this), false);
+ inputElement.addEventListener("input", this._validateEdit.bind(this, itemId), false);
this._addInputElements[columnId] = inputElement;
return;
}
@@ -1020,16 +909,16 @@ WebInspector.EditableSettingsList.prototype = {
var value = this._valuesProvider(itemId, columnId);
- var textElement = columnElement.createChild("span", "list-column-text");
+ var textElement = /** @type {!HTMLSpanElement} */ (columnElement.createChild("span", "list-column-text"));
textElement.textContent = value;
textElement.title = value;
columnElement.addEventListener("click", rowClicked.bind(this), false);
this._textElements[itemId][columnId] = textElement;
- var inputElement = columnElement.createChild("input", "list-column-editor");
+ var inputElement = /** @type {!HTMLInputElement} */ (columnElement.createChild("input", "list-column-editor"));
inputElement.value = value;
- inputElement.addEventListener("blur", this._editMappingBlur.bind(this, itemId));
- inputElement.addEventListener("input", this._validateEdit.bind(this, itemId));
+ inputElement.addEventListener("blur", this._editMappingBlur.bind(this, itemId), false);
+ inputElement.addEventListener("input", this._validateEdit.bind(this, itemId), false);
columnElement.inputElement = inputElement;
this._editInputElements[itemId][columnId] = inputElement;
@@ -1119,6 +1008,7 @@ WebInspector.EditableSettingsList.prototype = {
/**
* @param {string} itemId
+ * @param {?Event} event
*/
_editMappingBlur: function(itemId, event)
{
@@ -1169,3 +1059,5 @@ WebInspector.EditableSettingsList.prototype = {
__proto__: WebInspector.SettingsList.prototype
}
+
+WebInspector._settingsController = new WebInspector.SettingsController();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/settings/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/settings/module.json
new file mode 100644
index 00000000000..726a1487a09
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/settings/module.json
@@ -0,0 +1,23 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "settings.show",
+ "className": "WebInspector.SettingsController.SettingsScreenActionDelegate",
+ "bindings": [
+ {
+ "shortcut": "F1 Shift+?"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.StatusBarButton.Provider",
+ "actionId": "settings.show",
+ "location": "toolbar-right",
+ "title": "Settings",
+ "order": 0,
+ "elementClass": "settings-status-bar-item"
+ }
+ ],
+ "scripts": [ "SettingsScreen.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sidebarPane.css b/chromium/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
index 84d9aab00cc..85466d2ae66 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sidebarPane.css
@@ -29,14 +29,11 @@
.sidebar-pane {
position: relative;
- flex: auto;
}
.sidebar-pane > .body {
position: relative;
display: none;
- overflow-y: auto;
- overflow-x: hidden;
}
.sidebar-pane > .body .info {
@@ -47,6 +44,11 @@
color: #888;
}
+.sidebar-pane > .body .placard.dimmed {
+ opacity: 0.6;
+ font-style: italic;
+}
+
.sidebar-pane > .body .placard + .info {
border-top: 1px solid rgb(189, 189, 189);
background-color: rgb(255, 255, 194);
@@ -80,6 +82,7 @@
background-origin: padding;
background-clip: padding;
margin-top: -1px;
+ white-space: nowrap;
}
.sidebar-pane-title:active {
@@ -90,7 +93,7 @@
.sidebar-pane-title::before {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
float: left;
width: 11px;
@@ -104,7 +107,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar-pane-title::before {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -133,7 +136,7 @@
.sidebar-pane-toolbar > .pane-title-button,
.sidebar-pane-toolbar > label {
float: right;
- height: 17px;
+ height: 16px;
background-color: transparent;
border: none;
background-repeat: no-repeat;
@@ -169,12 +172,10 @@
background-image: url(Images/paneRefreshButtons.png);
}
-.sidebar-pane-toolbar > label > input {
- vertical-align: -2px;
-}
-
.sidebar-pane-toolbar > label.scripts-callstack-async {
+ margin: auto;
margin-right: 5px;
+ display: flex;
}
.sidebar-pane-subtitle {
@@ -186,7 +187,6 @@ body.platform-windows .sidebar-pane-subtitle {
padding-top: 1px;
}
-.sidebar-pane-subtitle input,
.section > .header input[type=checkbox] {
height: 1em;
width: 1em;
@@ -195,3 +195,11 @@ body.platform-windows .sidebar-pane-subtitle {
margin-bottom: 0.25em;
vertical-align: bottom;
}
+
+.hidden-placards-message {
+ text-align: center;
+ font-style: italic;
+ padding: 4px;
+ color: #888;
+ background-color: #FFFFC2;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js
index 1cec6fdb1b8..74c01b64bae 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CodeMirrorTextEditor.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorTextEditor.js
@@ -28,43 +28,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-importScript("cm/codemirror.js");
-importScript("cm/css.js");
-importScript("cm/javascript.js");
-importScript("cm/xml.js");
-importScript("cm/htmlmixed.js");
-
-importScript("cm/matchbrackets.js");
-importScript("cm/closebrackets.js");
-importScript("cm/markselection.js");
-importScript("cm/comment.js");
-importScript("cm/overlay.js");
-
-importScript("cm/htmlembedded.js");
-importScript("cm/clike.js");
-importScript("cm/coffeescript.js");
-importScript("cm/php.js");
-importScript("cm/python.js");
-importScript("cm/shell.js");
-importScript("CodeMirrorUtils.js");
-
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @implements {WebInspector.TextEditor}
* @param {?string} url
* @param {!WebInspector.TextEditorDelegate} delegate
*/
WebInspector.CodeMirrorTextEditor = function(url, delegate)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._delegate = delegate;
this._url = url;
this.registerRequiredCSS("cm/codemirror.css");
this.registerRequiredCSS("cm/cmdevtools.css");
- this._codeMirror = window.CodeMirror(this.element, {
+ this._codeMirror = new window.CodeMirror(this.element, {
lineNumbers: true,
gutters: ["CodeMirror-linenumbers"],
matchBrackets: true,
@@ -88,7 +68,8 @@ WebInspector.CodeMirrorTextEditor = function(url, delegate)
"Tab": "defaultTab",
"Shift-Tab": "indentLess",
"Enter": "smartNewlineAndIndent",
- "Ctrl-Space": "autocomplete"
+ "Ctrl-Space": "autocomplete",
+ "Esc": "dismissMultipleSelections"
};
CodeMirror.keyMap["devtools-pc"] = {
@@ -107,6 +88,8 @@ WebInspector.CodeMirrorTextEditor = function(url, delegate)
"Ctrl-Backspace": "delGroupBefore",
"Ctrl-Delete": "delGroupAfter",
"Ctrl-/": "toggleComment",
+ "Ctrl-D": "selectNextOccurrence",
+ "Ctrl-U": "undoLastSelection",
fallthrough: "devtools-common"
};
@@ -123,6 +106,8 @@ WebInspector.CodeMirrorTextEditor = function(url, delegate)
"Alt-Backspace": "delGroupBefore",
"Alt-Delete": "delGroupAfter",
"Cmd-/": "toggleComment",
+ "Cmd-D": "selectNextOccurrence",
+ "Cmd-U": "undoLastSelection",
fallthrough: "devtools-common"
};
@@ -142,21 +127,29 @@ WebInspector.CodeMirrorTextEditor = function(url, delegate)
this._shouldClearHistory = true;
this._lineSeparator = "\n";
- this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this._codeMirror);
+ this._autocompleteController = WebInspector.CodeMirrorTextEditor.AutocompleteController.Dummy;
+ this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighlighter(this, this._codeMirror);
this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockIndentController(this._codeMirror);
this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovement(this._codeMirror);
- this._autocompleteController = new WebInspector.CodeMirrorTextEditor.AutocompleteController(this, this._codeMirror);
+ this._selectNextOccurrenceController = new WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController(this, this._codeMirror);
- this._codeMirror.on("change", this._change.bind(this));
- this._codeMirror.on("beforeChange", this._beforeChange.bind(this));
+ this._codeMirror.on("changes", this._changes.bind(this));
this._codeMirror.on("gutterClick", this._gutterClick.bind(this));
this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this));
+ this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bind(this));
this._codeMirror.on("scroll", this._scroll.bind(this));
this._codeMirror.on("focus", this._focus.bind(this));
- this._codeMirror.on("blur", this._blur.bind(this));
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);
+ /**
+ * @this {WebInspector.CodeMirrorTextEditor}
+ */
+ function updateAnticipateJumpFlag(value)
+ {
+ this._isHandlingMouseDownEvent = value;
+ }
+ this.element.addEventListener("mousedown", updateAnticipateJumpFlag.bind(this, true), true);
+ this.element.addEventListener("mousedown", updateAnticipateJumpFlag.bind(this, false), false);
- this.element.classList.add("fill");
this.element.style.overflow = "hidden";
this.element.firstChild.classList.add("source-code");
this.element.firstChild.classList.add("fill");
@@ -165,27 +158,57 @@ WebInspector.CodeMirrorTextEditor = function(url, delegate)
this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), true);
+ this.element.addEventListener("keydown", this._handlePostKeyDown.bind(this), false);
this.element.tabIndex = 0;
- this._setupSelectionColor();
this._setupWhitespaceHighlight();
}
+/** @typedef {{canceled: boolean, from: !CodeMirror.Pos, to: !CodeMirror.Pos, text: string, origin: string, cancel: function()}} */
+WebInspector.CodeMirrorTextEditor.BeforeChangeObject;
+
+/** @typedef {{from: !CodeMirror.Pos, to: !CodeMirror.Pos, origin: string, text: !Array.<string>, removed: !Array.<string>}} */
+WebInspector.CodeMirrorTextEditor.ChangeObject;
+
WebInspector.CodeMirrorTextEditor.maxHighlightLength = 1000;
+/**
+ * @param {!CodeMirror} codeMirror
+ */
WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror)
{
codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();
}
CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocompleteCommand;
+/**
+ * @param {!CodeMirror} codeMirror
+ */
+WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand = function(codeMirror)
+{
+ codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.undoLastSelection();
+}
+CodeMirror.commands.undoLastSelection = WebInspector.CodeMirrorTextEditor.undoLastSelectionCommand;
+
+/**
+ * @param {!CodeMirror} codeMirror
+ */
+WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand = function(codeMirror)
+{
+ codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.selectNextOccurrence();
+}
+CodeMirror.commands.selectNextOccurrence = WebInspector.CodeMirrorTextEditor.selectNextOccurrenceCommand;
+
+/**
+ * @param {!CodeMirror} codeMirror
+ */
CodeMirror.commands.smartNewlineAndIndent = function(codeMirror)
{
- codeMirror.operation(innerSmartNewlineAndIndent.bind(this, codeMirror));
+ codeMirror.operation(innerSmartNewlineAndIndent.bind(null, codeMirror));
function countIndent(line)
{
- for(var i = 0; i < line.length; ++i) {
+ for (var i = 0; i < line.length; ++i) {
if (!WebInspector.TextUtils.isSpaceChar(line[i]))
return i;
}
@@ -211,6 +234,7 @@ CodeMirror.commands.undoAndReveal = function(codemirror)
codemirror.execCommand("undo");
var cursor = codemirror.getCursor("start");
codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
+ codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();
}
CodeMirror.commands.redoAndReveal = function(codemirror)
@@ -219,12 +243,42 @@ CodeMirror.commands.redoAndReveal = function(codemirror)
codemirror.execCommand("redo");
var cursor = codemirror.getCursor("start");
codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo);
+ codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete();
+}
+
+/**
+ * @return {!Object|undefined}
+ */
+CodeMirror.commands.dismissMultipleSelections = function(codemirror)
+{
+ var selections = codemirror.listSelections();
+ var selection = selections[0];
+ if (selections.length === 1) {
+ if (codemirror._codeMirrorTextEditor._isSearchActive())
+ return CodeMirror.Pass;
+ if (WebInspector.CodeMirrorUtils.toRange(selection.anchor, selection.head).isEmpty())
+ return CodeMirror.Pass;
+ codemirror.setSelection(selection.anchor, selection.anchor, {scroll: false});
+ codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);
+ return;
+ }
+
+ codemirror.setSelection(selection.anchor, selection.head, {scroll: false});
+ codemirror._codeMirrorTextEditor._revealLine(selection.anchor.line);
}
WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000;
WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16;
+WebInspector.CodeMirrorTextEditor.MaxEditableTextSize = 1024 * 1024 * 10;
WebInspector.CodeMirrorTextEditor.prototype = {
+ dispose: function()
+ {
+ WebInspector.settings.textEditorIndent.removeChangeListener(this._updateEditorIndentation, this);
+ WebInspector.settings.showWhitespacesInEditor.removeChangeListener(this._updateCodeMirrorMode, this);
+ WebInspector.settings.textEditorBracketMatching.removeChangeListener(this._enableBracketMatchingIfNeeded, this);
+ },
+
_enableBracketMatchingIfNeeded: function()
{
this._codeMirror.setOption("autoCloseBrackets", WebInspector.settings.textEditorBracketMatching.get() ? { explode: false } : false);
@@ -232,6 +286,9 @@ WebInspector.CodeMirrorTextEditor.prototype = {
wasShown: function()
{
+ if (this._wasOnceShown)
+ return;
+ this._wasOnceShown = true;
this._codeMirror.refresh();
},
@@ -256,7 +313,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
return;
indents[i] = 1 + (indents[i] || 0);
}
- this._codeMirror.eachLine(processLine);
+ this._codeMirror.eachLine(0, 1000, processLine);
var onePercentFilterThreshold = this.linesCount / 100;
if (tabLines && tabLines > onePercentFilterThreshold)
@@ -307,6 +364,14 @@ WebInspector.CodeMirrorTextEditor.prototype = {
},
/**
+ * @return {boolean}
+ */
+ _isSearchActive: function()
+ {
+ return !!this._tokenHighlighter.highlightedRegex();
+ },
+
+ /**
* @param {!RegExp} regex
* @param {?WebInspector.TextRange} range
*/
@@ -318,23 +383,29 @@ WebInspector.CodeMirrorTextEditor.prototype = {
function innerHighlightRegex()
{
if (range) {
- this.revealLine(range.startLine);
+ this._revealLine(range.startLine);
if (range.endColumn > WebInspector.CodeMirrorTextEditor.maxHighlightLength)
this.setSelection(range);
else
this.setSelection(WebInspector.TextRange.createFromLocation(range.startLine, range.startColumn));
} else {
- // Collapse selection to end on search start so that we jump to next occurence on the first enter press.
+ // Collapse selection to end on search start so that we jump to next occurrence on the first enter press.
this.setSelection(this.selection().collapseToEnd());
}
this._tokenHighlighter.highlightSearchResults(regex, range);
}
+ if (!this._selectionBeforeSearch)
+ this._selectionBeforeSearch = this.selection();
this._codeMirror.operation(innerHighlightRegex.bind(this));
},
cancelSearchResultsHighlight: function()
{
this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
+ if (this._selectionBeforeSearch) {
+ this._reportJump(this._selectionBeforeSearch, this.selection());
+ delete this._selectionBeforeSearch;
+ }
},
undo: function()
@@ -347,23 +418,6 @@ WebInspector.CodeMirrorTextEditor.prototype = {
this._codeMirror.redo();
},
- _setupSelectionColor: function()
- {
- if (WebInspector.CodeMirrorTextEditor._selectionStyleInjected)
- return;
- WebInspector.CodeMirrorTextEditor._selectionStyleInjected = true;
- var backgroundColor = WebInspector.getSelectionBackgroundColor();
- var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
- var foregroundColor = WebInspector.getSelectionForegroundColor();
- var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : "";
- if (!foregroundColorRule && !backgroundColorRule)
- return;
-
- var style = document.createElement("style");
- style.textContent = backgroundColorRule + foregroundColorRule;
- document.head.appendChild(style);
- },
-
_setupWhitespaceHighlight: function()
{
if (WebInspector.CodeMirrorTextEditor._whitespaceStyleInjected || !WebInspector.settings.showWhitespacesInEditor.get())
@@ -389,33 +443,10 @@ WebInspector.CodeMirrorTextEditor.prototype = {
e.consume(true);
},
- _shouldProcessWordForAutocompletion: function(word)
- {
- return word.length && (word[0] < '0' || word[0] > '9');
- },
-
- /**
- * @param {string} text
- */
- _addTextToCompletionDictionary: function(text)
+ _handlePostKeyDown: function(e)
{
- var words = WebInspector.TextUtils.textToWords(text);
- for(var i = 0; i < words.length; ++i) {
- if (this._shouldProcessWordForAutocompletion(words[i]))
- this._dictionary.addWord(words[i]);
- }
- },
-
- /**
- * @param {string} text
- */
- _removeTextFromCompletionDictionary: function(text)
- {
- var words = WebInspector.TextUtils.textToWords(text);
- for(var i = 0; i < words.length; ++i) {
- if (this._shouldProcessWordForAutocompletion(words[i]))
- this._dictionary.removeWord(words[i]);
- }
+ if (e.defaultPrevented)
+ e.consume(true);
},
/**
@@ -423,12 +454,11 @@ WebInspector.CodeMirrorTextEditor.prototype = {
*/
setCompletionDictionary: function(dictionary)
{
- if (!dictionary) {
- delete this._dictionary;
- return;
- }
- this._dictionary = dictionary;
- this._addTextToCompletionDictionary(this.text());
+ this._autocompleteController.dispose();
+ if (dictionary)
+ this._autocompleteController = new WebInspector.CodeMirrorTextEditor.AutocompleteController(this, this._codeMirror, dictionary);
+ else
+ this._autocompleteController = WebInspector.CodeMirrorTextEditor.AutocompleteController.Dummy;
},
/**
@@ -465,7 +495,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
y >= gutterBox.y && y <= gutterBox.y + gutterBox.height)
return null;
var coords = this._codeMirror.coordsChar({left: x, top: y});
- return this._toRange(coords, coords);
+ return WebInspector.CodeMirrorUtils.toRange(coords, coords);
},
/**
@@ -480,13 +510,10 @@ WebInspector.CodeMirrorTextEditor.prototype = {
var token = this._codeMirror.getTokenAt(new CodeMirror.Pos(lineNumber, (column || 0) + 1));
if (!token || !token.type)
return null;
- var convertedType = WebInspector.CodeMirrorUtils.convertTokenType(token.type);
- if (!convertedType)
- return null;
return {
startColumn: token.start,
endColumn: token.end - 1,
- type: convertedType
+ type: token.type
};
},
@@ -496,7 +523,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
*/
copyRange: function(textRange)
{
- var pos = this._toPos(textRange.normalize());
+ var pos = WebInspector.CodeMirrorUtils.toPos(textRange.normalize());
return this._codeMirror.getRange(pos.start, pos.end);
},
@@ -577,7 +604,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
_updateCodeMirrorMode: function()
{
var showWhitespaces = WebInspector.settings.showWhitespacesInEditor.get();
- this.element.enableStyleClass("show-whitespaces", showWhitespaces);
+ this.element.classList.toggle("show-whitespaces", showWhitespaces);
this._codeMirror.setOption("mode", showWhitespaces ? this._whitespaceOverlayMode(this._mimeType) : this._mimeType);
},
@@ -592,6 +619,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
else
this._disableLongLinesMode();
this._updateCodeMirrorMode();
+ this._autocompleteController.setMimeType(mimeType);
},
/**
@@ -599,7 +627,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
*/
setReadOnly: function(readOnly)
{
- this.element.enableStyleClass("CodeMirror-readonly", readOnly)
+ this.element.classList.toggle("CodeMirror-readonly", readOnly)
this._codeMirror.setOption("readOnly", readOnly);
},
@@ -627,7 +655,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
highlightRange: function(range, cssClass)
{
cssClass = "CodeMirror-persist-highlight " + cssClass;
- var pos = this._toPos(range);
+ var pos = WebInspector.CodeMirrorUtils.toPos(range);
++pos.end.ch;
return this._codeMirror.markText(pos.start, pos.end, {
className: cssClass,
@@ -668,7 +696,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
/**
* @param {number} lineNumber
*/
- revealLine: function(lineNumber)
+ _revealLine: function(lineNumber)
{
this._innerRevealLine(lineNumber, this._codeMirror.getScrollInfo());
},
@@ -731,7 +759,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
if (!wrapClasses)
return;
var classes = wrapClasses.split(" ");
- for(var i = 0; i < classes.length; ++i) {
+ for (var i = 0; i < classes.length; ++i) {
if (classes[i].startsWith("cm-breakpoint"))
this._codeMirror.removeLineClass(lineNumber, "wrap", classes[i]);
}
@@ -742,12 +770,16 @@ WebInspector.CodeMirrorTextEditor.prototype = {
*/
setExecutionLine: function(lineNumber)
{
+ this.clearPositionHighlight();
this._executionLine = this._codeMirror.getLineHandle(lineNumber);
+ if (!this._executionLine)
+ return;
this._codeMirror.addLineClass(this._executionLine, "wrap", "cm-execution-line");
},
clearExecutionLine: function()
{
+ this.clearPositionHighlight();
if (this._executionLine)
this._codeMirror.removeLineClass(this._executionLine, "wrap", "cm-execution-line");
delete this._executionLine;
@@ -777,24 +809,25 @@ WebInspector.CodeMirrorTextEditor.prototype = {
/**
* @param {number} lineNumber
* @param {number=} columnNumber
+ * @param {boolean=} shouldHighlight
*/
- highlightPosition: function(lineNumber, columnNumber)
+ revealPosition: function(lineNumber, columnNumber, shouldHighlight)
{
- if (lineNumber < 0)
- return;
- lineNumber = Math.min(lineNumber, this._codeMirror.lineCount() - 1);
- if (typeof columnNumber !== "number" || columnNumber < 0 || columnNumber > this._codeMirror.getLine(lineNumber).length)
+ lineNumber = Number.constrain(lineNumber, 0, this._codeMirror.lineCount() - 1);
+ if (typeof columnNumber !== "number")
columnNumber = 0;
+ columnNumber = Number.constrain(columnNumber, 0, this._codeMirror.getLine(lineNumber).length);
this.clearPositionHighlight();
this._highlightedLine = this._codeMirror.getLineHandle(lineNumber);
if (!this._highlightedLine)
return;
- this.revealLine(lineNumber);
- this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight");
- this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
- if (!this.readOnly())
- this._codeMirror.setSelection(new CodeMirror.Pos(lineNumber, columnNumber));
+ this._revealLine(lineNumber);
+ if (shouldHighlight) {
+ this._codeMirror.addLineClass(this._highlightedLine, null, "cm-highlight");
+ this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
+ }
+ this.setSelection(WebInspector.TextRange.createFromLocation(lineNumber, columnNumber));
},
clearPositionHighlight: function()
@@ -803,7 +836,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
clearTimeout(this._clearHighlightTimeout);
delete this._clearHighlightTimeout;
- if (this._highlightedLine)
+ if (this._highlightedLine)
this._codeMirror.removeLineClass(this._highlightedLine, null, "cm-highlight");
delete this._highlightedLine;
},
@@ -831,7 +864,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
{
var scrollInfo = this._codeMirror.getScrollInfo();
var newPaddingBottom;
- var linesElement = this.element.firstChild.querySelector(".CodeMirror-lines");
+ var linesElement = this.element.firstElementChild.querySelector(".CodeMirror-lines");
var lineCount = this._codeMirror.lineCount();
if (lineCount <= 1)
newPaddingBottom = 0;
@@ -847,16 +880,18 @@ WebInspector.CodeMirrorTextEditor.prototype = {
var parentElement = this.element.parentElement;
if (!parentElement || !this.isShowing())
return;
- var scrollInfo = this._codeMirror.getScrollInfo();
+ var scrollLeft = this._codeMirror.doc.scrollLeft;
+ var scrollTop = this._codeMirror.doc.scrollTop;
var width = parentElement.offsetWidth;
var height = parentElement.offsetHeight;
this._codeMirror.setSize(width, height);
this._updatePaddingBottom(width, height);
- this._codeMirror.scrollTo(scrollInfo.left, scrollInfo.top);
+ this._codeMirror.scrollTo(scrollLeft, scrollTop);
},
onResize: function()
{
+ this._autocompleteController.finishAutocomplete();
this._resizeEditor();
},
@@ -867,9 +902,9 @@ WebInspector.CodeMirrorTextEditor.prototype = {
*/
editRange: function(range, text)
{
- var pos = this._toPos(range);
+ var pos = WebInspector.CodeMirrorUtils.toPos(range);
this._codeMirror.replaceRange(text, pos.start, pos.end);
- var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
+ var newRange = WebInspector.CodeMirrorUtils.toRange(pos.start, this._codeMirror.posFromIndex(this._codeMirror.indexFromPos(pos.start) + text.length));
this._delegate.onTextChanged(range, newRange);
if (WebInspector.settings.textEditorAutoDetectIndent.get())
this._updateEditorIndentation();
@@ -879,40 +914,57 @@ WebInspector.CodeMirrorTextEditor.prototype = {
/**
* @param {number} lineNumber
* @param {number} column
- * @param {boolean=} prefixOnly
- * @return {?WebInspector.TextRange}
+ * @param {function(string):boolean} isWordChar
+ * @return {!WebInspector.TextRange}
*/
- _wordRangeForCursorPosition: function(lineNumber, column, prefixOnly)
+ _wordRangeForCursorPosition: function(lineNumber, column, isWordChar)
{
var line = this.line(lineNumber);
- if (column === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(column - 1)))
- return null;
- var wordStart = column - 1;
- while(wordStart > 0 && WebInspector.TextUtils.isWordChar(line.charAt(wordStart - 1)))
- --wordStart;
- if (prefixOnly)
- return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, column);
+ var wordStart = column;
+ if (column !== 0 && isWordChar(line.charAt(column - 1))) {
+ wordStart = column - 1;
+ while (wordStart > 0 && isWordChar(line.charAt(wordStart - 1)))
+ --wordStart;
+ }
var wordEnd = column;
- while(wordEnd < line.length && WebInspector.TextUtils.isWordChar(line.charAt(wordEnd)))
+ while (wordEnd < line.length && isWordChar(line.charAt(wordEnd)))
++wordEnd;
return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wordEnd);
},
- _beforeChange: function(codeMirror, changeObject)
- {
- if (!this._dictionary)
- return;
- this._updatedLines = this._updatedLines || {};
- for(var i = changeObject.from.line; i <= changeObject.to.line; ++i)
- this._updatedLines[i] = this.line(i);
+ /**
+ * @param {!WebInspector.CodeMirrorTextEditor.ChangeObject} changeObject
+ * @return {{oldRange: !WebInspector.TextRange, newRange: !WebInspector.TextRange}}
+ */
+ _changeObjectToEditOperation: function(changeObject)
+ {
+ var oldRange = WebInspector.CodeMirrorUtils.toRange(changeObject.from, changeObject.to);
+ var newRange = oldRange.clone();
+ var linesAdded = changeObject.text.length;
+ if (linesAdded === 0) {
+ newRange.endLine = newRange.startLine;
+ newRange.endColumn = newRange.startColumn;
+ } else if (linesAdded === 1) {
+ newRange.endLine = newRange.startLine;
+ newRange.endColumn = newRange.startColumn + changeObject.text[0].length;
+ } else {
+ newRange.endLine = newRange.startLine + linesAdded - 1;
+ newRange.endColumn = changeObject.text[linesAdded - 1].length;
+ }
+ return {
+ oldRange: oldRange,
+ newRange: newRange
+ };
},
/**
* @param {!CodeMirror} codeMirror
- * @param {!{origin: string, text: !Array.<string>, removed: !Array.<string>}} changeObject
+ * @param {!Array.<!WebInspector.CodeMirrorTextEditor.ChangeObject>} changes
*/
- _change: function(codeMirror, changeObject)
+ _changes: function(codeMirror, changes)
{
+ if (!changes.length)
+ return;
// We do not show "scroll beyond end of file" span for one line documents, so we need to check if "document has one line" changed.
var hasOneLine = this._codeMirror.lineCount() === 1;
if (hasOneLine !== this._hasOneLine)
@@ -923,59 +975,50 @@ WebInspector.CodeMirrorTextEditor.prototype = {
this._codeMirror.removeLineWidget(widgets[i]);
this._elementToWidget.clear();
- if (this._updatedLines) {
- for(var lineNumber in this._updatedLines)
- this._removeTextFromCompletionDictionary(this._updatedLines[lineNumber]);
- delete this._updatedLines;
- }
-
- var linesToUpdate = {};
- var singleCharInput = false;
- do {
- var oldRange = this._toRange(changeObject.from, changeObject.to);
- var newRange = oldRange.clone();
- var linesAdded = changeObject.text.length;
- singleCharInput = (changeObject.origin === "+input" && changeObject.text.length === 1 && changeObject.text[0].length === 1) ||
- (changeObject.origin === "+delete" && changeObject.removed.length === 1 && changeObject.removed[0].length === 1);
- if (linesAdded === 0) {
- newRange.endLine = newRange.startLine;
- newRange.endColumn = newRange.startColumn;
- } else if (linesAdded === 1) {
- newRange.endLine = newRange.startLine;
- newRange.endColumn = newRange.startColumn + changeObject.text[0].length;
- } else {
- newRange.endLine = newRange.startLine + linesAdded - 1;
- newRange.endColumn = changeObject.text[linesAdded - 1].length;
- }
+ for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
+ var changeObject = changes[changeIndex];
+ var editInfo = this._changeObjectToEditOperation(changeObject);
if (!this._muteTextChangedEvent)
- this._delegate.onTextChanged(oldRange, newRange);
-
- for(var i = newRange.startLine; i <= newRange.endLine; ++i) {
- linesToUpdate[i] = true;
- }
- if (this._dictionary) {
- for(var i = newRange.startLine; i <= newRange.endLine; ++i)
- linesToUpdate[i] = this.line(i);
- }
- } while (changeObject = changeObject.next);
- if (this._dictionary) {
- for(var lineNumber in linesToUpdate)
- this._addTextToCompletionDictionary(linesToUpdate[lineNumber]);
+ this._delegate.onTextChanged(editInfo.oldRange, editInfo.newRange);
}
- if (singleCharInput)
- this._autocompleteController.autocomplete();
},
_cursorActivity: function()
{
var start = this._codeMirror.getCursor("anchor");
var end = this._codeMirror.getCursor("head");
- this._delegate.selectionChanged(this._toRange(start, end));
- if (!this._tokenHighlighter.highlightedRegex())
+ this._delegate.selectionChanged(WebInspector.CodeMirrorUtils.toRange(start, end));
+ if (!this._isSearchActive())
this._codeMirror.operation(this._tokenHighlighter.highlightSelectedTokens.bind(this._tokenHighlighter));
},
+ /**
+ * @param {!CodeMirror} codeMirror
+ * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>}} selection
+ */
+ _beforeSelectionChange: function(codeMirror, selection)
+ {
+ this._selectNextOccurrenceController.selectionWillChange();
+ if (!this._isHandlingMouseDownEvent)
+ return;
+ if (!selection.ranges.length)
+ return;
+ var primarySelection = selection.ranges[0];
+ this._reportJump(this.selection(), WebInspector.CodeMirrorUtils.toRange(primarySelection.anchor, primarySelection.head));
+ },
+
+ /**
+ * @param {?WebInspector.TextRange} from
+ * @param {?WebInspector.TextRange} to
+ */
+ _reportJump: function(from, to)
+ {
+ if (from && to && from.equal(to))
+ return;
+ this._delegate.onJumpToPosition(from, to);
+ },
+
_scroll: function()
{
if (this._scrollTimer)
@@ -989,11 +1032,6 @@ WebInspector.CodeMirrorTextEditor.prototype = {
this._delegate.editorFocused();
},
- _blur: function()
- {
- this._autocompleteController.finishAutocomplete();
- },
-
/**
* @param {number} lineNumber
*/
@@ -1029,7 +1067,21 @@ WebInspector.CodeMirrorTextEditor.prototype = {
var start = this._codeMirror.getCursor("anchor");
var end = this._codeMirror.getCursor("head");
- return this._toRange(start, end);
+ return WebInspector.CodeMirrorUtils.toRange(start, end);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TextRange>}
+ */
+ selections: function()
+ {
+ var selectionList = this._codeMirror.listSelections();
+ var result = [];
+ for (var i = 0; i < selectionList.length; ++i) {
+ var selection = selectionList[i];
+ result.push(WebInspector.CodeMirrorUtils.toRange(selection.anchor, selection.head));
+ }
+ return result;
},
/**
@@ -1046,11 +1098,29 @@ WebInspector.CodeMirrorTextEditor.prototype = {
setSelection: function(textRange)
{
this._lastSelection = textRange;
- var pos = this._toPos(textRange);
+ var pos = WebInspector.CodeMirrorUtils.toPos(textRange);
this._codeMirror.setSelection(pos.start, pos.end);
},
/**
+ * @param {!Array.<!WebInspector.TextRange>} ranges
+ * @param {number=} primarySelectionIndex
+ */
+ setSelections: function(ranges, primarySelectionIndex)
+ {
+ var selections = [];
+ for (var i = 0; i < ranges.length; ++i) {
+ var selection = WebInspector.CodeMirrorUtils.toPos(ranges[i]);
+ selections.push({
+ anchor: selection.start,
+ head: selection.end
+ });
+ }
+ primarySelectionIndex = primarySelectionIndex || 0;
+ this._codeMirror.setSelections(selections, primarySelectionIndex, { scroll: false });
+ },
+
+ /**
* @param {string} text
*/
_detectLineSeparator: function(text)
@@ -1064,6 +1134,10 @@ WebInspector.CodeMirrorTextEditor.prototype = {
setText: function(text)
{
this._muteTextChangedEvent = true;
+ if (text.length > WebInspector.CodeMirrorTextEditor.MaxEditableTextSize) {
+ this._autocompleteController.setEnabled(false);
+ this.setReadOnly(true);
+ }
this._codeMirror.setValue(text);
this._updateEditorIndentation();
if (this._shouldClearHistory) {
@@ -1089,7 +1163,7 @@ WebInspector.CodeMirrorTextEditor.prototype = {
{
var lineCount = this.linesCount;
var lastLine = this._codeMirror.getLine(lineCount - 1);
- return this._toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
+ return WebInspector.CodeMirrorUtils.toRange(new CodeMirror.Pos(0, 0), new CodeMirror.Pos(lineCount - 1, lastLine.length));
},
/**
@@ -1150,31 +1224,64 @@ WebInspector.CodeMirrorTextEditor.prototype = {
},
/**
- * @param {!WebInspector.TextRange} range
- * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}}
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {!WebInspector.TextEditorPositionHandle}
*/
- _toPos: function(range)
+ textEditorPositionHandle: function(lineNumber, columnNumber)
{
- return {
- start: new CodeMirror.Pos(range.startLine, range.startColumn),
- end: new CodeMirror.Pos(range.endLine, range.endColumn)
- }
+ return new WebInspector.CodeMirrorPositionHandle(this._codeMirror, new CodeMirror.Pos(lineNumber, columnNumber));
},
- _toRange: function(start, end)
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.TextEditorPositionHandle}
+ * @param {!CodeMirror} codeMirror
+ * @param {!CodeMirror.Pos} pos
+ */
+WebInspector.CodeMirrorPositionHandle = function(codeMirror, pos)
+{
+ this._codeMirror = codeMirror;
+ this._lineHandle = codeMirror.getLineHandle(pos.line);
+ this._columnNumber = pos.ch;
+}
+
+WebInspector.CodeMirrorPositionHandle.prototype = {
+ /**
+ * @return {?{lineNumber: number, columnNumber: number}}
+ */
+ resolve: function()
{
- return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
+ var lineNumber = this._codeMirror.getLineNumber(this._lineHandle);
+ if (typeof lineNumber !== "number")
+ return null;
+ return {
+ lineNumber: lineNumber,
+ columnNumber: this._columnNumber
+ };
},
- __proto__: WebInspector.View.prototype
+ /**
+ * @param {!WebInspector.TextEditorPositionHandle} positionHandle
+ * @return {boolean}
+ */
+ equal: function(positionHandle)
+ {
+ return positionHandle._lineHandle === this._lineHandle && positionHandle._columnNumber == this._columnNumber && positionHandle._codeMirror === this._codeMirror;
+ }
}
/**
* @constructor
+ * @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {!CodeMirror} codeMirror
*/
-WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(codeMirror)
+WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(textEditor, codeMirror)
{
+ this._textEditor = textEditor;
this._codeMirror = codeMirror;
}
@@ -1206,11 +1313,14 @@ WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
this._setHighlighter(this._searchHighlighter.bind(this, this._highlightRegex), selectionStart);
}
if (this._highlightRange) {
- var pos = WebInspector.CodeMirrorTextEditor.prototype._toPos(this._highlightRange);
+ var pos = WebInspector.CodeMirrorUtils.toPos(this._highlightRange);
this._searchResultMarker = this._codeMirror.markText(pos.start, pos.end, {className: "cm-column-with-selection"});
}
},
+ /**
+ * @return {!RegExp|undefined}
+ */
highlightedRegex: function()
{
return this._highlightRegex;
@@ -1231,7 +1341,10 @@ WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
if (selectionStart.ch === selectionEnd.ch)
return;
- var selectedText = this._codeMirror.getSelection();
+ var selections = this._codeMirror.getSelections();
+ if (selections.length > 1)
+ return;
+ var selectedText = selections[0];
if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, selectionEnd.ch)) {
if (selectionStart)
this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-line-with-selection")
@@ -1270,7 +1383,7 @@ WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
if (stream.column() === 0)
delete this._searchMatchLength;
if (this._searchMatchLength) {
- if (this._searchMatchLength > 1) {
+ if (this._searchMatchLength > 2) {
for (var i = 0; i < this._searchMatchLength - 2; ++i)
stream.next();
this._searchMatchLength = 1;
@@ -1313,6 +1426,7 @@ WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
/**
* @param {function(!CodeMirror.StringStream)} highlighter
+ * @param {?CodeMirror.Pos} selectionStart
*/
_setHighlighter: function(highlighter, selectionStart)
{
@@ -1339,6 +1453,9 @@ WebInspector.CodeMirrorTextEditor.BlockIndentController = function(codeMirror)
WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = {
name: "blockIndentKeymap",
+ /**
+ * @return {*}
+ */
Enter: function(codeMirror)
{
if (codeMirror.somethingSelected())
@@ -1359,16 +1476,20 @@ WebInspector.CodeMirrorTextEditor.BlockIndentController.prototype = {
return CodeMirror.Pass;
},
+ /**
+ * @return {*}
+ */
"'}'": function(codeMirror)
{
var cursor = codeMirror.getCursor();
var line = codeMirror.getLine(cursor.line);
- for(var i = 0 ; i < line.length; ++i)
+ for (var i = 0 ; i < line.length; ++i) {
if (!WebInspector.TextUtils.isSpaceChar(line.charAt(i)))
return CodeMirror.Pass;
+ }
codeMirror.replaceRange("}", cursor);
- var matchingBracket = codeMirror.findMatchingBracket();
+ var matchingBracket = codeMirror.findMatchingBracket(cursor);
if (!matchingBracket || !matchingBracket.match)
return;
@@ -1389,77 +1510,326 @@ WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror)
{
function moveLeft(shift, codeMirror)
{
- var cursor = codeMirror.getCursor("head");
- if (cursor.ch !== 0 || cursor.line === 0)
- return CodeMirror.Pass;
codeMirror.setExtending(shift);
- codeMirror.execCommand("goLineUp");
- codeMirror.execCommand("goLineEnd")
+ var cursor = codeMirror.getCursor("head");
+ codeMirror.execCommand("goGroupLeft");
+ var newCursor = codeMirror.getCursor("head");
+ if (newCursor.ch === 0 && newCursor.line !== 0) {
+ codeMirror.setExtending(false);
+ return;
+ }
+
+ var skippedText = codeMirror.getRange(newCursor, cursor, "#");
+ if (/^\s+$/.test(skippedText))
+ codeMirror.execCommand("goGroupLeft");
codeMirror.setExtending(false);
}
+
function moveRight(shift, codeMirror)
{
- var cursor = codeMirror.getCursor("head");
- var line = codeMirror.getLine(cursor.line);
- if (cursor.ch !== line.length || cursor.line + 1 === codeMirror.lineCount())
- return CodeMirror.Pass;
codeMirror.setExtending(shift);
- codeMirror.execCommand("goLineDown");
- codeMirror.execCommand("goLineStart");
- codeMirror.setExtending(false);
- }
- function delWordBack(codeMirror)
- {
- if (codeMirror.somethingSelected())
- return CodeMirror.Pass;
var cursor = codeMirror.getCursor("head");
- if (cursor.ch === 0)
- codeMirror.execCommand("delCharBefore");
- else
- return CodeMirror.Pass;
+ codeMirror.execCommand("goGroupRight");
+ var newCursor = codeMirror.getCursor("head");
+ if (newCursor.ch === 0 && newCursor.line !== 0) {
+ codeMirror.setExtending(false);
+ return;
+ }
+
+ var skippedText = codeMirror.getRange(cursor, newCursor, "#");
+ if (/^\s+$/.test(skippedText))
+ codeMirror.execCommand("goGroupRight");
+ codeMirror.setExtending(false);
}
var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl";
var leftKey = modifierKey + "-Left";
var rightKey = modifierKey + "-Right";
var keyMap = {};
- keyMap[leftKey] = moveLeft.bind(this, false);
- keyMap[rightKey] = moveRight.bind(this, false);
- keyMap["Shift-" + leftKey] = moveLeft.bind(this, true);
- keyMap["Shift-" + rightKey] = moveRight.bind(this, true);
- keyMap[modifierKey + "-Backspace"] = delWordBack.bind(this);
+ keyMap[leftKey] = moveLeft.bind(null, false);
+ keyMap[rightKey] = moveRight.bind(null, false);
+ keyMap["Shift-" + leftKey] = moveLeft.bind(null, true);
+ keyMap["Shift-" + rightKey] = moveRight.bind(null, true);
codeMirror.addKeyMap(keyMap);
}
/**
+ * @interface
+ */
+WebInspector.CodeMirrorTextEditor.AutocompleteControllerAPI = function() {}
+
+WebInspector.CodeMirrorTextEditor.AutocompleteControllerAPI.prototype = {
+ dispose: function() { },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled) { },
+
+ /**
+ * @param {string} mimeType
+ */
+ setMimeType: function(mimeType) { },
+
+ autocomplete: function() { },
+
+ finishAutocomplete: function() { },
+
+ /**
+ * @param {?Event} e
+ * @return {boolean}
+ */
+ keyDown: function(e) { }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.CodeMirrorTextEditor.AutocompleteControllerAPI}
+ */
+WebInspector.CodeMirrorTextEditor.DummyAutocompleteController = function() { }
+
+WebInspector.CodeMirrorTextEditor.DummyAutocompleteController.prototype = {
+ dispose: function() { },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled) { },
+
+ /**
+ * @param {string} mimeType
+ */
+ setMimeType: function(mimeType) { },
+
+ autocomplete: function() { },
+
+ finishAutocomplete: function() { },
+
+ /**
+ * @param {?Event} e
+ * @return {boolean}
+ */
+ keyDown: function(e)
+ {
+ return false;
+ }
+}
+
+/**
* @constructor
* @implements {WebInspector.SuggestBoxDelegate}
+ * @implements {WebInspector.CodeMirrorTextEditor.AutocompleteControllerAPI}
* @param {!WebInspector.CodeMirrorTextEditor} textEditor
* @param {!CodeMirror} codeMirror
+ * @param {?WebInspector.CompletionDictionary} dictionary
*/
-WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor, codeMirror)
+WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor, codeMirror, dictionary)
{
this._textEditor = textEditor;
this._codeMirror = codeMirror;
- this._codeMirror.on("scroll", this._onScroll.bind(this));
- this._codeMirror.on("cursorActivity", this._onCursorActivity.bind(this));
+
+ this._onScroll = this._onScroll.bind(this);
+ this._onCursorActivity = this._onCursorActivity.bind(this);
+ this._changes = this._changes.bind(this);
+ this._beforeChange = this._beforeChange.bind(this);
+ this._blur = this._blur.bind(this);
+ this._codeMirror.on("scroll", this._onScroll);
+ this._codeMirror.on("cursorActivity", this._onCursorActivity);
+ this._codeMirror.on("changes", this._changes);
+ this._codeMirror.on("beforeChange", this._beforeChange);
+ this._codeMirror.on("blur", this._blur);
+
+ this._additionalWordChars = WebInspector.CodeMirrorTextEditor._NoAdditionalWordChars;
+ this._enabled = true;
+
+ this._dictionary = dictionary;
+ this._addTextToCompletionDictionary(this._textEditor.text());
}
+WebInspector.CodeMirrorTextEditor.AutocompleteController.Dummy = new WebInspector.CodeMirrorTextEditor.DummyAutocompleteController();
+WebInspector.CodeMirrorTextEditor._NoAdditionalWordChars = {};
+WebInspector.CodeMirrorTextEditor._CSSAdditionalWordChars = { ".": true, "-": true };
+
WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
+ dispose: function()
+ {
+ this._codeMirror.off("scroll", this._onScroll);
+ this._codeMirror.off("cursorActivity", this._onCursorActivity);
+ this._codeMirror.off("changes", this._changes);
+ this._codeMirror.off("beforeChange", this._beforeChange);
+ this._codeMirror.off("blur", this._blur);
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled)
+ {
+ if (enabled === this._enabled)
+ return;
+ this._enabled = enabled;
+ if (!enabled)
+ this._dictionary.reset();
+ else
+ this._addTextToCompletionDictionary(this._textEditor.text());
+ },
+
+ /**
+ * @param {string} mimeType
+ */
+ setMimeType: function(mimeType)
+ {
+ var additionalWordChars = mimeType.indexOf("css") !== -1 ? WebInspector.CodeMirrorTextEditor._CSSAdditionalWordChars : WebInspector.CodeMirrorTextEditor._NoAdditionalWordChars;
+ if (additionalWordChars !== this._additionalWordChars) {
+ this._additionalWordChars = additionalWordChars;
+ this._dictionary.reset();
+ this._addTextToCompletionDictionary(this._textEditor.text());
+ }
+ },
+
+ /**
+ * @param {string} char
+ * @return {boolean}
+ */
+ _isWordChar: function(char)
+ {
+ return WebInspector.TextUtils.isWordChar(char) || !!this._additionalWordChars[char];
+ },
+
+ /**
+ * @param {string} word
+ * @return {boolean}
+ */
+ _shouldProcessWordForAutocompletion: function(word)
+ {
+ return !!word.length && (word[0] < '0' || word[0] > '9');
+ },
+
+ /**
+ * @param {string} text
+ */
+ _addTextToCompletionDictionary: function(text)
+ {
+ if (!this._enabled)
+ return;
+ var words = WebInspector.TextUtils.textToWords(text, this._isWordChar.bind(this));
+ for (var i = 0; i < words.length; ++i) {
+ if (this._shouldProcessWordForAutocompletion(words[i]))
+ this._dictionary.addWord(words[i]);
+ }
+ },
+
+ /**
+ * @param {string} text
+ */
+ _removeTextFromCompletionDictionary: function(text)
+ {
+ if (!this._enabled)
+ return;
+ var words = WebInspector.TextUtils.textToWords(text, this._isWordChar.bind(this));
+ for (var i = 0; i < words.length; ++i) {
+ if (this._shouldProcessWordForAutocompletion(words[i]))
+ this._dictionary.removeWord(words[i]);
+ }
+ },
+
+ /**
+ * @param {!CodeMirror} codeMirror
+ * @param {!WebInspector.CodeMirrorTextEditor.BeforeChangeObject} changeObject
+ */
+ _beforeChange: function(codeMirror, changeObject)
+ {
+ if (!this._enabled)
+ return;
+ this._updatedLines = this._updatedLines || {};
+ for (var i = changeObject.from.line; i <= changeObject.to.line; ++i)
+ this._updatedLines[i] = this._textEditor.line(i);
+ },
+
+ /**
+ * @param {!CodeMirror} codeMirror
+ * @param {!Array.<!WebInspector.CodeMirrorTextEditor.ChangeObject>} changes
+ */
+ _changes: function(codeMirror, changes)
+ {
+ if (!changes.length || !this._enabled)
+ return;
+
+ if (this._updatedLines) {
+ for (var lineNumber in this._updatedLines)
+ this._removeTextFromCompletionDictionary(this._updatedLines[lineNumber]);
+ delete this._updatedLines;
+ }
+
+ var linesToUpdate = {};
+ var singleCharInput = false;
+ for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) {
+ var changeObject = changes[changeIndex];
+ singleCharInput = (changeObject.origin === "+input" && changeObject.text.length === 1 && changeObject.text[0].length === 1) ||
+ (changeObject.origin === "+delete" && changeObject.removed.length === 1 && changeObject.removed[0].length === 1);
+
+ var editInfo = this._textEditor._changeObjectToEditOperation(changeObject);
+ for (var i = editInfo.newRange.startLine; i <= editInfo.newRange.endLine; ++i)
+ linesToUpdate[i] = this._textEditor.line(i);
+ }
+ for (var lineNumber in linesToUpdate)
+ this._addTextToCompletionDictionary(linesToUpdate[lineNumber]);
+
+ if (singleCharInput)
+ this.autocomplete();
+ },
+
+ _blur: function()
+ {
+ this.finishAutocomplete();
+ },
+
+ /**
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {!WebInspector.TextRange}
+ */
+ _autocompleteWordRange: function(lineNumber, columnNumber)
+ {
+ return this._textEditor._wordRangeForCursorPosition(lineNumber, columnNumber, this._isWordChar.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.TextRange} mainSelection
+ * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selections
+ * @return {boolean}
+ */
+ _validateSelectionsContexts: function(mainSelection, selections)
+ {
+ var mainSelectionContext = this._textEditor.copyRange(mainSelection);
+ for (var i = 0; i < selections.length; ++i) {
+ var wordRange = this._autocompleteWordRange(selections[i].head.line, selections[i].head.ch);
+ if (!wordRange)
+ return false;
+ var context = this._textEditor.copyRange(wordRange);
+ if (context !== mainSelectionContext)
+ return false;
+ }
+ return true;
+ },
+
autocomplete: function()
{
- var dictionary = this._textEditor._dictionary;
- if (!dictionary || this._codeMirror.somethingSelected()) {
+ var dictionary = this._dictionary;
+ if (this._codeMirror.somethingSelected()) {
this.finishAutocomplete();
return;
}
- var cursor = this._codeMirror.getCursor();
- var substituteRange = this._textEditor._wordRangeForCursorPosition(cursor.line, cursor.ch, false);
- if (!substituteRange || substituteRange.startColumn === cursor.ch) {
+ var selections = this._codeMirror.listSelections().slice();
+ var topSelection = selections.shift();
+ var cursor = topSelection.head;
+ var substituteRange = this._autocompleteWordRange(cursor.line, cursor.ch);
+ if (!substituteRange || substituteRange.startColumn === cursor.ch || !this._validateSelectionsContexts(substituteRange, selections)) {
this.finishAutocomplete();
return;
}
+
var prefixRange = substituteRange.clone();
prefixRange.endColumn = cursor.ch;
@@ -1478,12 +1848,13 @@ WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
wordsWithPrefix.sort(sortSuggestions);
- if (!this._suggestBox) {
- this._suggestBox = new WebInspector.SuggestBox(this, this._textEditor.element, "generic-suggest", 6);
- this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch);
- }
- this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix, 0, true, this._textEditor.copyRange(prefixRange));
+ if (!this._suggestBox)
+ this._suggestBox = new WebInspector.SuggestBox(this, 6);
+ var oldPrefixRange = this._prefixRange;
this._prefixRange = prefixRange;
+ if (!oldPrefixRange || prefixRange.startLine !== oldPrefixRange.startLine || prefixRange.startColumn !== oldPrefixRange.startColumn)
+ this._updateAnchorBox();
+ this._suggestBox.updateSuggestions(this._anchorBox, wordsWithPrefix, 0, true, this._textEditor.copyRange(prefixRange));
if (!this._suggestBox.visible())
this.finishAutocomplete();
},
@@ -1500,6 +1871,7 @@ WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
/**
* @param {?Event} e
+ * @return {boolean}
*/
keyDown: function(e)
{
@@ -1528,9 +1900,15 @@ WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
acceptSuggestion: function()
{
- if (this._prefixRange.endColumn - this._prefixRange.startColumn !== this._currentSuggestion.length) {
- var pos = this._textEditor._toPos(this._prefixRange);
- this._codeMirror.replaceRange(this._currentSuggestion, pos.start, pos.end, "+autocomplete");
+ if (this._prefixRange.endColumn - this._prefixRange.startColumn === this._currentSuggestion.length)
+ return;
+
+ var selections = this._codeMirror.listSelections().slice();
+ var prefixLength = this._prefixRange.endColumn - this._prefixRange.startColumn;
+ for (var i = selections.length - 1; i >= 0; --i) {
+ var start = selections[i].head;
+ var end = new CodeMirror.Pos(start.line, start.ch - prefixLength);
+ this._codeMirror.replaceRange(this._currentSuggestion, start, end, "+autocomplete");
}
},
@@ -1545,7 +1923,7 @@ WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
if (cursor.line < topmostLineNumber || cursor.line > bottomLine)
this.finishAutocomplete();
else {
- this._anchorBox = this._anchorBoxForPosition(cursor.line, cursor.ch);
+ this._updateAnchorBox();
this._suggestBox.setPosition(this._anchorBox);
}
},
@@ -1555,18 +1933,204 @@ WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
if (!this._suggestBox)
return;
var cursor = this._codeMirror.getCursor();
- if (cursor.line !== this._prefixRange.startLine || cursor.ch > this._prefixRange.endColumn || cursor.ch < this._prefixRange.startColumn)
+ if (cursor.line !== this._prefixRange.startLine || cursor.ch > this._prefixRange.endColumn || cursor.ch <= this._prefixRange.startColumn)
this.finishAutocomplete();
},
+ _updateAnchorBox: function()
+ {
+ var line = this._prefixRange.startLine;
+ var column = this._prefixRange.startColumn;
+ var metrics = this._textEditor.cursorPositionToCoordinates(line, column);
+ this._anchorBox = metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
+ },
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.CodeMirrorTextEditor} textEditor
+ * @param {!CodeMirror} codeMirror
+ */
+WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController = function(textEditor, codeMirror)
+{
+ this._textEditor = textEditor;
+ this._codeMirror = codeMirror;
+}
+
+WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController.prototype = {
+ selectionWillChange: function()
+ {
+ if (!this._muteSelectionListener)
+ delete this._fullWordSelection;
+ },
+
/**
- * @param {number} line
- * @param {number} column
- * @return {?AnchorBox}
+ * @param {!Array.<!WebInspector.TextRange>} selections
+ * @param {!WebInspector.TextRange} range
+ * @return {boolean}
*/
- _anchorBoxForPosition: function(line, column)
+ _findRange: function(selections, range)
{
- var metrics = this._textEditor.cursorPositionToCoordinates(line, column);
- return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
+ for (var i = 0; i < selections.length; ++i) {
+ if (range.equal(selections[i]))
+ return true;
+ }
+ return false;
+ },
+
+ undoLastSelection: function()
+ {
+ this._muteSelectionListener = true;
+ this._codeMirror.execCommand("undoSelection");
+ this._muteSelectionListener = false;
},
+
+ selectNextOccurrence: function()
+ {
+ var selections = this._textEditor.selections();
+ var anyEmptySelection = false;
+ for (var i = 0; i < selections.length; ++i) {
+ var selection = selections[i];
+ anyEmptySelection = anyEmptySelection || selection.isEmpty();
+ if (selection.startLine !== selection.endLine)
+ return;
+ }
+ if (anyEmptySelection) {
+ this._expandSelectionsToWords(selections);
+ return;
+ }
+
+ var last = selections[selections.length - 1];
+ var next = last;
+ do {
+ next = this._findNextOccurrence(next, !!this._fullWordSelection);
+ } while (next && this._findRange(selections, next) && !next.equal(last));
+
+ if (!next)
+ return;
+ selections.push(next);
+
+ this._muteSelectionListener = true;
+ this._textEditor.setSelections(selections, selections.length - 1);
+ delete this._muteSelectionListener;
+
+ this._textEditor._revealLine(next.startLine);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.TextRange>} selections
+ */
+ _expandSelectionsToWords: function(selections)
+ {
+ var newSelections = [];
+ for (var i = 0; i < selections.length; ++i) {
+ var selection = selections[i];
+ var startRangeWord = this._textEditor._wordRangeForCursorPosition(selection.startLine, selection.startColumn, WebInspector.TextUtils.isWordChar)
+ || WebInspector.TextRange.createFromLocation(selection.startLine, selection.startColumn);
+ var endRangeWord = this._textEditor._wordRangeForCursorPosition(selection.endLine, selection.endColumn, WebInspector.TextUtils.isWordChar)
+ || WebInspector.TextRange.createFromLocation(selection.endLine, selection.endColumn);
+ var newSelection = new WebInspector.TextRange(startRangeWord.startLine, startRangeWord.startColumn, endRangeWord.endLine, endRangeWord.endColumn);
+ newSelections.push(newSelection);
+ }
+ this._textEditor.setSelections(newSelections, newSelections.length - 1);
+ this._fullWordSelection = true;
+ },
+
+ /**
+ * @param {!WebInspector.TextRange} range
+ * @param {boolean} fullWord
+ * @return {?WebInspector.TextRange}
+ */
+ _findNextOccurrence: function(range, fullWord)
+ {
+ range = range.normalize();
+ var matchedLineNumber;
+ var matchedColumnNumber;
+ var textToFind = this._textEditor.copyRange(range);
+ function findWordInLine(wordRegex, lineNumber, lineText, from, to)
+ {
+ if (typeof matchedLineNumber === "number")
+ return true;
+ wordRegex.lastIndex = from;
+ var result = wordRegex.exec(lineText);
+ if (!result || result.index + textToFind.length > to)
+ return false;
+ matchedLineNumber = lineNumber;
+ matchedColumnNumber = result.index;
+ return true;
+ }
+
+ var iteratedLineNumber;
+ function lineIterator(regex, lineHandle)
+ {
+ if (findWordInLine(regex, iteratedLineNumber++, lineHandle.text, 0, lineHandle.text.length))
+ return true;
+ }
+
+ var regexSource = textToFind.escapeForRegExp();
+ if (fullWord)
+ regexSource = "\\b" + regexSource + "\\b";
+ var wordRegex = new RegExp(regexSource, "gi");
+ var currentLineText = this._codeMirror.getLine(range.startLine);
+
+ findWordInLine(wordRegex, range.startLine, currentLineText, range.endColumn, currentLineText.length);
+ iteratedLineNumber = range.startLine + 1;
+ this._codeMirror.eachLine(range.startLine + 1, this._codeMirror.lineCount(), lineIterator.bind(null, wordRegex));
+ iteratedLineNumber = 0;
+ this._codeMirror.eachLine(0, range.startLine, lineIterator.bind(null, wordRegex));
+ findWordInLine(wordRegex, range.startLine, currentLineText, 0, range.startColumn);
+
+ if (typeof matchedLineNumber !== "number")
+ return null;
+ return new WebInspector.TextRange(matchedLineNumber, matchedColumnNumber, matchedLineNumber, matchedColumnNumber + textToFind.length);
+ }
}
+
+/**
+ * @param {string} modeName
+ * @param {string} tokenPrefix
+ */
+WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(modeName, tokenPrefix)
+{
+ var oldModeName = modeName + "-old";
+ if (CodeMirror.modes[oldModeName])
+ return;
+
+ CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]);
+ CodeMirror.defineMode(modeName, modeConstructor);
+
+ function modeConstructor(config, parserConfig)
+ {
+ var innerConfig = {};
+ for (var i in parserConfig)
+ innerConfig[i] = parserConfig[i];
+ innerConfig.name = oldModeName;
+ var codeMirrorMode = CodeMirror.getMode(config, innerConfig);
+ codeMirrorMode.name = modeName;
+ codeMirrorMode.token = tokenOverride.bind(null, codeMirrorMode.token);
+ return codeMirrorMode;
+ }
+
+ function tokenOverride(superToken, stream, state)
+ {
+ var token = superToken(stream, state);
+ return token ? tokenPrefix + token : token;
+ }
+}
+
+WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("css", "css-");
+WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("javascript", "js-");
+WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens("xml", "xml-");
+
+(function() {
+ var backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor();
+ var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selected { background-color: " + backgroundColor + ";}" : "";
+ var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor();
+ var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!important;}" : "";
+ if (!foregroundColorRule && !backgroundColorRule)
+ return;
+
+ var style = document.createElement("style");
+ style.textContent = backgroundColorRule + foregroundColorRule;
+ document.head.appendChild(style);
+})();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorUtils.js
new file mode 100644
index 00000000000..01856a1f903
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/CodeMirrorUtils.js
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.InplaceEditor}
+ */
+WebInspector.CodeMirrorUtils = function()
+{
+ WebInspector.InplaceEditor.call(this);
+}
+
+/**
+ * @param {!WebInspector.TextRange} range
+ * @return {!{start: !CodeMirror.Pos, end: !CodeMirror.Pos}}
+ */
+WebInspector.CodeMirrorUtils.toPos = function(range)
+{
+ return {
+ start: new CodeMirror.Pos(range.startLine, range.startColumn),
+ end: new CodeMirror.Pos(range.endLine, range.endColumn)
+ }
+}
+
+/**
+ * @param {!CodeMirror.Pos} start
+ * @param {!CodeMirror.Pos} end
+ * @return {!WebInspector.TextRange}
+ */
+WebInspector.CodeMirrorUtils.toRange = function(start, end)
+{
+ return new WebInspector.TextRange(start.line, start.ch, end.line, end.ch);
+}
+
+WebInspector.CodeMirrorUtils.prototype = {
+ /**
+ * @return {string}
+ */
+ editorContent: function(editingContext) {
+ return editingContext.codeMirror.getValue();
+ },
+
+ /**
+ * @param {?Event} e
+ */
+ _consumeCopy: function(e)
+ {
+ e.consume();
+ },
+
+ setUpEditor: function(editingContext)
+ {
+ var element = editingContext.element;
+ var config = editingContext.config;
+ editingContext.cssLoadView = new WebInspector.CodeMirrorCSSLoadView();
+ editingContext.cssLoadView.show(element);
+ WebInspector.setCurrentFocusElement(element);
+ element.addEventListener("copy", this._consumeCopy, false);
+ var codeMirror = new window.CodeMirror(element, {
+ mode: config.mode,
+ lineWrapping: config.lineWrapping,
+ smartIndent: config.smartIndent,
+ autofocus: true,
+ theme: config.theme,
+ value: config.initialValue
+ });
+ codeMirror.getWrapperElement().classList.add("source-code");
+ codeMirror.on("cursorActivity", function(cm) {
+ cm.display.cursorDiv.scrollIntoViewIfNeeded(false);
+ });
+ editingContext.codeMirror = codeMirror;
+ },
+
+ closeEditor: function(editingContext)
+ {
+ editingContext.element.removeEventListener("copy", this._consumeCopy, false);
+ editingContext.cssLoadView.detach();
+ },
+
+ cancelEditing: function(editingContext)
+ {
+ editingContext.codeMirror.setValue(editingContext.oldText);
+ },
+
+ augmentEditingHandle: function(editingContext, handle)
+ {
+ function setWidth(editingContext, width)
+ {
+ var padding = 30;
+ var codeMirror = editingContext.codeMirror;
+ codeMirror.getWrapperElement().style.width = (width - codeMirror.getWrapperElement().offsetLeft - padding) + "px";
+ codeMirror.refresh();
+ }
+
+ handle.codeMirror = editingContext.codeMirror;
+ handle.setWidth = setWidth.bind(null, editingContext);
+ },
+
+ __proto__: WebInspector.InplaceEditor.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.TokenizerFactory}
+ */
+WebInspector.CodeMirrorUtils.TokenizerFactory = function() { }
+
+WebInspector.CodeMirrorUtils.TokenizerFactory.prototype = {
+ /**
+ * @param {string} mimeType
+ * @return {function(string, function(string, ?string, number, number))}
+ */
+ createTokenizer: function(mimeType)
+ {
+ var mode = CodeMirror.getMode({indentUnit: 2}, mimeType);
+ var state = CodeMirror.startState(mode);
+ function tokenize(line, callback)
+ {
+ var stream = new CodeMirror.StringStream(line);
+ while (!stream.eol()) {
+ var style = mode.token(stream, state);
+ var value = stream.current();
+ callback(value, style, stream.start, stream.start + value.length);
+ stream.start = stream.pos;
+ }
+ }
+ return tokenize;
+ }
+}
+
+/**
+ * This bogus view is needed to load/unload CodeMirror-related CSS on demand.
+ *
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.CodeMirrorCSSLoadView = function()
+{
+ WebInspector.VBox.call(this);
+ this.element.classList.add("hidden");
+ this.registerRequiredCSS("cm/codemirror.css");
+ this.registerRequiredCSS("cm/cmdevtools.css");
+}
+
+WebInspector.CodeMirrorCSSLoadView.prototype = {
+ __proto__: WebInspector.VBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FontView.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/FontView.js
index 4c36314a555..ec4e5d12d74 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FontView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/FontView.js
@@ -44,6 +44,9 @@ WebInspector.FontView._fontId = 0;
WebInspector.FontView._measureFontSize = 50;
WebInspector.FontView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/GoToLineDialog.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/GoToLineDialog.js
index a95fec76ccc..7e7414c0b7b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/GoToLineDialog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/GoToLineDialog.js
@@ -31,11 +31,12 @@
/**
* @constructor
* @extends {WebInspector.DialogDelegate}
+ * @param {!WebInspector.SourceFrame} sourceFrame
*/
-WebInspector.GoToLineDialog = function(view)
+WebInspector.GoToLineDialog = function(sourceFrame)
{
WebInspector.DialogDelegate.call(this);
-
+
this.element = document.createElement("div");
this.element.className = "go-to-line-dialog";
@@ -49,30 +50,30 @@ WebInspector.GoToLineDialog = function(view)
this._goButton.textContent = WebInspector.UIString("Go");
this._goButton.addEventListener("click", this._onGoClick.bind(this), false);
- this._view = view;
+ this._sourceFrame = sourceFrame;
}
/**
* @param {!WebInspector.Panel} panel
- * @param {function():?WebInspector.View} viewGetter
+ * @param {function():?WebInspector.SourceFrame} sourceFrameGetter
*/
-WebInspector.GoToLineDialog.install = function(panel, viewGetter)
+WebInspector.GoToLineDialog.install = function(panel, sourceFrameGetter)
{
var goToLineShortcut = WebInspector.GoToLineDialog.createShortcut();
- panel.registerShortcuts([goToLineShortcut], WebInspector.GoToLineDialog._show.bind(null, viewGetter));
+ panel.registerShortcuts([goToLineShortcut], WebInspector.GoToLineDialog._show.bind(null, sourceFrameGetter));
}
/**
- * @param {function():?WebInspector.View} viewGetter
+ * @param {function():?WebInspector.SourceFrame} sourceFrameGetter
* @param {?Event=} event
* @return {boolean}
*/
-WebInspector.GoToLineDialog._show = function(viewGetter, event)
+WebInspector.GoToLineDialog._show = function(sourceFrameGetter, event)
{
- var sourceView = viewGetter();
- if (!sourceView || !sourceView.canHighlightPosition())
+ var sourceFrame = sourceFrameGetter();
+ if (!sourceFrame)
return false;
- WebInspector.Dialog.show(sourceView.element, new WebInspector.GoToLineDialog(sourceView));
+ WebInspector.Dialog.show(sourceFrame.element, new WebInspector.GoToLineDialog(sourceFrame));
return true;
}
@@ -81,8 +82,6 @@ WebInspector.GoToLineDialog._show = function(viewGetter, event)
*/
WebInspector.GoToLineDialog.createShortcut = function()
{
- var isMac = WebInspector.isMac();
- var shortcut;
return WebInspector.KeyboardShortcut.makeDescriptor("g", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
}
@@ -92,21 +91,21 @@ WebInspector.GoToLineDialog.prototype = {
WebInspector.setCurrentFocusElement(this._input);
this._input.select();
},
-
+
_onGoClick: function()
{
this._applyLineNumber();
WebInspector.Dialog.hide();
},
-
+
_applyLineNumber: function()
{
var value = this._input.value;
var lineNumber = parseInt(value, 10) - 1;
if (!isNaN(lineNumber) && lineNumber >= 0)
- this._view.highlightPosition(lineNumber);
+ this._sourceFrame.revealPosition(lineNumber, 0, true);
},
-
+
onEnter: function()
{
this._applyLineNumber();
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ImageView.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ImageView.js
index 7bfaa7473af..71199a0ac0e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ImageView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ImageView.js
@@ -38,6 +38,9 @@ WebInspector.ImageView = function(resource)
}
WebInspector.ImageView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceView.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ResourceView.js
index 0a7b28f9625..99beeec2a95 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ResourceView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/ResourceView.js
@@ -28,12 +28,12 @@
*/
/**
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @constructor
*/
WebInspector.ResourceView = function(resource)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("resourceView.css");
this.element.classList.add("resource-view");
@@ -41,28 +41,33 @@ WebInspector.ResourceView = function(resource)
}
WebInspector.ResourceView.prototype = {
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return false;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
* @param {!WebInspector.Resource} resource
+ * @return {boolean}
*/
WebInspector.ResourceView.hasTextContent = function(resource)
{
if (resource.type.isTextType())
- return true;
+ return true;
if (resource.type === WebInspector.resourceTypes.Other)
- return resource.content && !resource.contentEncoded;
+ return !!resource.content && !resource.contentEncoded;
return false;
}
/**
* @param {!WebInspector.Resource} resource
+ * @return {!WebInspector.ResourceView}
*/
WebInspector.ResourceView.nonSourceViewForResource = function(resource)
{
@@ -103,14 +108,13 @@ WebInspector.ResourceSourceFrame.prototype = {
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.Resource} resource
*/
WebInspector.ResourceSourceFrameFallback = function(resource)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._resource = resource;
- this.element.classList.add("fill");
this.element.classList.add("script-view");
this._content = this.element.createChild("div", "script-view-fallback monospace");
}
@@ -132,5 +136,5 @@ WebInspector.ResourceSourceFrameFallback.prototype = {
this._content.textContent = content;
},
- __proto__: WebInspector.View.prototype
-} \ No newline at end of file
+ __proto__: WebInspector.VBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SourceFrame.js b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/SourceFrame.js
index b0dd8e3c6c5..1fb01d8c55a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SourceFrame.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/SourceFrame.js
@@ -28,23 +28,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+importScript("../cm/codemirror.js");
+importScript("../cm/css.js");
+importScript("../cm/javascript.js");
+importScript("../cm/xml.js");
+importScript("../cm/htmlmixed.js");
+
+importScript("../cm/matchbrackets.js");
+importScript("../cm/closebrackets.js");
+importScript("../cm/markselection.js");
+importScript("../cm/comment.js");
+importScript("../cm/overlay.js");
+
+importScript("../cm/htmlembedded.js");
+importScript("../cm/clike.js");
+importScript("../cm/coffeescript.js");
+importScript("../cm/php.js");
+importScript("../cm/python.js");
+importScript("../cm/shell.js");
+importScript("CodeMirrorUtils.js");
+importScript("CodeMirrorTextEditor.js");
+
/**
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @constructor
+ * @implements {WebInspector.Replaceable}
* @param {!WebInspector.ContentProvider} contentProvider
*/
WebInspector.SourceFrame = function(contentProvider)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.element.classList.add("script-view");
- this.element.classList.add("fill");
this._url = contentProvider.contentURL();
this._contentProvider = contentProvider;
var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);
- loadScript("CodeMirrorTextEditor.js");
this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
this._currentSearchResultIndex = -1;
@@ -57,7 +77,6 @@ WebInspector.SourceFrame = function(contentProvider)
this._textEditor.setReadOnly(!this.canEditSource());
this._shortcuts = {};
- this.addShortcut(WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta), this._commitEditing.bind(this));
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this._sourcePosition = new WebInspector.StatusBarText("", "source-frame-cursor-position");
@@ -92,7 +111,8 @@ WebInspector.SourceFrame.createSearchRegex = function(query, modifiers)
WebInspector.SourceFrame.Events = {
ScrollChanged: "ScrollChanged",
- SelectionChanged: "SelectionChanged"
+ SelectionChanged: "SelectionChanged",
+ JumpHappened: "JumpHappened"
}
WebInspector.SourceFrame.prototype = {
@@ -125,8 +145,7 @@ WebInspector.SourceFrame.prototype = {
{
WebInspector.View.prototype.willHide.call(this);
- this._clearPositionHighlight();
- this._clearLineToReveal();
+ this._clearPositionToReveal();
},
/**
@@ -145,6 +164,9 @@ WebInspector.SourceFrame.prototype = {
return [];
},
+ /**
+ * @return {!Element}
+ */
defaultFocusedElement: function()
{
return this._textEditor.defaultFocusedElement();
@@ -155,6 +177,9 @@ WebInspector.SourceFrame.prototype = {
return this._loaded;
},
+ /**
+ * @return {boolean}
+ */
hasContent: function()
{
return true;
@@ -194,68 +219,34 @@ WebInspector.SourceFrame.prototype = {
},
/**
- * @override
- */
- canHighlightPosition: function()
- {
- return true;
- },
-
- /**
- * @override
+ * @param {number} line
+ * @param {number=} column
+ * @param {boolean=} shouldHighlight
*/
- highlightPosition: function(line, column)
+ revealPosition: function(line, column, shouldHighlight)
{
- this._clearLineToReveal();
this._clearLineToScrollTo();
this._clearSelectionToSet();
- this._positionToHighlight = { line: line, column: column };
- this._innerHighlightPositionIfNeeded();
+ this._positionToReveal = { line: line, column: column, shouldHighlight: shouldHighlight };
+ this._innerRevealPositionIfNeeded();
},
- _innerHighlightPositionIfNeeded: function()
+ _innerRevealPositionIfNeeded: function()
{
- if (!this._positionToHighlight)
+ if (!this._positionToReveal)
return;
if (!this.loaded || !this._isEditorShowing())
return;
- this._textEditor.highlightPosition(this._positionToHighlight.line, this._positionToHighlight.column);
- delete this._positionToHighlight;
+ this._textEditor.revealPosition(this._positionToReveal.line, this._positionToReveal.column, this._positionToReveal.shouldHighlight);
+ delete this._positionToReveal;
},
- _clearPositionHighlight: function()
+ _clearPositionToReveal: function()
{
this._textEditor.clearPositionHighlight();
- delete this._positionToHighlight;
- },
-
- /**
- * @param {number} line
- */
- revealLine: function(line)
- {
- this._clearPositionHighlight();
- this._clearLineToScrollTo();
- this._clearSelectionToSet();
- this._lineToReveal = line;
- this._innerRevealLineIfNeeded();
- },
-
- _innerRevealLineIfNeeded: function()
- {
- if (typeof this._lineToReveal === "number") {
- if (this.loaded && this._isEditorShowing()) {
- this._textEditor.revealLine(this._lineToReveal);
- delete this._lineToReveal;
- }
- }
- },
-
- _clearLineToReveal: function()
- {
- delete this._lineToReveal;
+ delete this._positionToReveal;
},
/**
@@ -263,8 +254,7 @@ WebInspector.SourceFrame.prototype = {
*/
scrollToLine: function(line)
{
- this._clearPositionHighlight();
- this._clearLineToReveal();
+ this._clearPositionToReveal();
this._lineToScrollTo = line;
this._innerScrollToLineIfNeeded();
},
@@ -285,6 +275,14 @@ WebInspector.SourceFrame.prototype = {
},
/**
+ * @return {!WebInspector.TextRange}
+ */
+ selection: function()
+ {
+ return this.textEditor.selection();
+ },
+
+ /**
* @param {!WebInspector.TextRange} textRange
*/
setSelection: function(textRange)
@@ -308,8 +306,7 @@ WebInspector.SourceFrame.prototype = {
_wasShownOrLoaded: function()
{
- this._innerHighlightPositionIfNeeded();
- this._innerRevealLineIfNeeded();
+ this._innerRevealPositionIfNeeded();
this._innerSetSelectionIfNeeded();
this._innerScrollToLineIfNeeded();
},
@@ -404,11 +401,12 @@ WebInspector.SourceFrame.prototype = {
/**
* @param {string} query
* @param {boolean} shouldJump
+ * @param {boolean} jumpBackwards
* @param {function(!WebInspector.View, number)} callback
* @param {function(number)} currentMatchChangedCallback
* @param {function()} searchResultsChangedCallback
*/
- performSearch: function(query, shouldJump, callback, currentMatchChangedCallback, searchResultsChangedCallback)
+ performSearch: function(query, shouldJump, jumpBackwards, callback, currentMatchChangedCallback, searchResultsChangedCallback)
{
/**
* @param {string} query
@@ -424,6 +422,8 @@ WebInspector.SourceFrame.prototype = {
this._searchResults = this._collectRegexMatches(regex);
if (!this._searchResults.length)
this._textEditor.cancelSearchResultsHighlight();
+ else if (shouldJump && jumpBackwards)
+ this.jumpToPreviousSearchResult();
else if (shouldJump)
this.jumpToNextSearchResult();
else
@@ -444,6 +444,11 @@ WebInspector.SourceFrame.prototype = {
_editorFocused: function()
{
+ this._resetCurrentSearchResultIndex();
+ },
+
+ _resetCurrentSearchResultIndex: function()
+ {
if (!this._searchResults.length)
return;
this._currentSearchResultIndex = -1;
@@ -452,17 +457,6 @@ WebInspector.SourceFrame.prototype = {
this._textEditor.highlightSearchResults(this._searchRegex, null);
},
- _searchResultAfterSelectionIndex: function(selection)
- {
- if (!selection)
- return 0;
- for (var i = 0; i < this._searchResults.length; ++i) {
- if (this._searchResults[i].compareTo(selection) >= 0)
- return i;
- }
- return 0;
- },
-
_resetSearch: function()
{
delete this._delayedFindSearchMatches;
@@ -484,6 +478,9 @@ WebInspector.SourceFrame.prototype = {
this._textEditor.setSelection(range);
},
+ /**
+ * @return {boolean}
+ */
hasSearchResults: function()
{
return this._searchResults.length > 0;
@@ -499,24 +496,38 @@ WebInspector.SourceFrame.prototype = {
this.jumpToSearchResult(this._searchResults.length - 1);
},
+ /**
+ * @return {number}
+ */
+ _searchResultIndexForCurrentSelection: function()
+ {
+ return insertionIndexForObjectInListSortedByFunction(this._textEditor.selection(), this._searchResults, WebInspector.TextRange.comparator);
+ },
+
jumpToNextSearchResult: function()
{
- var currentIndex = this._searchResultAfterSelectionIndex(this._textEditor.selection());
+ var currentIndex = this._searchResultIndexForCurrentSelection();
var nextIndex = this._currentSearchResultIndex === -1 ? currentIndex : currentIndex + 1;
this.jumpToSearchResult(nextIndex);
},
jumpToPreviousSearchResult: function()
{
- var currentIndex = this._searchResultAfterSelectionIndex(this._textEditor.selection());
+ var currentIndex = this._searchResultIndexForCurrentSelection();
this.jumpToSearchResult(currentIndex - 1);
},
+ /**
+ * @return {boolean}
+ */
showingFirstSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === 0;
},
+ /**
+ * @return {boolean}
+ */
showingLastSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
@@ -540,7 +551,7 @@ WebInspector.SourceFrame.prototype = {
/**
* @param {string} text
*/
- replaceSearchMatchWith: function(text)
+ replaceSelectionWith: function(text)
{
var range = this._searchResults[this._currentSearchResultIndex];
if (!range)
@@ -560,7 +571,7 @@ WebInspector.SourceFrame.prototype = {
*/
replaceAllWith: function(query, replacement)
{
- this._textEditor.highlightSearchResults(this._searchRegex, null);
+ this._resetCurrentSearchResultIndex();
var text = this._textEditor.text();
var range = this._textEditor.range();
@@ -570,8 +581,25 @@ WebInspector.SourceFrame.prototype = {
else
text = text.replace(regex, function() { return replacement; });
+ var ranges = this._collectRegexMatches(regex);
+ if (!ranges.length)
+ return;
+
+ // Calculate the position of the end of the last range to be edited.
+ var currentRangeIndex = insertionIndexForObjectInListSortedByFunction(this._textEditor.selection(), ranges, WebInspector.TextRange.comparator);
+ var lastRangeIndex = mod(currentRangeIndex - 1, ranges.length);
+ var lastRange = ranges[lastRangeIndex];
+ var replacementLineEndings = replacement.lineEndings();
+ var replacementLineCount = replacementLineEndings.length;
+ var lastLineNumber = lastRange.startLine + replacementLineEndings.length - 1;
+ var lastColumnNumber = lastRange.startColumn;
+ if (replacementLineEndings.length > 1)
+ lastColumnNumber = replacementLineEndings[replacementLineCount - 1] - replacementLineEndings[replacementLineCount - 2] - 1;
+
this._isReplacing = true;
this._textEditor.editRange(range, text);
+ this._textEditor.revealPosition(lastLineNumber, lastColumnNumber);
+ this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(lastLineNumber, lastColumnNumber));
delete this._isReplacing;
},
@@ -620,7 +648,7 @@ WebInspector.SourceFrame.prototype = {
for (var i = 0; i < rowMessages.length; ++i) {
if (rowMessages[i].consoleMessage.isEqual(msg)) {
- rowMessages[i].repeatCount = msg.totalRepeatCount;
+ rowMessages[i].repeatCount++;
this._updateMessageRepeatCount(rowMessages[i]);
return;
}
@@ -656,10 +684,10 @@ WebInspector.SourceFrame.prototype = {
// Create the image element in the Inspector's document so we can use relative image URLs.
messageLineElement.appendChild(imageElement);
- messageLineElement.appendChild(document.createTextNode(msg.message));
+ messageLineElement.appendChild(document.createTextNode(msg.messageText));
rowMessage.element = messageLineElement;
- rowMessage.repeatCount = msg.totalRepeatCount;
+ rowMessage.repeatCount = 1;
this._updateMessageRepeatCount(rowMessage);
this._textEditor.endUpdates();
},
@@ -717,6 +745,18 @@ WebInspector.SourceFrame.prototype = {
{
},
+ /**
+ * @param {?WebInspector.TextRange} from
+ * @param {?WebInspector.TextRange} to
+ */
+ onJumpToPosition: function(from, to)
+ {
+ this.dispatchEventToListeners(WebInspector.SourceFrame.Events.JumpHappened, {
+ from: from,
+ to: to
+ });
+ },
+
inheritScrollPositions: function(sourceFrame)
{
this._textEditor.inheritScrollPositions(sourceFrame._textEditor);
@@ -731,30 +771,25 @@ WebInspector.SourceFrame.prototype = {
},
/**
- * @param {string} text
- */
- commitEditing: function(text)
- {
- },
-
- /**
* @param {!WebInspector.TextRange} textRange
*/
selectionChanged: function(textRange)
{
- this._updateSourcePosition(textRange);
+ this._updateSourcePosition();
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
WebInspector.notifications.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
},
- /**
- * @param {!WebInspector.TextRange} textRange
- */
- _updateSourcePosition: function(textRange)
+ _updateSourcePosition: function()
{
- if (!textRange)
+ var selections = this._textEditor.selections();
+ if (!selections.length)
return;
-
+ if (selections.length > 1) {
+ this._sourcePosition.setText(WebInspector.UIString("%d selection regions", selections.length));
+ return;
+ }
+ var textRange = selections[0];
if (textRange.isEmpty()) {
this._sourcePosition.setText(WebInspector.UIString("Line %d, Column %d", textRange.endLine + 1, textRange.endColumn + 1));
return;
@@ -784,17 +819,7 @@ WebInspector.SourceFrame.prototype = {
e.consume(true);
},
- _commitEditing: function()
- {
- if (this._textEditor.readOnly())
- return false;
-
- var content = this._textEditor.text();
- this.commitEditing(content);
- return true;
- },
-
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
@@ -855,5 +880,17 @@ WebInspector.TextEditorDelegateForSourceFrame.prototype = {
return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal);
},
- __proto__: WebInspector.TextEditorDelegate.prototype
+ /**
+ * @param {?WebInspector.TextRange} from
+ * @param {?WebInspector.TextRange} to
+ */
+ onJumpToPosition: function(from, to)
+ {
+ this._sourceFrame.onJumpToPosition(from, to);
+ }
}
+
+importScript("GoToLineDialog.js");
+importScript("ResourceView.js");
+importScript("FontView.js");
+importScript("ImageView.js");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/module.json
new file mode 100644
index 00000000000..2b72a6869fe
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/source_frame/module.json
@@ -0,0 +1,26 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.InplaceEditor",
+ "className": "WebInspector.CodeMirrorUtils"
+ },
+ {
+ "type": "@WebInspector.TokenizerFactory",
+ "className": "WebInspector.CodeMirrorUtils.TokenizerFactory"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Default indentation",
+ "settingName": "textEditorIndent",
+ "settingType": "select",
+ "options": [
+ ["2 spaces", " "],
+ ["4 spaces", " "],
+ ["8 spaces", " "],
+ ["Tab character", "\t"]
+ ]
+ }
+ ],
+ "scripts": [ "SourceFrame.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/BreakpointsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/BreakpointsSidebarPane.js
index 3eb992cd04f..ab6b8b18a74 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/BreakpointsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/BreakpointsSidebarPane.js
@@ -25,12 +25,15 @@
/**
* @constructor
- * @param {!WebInspector.BreakpointManager} breakpointManager
* @extends {WebInspector.SidebarPane}
+ * @param {!WebInspector.DebuggerModel} debuggerModel
+ * @param {!WebInspector.BreakpointManager} breakpointManager
+ * @param {function(!WebInspector.UISourceCode, number=, number=, boolean=)} showSourceLineDelegate
*/
-WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, showSourceLineDelegate)
+WebInspector.JavaScriptBreakpointsSidebarPane = function(debuggerModel, breakpointManager, showSourceLineDelegate)
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Breakpoints"));
+ this._debuggerModel = debuggerModel;
this.registerRequiredCSS("breakpointsList.css");
this._breakpointManager = breakpointManager;
@@ -46,7 +49,7 @@ WebInspector.JavaScriptBreakpointsSidebarPane = function(breakpointManager, show
this.bodyElement.appendChild(this.emptyElement);
this._items = new Map();
-
+
var breakpointLocations = this._breakpointManager.allBreakpointLocations();
for (var i = 0; i < breakpointLocations.length; ++i)
this._addBreakpoint(breakpointLocations[i].breakpoint, breakpointLocations[i].uiLocation);
@@ -61,11 +64,11 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
_emptyElementContextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu(event);
- var breakpointActive = WebInspector.debuggerModel.breakpointsActive();
+ var breakpointActive = this._debuggerModel.breakpointsActive();
var breakpointActiveTitle = breakpointActive ?
WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") :
WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints");
- contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive));
+ contextMenu.appendItem(breakpointActiveTitle, this._debuggerModel.setBreakpointsActive.bind(this._debuggerModel, !breakpointActive));
contextMenu.show();
},
@@ -111,11 +114,17 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
*/
function didRequestContent(content)
{
- var lineEndings = content.lineEndings();
- if (uiLocation.lineNumber < lineEndings.length)
- snippetElement.textContent = content.substring(lineEndings[uiLocation.lineNumber - 1], lineEndings[uiLocation.lineNumber]);
+ var lineNumber = uiLocation.lineNumber
+ var columnNumber = uiLocation.columnNumber;
+ var contentString = new String(content);
+ if (lineNumber < contentString.lineCount()) {
+ var lineText = contentString.lineAt(lineNumber);
+ var maxSnippetLength = 200;
+ snippetElement.textContent = lineText.substr(columnNumber).trimEnd(maxSnippetLength);
+ }
}
- uiLocation.uiSourceCode.requestContent(didRequestContent.bind(this));
+
+ uiLocation.uiSourceCode.requestContent(didRequestContent);
element._data = uiLocation;
var currentElement = this.listElement.firstChild;
@@ -175,6 +184,7 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
+ * @param {?Event} event
*/
_breakpointCheckboxClicked: function(breakpoint, event)
{
@@ -185,6 +195,7 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
/**
* @param {!WebInspector.BreakpointManager.Breakpoint} breakpoint
+ * @param {?Event} event
*/
_breakpointContextMenu: function(breakpoint, event)
{
@@ -197,11 +208,11 @@ WebInspector.JavaScriptBreakpointsSidebarPane.prototype = {
}
contextMenu.appendSeparator();
- var breakpointActive = WebInspector.debuggerModel.breakpointsActive();
+ var breakpointActive = this._debuggerModel.breakpointsActive();
var breakpointActiveTitle = breakpointActive ?
WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Deactivate breakpoints" : "Deactivate Breakpoints") :
WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Activate breakpoints" : "Activate Breakpoints");
- contextMenu.appendItem(breakpointActiveTitle, WebInspector.debuggerModel.setBreakpointsActive.bind(WebInspector.debuggerModel, !breakpointActive));
+ contextMenu.appendItem(breakpointActiveTitle, this._debuggerModel.setBreakpointsActive.bind(this._debuggerModel, !breakpointActive));
function enabledBreakpointCount(breakpoints)
{
@@ -333,8 +344,8 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
}
}
- var config = new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false));
- WebInspector.startEditing(inputElement, config);
+ var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
+ WebInspector.InplaceEditor.startEditing(inputElement, config);
},
_setBreakpoint: function(url, enabled)
@@ -452,7 +463,7 @@ WebInspector.XHRBreakpointsSidebarPane.prototype = {
element.classList.remove("hidden");
}
- WebInspector.startEditing(inputElement, new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false)));
+ WebInspector.InplaceEditor.startEditing(inputElement, new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false)));
},
highlightBreakpoint: function(url)
@@ -510,27 +521,30 @@ WebInspector.EventListenerBreakpointsSidebarPane = function()
this.categoriesTreeOutline = new TreeOutline(this.categoriesElement);
this.bodyElement.appendChild(this.categoriesElement);
- this._breakpointItems = {};
+ this._categoryItems = [];
// FIXME: uncomment following once inspector stops being drop targer in major ports.
// Otherwise, inspector page reacts on drop event and tries to load the event data.
- // this._createCategory(WebInspector.UIString("Drag"), true, ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]);
- this._createCategory(WebInspector.UIString("Animation"), false, ["requestAnimationFrame", "cancelAnimationFrame", "animationFrameFired"]);
- this._createCategory(WebInspector.UIString("Control"), true, ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
- this._createCategory(WebInspector.UIString("Clipboard"), true, ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
- this._createCategory(WebInspector.UIString("DOM Mutation"), true, ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
- this._createCategory(WebInspector.UIString("Device"), true, ["deviceorientation", "devicemotion"]);
- this._createCategory(WebInspector.UIString("Keyboard"), true, ["keydown", "keyup", "keypress", "input"]);
- this._createCategory(WebInspector.UIString("Load"), true, ["load", "beforeunload", "unload", "abort", "error", "hashchange", "popstate"]);
- this._createCategory(WebInspector.UIString("Mouse"), true, ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel"]);
- this._createCategory(WebInspector.UIString("Timer"), false, ["setTimer", "clearTimer", "timerFired"]);
- this._createCategory(WebInspector.UIString("Touch"), true, ["touchstart", "touchmove", "touchend", "touchcancel"]);
- this._createCategory(WebInspector.UIString("WebGL"), false, ["webglErrorFired", "webglWarningFired"]);
+ // this._createCategory(WebInspector.UIString("Drag"), ["drag", "drop", "dragstart", "dragend", "dragenter", "dragleave", "dragover"]);
+ this._createCategory(WebInspector.UIString("Animation"), ["requestAnimationFrame", "cancelAnimationFrame", "animationFrameFired"], true);
+ this._createCategory(WebInspector.UIString("Control"), ["resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset"]);
+ this._createCategory(WebInspector.UIString("Clipboard"), ["copy", "cut", "paste", "beforecopy", "beforecut", "beforepaste"]);
+ this._createCategory(WebInspector.UIString("DOM Mutation"), ["DOMActivate", "DOMFocusIn", "DOMFocusOut", "DOMAttrModified", "DOMCharacterDataModified", "DOMNodeInserted", "DOMNodeInsertedIntoDocument", "DOMNodeRemoved", "DOMNodeRemovedFromDocument", "DOMSubtreeModified", "DOMContentLoaded"]);
+ this._createCategory(WebInspector.UIString("Device"), ["deviceorientation", "devicemotion"]);
+ this._createCategory(WebInspector.UIString("Drag / drop"), ["dragenter", "dragover", "dragleave", "drop"]);
+ this._createCategory(WebInspector.UIString("Keyboard"), ["keydown", "keyup", "keypress", "input"]);
+ this._createCategory(WebInspector.UIString("Load"), ["load", "beforeunload", "unload", "abort", "error", "hashchange", "popstate"]);
+ this._createCategory(WebInspector.UIString("Mouse"), ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove", "mouseout", "mousewheel", "wheel"]);
+ this._createCategory(WebInspector.UIString("Timer"), ["setTimer", "clearTimer", "timerFired"], true);
+ this._createCategory(WebInspector.UIString("Touch"), ["touchstart", "touchmove", "touchend", "touchcancel"]);
+ this._createCategory(WebInspector.UIString("XHR"), ["readystatechange", "load", "loadstart", "loadend", "abort", "error", "progress", "timeout"], false, ["XMLHttpRequest", "XMLHttpRequestUpload"]);
+ this._createCategory(WebInspector.UIString("WebGL"), ["webglErrorFired", "webglWarningFired"], true);
this._restoreBreakpoints();
}
-WebInspector.EventListenerBreakpointsSidebarPane.categotyListener = "listener:";
-WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation = "instrumentation:";
+WebInspector.EventListenerBreakpointsSidebarPane.categoryListener = "listener:";
+WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation = "instrumentation:";
+WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny = "*";
/**
* @param {string} eventName
@@ -563,46 +577,76 @@ WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI = function(event
}
WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
- _createCategory: function(name, isDOMEvent, eventNames)
+ /**
+ * @param {string} name
+ * @param {!Array.<string>} eventNames
+ * @param {boolean=} isInstrumentationEvent
+ * @param {!Array.<string>=} targetNames
+ */
+ _createCategory: function(name, eventNames, isInstrumentationEvent, targetNames)
{
+ var labelNode = document.createElement("label");
+ labelNode.textContent = name;
+
var categoryItem = {};
- categoryItem.element = new TreeElement(name);
+ categoryItem.element = new TreeElement(labelNode);
this.categoriesTreeOutline.appendChild(categoryItem.element);
categoryItem.element.listItemElement.classList.add("event-category");
categoryItem.element.selectable = true;
- categoryItem.checkbox = this._createCheckbox(categoryItem.element);
+ categoryItem.checkbox = this._createCheckbox(labelNode);
categoryItem.checkbox.addEventListener("click", this._categoryCheckboxClicked.bind(this, categoryItem), true);
+ categoryItem.targetNames = this._stringArrayToLowerCase(targetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny]);
categoryItem.children = {};
+ var category = (isInstrumentationEvent ? WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation : WebInspector.EventListenerBreakpointsSidebarPane.categoryListener);
for (var i = 0; i < eventNames.length; ++i) {
- var eventName = (isDOMEvent ? WebInspector.EventListenerBreakpointsSidebarPane.categotyListener : WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation) + eventNames[i];
+ var eventName = category + eventNames[i];
var breakpointItem = {};
var title = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName);
- breakpointItem.element = new TreeElement(title);
+
+ labelNode = document.createElement("label");
+ labelNode.textContent = title;
+
+ breakpointItem.element = new TreeElement(labelNode);
categoryItem.element.appendChild(breakpointItem.element);
- var hitMarker = document.createElement("div");
- hitMarker.className = "breakpoint-hit-marker";
- breakpointItem.element.listItemElement.appendChild(hitMarker);
+
+ breakpointItem.element.listItemElement.createChild("div", "breakpoint-hit-marker");
breakpointItem.element.listItemElement.classList.add("source-code");
breakpointItem.element.selectable = false;
- breakpointItem.checkbox = this._createCheckbox(breakpointItem.element);
- breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, eventName), true);
+ breakpointItem.checkbox = this._createCheckbox(labelNode);
+ breakpointItem.checkbox.addEventListener("click", this._breakpointCheckboxClicked.bind(this, eventName, categoryItem.targetNames), true);
breakpointItem.parent = categoryItem;
- this._breakpointItems[eventName] = breakpointItem;
categoryItem.children[eventName] = breakpointItem;
}
+ this._categoryItems.push(categoryItem);
+ },
+
+ /**
+ * @param {!Array.<string>} array
+ * @return {!Array.<string>}
+ */
+ _stringArrayToLowerCase: function(array)
+ {
+ return array.map(function(value) {
+ return value.toLowerCase();
+ });
},
- _createCheckbox: function(treeElement)
+ /**
+ * @param {!Element} labelNode
+ * @return {!Element}
+ */
+ _createCheckbox: function(labelNode)
{
var checkbox = document.createElement("input");
checkbox.className = "checkbox-elem";
checkbox.type = "checkbox";
- treeElement.listItemElement.insertBefore(checkbox, treeElement.listItemElement.firstChild);
+
+ labelNode.insertBefore(checkbox, labelNode.firstChild);
return checkbox;
},
@@ -614,65 +658,120 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
if (breakpointItem.checkbox.checked === checked)
continue;
if (checked)
- this._setBreakpoint(eventName);
+ this._setBreakpoint(eventName, categoryItem.targetNames);
else
- this._removeBreakpoint(eventName);
+ this._removeBreakpoint(eventName, categoryItem.targetNames);
}
this._saveBreakpoints();
},
- _breakpointCheckboxClicked: function(eventName, event)
+ /**
+ * @param {string} eventName
+ * @param {!Array.<string>} targetNames
+ * @param {?Event} event
+ */
+ _breakpointCheckboxClicked: function(eventName, targetNames, event)
{
if (event.target.checked)
- this._setBreakpoint(eventName);
+ this._setBreakpoint(eventName, targetNames);
else
- this._removeBreakpoint(eventName);
+ this._removeBreakpoint(eventName, targetNames);
this._saveBreakpoints();
},
- _setBreakpoint: function(eventName)
+ /**
+ * @param {string} eventName
+ * @param {?Array.<string>=} targetNames
+ */
+ _setBreakpoint: function(eventName, targetNames)
{
- var breakpointItem = this._breakpointItems[eventName];
- if (!breakpointItem)
- return;
- breakpointItem.checkbox.checked = true;
- if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener))
- DOMDebuggerAgent.setEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length));
- else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation))
- DOMDebuggerAgent.setInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length));
- this._updateCategoryCheckbox(breakpointItem.parent);
+ targetNames = targetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];
+ for (var i = 0; i < targetNames.length; ++i) {
+ var targetName = targetNames[i];
+ var breakpointItem = this._findBreakpointItem(eventName, targetName);
+ if (!breakpointItem)
+ continue;
+ breakpointItem.checkbox.checked = true;
+ breakpointItem.parent.dirtyCheckbox = true;
+ if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener))
+ DOMDebuggerAgent.setEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener.length), targetName);
+ else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation))
+ DOMDebuggerAgent.setInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation.length));
+ }
+ this._updateCategoryCheckboxes();
},
- _removeBreakpoint: function(eventName)
+ /**
+ * @param {string} eventName
+ * @param {?Array.<string>=} targetNames
+ */
+ _removeBreakpoint: function(eventName, targetNames)
{
- var breakpointItem = this._breakpointItems[eventName];
- if (!breakpointItem)
- return;
- breakpointItem.checkbox.checked = false;
- if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener))
- DOMDebuggerAgent.removeEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyListener.length));
- else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation))
- DOMDebuggerAgent.removeInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categotyInstrumentation.length));
- this._updateCategoryCheckbox(breakpointItem.parent);
+ targetNames = targetNames || [WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny];
+ for (var i = 0; i < targetNames.length; ++i) {
+ var targetName = targetNames[i];
+ var breakpointItem = this._findBreakpointItem(eventName, targetName);
+ if (!breakpointItem)
+ continue;
+ breakpointItem.checkbox.checked = false;
+ breakpointItem.parent.dirtyCheckbox = true;
+ if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener))
+ DOMDebuggerAgent.removeEventListenerBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryListener.length), targetName);
+ else if (eventName.startsWith(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation))
+ DOMDebuggerAgent.removeInstrumentationBreakpoint(eventName.substring(WebInspector.EventListenerBreakpointsSidebarPane.categoryInstrumentation.length));
+ }
+ this._updateCategoryCheckboxes();
},
- _updateCategoryCheckbox: function(categoryItem)
+ _updateCategoryCheckboxes: function()
{
- var hasEnabled = false, hasDisabled = false;
- for (var eventName in categoryItem.children) {
+ for (var i = 0; i < this._categoryItems.length; ++i) {
+ var categoryItem = this._categoryItems[i];
+ if (!categoryItem.dirtyCheckbox)
+ continue;
+ categoryItem.dirtyCheckbox = false;
+ var hasEnabled = false;
+ var hasDisabled = false;
+ for (var eventName in categoryItem.children) {
+ var breakpointItem = categoryItem.children[eventName];
+ if (breakpointItem.checkbox.checked)
+ hasEnabled = true;
+ else
+ hasDisabled = true;
+ }
+ categoryItem.checkbox.checked = hasEnabled;
+ categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
+ }
+ },
+
+ /**
+ * @param {string} eventName
+ * @param {string=} targetName
+ * @return {?Object}
+ */
+ _findBreakpointItem: function(eventName, targetName)
+ {
+ targetName = (targetName || WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny).toLowerCase();
+ for (var i = 0; i < this._categoryItems.length; ++i) {
+ var categoryItem = this._categoryItems[i];
+ if (categoryItem.targetNames.indexOf(targetName) === -1)
+ continue;
var breakpointItem = categoryItem.children[eventName];
- if (breakpointItem.checkbox.checked)
- hasEnabled = true;
- else
- hasDisabled = true;
+ if (breakpointItem)
+ return breakpointItem;
}
- categoryItem.checkbox.checked = hasEnabled;
- categoryItem.checkbox.indeterminate = hasEnabled && hasDisabled;
+ return null;
},
- highlightBreakpoint: function(eventName)
+ /**
+ * @param {string} eventName
+ * @param {string=} targetName
+ */
+ highlightBreakpoint: function(eventName, targetName)
{
- var breakpointItem = this._breakpointItems[eventName];
+ var breakpointItem = this._findBreakpointItem(eventName, targetName);
+ if (!breakpointItem || !breakpointItem.checkbox.checked)
+ breakpointItem = this._findBreakpointItem(eventName, WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny);
if (!breakpointItem)
return;
this.expand();
@@ -692,9 +791,13 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
_saveBreakpoints: function()
{
var breakpoints = [];
- for (var eventName in this._breakpointItems) {
- if (this._breakpointItems[eventName].checkbox.checked)
- breakpoints.push({ eventName: eventName });
+ for (var i = 0; i < this._categoryItems.length; ++i) {
+ var categoryItem = this._categoryItems[i];
+ for (var eventName in categoryItem.children) {
+ var breakpointItem = categoryItem.children[eventName];
+ if (breakpointItem.checkbox.checked)
+ breakpoints.push({ eventName: eventName, targetNames: categoryItem.targetNames });
+ }
}
WebInspector.settings.eventListenerBreakpoints.set(breakpoints);
},
@@ -705,7 +808,7 @@ WebInspector.EventListenerBreakpointsSidebarPane.prototype = {
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint && typeof breakpoint.eventName === "string")
- this._setBreakpoint(breakpoint.eventName);
+ this._setBreakpoint(breakpoint.eventName, breakpoint.targetNames);
}
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CSSSourceFrame.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js
index 06d2d9a5878..3feba90437b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CSSSourceFrame.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/CSSSourceFrame.js
@@ -42,7 +42,7 @@ WebInspector.CSSSourceFrame = function(uiSourceCode)
WebInspector.CSSSourceFrame.prototype = {
_registerShortcuts: function()
{
- var shortcutKeys = WebInspector.SourcesPanelDescriptor.ShortcutKeys;
+ var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts;
for (var i = 0; i < shortcutKeys.IncreaseCSSUnitByOne.length; ++i)
this.addShortcut(shortcutKeys.IncreaseCSSUnitByOne[i].key, this._handleUnitModification.bind(this, 1));
for (var i = 0; i < shortcutKeys.DecreaseCSSUnitByOne.length; ++i)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/CallStackSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
index 153a799d734..ce6eb9cd5b6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/CallStackSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
@@ -33,13 +33,10 @@ WebInspector.CallStackSidebarPane = function()
this.bodyElement.addEventListener("keydown", this._keyDown.bind(this), true);
this.bodyElement.tabIndex = 0;
- if (WebInspector.experimentsSettings.asyncStackTraces.isEnabled()) {
- var asyncCheckbox = this.titleElement.appendChild(WebInspector.SettingsTab.createSettingCheckbox(WebInspector.UIString("Async"), WebInspector.settings.enableAsyncStackTraces, true, undefined, WebInspector.UIString("Capture async stack traces")));
- asyncCheckbox.classList.add("scripts-callstack-async");
- asyncCheckbox.addEventListener("click", consumeEvent, false);
-
- WebInspector.settings.enableAsyncStackTraces.addChangeListener(this._asyncStackTracesStateChanged, this);
- }
+ var asyncCheckbox = this.titleElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Async"), WebInspector.settings.enableAsyncStackTraces, true, undefined, WebInspector.UIString("Capture async stack traces")));
+ asyncCheckbox.classList.add("scripts-callstack-async");
+ asyncCheckbox.addEventListener("click", consumeEvent, false);
+ WebInspector.settings.enableAsyncStackTraces.addChangeListener(this._asyncStackTracesStateChanged, this);
}
WebInspector.CallStackSidebarPane.Events = {
@@ -49,31 +46,61 @@ WebInspector.CallStackSidebarPane.Events = {
WebInspector.CallStackSidebarPane.prototype = {
/**
- * @param {?Array.<!WebInspector.DebuggerModel.CallFrame>} callFrames
- * @param {?WebInspector.DebuggerModel.StackTrace} asyncStackTrace
+ * @param {?WebInspector.DebuggerPausedDetails} details
*/
- update: function(callFrames, asyncStackTrace)
+ update: function(details)
{
this.bodyElement.removeChildren();
- delete this._statusMessageElement;
- /** @type {!Array.<!WebInspector.CallStackSidebarPane.Placard>} */
- this.placards = [];
- if (!callFrames) {
+ if (!details) {
var infoElement = this.bodyElement.createChild("div", "info");
infoElement.textContent = WebInspector.UIString("Not Paused");
return;
}
+ this._target = details.target();
+ var callFrames = details.callFrames;
+ var asyncStackTrace = details.asyncStackTrace;
+
+ delete this._statusMessageElement;
+ delete this._hiddenPlacardsMessageElement;
+ /** @type {!Array.<!WebInspector.CallStackSidebarPane.Placard>} */
+ this.placards = [];
+ this._hiddenPlacards = 0;
+
this._appendSidebarPlacards(callFrames);
+ var topStackHidden = (this._hiddenPlacards === this.placards.length);
while (asyncStackTrace) {
- var title = "[" + (asyncStackTrace.description || WebInspector.UIString("Async Call")) + "]";
+ var title = asyncStackTrace.description;
+ if (title)
+ title += " " + WebInspector.UIString("(async)");
+ else
+ title = WebInspector.UIString("Async Call");
var asyncPlacard = new WebInspector.Placard(title, "");
+ asyncPlacard.element.addEventListener("click", this._selectNextVisiblePlacard.bind(this, this.placards.length, false), false);
+ asyncPlacard.element.addEventListener("contextmenu", this._asyncPlacardContextMenu.bind(this, this.placards.length), true);
+ asyncPlacard.element.classList.add("placard-label");
this.bodyElement.appendChild(asyncPlacard.element);
this._appendSidebarPlacards(asyncStackTrace.callFrames, asyncPlacard);
asyncStackTrace = asyncStackTrace.asyncStackTrace;
}
+
+ if (topStackHidden)
+ this._revealHiddenPlacards();
+ if (this._hiddenPlacards) {
+ var element = document.createElementWithClass("div", "hidden-placards-message");
+ if (this._hiddenPlacards === 1)
+ element.textContent = WebInspector.UIString("1 stack frame is hidden (black-boxed).");
+ else
+ element.textContent = WebInspector.UIString("%d stack frames are hidden (black-boxed).", this._hiddenPlacards);
+ element.createTextChild(" ");
+ var showAllLink = element.createChild("span", "node-link");
+ showAllLink.textContent = WebInspector.UIString("Show");
+ showAllLink.addEventListener("click", this._revealHiddenPlacards.bind(this), false);
+ this.bodyElement.insertBefore(element, this.bodyElement.firstChild);
+ this._hiddenPlacardsMessageElement = element;
+ }
},
/**
@@ -82,27 +109,53 @@ WebInspector.CallStackSidebarPane.prototype = {
*/
_appendSidebarPlacards: function(callFrames, asyncPlacard)
{
+ var allPlacardsHidden = true;
for (var i = 0, n = callFrames.length; i < n; ++i) {
- var placard = new WebInspector.CallStackSidebarPane.Placard(callFrames[i], asyncPlacard);
+ var callFrame = callFrames[i];
+ var placard = new WebInspector.CallStackSidebarPane.Placard(callFrame, asyncPlacard);
placard.element.addEventListener("click", this._placardSelected.bind(this, placard), false);
placard.element.addEventListener("contextmenu", this._placardContextMenu.bind(this, placard), true);
- if (!i && asyncPlacard) {
- asyncPlacard.element.addEventListener("click", this._placardSelected.bind(this, placard), false);
- asyncPlacard.element.addEventListener("contextmenu", this._placardContextMenu.bind(this, placard), true);
- }
this.placards.push(placard);
this.bodyElement.appendChild(placard.element);
+
+ if (callFrame.script.isFramework()) {
+ placard.setHidden(true);
+ placard.element.classList.add("dimmed");
+ ++this._hiddenPlacards;
+ } else {
+ allPlacardsHidden = false;
+ }
+ }
+ if (allPlacardsHidden && asyncPlacard)
+ asyncPlacard.setHidden(true);
+ },
+
+ _revealHiddenPlacards: function()
+ {
+ if (!this._hiddenPlacards)
+ return;
+ this._hiddenPlacards = 0;
+ for (var i = 0; i < this.placards.length; ++i) {
+ var placard = this.placards[i];
+ placard.setHidden(false);
+ if (placard._asyncPlacard)
+ placard._asyncPlacard.setHidden(false);
+ }
+ if (this._hiddenPlacardsMessageElement) {
+ this._hiddenPlacardsMessageElement.remove();
+ delete this._hiddenPlacardsMessageElement;
}
},
/**
* @param {!WebInspector.CallStackSidebarPane.Placard} placard
+ * @param {?Event} event
*/
_placardContextMenu: function(placard, event)
{
var contextMenu = new WebInspector.ContextMenu(event);
- if (!placard._callFrame.isAsync() && WebInspector.debuggerModel.canSetScriptSource())
+ if (!placard._callFrame.isAsync())
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Restart frame" : "Restart Frame"), this._restartFrame.bind(this, placard));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy stack trace" : "Copy Stack Trace"), this._copyStackTrace.bind(this));
@@ -110,6 +163,21 @@ WebInspector.CallStackSidebarPane.prototype = {
},
/**
+ * @param {number} index
+ * @param {?Event} event
+ */
+ _asyncPlacardContextMenu: function(index, event)
+ {
+ for (; index < this.placards.length; ++index) {
+ var placard = this.placards[index];
+ if (!placard.isHidden()) {
+ this._placardContextMenu(placard, event);
+ break;
+ }
+ }
+ },
+
+ /**
* @param {!WebInspector.CallStackSidebarPane.Placard} placard
*/
_restartFrame: function(placard)
@@ -142,7 +210,7 @@ WebInspector.CallStackSidebarPane.prototype = {
}
this.placards.length = lastSyncPlacardIndex + 1;
if (shouldSelectTopFrame)
- this._selectPlacardByIndex(0);
+ this._selectNextVisiblePlacard(0);
},
/**
@@ -153,6 +221,8 @@ WebInspector.CallStackSidebarPane.prototype = {
for (var i = 0; i < this.placards.length; ++i) {
var placard = this.placards[i];
placard.selected = (placard._callFrame === x);
+ if (placard.selected && placard.isHidden())
+ this._revealHiddenPlacards();
}
},
@@ -164,7 +234,7 @@ WebInspector.CallStackSidebarPane.prototype = {
var index = this._selectedCallFrameIndex();
if (index === -1)
return false;
- return this._selectPlacardByIndex(index + 1);
+ return this._selectNextVisiblePlacard(index + 1);
},
/**
@@ -175,19 +245,25 @@ WebInspector.CallStackSidebarPane.prototype = {
var index = this._selectedCallFrameIndex();
if (index === -1)
return false;
- return this._selectPlacardByIndex(index - 1);
+ return this._selectNextVisiblePlacard(index - 1, true);
},
/**
* @param {number} index
+ * @param {boolean=} backward
* @return {boolean}
*/
- _selectPlacardByIndex: function(index)
+ _selectNextVisiblePlacard: function(index, backward)
{
- if (index < 0 || index >= this.placards.length)
- return false;
- this._placardSelected(this.placards[index]);
- return true;
+ while (0 <= index && index < this.placards.length) {
+ var placard = this.placards[index];
+ if (!placard.isHidden()) {
+ this._placardSelected(placard);
+ return true;
+ }
+ index += backward ? -1 : 1;
+ }
+ return false;
},
/**
@@ -195,7 +271,7 @@ WebInspector.CallStackSidebarPane.prototype = {
*/
_selectedCallFrameIndex: function()
{
- var selectedCallFrame = WebInspector.debuggerModel.selectedCallFrame();
+ var selectedCallFrame = this._target.debuggerModel.selectedCallFrame();
if (!selectedCallFrame)
return -1;
for (var i = 0; i < this.placards.length; ++i) {
@@ -218,10 +294,15 @@ WebInspector.CallStackSidebarPane.prototype = {
_copyStackTrace: function()
{
var text = "";
+ var lastPlacard = null;
for (var i = 0; i < this.placards.length; ++i) {
- if (i && this.placards[i]._asyncPlacard !== this.placards[i - 1]._asyncPlacard)
- text += this.placards[i]._asyncPlacard.title + "\n";
- text += this.placards[i].title + " (" + this.placards[i].subtitle + ")\n";
+ var placard = this.placards[i];
+ if (placard.isHidden())
+ continue;
+ if (lastPlacard && placard._asyncPlacard !== lastPlacard._asyncPlacard)
+ text += placard._asyncPlacard.title + "\n";
+ text += placard.title + " (" + placard.subtitle + ")\n";
+ lastPlacard = placard;
}
InspectorFrontendHost.copyText(text);
},
@@ -231,8 +312,8 @@ WebInspector.CallStackSidebarPane.prototype = {
*/
registerShortcuts: function(registerShortcutDelegate)
{
- registerShortcutDelegate(WebInspector.SourcesPanelDescriptor.ShortcutKeys.NextCallFrame, this._selectNextCallFrameOnStack.bind(this));
- registerShortcutDelegate(WebInspector.SourcesPanelDescriptor.ShortcutKeys.PrevCallFrame, this._selectPreviousCallFrameOnStack.bind(this));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.NextCallFrame, this._selectNextCallFrameOnStack.bind(this));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortcuts.PrevCallFrame, this._selectPreviousCallFrameOnStack.bind(this));
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/EditingLocationHistoryManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/EditingLocationHistoryManager.js
new file mode 100644
index 00000000000..9883664e060
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/EditingLocationHistoryManager.js
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {!WebInspector.SourcesView} sourcesView
+ * @param {!function():?WebInspector.SourceFrame} currentSourceFrameCallback
+ */
+WebInspector.EditingLocationHistoryManager = function(sourcesView, currentSourceFrameCallback)
+{
+ this._sourcesView = sourcesView;
+ this._historyManager = new WebInspector.SimpleHistoryManager(WebInspector.EditingLocationHistoryManager.HistoryDepth);
+ this._currentSourceFrameCallback = currentSourceFrameCallback;
+}
+
+WebInspector.EditingLocationHistoryManager.HistoryDepth = 20;
+
+WebInspector.EditingLocationHistoryManager.prototype = {
+ /**
+ * @param {!WebInspector.UISourceCodeFrame} sourceFrame
+ */
+ trackSourceFrameCursorJumps: function(sourceFrame)
+ {
+ sourceFrame.addEventListener(WebInspector.SourceFrame.Events.JumpHappened, this._onJumpHappened.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onJumpHappened: function(event)
+ {
+ if (event.data.from)
+ this._updateActiveState(event.data.from);
+ if (event.data.to)
+ this._pushActiveState(event.data.to);
+ },
+
+ rollback: function()
+ {
+ this._historyManager.rollback();
+ },
+
+ rollover: function()
+ {
+ this._historyManager.rollover();
+ },
+
+ updateCurrentState: function()
+ {
+ var sourceFrame = this._currentSourceFrameCallback();
+ if (!sourceFrame)
+ return;
+ this._updateActiveState(sourceFrame.textEditor.selection());
+ },
+
+ pushNewState: function()
+ {
+ var sourceFrame = this._currentSourceFrameCallback();
+ if (!sourceFrame)
+ return;
+ this._pushActiveState(sourceFrame.textEditor.selection());
+ },
+
+ /**
+ * @param {!WebInspector.TextRange} selection
+ */
+ _updateActiveState: function(selection)
+ {
+ var active = this._historyManager.active();
+ if (!active)
+ return;
+ var sourceFrame = this._currentSourceFrameCallback();
+ if (!sourceFrame)
+ return;
+ var entry = new WebInspector.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
+ active.merge(entry);
+ },
+
+ /**
+ * @param {!WebInspector.TextRange} selection
+ */
+ _pushActiveState: function(selection)
+ {
+ var sourceFrame = this._currentSourceFrameCallback();
+ if (!sourceFrame)
+ return;
+ var entry = new WebInspector.EditingLocationHistoryEntry(this._sourcesView, this, sourceFrame, selection);
+ this._historyManager.push(entry);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ removeHistoryForSourceCode: function(uiSourceCode)
+ {
+ function filterOut(entry)
+ {
+ return entry._projectId === uiSourceCode.project().id() && entry._path === uiSourceCode.path();
+ }
+
+ this._historyManager.filterOut(filterOut);
+ },
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.HistoryEntry}
+ * @param {!WebInspector.SourcesView} sourcesView
+ * @param {!WebInspector.EditingLocationHistoryManager} editingLocationManager
+ * @param {!WebInspector.SourceFrame} sourceFrame
+ * @param {!WebInspector.TextRange} selection
+ */
+WebInspector.EditingLocationHistoryEntry = function(sourcesView, editingLocationManager, sourceFrame, selection)
+{
+ this._sourcesView = sourcesView;
+ this._editingLocationManager = editingLocationManager;
+ var uiSourceCode = sourceFrame.uiSourceCode();
+ this._projectId = uiSourceCode.project().id();
+ this._path = uiSourceCode.path();
+
+ var position = this._positionFromSelection(selection);
+ this._positionHandle = sourceFrame.textEditor.textEditorPositionHandle(position.lineNumber, position.columnNumber);
+}
+
+WebInspector.EditingLocationHistoryEntry.prototype = {
+ /**
+ * @param {!WebInspector.HistoryEntry} entry
+ */
+ merge: function(entry)
+ {
+ if (this._projectId !== entry._projectId || this._path !== entry._path)
+ return;
+ this._positionHandle = entry._positionHandle;
+ },
+
+ /**
+ * @param {!WebInspector.TextRange} selection
+ * @return {!{lineNumber: number, columnNumber: number}}
+ */
+ _positionFromSelection: function(selection)
+ {
+ return {
+ lineNumber: selection.endLine,
+ columnNumber: selection.endColumn
+ };
+ },
+
+ /**
+ * @return {boolean}
+ */
+ valid: function()
+ {
+ var position = this._positionHandle.resolve();
+ var uiSourceCode = WebInspector.workspace.project(this._projectId).uiSourceCode(this._path);
+ return !!(position && uiSourceCode);
+ },
+
+ reveal: function()
+ {
+ var position = this._positionHandle.resolve();
+ var uiSourceCode = WebInspector.workspace.project(this._projectId).uiSourceCode(this._path);
+ if (!position || !uiSourceCode)
+ return;
+
+ this._editingLocationManager.updateCurrentState();
+ this._sourcesView.showSourceLocation(uiSourceCode, position.lineNumber, position.columnNumber);
+ }
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FilePathScoreFunction.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js
index cc6fc68d216..cc6fc68d216 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FilePathScoreFunction.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/FilePathScoreFunction.js
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/FilteredItemSelectionDialog.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
index fd4aa1d1719..b5deee9cff0 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/FilteredItemSelectionDialog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
@@ -38,16 +38,14 @@ WebInspector.FilteredItemSelectionDialog = function(delegate)
{
WebInspector.DialogDelegate.call(this);
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "filteredItemSelectionDialog.css", false);
- xhr.send(null);
+ if (!WebInspector.FilteredItemSelectionDialog._stylesLoaded) {
+ WebInspector.View.createStyleElement("filteredItemSelectionDialog.css");
+ WebInspector.FilteredItemSelectionDialog._stylesLoaded = true;
+ }
this.element = document.createElement("div");
this.element.className = "filtered-item-list-dialog";
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
- var styleElement = this.element.createChild("style");
- styleElement.type = "text/css";
- styleElement.textContent = xhr.responseText;
this._promptElement = this.element.createChild("input", "monospace");
this._promptElement.addEventListener("input", this._onInput.bind(this), false);
@@ -56,6 +54,7 @@ WebInspector.FilteredItemSelectionDialog = function(delegate)
this._filteredItems = [];
this._viewportControl = new WebInspector.ViewportControl(this);
+ this._viewportControl.element.classList.add("fill");
this._itemElementsContainer = this._viewportControl.element;
this._itemElementsContainer.classList.add("container");
this._itemElementsContainer.classList.add("monospace");
@@ -65,8 +64,6 @@ WebInspector.FilteredItemSelectionDialog = function(delegate)
this._delegate = delegate;
this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));
this._itemsLoaded();
-
- this._shouldShowMatchingItems = true;
}
WebInspector.FilteredItemSelectionDialog.prototype = {
@@ -76,17 +73,21 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
*/
position: function(element, relativeToElement)
{
- const minWidth = 500;
- const minHeight = 204;
- var width = Math.max(relativeToElement.offsetWidth * 2 / 3, minWidth);
- var height = Math.max(relativeToElement.offsetHeight * 2 / 3, minHeight);
+ const shadow = 10;
+ const shadowPadding = 20; // shadow + padding
+ var container = WebInspector.Dialog.modalHostView().element;
+ var preferredWidth = Math.max(relativeToElement.offsetWidth * 2 / 3, 500);
+ var width = Math.min(preferredWidth, container.offsetWidth - 2 * shadowPadding);
+ var preferredHeight = Math.max(relativeToElement.offsetHeight * 2 / 3, 204);
+ var height = Math.min(preferredHeight, container.offsetHeight - 2 * shadowPadding);
this.element.style.width = width + "px";
-
- const shadowPadding = 20; // shadow + padding
- element.positionAt(
- relativeToElement.totalOffsetLeft() + Math.max((relativeToElement.offsetWidth - width - 2 * shadowPadding) / 2, shadowPadding),
- relativeToElement.totalOffsetTop() + Math.max((relativeToElement.offsetHeight - height - 2 * shadowPadding) / 2, shadowPadding));
+ var box = relativeToElement.boxInWindow(window).relativeToElement(container);
+ var positionX = box.x + Math.max((box.width - width - 2 * shadowPadding) / 2, shadow);
+ positionX = Math.max(shadow, Math.min(container.offsetWidth - width - 2 * shadowPadding, positionX));
+ var positionY = box.y + Math.max((box.height - height - 2 * shadowPadding) / 2, shadow);
+ positionY = Math.max(shadow, Math.min(container.offsetHeight - height - 2 * shadowPadding, positionY));
+ element.positionAt(positionX, positionY, container);
this._dialogHeight = height;
this._updateShowMatchingItems();
@@ -118,7 +119,8 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
{
if (!this._delegate.itemCount())
return;
- this._delegate.selectItem(this._filteredItems[this._selectedIndexInFiltered], this._promptElement.value.trim());
+ var selectedIndex = this._shouldShowMatchingItems() && this._selectedIndexInFiltered < this._filteredItems.length ? this._filteredItems[this._selectedIndexInFiltered] : null;
+ this._delegate.selectItem(selectedIndex, this._promptElement.value.trim());
},
_itemsLoaded: function()
@@ -143,8 +145,7 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
{
var itemElement = document.createElement("div");
itemElement.className = "filtered-item-list-dialog-item " + (this._renderAsTwoRows ? "two-rows" : "one-row");
- itemElement._titleElement = itemElement.createChild("span");
- itemElement._titleSuffixElement = itemElement.createChild("span");
+ itemElement._titleElement = itemElement.createChild("div", "filtered-item-list-dialog-title");
itemElement._subtitleElement = itemElement.createChild("div", "filtered-item-list-dialog-subtitle");
itemElement._subtitleElement.textContent = "\u200B";
itemElement._index = index;
@@ -244,24 +245,40 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
break;
}
}
- this._viewportControl.refresh();
+ this._viewportControl.invalidate();
if (!query)
this._selectedIndexInFiltered = 0;
this._updateSelection(this._selectedIndexInFiltered, false);
}
},
+ /**
+ * @return {boolean}
+ */
+ _shouldShowMatchingItems: function()
+ {
+ return this._delegate.shouldShowMatchingItems(this._promptElement.value);
+ },
+
_onInput: function(event)
{
- this._shouldShowMatchingItems = this._delegate.shouldShowMatchingItems(this._promptElement.value);
this._updateShowMatchingItems();
this._scheduleFilter();
},
_updateShowMatchingItems: function()
{
- this._itemElementsContainer.enableStyleClass("hidden", !this._shouldShowMatchingItems);
- this.element.style.height = this._shouldShowMatchingItems ? this._dialogHeight + "px" : "auto";
+ var shouldShowMatchingItems = this._shouldShowMatchingItems();
+ this._itemElementsContainer.classList.toggle("hidden", !shouldShowMatchingItems);
+ this.element.style.height = shouldShowMatchingItems ? this._dialogHeight + "px" : "auto";
+ },
+
+ /**
+ * @return {number}
+ */
+ _rowsPerViewport: function()
+ {
+ return Math.floor(this._viewportControl.element.clientHeight / this._rowHeight);
},
_onKeyDown: function(event)
@@ -282,12 +299,12 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.PageDown.code:
- newSelectedIndex = Math.min(newSelectedIndex + this._viewportControl.rowsPerViewport(), this._filteredItems.length - 1);
+ newSelectedIndex = Math.min(newSelectedIndex + this._rowsPerViewport(), this._filteredItems.length - 1);
this._updateSelection(newSelectedIndex, true);
event.consume(true);
break;
case WebInspector.KeyboardShortcut.Keys.PageUp.code:
- newSelectedIndex = Math.max(newSelectedIndex - this._viewportControl.rowsPerViewport(), 0);
+ newSelectedIndex = Math.max(newSelectedIndex - this._rowsPerViewport(), 0);
this._updateSelection(newSelectedIndex, false);
event.consume(true);
break;
@@ -303,11 +320,11 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
},
/**
- * @param {number} index
+ * @param {number} index
* @param {boolean} makeLast
*/
_updateSelection: function(index, makeLast)
- {
+ {
var element = this._viewportControl.renderedElementAt(this._selectedIndexInFiltered);
if (element)
element.classList.remove("selected");
@@ -337,7 +354,21 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
/**
* @param {number} index
- * @return {!Element}
+ * @return {number}
+ */
+ fastHeight: function(index)
+ {
+ if (!this._rowHeight) {
+ var delegateIndex = this._filteredItems[index];
+ var element = this._createItemElement(delegateIndex);
+ this._rowHeight = element.measurePreferredSize(this._viewportControl.contentElement()).height;
+ }
+ return this._rowHeight;
+ },
+
+ /**
+ * @param {number} index
+ * @return {!WebInspector.ViewportElement}
*/
itemElement: function(index)
{
@@ -345,7 +376,15 @@ WebInspector.FilteredItemSelectionDialog.prototype = {
var element = this._createItemElement(delegateIndex);
if (index === this._selectedIndexInFiltered)
element.classList.add("selected");
- return element;
+ return new WebInspector.StaticViewportElement(element);
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRowHeight: function()
+ {
+ return this.fastHeight(0);
},
__proto__: WebInspector.DialogDelegate.prototype
@@ -456,7 +495,7 @@ WebInspector.SelectionDialogContentProvider.prototype = {
},
/**
- * @param {number} itemIndex
+ * @param {?number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
@@ -485,53 +524,45 @@ WebInspector.SelectionDialogContentProvider.prototype = {
/**
* @constructor
* @extends {WebInspector.SelectionDialogContentProvider}
- * @param {!WebInspector.View} view
- * @param {!WebInspector.ContentProvider} contentProvider
+ * @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
-WebInspector.JavaScriptOutlineDialog = function(view, contentProvider, selectItemCallback)
+WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback)
{
WebInspector.SelectionDialogContentProvider.call(this);
this._functionItems = [];
- this._view = view;
this._selectItemCallback = selectItemCallback;
- contentProvider.requestContent(this._contentAvailable.bind(this));
+ this._outlineWorker = new Worker("script_formatter_worker/ScriptFormatterWorker.js");
+ this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
+ this._outlineWorker.postMessage({ method: "javaScriptOutline", params: { content: uiSourceCode.workingCopy() } });
}
/**
* @param {!WebInspector.View} view
- * @param {!WebInspector.ContentProvider} contentProvider
+ * @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
-WebInspector.JavaScriptOutlineDialog.show = function(view, contentProvider, selectItemCallback)
+WebInspector.JavaScriptOutlineDialog.show = function(view, uiSourceCode, selectItemCallback)
{
if (WebInspector.Dialog.currentInstance())
- return null;
- var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.JavaScriptOutlineDialog(view, contentProvider, selectItemCallback));
+ return;
+ var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback));
WebInspector.Dialog.show(view.element, filteredItemSelectionDialog);
}
WebInspector.JavaScriptOutlineDialog.prototype = {
/**
- * @param {?string} content
+ * @param {!MessageEvent} event
*/
- _contentAvailable: function(content)
- {
- this._outlineWorker = new Worker("ScriptFormatterWorker.js");
- this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
- const method = "outline";
- this._outlineWorker.postMessage({ method: method, params: { content: content } });
- },
-
_didBuildOutlineChunk: function(event)
{
- var data = event.data;
- var chunk = data["chunk"];
+ var data = /** @type {!WebInspector.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
+ var chunk = data.chunk;
for (var i = 0; i < chunk.length; ++i)
this._functionItems.push(chunk[i]);
- if (data.total === data.index)
+ if (data.total === data.index + 1)
this.dispose();
this.refresh();
@@ -580,11 +611,13 @@ WebInspector.JavaScriptOutlineDialog.prototype = {
},
/**
- * @param {number} itemIndex
+ * @param {?number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
+ if (itemIndex === null)
+ return;
var lineNumber = this._functionItems[itemIndex].line;
if (!isNaN(lineNumber) && lineNumber >= 0)
this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
@@ -610,28 +643,49 @@ WebInspector.SelectUISourceCodeDialog = function(defaultScores)
{
WebInspector.SelectionDialogContentProvider.call(this);
- /** @type {!Array.<!WebInspector.UISourceCode>} */
- this._uiSourceCodes = [];
- var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
- for (var i = 0; i < projects.length; ++i)
- this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
+ this._populate();
this._defaultScores = defaultScores;
this._scorer = new WebInspector.FilePathScoreFunction("");
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
+ WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
}
WebInspector.SelectUISourceCodeDialog.prototype = {
+ _projectRemoved: function(event)
+ {
+ var project = /** @type {!WebInspector.Project} */ (event.data);
+ this._populate(project);
+ this.refresh();
+ },
+
+ /**
+ * @param {!WebInspector.Project=} skipProject
+ */
+ _populate: function(skipProject)
+ {
+ /** @type {!Array.<!WebInspector.UISourceCode>} */
+ this._uiSourceCodes = [];
+ var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
+ for (var i = 0; i < projects.length; ++i) {
+ if (skipProject && projects[i] === skipProject)
+ continue;
+ this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
+ }
+ },
+
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
+ * @param {number=} columnNumber
*/
- uiSourceCodeSelected: function(uiSourceCode, lineNumber)
+ uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
// Overridden by subclasses
},
/**
* @param {!WebInspector.Project} project
+ * @return {boolean}
*/
filterProject: function(project)
{
@@ -682,12 +736,13 @@ WebInspector.SelectUISourceCodeDialog.prototype = {
* @param {string} query
* @param {!Element} titleElement
* @param {!Element} subtitleElement
+ * @return {!Array.<!Element>}
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
query = this.rewriteQuery(query);
var uiSourceCode = this._uiSourceCodes[itemIndex];
- titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumber ? this._queryLineNumber : "");
+ titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || "");
subtitleElement.textContent = uiSourceCode.fullDisplayName().trimEnd(100);
var indexes = [];
@@ -706,20 +761,23 @@ WebInspector.SelectUISourceCodeDialog.prototype = {
},
/**
- * @param {number} itemIndex
+ * @param {?number} itemIndex
* @param {string} promptValue
*/
selectItem: function(itemIndex, promptValue)
{
- if (/^:\d+$/.test(promptValue.trimRight())) {
- var lineNumber = parseInt(promptValue.trimRight().substring(1), 10) - 1;
- if (!isNaN(lineNumber) && lineNumber >= 0)
- this.uiSourceCodeSelected(null, lineNumber);
+ var parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
+ if (!parsedExpression)
return;
- }
- var lineNumberMatch = promptValue.match(/[^:]+\:([\d]*)$/);
- var lineNumber = lineNumberMatch ? Math.max(parseInt(lineNumberMatch[1], 10) - 1, 0) : undefined;
- this.uiSourceCodeSelected(this._uiSourceCodes[itemIndex], lineNumber);
+
+ var lineNumber;
+ var columnNumber;
+ if (parsedExpression[2])
+ lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
+ if (parsedExpression[3])
+ columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
+ var uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
+ this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
},
/**
@@ -731,8 +789,8 @@ WebInspector.SelectUISourceCodeDialog.prototype = {
if (!query)
return query;
query = query.trim();
- var lineNumberMatch = query.match(/([^:]+)(\:[\d]*)$/);
- this._queryLineNumber = lineNumberMatch ? lineNumberMatch[2] : "";
+ var lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
+ this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : "";
return lineNumberMatch ? lineNumberMatch[1] : query;
},
@@ -751,6 +809,7 @@ WebInspector.SelectUISourceCodeDialog.prototype = {
dispose: function()
{
WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
+ WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
},
__proto__: WebInspector.SelectionDialogContentProvider.prototype
@@ -759,13 +818,13 @@ WebInspector.SelectUISourceCodeDialog.prototype = {
/**
* @constructor
* @extends {WebInspector.SelectUISourceCodeDialog}
- * @param {!WebInspector.SourcesPanel} panel
+ * @param {!WebInspector.SourcesView} sourcesView
* @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
*/
-WebInspector.OpenResourceDialog = function(panel, defaultScores)
+WebInspector.OpenResourceDialog = function(sourcesView, defaultScores)
{
WebInspector.SelectUISourceCodeDialog.call(this, defaultScores);
- this._panel = panel;
+ this._sourcesView = sourcesView;
}
WebInspector.OpenResourceDialog.prototype = {
@@ -773,14 +832,15 @@ WebInspector.OpenResourceDialog.prototype = {
/**
* @param {?WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
+ * @param {number=} columnNumber
*/
- uiSourceCodeSelected: function(uiSourceCode, lineNumber)
+ uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
if (!uiSourceCode)
- uiSourceCode = this._panel.currentUISourceCode();
+ uiSourceCode = this._sourcesView.currentUISourceCode();
if (!uiSourceCode)
return;
- this._panel.showUISourceCode(uiSourceCode, lineNumber);
+ this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
},
/**
@@ -794,6 +854,7 @@ WebInspector.OpenResourceDialog.prototype = {
/**
* @param {!WebInspector.Project} project
+ * @return {boolean}
*/
filterProject: function(project)
{
@@ -804,69 +865,77 @@ WebInspector.OpenResourceDialog.prototype = {
}
/**
- * @param {!WebInspector.SourcesPanel} panel
+ * @param {!WebInspector.SourcesView} sourcesView
* @param {!Element} relativeToElement
- * @param {string=} name
+ * @param {string=} query
* @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
*/
-WebInspector.OpenResourceDialog.show = function(panel, relativeToElement, name, defaultScores)
+WebInspector.OpenResourceDialog.show = function(sourcesView, relativeToElement, query, defaultScores)
{
if (WebInspector.Dialog.currentInstance())
return;
- var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.OpenResourceDialog(panel, defaultScores));
+ var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.OpenResourceDialog(sourcesView, defaultScores));
filteredItemSelectionDialog.renderAsTwoRows();
- if (name)
- filteredItemSelectionDialog.setQuery(name);
+ if (query)
+ filteredItemSelectionDialog.setQuery(query);
WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
}
/**
* @constructor
* @extends {WebInspector.SelectUISourceCodeDialog}
- * @param {string} type
+ * @param {!Array.<string>} types
* @param {function(!WebInspector.UISourceCode)} callback
*/
-WebInspector.SelectUISourceCodeForProjectTypeDialog = function(type, callback)
+WebInspector.SelectUISourceCodeForProjectTypesDialog = function(types, callback)
{
- this._type = type;
+ this._types = types;
WebInspector.SelectUISourceCodeDialog.call(this);
this._callback = callback;
}
-WebInspector.SelectUISourceCodeForProjectTypeDialog.prototype = {
+WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {number=} lineNumber
+ * @param {number=} columnNumber
*/
- uiSourceCodeSelected: function(uiSourceCode, lineNumber)
+ uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
{
this._callback(uiSourceCode);
},
/**
* @param {!WebInspector.Project} project
+ * @return {boolean}
*/
filterProject: function(project)
{
- return project.type() === this._type;
+ return this._types.indexOf(project.type()) !== -1;
},
__proto__: WebInspector.SelectUISourceCodeDialog.prototype
}
/**
- * @param {string} type
+ * @param {string} name
+ * @param {!Array.<string>} types
* @param {function(!WebInspector.UISourceCode)} callback
* @param {!Element} relativeToElement
*/
-WebInspector.SelectUISourceCodeForProjectTypeDialog.show = function(name, type, callback, relativeToElement)
+WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback, relativeToElement)
{
if (WebInspector.Dialog.currentInstance())
return;
- var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.SelectUISourceCodeForProjectTypeDialog(type, callback));
+ var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback));
filteredItemSelectionDialog.setQuery(name);
filteredItemSelectionDialog.renderAsTwoRows();
WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
}
+
+/**
+ * @typedef {{index: number, total: number, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
+ */
+WebInspector.JavaScriptOutlineDialog.MessageEventData;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
new file mode 100644
index 00000000000..37d93b3c06e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
@@ -0,0 +1,115 @@
+
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.SourcesView.EditorAction}
+ */
+WebInspector.InplaceFormatterEditorAction = function()
+{
+}
+
+WebInspector.InplaceFormatterEditorAction.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorSelected: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._updateButton(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorClosed: function(event)
+ {
+ var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
+ if (wasSelected)
+ this._updateButton(null);
+ },
+
+ /**
+ * @param {?WebInspector.UISourceCode} uiSourceCode
+ */
+ _updateButton: function(uiSourceCode)
+ {
+ this._button.element.classList.toggle("hidden", !this._isFormattable(uiSourceCode));
+ },
+
+ /**
+ * @param {!WebInspector.SourcesView} sourcesView
+ * @return {!Element}
+ */
+ button: function(sourcesView)
+ {
+ if (this._button)
+ return this._button.element;
+
+ this._sourcesView = sourcesView;
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
+
+ this._button = new WebInspector.StatusBarButton(WebInspector.UIString("Format"), "sources-toggle-pretty-print-status-bar-item");
+ this._button.toggled = false;
+ this._button.addEventListener("click", this._formatSourceInPlace, this);
+ this._updateButton(null);
+
+ return this._button.element;
+ },
+
+ /**
+ * @param {?WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ _isFormattable: function(uiSourceCode)
+ {
+ if (!uiSourceCode)
+ return false;
+ return uiSourceCode.contentType() === WebInspector.resourceTypes.Stylesheet
+ || uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
+ },
+
+ _formatSourceInPlace: function()
+ {
+ var uiSourceCode = this._sourcesView.currentUISourceCode();
+ if (!this._isFormattable(uiSourceCode))
+ return;
+
+ if (uiSourceCode.isDirty())
+ contentLoaded.call(this, uiSourceCode.workingCopy());
+ else
+ uiSourceCode.requestContent(contentLoaded.bind(this));
+
+ /**
+ * @this {WebInspector.InplaceFormatterEditorAction}
+ * @param {?string} content
+ */
+ function contentLoaded(content)
+ {
+ var formatter = WebInspector.Formatter.createFormatter(uiSourceCode.contentType());
+ formatter.formatContent(uiSourceCode.highlighterType(), content || "", innerCallback.bind(this));
+ }
+
+ /**
+ * @this {WebInspector.InplaceFormatterEditorAction}
+ * @param {string} formattedContent
+ * @param {!WebInspector.FormatterSourceMapping} formatterMapping
+ */
+ function innerCallback(formattedContent, formatterMapping)
+ {
+ if (uiSourceCode.workingCopy() === formattedContent)
+ return;
+ var sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
+ var start = [0, 0];
+ if (sourceFrame) {
+ var selection = sourceFrame.selection();
+ start = formatterMapping.originalToFormatted(selection.startLine, selection.startColumn);
+ }
+ uiSourceCode.setWorkingCopy(formattedContent);
+ this._sourcesView.showSourceLocation(uiSourceCode, start[0], start[1]);
+ }
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptSourceFrame.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 60029814821..f2331b8913c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/JavaScriptSourceFrame.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -51,10 +51,6 @@ WebInspector.JavaScriptSourceFrame = function(scriptsPanel, uiSourceCode)
this.textEditor.addEventListener(WebInspector.TextEditor.Events.GutterClick, this._handleGutterClick.bind(this), this);
- this.textEditor.element.addEventListener("mousedown", this._onMouseDownAndClick.bind(this, true), true);
- this.textEditor.element.addEventListener("click", this._onMouseDownAndClick.bind(this, false), true);
-
-
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
this._breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, this._breakpointRemoved, this);
@@ -65,14 +61,127 @@ WebInspector.JavaScriptSourceFrame = function(scriptsPanel, uiSourceCode)
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
+ /** @type {!Map.<!WebInspector.Target, !WebInspector.ScriptFile>}*/
+ this._scriptFileForTarget = new Map();
this._registerShortcuts();
- this._updateScriptFile();
+ var targets = WebInspector.targetManager.targets();
+ for (var i = 0; i < targets.length; ++i) {
+ var scriptFile = uiSourceCode.scriptFileForTarget(targets[i]);
+ if (scriptFile)
+ this._updateScriptFile(targets[i]);
+ }
}
WebInspector.JavaScriptSourceFrame.prototype = {
+ /**
+ * @param {!Element} infobarElement
+ */
+ _showInfobar: function(infobarElement)
+ {
+ if (this._infobarElement)
+ this._infobarElement.remove();
+ this._infobarElement = infobarElement;
+ this._infobarElement.classList.add("java-script-source-frame-infobar");
+ this.element.insertBefore(this._infobarElement, this.element.children[0]);
+ this.doResize();
+ },
+
+ /**
+ * @param {!Element} infobarElement
+ */
+ _hideInfobar: function(infobarElement)
+ {
+ infobarElement.remove();
+ this.doResize();
+ },
+
+ _showDivergedInfobar: function()
+ {
+ if (this._uiSourceCode.contentType() !== WebInspector.resourceTypes.Script)
+ return;
+
+ this._divergedInfobarElement = document.createElement("div");
+ var infobarMainRow = this._divergedInfobarElement.createChild("div", "java-script-source-frame-infobar-main-row");
+ var infobarDetailsContainer = this._divergedInfobarElement.createChild("span", "java-script-source-frame-infobar-details-container");
+
+ infobarMainRow.createChild("span", "java-script-source-frame-infobar-warning-icon");
+ var infobarMessage = infobarMainRow.createChild("span", "java-script-source-frame-infobar-row-message");
+ infobarMessage.textContent = WebInspector.UIString("Workspace mapping mismatch");
+
+ /**
+ * @this {WebInspector.JavaScriptSourceFrame}
+ */
+ function updateDetailsVisibility()
+ {
+ detailsToggleElement.textContent = detailsToggleElement._toggled ? WebInspector.UIString("less") : WebInspector.UIString("more");
+ infobarDetailsContainer.classList.toggle("hidden", !detailsToggleElement._toggled);
+ this.doResize();
+ }
+
+ /**
+ * @this {WebInspector.JavaScriptSourceFrame}
+ */
+ function toggleDetails()
+ {
+ detailsToggleElement._toggled = !detailsToggleElement._toggled;
+ updateDetailsVisibility.call(this);
+ }
+
+ infobarMainRow.appendChild(document.createTextNode("\u00a0"));
+ var detailsToggleElement = infobarMainRow.createChild("div", "java-script-source-frame-infobar-toggle");
+ detailsToggleElement.addEventListener("click", toggleDetails.bind(this), false);
+ updateDetailsVisibility.call(this);
+
+ function createDetailsRowMessage()
+ {
+ var infobarDetailsRow = infobarDetailsContainer.createChild("div", "java-script-source-frame-infobar-details-row");
+ return infobarDetailsRow.createChild("span", "java-script-source-frame-infobar-row-message");
+ }
+
+ var infobarDetailsRowMessage;
+
+ infobarDetailsRowMessage = createDetailsRowMessage();
+ infobarDetailsRowMessage.appendChild(document.createTextNode(WebInspector.UIString("The content of this file on the file system:\u00a0")));
+ var fileURL = this._uiSourceCode.originURL();
+ infobarDetailsRowMessage.appendChild(WebInspector.linkifyURLAsNode(fileURL, fileURL, "java-script-source-frame-infobar-details-url", true, fileURL));
+
+ infobarDetailsRowMessage = createDetailsRowMessage();
+ infobarDetailsRowMessage.appendChild(document.createTextNode(WebInspector.UIString("does not match the loaded script:\u00a0")));
+ var scriptURL = this._uiSourceCode.url;
+ infobarDetailsRowMessage.appendChild(WebInspector.linkifyURLAsNode(scriptURL, scriptURL, "java-script-source-frame-infobar-details-url", true, scriptURL));
+
+ // Add an empty row
+ createDetailsRowMessage();
+
+ createDetailsRowMessage().textContent = WebInspector.UIString("Possible solutions are:");;
+
+ function createDetailsRowMessageAction(title)
+ {
+ infobarDetailsRowMessage = createDetailsRowMessage();
+ infobarDetailsRowMessage.appendChild(document.createTextNode(" - "));
+ infobarDetailsRowMessage.appendChild(document.createTextNode(title));
+ }
+
+ if (WebInspector.settings.cacheDisabled.get())
+ createDetailsRowMessageAction(WebInspector.UIString("Reload inspected page"));
+ else
+ createDetailsRowMessageAction(WebInspector.UIString("Check \"Disable cache\" in settings and reload inspected page (recommended setup for authoring and debugging)"));
+ createDetailsRowMessageAction(WebInspector.UIString("Check that your file and script are both loaded from the correct source and their contents match."));
+
+ this._showInfobar(this._divergedInfobarElement);
+ },
+
+ _hideDivergedInfobar: function()
+ {
+ if (!this._divergedInfobarElement)
+ return;
+ this._hideInfobar(this._divergedInfobarElement);
+ delete this._divergedInfobarElement;
+ },
+
_registerShortcuts: function()
{
- var shortcutKeys = WebInspector.SourcesPanelDescriptor.ShortcutKeys;
+ var shortcutKeys = WebInspector.ShortcutsScreen.SourcesPanelShortcuts;
for (var i = 0; i < shortcutKeys.EvaluateSelectionInConsole.length; ++i) {
var keyDescriptor = shortcutKeys.EvaluateSelectionInConsole[i];
this.addShortcut(keyDescriptor.key, this._evaluateSelectionInConsole.bind(this));
@@ -106,10 +215,20 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var selection = this.textEditor.selection();
if (!selection || selection.isEmpty())
return false;
- WebInspector.evaluateInConsole(this.textEditor.copyRange(selection));
+ this._evaluateInConsole(this.textEditor.copyRange(selection));
return true;
},
+ /**
+ * @param {string} expression
+ */
+ _evaluateInConsole: function(expression)
+ {
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (currentExecutionContext)
+ WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, expression);
+ },
+
// View events
wasShown: function()
{
@@ -131,11 +250,10 @@ WebInspector.JavaScriptSourceFrame.prototype = {
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Continue to here" : "Continue to Here"), this._continueToLine.bind(this, lineNumber));
-
- var breakpoint = this._breakpointManager.findBreakpoint(this._uiSourceCode, lineNumber);
+ var breakpoint = this._breakpointManager.findBreakpointOnLine(this._uiSourceCode, lineNumber);
if (!breakpoint) {
// This row doesn't have a breakpoint: We want to show Add Breakpoint and Add and Edit Breakpoint.
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, "", true));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add breakpoint" : "Add Breakpoint"), this._setBreakpoint.bind(this, lineNumber, 0, "", true));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add conditional breakpoint…" : "Add Conditional Breakpoint…"), this._editBreakpointCondition.bind(this, lineNumber));
} else {
// This row has a breakpoint, we want to show edit and remove breakpoint, and either disable or enable.
@@ -156,10 +274,9 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var addToWatchLabel = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add to watch" : "Add to Watch");
contextMenu.appendItem(addToWatchLabel, this._innerAddToWatch.bind(this, selection));
var evaluateLabel = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Evaluate in console" : "Evaluate in Console");
- contextMenu.appendItem(evaluateLabel, WebInspector.evaluateInConsole.bind(WebInspector, selection));
+ contextMenu.appendItem(evaluateLabel, this._evaluateInConsole.bind(this, selection));
contextMenu.appendSeparator();
- } else if (!this._uiSourceCode.isEditable() && this._uiSourceCode.contentType() === WebInspector.resourceTypes.Script) {
-
+ } else if (this._uiSourceCode.project().type() === WebInspector.projectTypes.Debugger) {
// FIXME: Change condition above to explicitly check that current uiSourceCode is created by default debugger mapping
// and move the code adding this menu item to generic context menu provider for UISourceCode.
var liveEditLabel = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Live edit" : "Live Edit");
@@ -173,7 +290,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
function liveEdit()
{
var liveEditUISourceCode = WebInspector.liveEditSupport.uiSourceCodeForLiveEdit(this._uiSourceCode);
- this._scriptsPanel.showUISourceCode(liveEditUISourceCode, lineNumber)
+ WebInspector.Revealer.reveal(liveEditUISourceCode.uiLocation(lineNumber));
}
WebInspector.UISourceCodeFrame.prototype.populateTextAreaContextMenu.call(this, contextMenu, lineNumber);
@@ -181,7 +298,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
_workingCopyChanged: function(event)
{
- if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFile)
+ if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFileForTarget.size())
return;
if (this._uiSourceCode.isDirty())
@@ -192,8 +309,15 @@ WebInspector.JavaScriptSourceFrame.prototype = {
_workingCopyCommitted: function(event)
{
- if (this._supportsEnabledBreakpointsWhileEditing() || this._scriptFile)
+ if (this._supportsEnabledBreakpointsWhileEditing())
+ return;
+ if (this._scriptFileForTarget.size()) {
+ this._hasCommittedLiveEdit = true;
+ var scriptFiles = this._scriptFileForTarget.values();
+ for (var i = 0; i < scriptFiles.length; ++i)
+ scriptFiles[i].commitLiveEdit();
return;
+ }
this._restoreBreakpointsAfterEditing();
},
@@ -201,13 +325,15 @@ WebInspector.JavaScriptSourceFrame.prototype = {
{
if (this._supportsEnabledBreakpointsWhileEditing())
return;
- this._restoreBreakpointsAfterEditing();
+ this._updateDivergedInfobar();
+ this._restoreBreakpointsIfConsistentScripts();
},
_didDivergeFromVM: function()
{
if (this._supportsEnabledBreakpointsWhileEditing())
return;
+ this._updateDivergedInfobar();
this._muteBreakpointsWhileEditing();
},
@@ -220,16 +346,47 @@ WebInspector.JavaScriptSourceFrame.prototype = {
if (!breakpointDecoration)
continue;
this._removeBreakpointDecoration(lineNumber);
- this._addBreakpointDecoration(lineNumber, breakpointDecoration.condition, breakpointDecoration.enabled, true);
+ this._addBreakpointDecoration(lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled, true);
}
this._muted = true;
},
+ _updateDivergedInfobar: function()
+ {
+ if (this._uiSourceCode.project().type() !== WebInspector.projectTypes.FileSystem) {
+ this._hideDivergedInfobar();
+ return;
+ }
+
+ var scriptFiles = this._scriptFileForTarget.values();
+ var hasDivergedScript = false;
+ for (var i = 0; i < scriptFiles.length; ++i)
+ hasDivergedScript = hasDivergedScript || scriptFiles[i].hasDivergedFromVM();
+
+ if (this._divergedInfobarElement) {
+ if (!hasDivergedScript || this._hasCommittedLiveEdit)
+ this._hideDivergedInfobar();
+ } else {
+ if (hasDivergedScript && !this._uiSourceCode.isDirty() && !this._hasCommittedLiveEdit)
+ this._showDivergedInfobar();
+ }
+ },
+
_supportsEnabledBreakpointsWhileEditing: function()
{
return this._uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
},
+ _restoreBreakpointsIfConsistentScripts: function()
+ {
+ var scriptFiles = this._scriptFileForTarget.values();
+ for (var i = 0; i < scriptFiles.length; ++i)
+ if (scriptFiles[i].hasDivergedFromVM() || scriptFiles[i].isMergingToVM())
+ return;
+
+ this._restoreBreakpointsAfterEditing();
+ },
+
_restoreBreakpointsAfterEditing: function()
{
delete this._muted;
@@ -252,7 +409,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
if (isNaN(lineNumber))
continue;
var breakpointDecoration = breakpoints[lineNumberString];
- this._setBreakpoint(lineNumber, breakpointDecoration.condition, breakpointDecoration.enabled);
+ this._setBreakpoint(lineNumber, breakpointDecoration.columnNumber, breakpointDecoration.condition, breakpointDecoration.enabled);
}
},
@@ -296,7 +453,9 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var lineNumber = textPosition.startLine;
var line = this.textEditor.line(lineNumber);
var tokenContent = line.substring(token.startColumn, token.endColumn + 1);
- if (token.type !== "javascript-ident" && (token.type !== "javascript-keyword" || tokenContent !== "this"))
+
+ var isIdentifier = token.type.startsWith("js-variable") || token.type.startsWith("js-property") || token.type == "js-def";
+ if (!isIdentifier && (token.type !== "js-keyword" || tokenContent !== "this"))
return null;
var leftCorner = this.textEditor.cursorPositionToCoordinates(lineNumber, token.startColumn);
@@ -314,26 +473,6 @@ WebInspector.JavaScriptSourceFrame.prototype = {
_resolveObjectForPopover: function(anchorBox, showCallback, objectGroupName)
{
- /**
- * @param {?RuntimeAgent.RemoteObject} result
- * @param {boolean=} wasThrown
- * @this {WebInspector.JavaScriptSourceFrame}
- */
- function showObjectPopover(result, wasThrown)
- {
- if (!WebInspector.debuggerModel.isPaused() || !result) {
- this._popoverHelper.hidePopover();
- return;
- }
- this._popoverAnchorBox = anchorBox;
- showCallback(WebInspector.RemoteObject.fromPayload(result), wasThrown, this._popoverAnchorBox);
- // Popover may have been removed by showCallback().
- if (this._popoverAnchorBox) {
- var highlightRange = new WebInspector.TextRange(lineNumber, startHighlight, lineNumber, endHighlight);
- this._popoverAnchorBox._highlightDescriptor = this.textEditor.highlightRange(highlightRange, "source-frame-eval-expression");
- }
- }
-
if (!WebInspector.debuggerModel.isPaused()) {
this._popoverHelper.hidePopover();
return;
@@ -355,6 +494,26 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var evaluationText = line.substring(startHighlight, endHighlight + 1);
var selectedCallFrame = WebInspector.debuggerModel.selectedCallFrame();
selectedCallFrame.evaluate(evaluationText, objectGroupName, false, true, false, false, showObjectPopover.bind(this));
+
+ /**
+ * @param {?RuntimeAgent.RemoteObject} result
+ * @param {boolean=} wasThrown
+ * @this {WebInspector.JavaScriptSourceFrame}
+ */
+ function showObjectPopover(result, wasThrown)
+ {
+ if (!WebInspector.debuggerModel.isPaused() || !result) {
+ this._popoverHelper.hidePopover();
+ return;
+ }
+ this._popoverAnchorBox = anchorBox;
+ showCallback(selectedCallFrame.target().runtimeModel.createRemoteObject(result), wasThrown, this._popoverAnchorBox);
+ // Popover may have been removed by showCallback().
+ if (this._popoverAnchorBox) {
+ var highlightRange = new WebInspector.TextRange(lineNumber, startHighlight, lineNumber, endHighlight);
+ this._popoverAnchorBox._highlightDescriptor = this.textEditor.highlightRange(highlightRange, "source-frame-eval-expression");
+ }
+ }
},
_onHidePopover: function()
@@ -368,15 +527,17 @@ WebInspector.JavaScriptSourceFrame.prototype = {
/**
* @param {number} lineNumber
+ * @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
* @param {boolean} mutedWhileEditing
*/
- _addBreakpointDecoration: function(lineNumber, condition, enabled, mutedWhileEditing)
+ _addBreakpointDecoration: function(lineNumber, columnNumber, condition, enabled, mutedWhileEditing)
{
var breakpoint = {
condition: condition,
- enabled: enabled
+ enabled: enabled,
+ columnNumber: columnNumber
};
this.textEditor.setAttribute(lineNumber, "breakpoint", breakpoint);
@@ -397,12 +558,6 @@ WebInspector.JavaScriptSourceFrame.prototype = {
if (this._popoverHelper.isPopoverVisible()) {
this._popoverHelper.hidePopover();
event.consume();
- return;
- }
- if (this._stepIntoMarkup && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
- this._stepIntoMarkup.stoptIteratingSelection();
- event.consume();
- return;
}
}
},
@@ -430,11 +585,11 @@ WebInspector.JavaScriptSourceFrame.prototype = {
if (breakpoint)
breakpoint.setCondition(newText);
else
- this._setBreakpoint(lineNumber, newText, true);
+ this._setBreakpoint(lineNumber, 0, newText, true);
}
- var config = new WebInspector.EditingConfig(finishEditing.bind(this, true), finishEditing.bind(this, false));
- WebInspector.startEditing(this._conditionEditorElement, config);
+ var config = new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false));
+ WebInspector.InplaceEditor.startEditing(this._conditionEditorElement, config);
this._conditionEditorElement.value = breakpoint ? breakpoint.condition() : "";
this._conditionEditorElement.select();
},
@@ -447,7 +602,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var labelElement = document.createElement("label");
labelElement.className = "source-frame-breakpoint-message";
labelElement.htmlFor = "source-frame-breakpoint-condition";
- labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber)));
+ labelElement.appendChild(document.createTextNode(WebInspector.UIString("The breakpoint on line %d will stop only if this expression is true:", lineNumber + 1)));
conditionElement.appendChild(labelElement);
var editorElement = document.createElement("input");
@@ -462,83 +617,19 @@ WebInspector.JavaScriptSourceFrame.prototype = {
/**
* @param {number} lineNumber
- * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
*/
- setExecutionLine: function(lineNumber, callFrame)
+ setExecutionLine: function(lineNumber)
{
this._executionLineNumber = lineNumber;
- this._executionCallFrame = callFrame;
- if (this.loaded) {
+ if (this.loaded)
this.textEditor.setExecutionLine(lineNumber);
-
- if (WebInspector.experimentsSettings.stepIntoSelection.isEnabled())
- callFrame.getStepIntoLocations(locationsCallback.bind(this));
- }
-
- /**
- * @param {!Array.<!DebuggerAgent.Location>} locations
- * @this {WebInspector.JavaScriptSourceFrame}
- */
- function locationsCallback(locations)
- {
- if (this._executionCallFrame !== callFrame || this._stepIntoMarkup)
- return;
- this._stepIntoMarkup = WebInspector.JavaScriptSourceFrame.StepIntoMarkup.create(this, locations);
- if (this._stepIntoMarkup)
- this._stepIntoMarkup.show();
- }
},
clearExecutionLine: function()
{
- if (this._stepIntoMarkup) {
- this._stepIntoMarkup.dispose();
- delete this._stepIntoMarkup;
- }
-
if (this.loaded && typeof this._executionLineNumber === "number")
this.textEditor.clearExecutionLine();
delete this._executionLineNumber;
- delete this._executionCallFrame;
- },
-
- _lineNumberAfterEditing: function(lineNumber, oldRange, newRange)
- {
- var shiftOffset = lineNumber <= oldRange.startLine ? 0 : newRange.linesCount - oldRange.linesCount;
-
- // Special case of editing the line itself. We should decide whether the line number should move below or not.
- if (lineNumber === oldRange.startLine) {
- var whiteSpacesRegex = /^[\s\xA0]*$/;
- for (var i = 0; lineNumber + i <= newRange.endLine; ++i) {
- if (!whiteSpacesRegex.test(this.textEditor.line(lineNumber + i))) {
- shiftOffset = i;
- break;
- }
- }
- }
-
- var newLineNumber = Math.max(0, lineNumber + shiftOffset);
- if (oldRange.startLine < lineNumber && lineNumber < oldRange.endLine)
- newLineNumber = oldRange.startLine;
- return newLineNumber;
- },
-
- _onMouseDownAndClick: function(isMouseDown, event)
- {
- var markup = this._stepIntoMarkup;
- if (!markup)
- return;
- var index = markup.findItemByCoordinates(event.x, event.y);
- if (typeof index === "undefined")
- return;
-
- if (isMouseDown) {
- // Do not let text editor to spoil 'click' event that is coming for us.
- event.consume();
- } else {
- var rawLocation = markup.getRawPosition(index);
- this._scriptsPanel.doStepIntoSelection(rawLocation);
- }
},
/**
@@ -550,7 +641,12 @@ WebInspector.JavaScriptSourceFrame.prototype = {
return false;
if (this._muted)
return true;
- return this._scriptFile && (this._scriptFile.isDivergingFromVM() || this._scriptFile.isMergingToVM());
+ var scriptFiles = this._scriptFileForTarget.values();
+ var hasDivergingOrMergingFile = false;
+ for (var i = 0; i < scriptFiles.length; ++i)
+ if (scriptFiles[i].isDivergingFromVM() || scriptFiles[i].isMergingToVM())
+ return true;
+ return false;
},
_breakpointAdded: function(event)
@@ -563,7 +659,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
if (this.loaded)
- this._addBreakpointDecoration(uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled(), false);
+ this._addBreakpointDecoration(uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled(), false);
},
_breakpointRemoved: function(event)
@@ -575,7 +671,7 @@ WebInspector.JavaScriptSourceFrame.prototype = {
return;
var breakpoint = /** @type {!WebInspector.BreakpointManager.Breakpoint} */ (event.data.breakpoint);
- var remainingBreakpoint = this._breakpointManager.findBreakpoint(this._uiSourceCode, uiLocation.lineNumber);
+ var remainingBreakpoint = this._breakpointManager.findBreakpointOnLine(this._uiSourceCode, uiLocation.lineNumber);
if (!remainingBreakpoint && this.loaded)
this._removeBreakpointDecoration(uiLocation.lineNumber);
},
@@ -604,31 +700,42 @@ WebInspector.JavaScriptSourceFrame.prototype = {
*/
_onSourceMappingChanged: function(event)
{
- this._updateScriptFile();
+ var data = /** @type {{target: !WebInspector.Target}} */ (event.data);
+ this._updateScriptFile(data.target);
},
- _updateScriptFile: function()
- {
- if (this._scriptFile) {
- this._scriptFile.removeEventListener(WebInspector.ScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
- this._scriptFile.removeEventListener(WebInspector.ScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ _updateScriptFile: function(target)
+ {
+ var oldScriptFile = this._scriptFileForTarget.get(target);
+ var newScriptFile = this._uiSourceCode.scriptFileForTarget(target);
+ this._scriptFileForTarget.remove(target);
+ if (oldScriptFile) {
+ oldScriptFile.removeEventListener(WebInspector.ScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
+ oldScriptFile.removeEventListener(WebInspector.ScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
if (this._muted && !this._uiSourceCode.isDirty())
- this._restoreBreakpointsAfterEditing();
+ this._restoreBreakpointsIfConsistentScripts();
}
- this._scriptFile = this._uiSourceCode.scriptFile();
- if (this._scriptFile) {
- this._scriptFile.addEventListener(WebInspector.ScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
- this._scriptFile.addEventListener(WebInspector.ScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
+ if (newScriptFile)
+ this._scriptFileForTarget.put(target, newScriptFile);
+
+ delete this._hasCommittedLiveEdit;
+ this._updateDivergedInfobar();
+ if (newScriptFile) {
+ newScriptFile.addEventListener(WebInspector.ScriptFile.Events.DidMergeToVM, this._didMergeToVM, this);
+ newScriptFile.addEventListener(WebInspector.ScriptFile.Events.DidDivergeFromVM, this._didDivergeFromVM, this);
if (this.loaded)
- this._scriptFile.checkMapping();
+ newScriptFile.checkMapping();
}
},
onTextEditorContentLoaded: function()
{
if (typeof this._executionLineNumber === "number")
- this.setExecutionLine(this._executionLineNumber, this._executionCallFrame);
+ this.setExecutionLine(this._executionLineNumber);
var breakpointLocations = this._breakpointManager.breakpointLocationsForUISourceCode(this._uiSourceCode);
for (var i = 0; i < breakpointLocations.length; ++i)
@@ -640,8 +747,9 @@ WebInspector.JavaScriptSourceFrame.prototype = {
this.addMessageToSource(message.lineNumber, message.originalMessage);
}
- if (this._scriptFile)
- this._scriptFile.checkMapping();
+ var scriptFiles = this._scriptFileForTarget.values();
+ for (var i = 0; i < scriptFiles.length; ++i)
+ scriptFiles[i].checkMapping();
},
/**
@@ -669,14 +777,14 @@ WebInspector.JavaScriptSourceFrame.prototype = {
*/
_toggleBreakpoint: function(lineNumber, onlyDisable)
{
- var breakpoint = this._breakpointManager.findBreakpoint(this._uiSourceCode, lineNumber);
+ var breakpoint = this._breakpointManager.findBreakpointOnLine(this._uiSourceCode, lineNumber);
if (breakpoint) {
if (onlyDisable)
breakpoint.setEnabled(!breakpoint.enabled());
else
breakpoint.remove();
} else
- this._setBreakpoint(lineNumber, "", true);
+ this._setBreakpoint(lineNumber, 0, "", true);
},
toggleBreakpointOnCurrentLine: function()
@@ -692,12 +800,13 @@ WebInspector.JavaScriptSourceFrame.prototype = {
/**
* @param {number} lineNumber
+ * @param {number} columnNumber
* @param {string} condition
* @param {boolean} enabled
*/
- _setBreakpoint: function(lineNumber, condition, enabled)
+ _setBreakpoint: function(lineNumber, columnNumber, condition, enabled)
{
- this._breakpointManager.setBreakpoint(this._uiSourceCode, lineNumber, condition, enabled);
+ this._breakpointManager.setBreakpoint(this._uiSourceCode, lineNumber, columnNumber, condition, enabled);
WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.SetBreakpoint,
@@ -712,18 +821,13 @@ WebInspector.JavaScriptSourceFrame.prototype = {
*/
_continueToLine: function(lineNumber)
{
- var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (this._uiSourceCode.uiLocationToRawLocation(lineNumber, 0));
+ var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (!executionContext)
+ return;
+ var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (this._uiSourceCode.uiLocationToRawLocation(executionContext.target(), lineNumber, 0));
this._scriptsPanel.continueToLocation(rawLocation);
},
- /**
- * @return {!WebInspector.JavaScriptSourceFrame.StepIntoMarkup|undefined}
- */
- stepIntoMarkup: function()
- {
- return this._stepIntoMarkup;
- },
-
dispose: function()
{
this._breakpointManager.removeEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this);
@@ -739,199 +843,3 @@ WebInspector.JavaScriptSourceFrame.prototype = {
__proto__: WebInspector.UISourceCodeFrame.prototype
}
-
-/**
- * @constructor
- * @param {!Array.<!DebuggerAgent.Location>} rawPositions
- * @param {!Array.<!WebInspector.TextRange>} editorRanges
- * @param {number} firstToExecute
- * @param {!WebInspector.JavaScriptSourceFrame} sourceFrame
- */
-WebInspector.JavaScriptSourceFrame.StepIntoMarkup = function(rawPositions, editorRanges, firstToExecute, sourceFrame)
-{
- this._positions = rawPositions;
- this._editorRanges = editorRanges;
- this._highlightDescriptors = new Array(rawPositions.length);
- this._currentHighlight = undefined;
- this._firstToExecute = firstToExecute;
- this._currentSelection = undefined;
- this._sourceFrame = sourceFrame;
-};
-
-WebInspector.JavaScriptSourceFrame.StepIntoMarkup.prototype = {
- show: function()
- {
- var highlight = this._getVisibleHighlight();
- for (var i = 0; i < this._positions.length; ++i)
- this._highlightItem(i, i === highlight);
- this._shownVisibleHighlight = highlight;
- },
-
- startIteratingSelection: function()
- {
- this._currentSelection = this._positions.length
- this._redrawHighlight();
- },
-
- stopIteratingSelection: function()
- {
- this._currentSelection = undefined;
- this._redrawHighlight();
- },
-
- /**
- * @param {boolean} backward
- */
- iterateSelection: function(backward)
- {
- if (typeof this._currentSelection === "undefined")
- return;
- var nextSelection = backward ? this._currentSelection - 1 : this._currentSelection + 1;
- var modulo = this._positions.length + 1;
- nextSelection = (nextSelection + modulo) % modulo;
- this._currentSelection = nextSelection;
- this._redrawHighlight();
- },
-
- _redrawHighlight: function()
- {
- var visibleHighlight = this._getVisibleHighlight();
- if (this._shownVisibleHighlight === visibleHighlight)
- return;
- this._hideItemHighlight(this._shownVisibleHighlight);
- this._hideItemHighlight(visibleHighlight);
- this._highlightItem(this._shownVisibleHighlight, false);
- this._highlightItem(visibleHighlight, true);
- this._shownVisibleHighlight = visibleHighlight;
- },
-
- /**
- * @return {number}
- */
- _getVisibleHighlight: function()
- {
- return typeof this._currentSelection === "undefined" ? this._firstToExecute : this._currentSelection;
- },
-
- /**
- * @param {number} position
- * @param {boolean} selected
- */
- _highlightItem: function(position, selected)
- {
- if (position === this._positions.length)
- return;
- var styleName = selected ? "source-frame-stepin-mark-highlighted" : "source-frame-stepin-mark";
- var textEditor = this._sourceFrame.textEditor;
- var highlightDescriptor = textEditor.highlightRange(this._editorRanges[position], styleName);
- this._highlightDescriptors[position] = highlightDescriptor;
- },
-
- /**
- * @param {number} position
- */
- _hideItemHighlight: function(position)
- {
- if (position === this._positions.length)
- return;
- var highlightDescriptor = this._highlightDescriptors[position];
- console.assert(highlightDescriptor);
- var textEditor = this._sourceFrame.textEditor;
- textEditor.removeHighlight(highlightDescriptor);
- this._highlightDescriptors[position] = undefined;
- },
-
- dispose: function()
- {
- for (var i = 0; i < this._positions.length; ++i)
- this._hideItemHighlight(i);
- },
-
- /**
- * @param {number} x
- * @param {number} y
- * @return {number|undefined}
- */
- findItemByCoordinates: function(x, y)
- {
- var textPosition = this._sourceFrame.textEditor.coordinatesToCursorPosition(x, y);
- if (!textPosition)
- return;
-
- var ranges = this._editorRanges;
-
- for (var i = 0; i < ranges.length; ++i) {
- var nextRange = ranges[i];
- if (nextRange.startLine == textPosition.startLine && nextRange.startColumn <= textPosition.startColumn && nextRange.endColumn >= textPosition.startColumn)
- return i;
- }
- },
-
- /**
- * @return {number|undefined}
- */
- getSelectedItemIndex: function()
- {
- if (this._currentSelection === this._positions.length)
- return undefined;
- return this._currentSelection;
- },
-
- /**
- * @return {!WebInspector.DebuggerModel.Location}
- */
- getRawPosition: function(position)
- {
- return /** @type {!WebInspector.DebuggerModel.Location} */ (this._positions[position]);
- }
-
-};
-
-/**
- * @param {!WebInspector.JavaScriptSourceFrame} sourceFrame
- * @param {!Array.<!DebuggerAgent.Location>} stepIntoRawLocations
- * @return {?WebInspector.JavaScriptSourceFrame.StepIntoMarkup}
- */
-WebInspector.JavaScriptSourceFrame.StepIntoMarkup.create = function(sourceFrame, stepIntoRawLocations)
-{
- if (!stepIntoRawLocations.length)
- return null;
-
- var firstToExecute = stepIntoRawLocations[0];
- stepIntoRawLocations.sort(WebInspector.JavaScriptSourceFrame.StepIntoMarkup._Comparator);
- var firstToExecuteIndex = stepIntoRawLocations.indexOf(firstToExecute);
-
- var textEditor = sourceFrame.textEditor;
- var uiRanges = [];
- for (var i = 0; i < stepIntoRawLocations.length; ++i) {
- var uiLocation = WebInspector.debuggerModel.rawLocationToUILocation(/** @type {!WebInspector.DebuggerModel.Location} */ (stepIntoRawLocations[i]));
-
- var token = textEditor.tokenAtTextPosition(uiLocation.lineNumber, uiLocation.columnNumber);
- var startColumn;
- var endColumn;
- if (token) {
- startColumn = token.startColumn;
- endColumn = token.endColumn;
- } else {
- startColumn = uiLocation.columnNumber;
- endColumn = uiLocation.columnNumber;
- }
- var range = new WebInspector.TextRange(uiLocation.lineNumber, startColumn, uiLocation.lineNumber, endColumn);
- uiRanges.push(range);
- }
-
- return new WebInspector.JavaScriptSourceFrame.StepIntoMarkup(stepIntoRawLocations, uiRanges, firstToExecuteIndex, sourceFrame);
-};
-
-/**
- * @param {!DebuggerAgent.Location} locationA
- * @param {!DebuggerAgent.Location} locationB
- * @return {number}
- */
-WebInspector.JavaScriptSourceFrame.StepIntoMarkup._Comparator = function(locationA, locationB)
-{
- if (locationA.lineNumber === locationB.lineNumber)
- return locationA.columnNumber - locationB.columnNumber;
- else
- return locationA.lineNumber - locationB.lineNumber;
-};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NavigatorView.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
index aeff0781202..9ff239d3b5f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NavigatorView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -27,24 +27,22 @@
*/
/**
- * @extends {WebInspector.View}
* @constructor
+ * @extends {WebInspector.VBox}
*/
WebInspector.NavigatorView = function()
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("navigatorView.css");
var scriptsTreeElement = document.createElement("ol");
this._scriptsTree = new WebInspector.NavigatorTreeOutline(scriptsTreeElement);
- this._scriptsTree.childrenListElement.addEventListener("keypress", this._treeKeyPress.bind(this), true);
var scriptsOutlineElement = document.createElement("div");
scriptsOutlineElement.classList.add("outline-disclosure");
scriptsOutlineElement.classList.add("navigator");
scriptsOutlineElement.appendChild(scriptsTreeElement);
- this.element.classList.add("fill");
this.element.classList.add("navigator-container");
this.element.appendChild(scriptsOutlineElement);
this.setDefaultFocusedElement(this._scriptsTree.element);
@@ -57,17 +55,18 @@ WebInspector.NavigatorView = function()
this._rootNode = new WebInspector.NavigatorRootTreeNode(this);
this._rootNode.populate();
- WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
this.element.addEventListener("contextmenu", this.handleContextMenu.bind(this), false);
}
WebInspector.NavigatorView.Events = {
ItemSelected: "ItemSelected",
- ItemSearchStarted: "ItemSearchStarted",
- ItemRenamingRequested: "ItemRenamingRequested",
- ItemCreationRequested: "ItemCreationRequested"
+ ItemRenamed: "ItemRenamed",
}
+/**
+ * @param {string} type
+ * @return {string}
+ */
WebInspector.NavigatorView.iconClassForType = function(type)
{
if (type === WebInspector.NavigatorTreeOutline.Types.Domain)
@@ -78,31 +77,72 @@ WebInspector.NavigatorView.iconClassForType = function(type)
}
WebInspector.NavigatorView.prototype = {
+ setWorkspace: function(workspace)
+ {
+ this._workspace = workspace;
+ this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
+ },
+
+ wasShown: function()
+ {
+ if (this._loaded)
+ return;
+ this._loaded = true;
+ this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ accept: function(uiSourceCode)
+ {
+ return !uiSourceCode.project().isServiceProject();
+ },
+
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
- addUISourceCode: function(uiSourceCode)
+ _addUISourceCode: function(uiSourceCode)
{
+ if (!this.accept(uiSourceCode))
+ return;
var projectNode = this._projectNode(uiSourceCode.project());
var folderNode = this._folderNode(projectNode, uiSourceCode.parentPath());
var uiSourceCodeNode = new WebInspector.NavigatorUISourceCodeTreeNode(this, uiSourceCode);
this._uiSourceCodeNodes.put(uiSourceCode, uiSourceCodeNode);
folderNode.appendChild(uiSourceCodeNode);
- if (uiSourceCode.url === WebInspector.inspectedPageURL)
- this.revealUISourceCode(uiSourceCode);
},
/**
* @param {!WebInspector.Event} event
*/
- _inspectedURLChanged: function(event)
+ _uiSourceCodeAdded: function(event)
{
- var nodes = this._uiSourceCodeNodes.values();
- for (var i = 0; i < nodes.length; ++i) {
- var uiSourceCode = nodes[i].uiSourceCode();
- if (uiSourceCode.url === WebInspector.inspectedPageURL)
- this.revealUISourceCode(uiSourceCode);
- }
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._addUISourceCode(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _uiSourceCodeRemoved: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._removeUISourceCode(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _projectRemoved: function(event)
+ {
+ var project = /** @type {!WebInspector.Project} */ (event.data);
+ var uiSourceCodes = project.uiSourceCodes();
+ for (var i = 0; i < uiSourceCodes.length; ++i)
+ this._removeUISourceCode(uiSourceCodes[i]);
},
/**
@@ -163,7 +203,7 @@ WebInspector.NavigatorView.prototype = {
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
if (!node)
- return null;
+ return;
if (this._scriptsTree.selectedTreeElement)
this._scriptsTree.selectedTreeElement.deselect();
this._lastSelectedUISourceCode = uiSourceCode;
@@ -191,7 +231,7 @@ WebInspector.NavigatorView.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
- removeUISourceCode: function(uiSourceCode)
+ _removeUISourceCode: function(uiSourceCode)
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
if (!node)
@@ -218,32 +258,12 @@ WebInspector.NavigatorView.prototype = {
/**
* @param {!WebInspector.UISourceCode} uiSourceCode
*/
- updateIcon: function(uiSourceCode)
+ _updateIcon: function(uiSourceCode)
{
var node = this._uiSourceCodeNodes.get(uiSourceCode);
node.updateIcon();
},
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- */
- requestRename: function(uiSourceCode)
- {
- this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.ItemRenamingRequested, uiSourceCode);
- },
-
- /**
- * @param {!WebInspector.UISourceCode} uiSourceCode
- * @param {function(boolean)=} callback
- */
- rename: function(uiSourceCode, callback)
- {
- var node = this._uiSourceCodeNodes.get(uiSourceCode);
- if (!node)
- return null;
- node.rename(callback);
- },
-
reset: function()
{
var nodes = this._uiSourceCodeNodes.values();
@@ -296,11 +316,15 @@ WebInspector.NavigatorView.prototype = {
*/
_handleContextMenuCreate: function(project, path, uiSourceCode)
{
- var data = {};
- data.project = project;
- data.path = path;
- data.uiSourceCode = uiSourceCode;
- this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemCreationRequested, data);
+ this.create(project, path, uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _handleContextMenuRename: function(uiSourceCode)
+ {
+ this.rename(uiSourceCode, false);
},
/**
@@ -338,12 +362,14 @@ WebInspector.NavigatorView.prototype = {
contextMenu.appendSeparator();
var project = uiSourceCode.project();
- var path = uiSourceCode.parentPath();
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Refresh parent" : "Refresh Parent"), this._handleContextMenuRefresh.bind(this, project, path));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Duplicate file" : "Duplicate File"), this._handleContextMenuCreate.bind(this, project, path, uiSourceCode));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Exclude parent folder" : "Exclude Parent Folder"), this._handleContextMenuExclude.bind(this, project, path));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete file" : "Delete File"), this._handleContextMenuDelete.bind(this, uiSourceCode));
- contextMenu.appendSeparator();
+ if (project.type() === WebInspector.projectTypes.FileSystem) {
+ var path = uiSourceCode.parentPath();
+ contextMenu.appendItem(WebInspector.UIString("Rename\u2026"), this._handleContextMenuRename.bind(this, uiSourceCode));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Make a copy\u2026" : "Make a Copy\u2026"), this._handleContextMenuCreate.bind(this, project, path, uiSourceCode));
+ contextMenu.appendItem(WebInspector.UIString("Delete"), this._handleContextMenuDelete.bind(this, uiSourceCode));
+ contextMenu.appendSeparator();
+ }
+
this._appendAddFolderItem(contextMenu);
contextMenu.show();
},
@@ -388,21 +414,162 @@ WebInspector.NavigatorView.prototype = {
},
/**
- * @param {?Event} event
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {boolean} deleteIfCanceled
*/
- _treeKeyPress: function(event)
- {
- if (WebInspector.isBeingEdited(this._scriptsTree.childrenListElement))
- return;
+ rename: function(uiSourceCode, deleteIfCanceled)
+ {
+ var node = this._uiSourceCodeNodes.get(uiSourceCode);
+ console.assert(node);
+ node.rename(callback.bind(this));
- var searchText = String.fromCharCode(event.charCode);
- if (searchText.trim() !== searchText)
- return;
- this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemSearchStarted, searchText);
- event.consume(true);
- },
+ /**
+ * @this {WebInspector.NavigatorView}
+ * @param {boolean} committed
+ */
+ function callback(committed)
+ {
+ if (!committed) {
+ if (deleteIfCanceled)
+ uiSourceCode.remove();
+ return;
+ }
+
+ this.dispatchEventToListeners(WebInspector.NavigatorView.Events.ItemRenamed, uiSourceCode);
+ this._updateIcon(uiSourceCode);
+ this._sourceSelected(uiSourceCode, true)
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Project} project
+ * @param {string} path
+ * @param {!WebInspector.UISourceCode=} uiSourceCodeToCopy
+ */
+ create: function(project, path, uiSourceCodeToCopy)
+ {
+ var filePath;
+ var uiSourceCode;
+
+ /**
+ * @this {WebInspector.NavigatorView}
+ * @param {?string} content
+ */
+ function contentLoaded(content)
+ {
+ createFile.call(this, content || "");
+ }
+
+ if (uiSourceCodeToCopy)
+ uiSourceCodeToCopy.requestContent(contentLoaded.bind(this));
+ else
+ createFile.call(this);
+
+ /**
+ * @this {WebInspector.NavigatorView}
+ * @param {string=} content
+ */
+ function createFile(content)
+ {
+ project.createFile(path, null, content || "", fileCreated.bind(this));
+ }
+
+ /**
+ * @this {WebInspector.NavigatorView}
+ * @param {?string} path
+ */
+ function fileCreated(path)
+ {
+ if (!path)
+ return;
+ filePath = path;
+ uiSourceCode = project.uiSourceCode(filePath);
+ if (!uiSourceCode) {
+ console.assert(uiSourceCode)
+ return;
+ }
+ this._sourceSelected(uiSourceCode, false);
+ this.revealUISourceCode(uiSourceCode, true);
+ this.rename(uiSourceCode, true);
+ }
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.NavigatorView}
+ */
+WebInspector.SourcesNavigatorView = function()
+{
+ WebInspector.NavigatorView.call(this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
+}
+
+WebInspector.SourcesNavigatorView.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ accept: function(uiSourceCode)
+ {
+ if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
+ return false;
+ return uiSourceCode.project().type() !== WebInspector.projectTypes.ContentScripts && uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets;
+
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _inspectedURLChanged: function(event)
+ {
+ var nodes = this._uiSourceCodeNodes.values();
+ for (var i = 0; i < nodes.length; ++i) {
+ var uiSourceCode = nodes[i].uiSourceCode();
+ if (uiSourceCode.url === WebInspector.resourceTreeModel.inspectedPageURL())
+ this.revealUISourceCode(uiSourceCode, true);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _addUISourceCode: function(uiSourceCode)
+ {
+ WebInspector.NavigatorView.prototype._addUISourceCode.call(this, uiSourceCode);
+ if (uiSourceCode.url === WebInspector.resourceTreeModel.inspectedPageURL())
+ this.revealUISourceCode(uiSourceCode, true);
+ },
+
+ __proto__: WebInspector.NavigatorView.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.NavigatorView}
+ */
+WebInspector.ContentScriptsNavigatorView = function()
+{
+ WebInspector.NavigatorView.call(this);
+}
+
+WebInspector.ContentScriptsNavigatorView.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ accept: function(uiSourceCode)
+ {
+ if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
+ return false;
+ return uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts;
+ },
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.NavigatorView.prototype
}
/**
@@ -426,6 +593,11 @@ WebInspector.NavigatorTreeOutline.Types = {
FileSystem: "FileSystem"
}
+/**
+ * @param {!TreeElement} treeElement1
+ * @param {!TreeElement} treeElement2
+ * @return {number}
+ */
WebInspector.NavigatorTreeOutline._treeElementsCompare = function compare(treeElement1, treeElement2)
{
// Insert in the alphabetical order, first domains, then folders, then scripts.
@@ -433,7 +605,7 @@ WebInspector.NavigatorTreeOutline._treeElementsCompare = function compare(treeEl
{
var type = treeElement.type();
if (type === WebInspector.NavigatorTreeOutline.Types.Domain) {
- if (treeElement.titleText === WebInspector.inspectedPageDomain)
+ if (treeElement.titleText === WebInspector.resourceTreeModel.inspectedPageDomain())
return 1;
return 2;
}
@@ -515,7 +687,7 @@ WebInspector.BaseNavigatorTreeElement.prototype = {
this.imageElement.className = "icon";
this.listItemElement.appendChild(this.imageElement);
}
-
+
this.titleElement = document.createElement("div");
this.titleElement.className = "base-navigator-tree-element-title";
this._titleTextNode = document.createTextNode("");
@@ -555,7 +727,7 @@ WebInspector.BaseNavigatorTreeElement.prototype = {
if (this.titleElement)
this.titleElement.textContent = this._titleText;
},
-
+
/**
* @return {string}
*/
@@ -707,7 +879,7 @@ WebInspector.NavigatorSourceTreeElement.prototype = {
function rename()
{
if (this._shouldRenameOnMouseDown())
- this._navigatorView.requestRename(this._uiSourceCode);
+ this._navigatorView.rename(this.uiSourceCode, false);
}
},
@@ -718,6 +890,9 @@ WebInspector.NavigatorSourceTreeElement.prototype = {
return true;
},
+ /**
+ * @return {boolean}
+ */
onspace: function()
{
this._navigatorView._sourceSelected(this.uiSourceCode, true);
@@ -734,6 +909,7 @@ WebInspector.NavigatorSourceTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
ondblclick: function(event)
{
@@ -744,6 +920,7 @@ WebInspector.NavigatorSourceTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
onenter: function()
{
@@ -753,6 +930,7 @@ WebInspector.NavigatorSourceTreeElement.prototype = {
/**
* @override
+ * @return {boolean}
*/
ondelete: function()
{
@@ -787,7 +965,7 @@ WebInspector.NavigatorTreeNode.prototype = {
/**
* @return {!TreeElement}
*/
- treeElement: function() { },
+ treeElement: function() { throw "Not implemented"; },
dispose: function() { },
@@ -860,11 +1038,11 @@ WebInspector.NavigatorTreeNode.prototype = {
/**
* @param {string} id
- * @return {!WebInspector.NavigatorTreeNode}
+ * @return {?WebInspector.NavigatorTreeNode}
*/
child: function(id)
{
- return this._children.get(id);
+ return this._children.get(id) || null;
},
/**
@@ -976,7 +1154,6 @@ WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._titleChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
- this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._formattedChanged, this);
return this._treeElement;
},
@@ -1010,7 +1187,6 @@ WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleChanged, this._titleChanged, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
- this._uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._formattedChanged, this);
},
_titleChanged: function(event)
@@ -1028,11 +1204,6 @@ WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
this.updateTitle();
},
- _formattedChanged: function(event)
- {
- this.updateTitle();
- },
-
/**
* @param {boolean=} select
*/
@@ -1042,7 +1213,7 @@ WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
this.parent.treeElement().expand();
this._treeElement.reveal();
if (select)
- this._treeElement.select();
+ this._treeElement.select(true);
},
/**
@@ -1109,9 +1280,9 @@ WebInspector.NavigatorUISourceCodeTreeNode.prototype = {
callback(committed);
}
- var editingConfig = new WebInspector.EditingConfig(commitHandler.bind(this), cancelHandler.bind(this));
+ var editingConfig = new WebInspector.InplaceEditor.Config(commitHandler.bind(this), cancelHandler.bind(this));
this.updateTitle(true);
- WebInspector.startEditing(this._treeElement.titleElement, editingConfig);
+ WebInspector.InplaceEditor.startEditing(this._treeElement.titleElement, editingConfig);
window.getSelection().setBaseAndExtent(this._treeElement.titleElement, 0, this._treeElement.titleElement, 1);
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Placard.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/Placard.js
index 7bdb94acad5..bb233d2b6c7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Placard.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/Placard.js
@@ -37,6 +37,7 @@ WebInspector.Placard = function(title, subtitle)
this.subtitleElement = this.element.createChild("div", "subtitle");
this.titleElement = this.element.createChild("div", "title");
+ this._hidden = false;
this.title = title;
this.subtitle = subtitle;
this.selected = false;
@@ -106,6 +107,25 @@ WebInspector.Placard.prototype = {
this.selected = !this.selected;
},
+ /**
+ * @return {boolean}
+ */
+ isHidden: function()
+ {
+ return this._hidden;
+ },
+
+ /**
+ * @param {boolean} x
+ */
+ setHidden: function(x)
+ {
+ if (this._hidden === x)
+ return;
+ this._hidden = x;
+ this.element.classList.toggle("hidden", x);
+ },
+
discard: function()
{
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/RevisionHistoryView.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/RevisionHistoryView.js
index 812cda43cb2..e7a64c1fd03 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/RevisionHistoryView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/RevisionHistoryView.js
@@ -30,14 +30,13 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.RevisionHistoryView = function()
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this.registerRequiredCSS("revisionHistory.css");
this.element.classList.add("revision-history-drawer");
- this.element.classList.add("fill");
this.element.classList.add("outline-disclosure");
this._uiSourceCodeItems = new Map();
@@ -57,7 +56,7 @@ WebInspector.RevisionHistoryView = function()
WebInspector.workspace.uiSourceCodes().forEach(populateRevisions.bind(this));
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeContentCommitted, this._revisionAdded, this);
WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
- WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillReset, this._projectWillReset, this);
+ WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
}
/**
@@ -65,7 +64,7 @@ WebInspector.RevisionHistoryView = function()
*/
WebInspector.RevisionHistoryView.showHistory = function(uiSourceCode)
{
- if (!WebInspector.RevisionHistoryView._view)
+ if (!WebInspector.RevisionHistoryView._view)
WebInspector.RevisionHistoryView._view = new WebInspector.RevisionHistoryView();
var view = WebInspector.RevisionHistoryView._view;
WebInspector.inspectorView.showCloseableViewInDrawer("history", WebInspector.UIString("History"), view);
@@ -168,13 +167,13 @@ WebInspector.RevisionHistoryView.prototype = {
this._uiSourceCodeItems.remove(uiSourceCode);
},
- _projectWillReset: function(event)
+ _projectRemoved: function(event)
{
var project = event.data;
project.uiSourceCodes().forEach(this._removeUISourceCode.bind(this));
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ScopeChainSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
index b9203c5f788..affe79cb8f8 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ScopeChainSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
@@ -80,17 +80,19 @@ WebInspector.ScopeChainSidebarPane.prototype = {
title = WebInspector.UIString("Local");
emptyPlaceholder = WebInspector.UIString("No Variables");
subtitle = undefined;
- if (callFrame.this)
- extraProperties.push(new WebInspector.RemoteObjectProperty("this", WebInspector.RemoteObject.fromPayload(callFrame.this)));
+ var thisObject = callFrame.thisObject();
+ if (thisObject)
+ extraProperties.push(new WebInspector.RemoteObjectProperty("this", thisObject));
if (i == 0) {
- var details = WebInspector.debuggerModel.debuggerPausedDetails();
- var exception = details.reason === WebInspector.DebuggerModel.BreakReason.Exception ? details.auxData : 0;
- if (exception) {
- var exceptionObject = /** @type {!RuntimeAgent.RemoteObject} */ (exception);
- extraProperties.push(new WebInspector.RemoteObjectProperty("<exception>", WebInspector.RemoteObject.fromPayload(exceptionObject)));
+ var details = callFrame.target().debuggerModel.debuggerPausedDetails();
+ if (!callFrame.isAsync()) {
+ var exception = details.exception();
+ if (exception)
+ extraProperties.push(new WebInspector.RemoteObjectProperty("<exception>", exception));
}
- if (callFrame.returnValue)
- extraProperties.push(new WebInspector.RemoteObjectProperty("<return>", WebInspector.RemoteObject.fromPayload(callFrame.returnValue)));
+ var returnValue = callFrame.returnValue();
+ if (returnValue)
+ extraProperties.push(new WebInspector.RemoteObjectProperty("<return>", returnValue));
}
declarativeScope = true;
break;
@@ -118,8 +120,12 @@ WebInspector.ScopeChainSidebarPane.prototype = {
if (!title || title === subtitle)
subtitle = undefined;
- var scopeRef = declarativeScope ? new WebInspector.ScopeRef(i, callFrame.id, undefined) : undefined;
- var scopeObject = WebInspector.ScopeRemoteObject.fromPayload(scope.object, scopeRef);
+ var runtimeModel = callFrame.target().runtimeModel;
+ if (declarativeScope)
+ var scopeObject = runtimeModel.createScopeRemoteObject(scope.object, new WebInspector.ScopeRef(i, callFrame.id, undefined));
+ else
+ var scopeObject = runtimeModel.createRemoteObject(scope.object);
+
var section = new WebInspector.ObjectPropertiesSection(scopeObject, title, subtitle, emptyPlaceholder, true, extraProperties, WebInspector.ScopeVariableTreeElement);
section.editInSelectedCallFrameWhenPaused = true;
section.pane = this;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatter.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js
index 4ae083a3daa..b980bc67aa2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ScriptFormatter.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatter.js
@@ -124,7 +124,7 @@ WebInspector.ScriptFormatter.prototype = {
get _worker()
{
if (!this._cachedWorker) {
- this._cachedWorker = new Worker("ScriptFormatterWorker.js");
+ this._cachedWorker = new Worker("script_formatter_worker/ScriptFormatterWorker.js");
this._cachedWorker.onmessage = /** @type {function(this:Worker)} */ (this._didFormatContent.bind(this));
}
return this._cachedWorker;
@@ -200,7 +200,7 @@ WebInspector.IdentityFormatterSourceMapping.prototype = {
*/
originalToFormatted: function(lineNumber, columnNumber)
{
- return [lineNumber, columnNumber || 0];
+ return [lineNumber, columnNumber || 0];
},
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
new file mode 100644
index 00000000000..b87af340451
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
@@ -0,0 +1,379 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.SourceMapping}
+ * @param {!WebInspector.Workspace} workspace
+ * @param {!WebInspector.DebuggerModel} debuggerModel
+ */
+WebInspector.FormatterScriptMapping = function(workspace, debuggerModel)
+{
+ this._workspace = workspace;
+ this._debuggerModel = debuggerModel;
+
+ this._init();
+
+ this._projectId = "formatter:";
+ this._projectDelegate = new WebInspector.FormatterProjectDelegate(workspace, this._projectId);
+ this._debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+}
+
+WebInspector.FormatterScriptMapping.prototype = {
+ /**
+ * @param {!WebInspector.RawLocation} rawLocation
+ * @return {?WebInspector.UILocation}
+ */
+ rawLocationToUILocation: function(rawLocation)
+ {
+ var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (rawLocation);
+ var script = debuggerModelLocation.script();
+ var uiSourceCode = this._uiSourceCodes.get(script);
+ if (!uiSourceCode)
+ return null;
+
+ var formatData = this._formatData.get(uiSourceCode);
+ if (!formatData)
+ return null;
+ var mapping = formatData.mapping;
+ var lineNumber = debuggerModelLocation.lineNumber;
+ var columnNumber = debuggerModelLocation.columnNumber || 0;
+ var formattedLocation = mapping.originalToFormatted(lineNumber, columnNumber);
+ return uiSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {?WebInspector.DebuggerModel.Location}
+ */
+ uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
+ {
+ var formatData = this._formatData.get(uiSourceCode);
+ if (!formatData)
+ return null;
+ var originalLocation = formatData.mapping.formattedToOriginal(lineNumber, columnNumber)
+ return this._debuggerModel.createRawLocation(formatData.scripts[0], originalLocation[0], originalLocation[1]);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isIdentity: function()
+ {
+ return false;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {!Array.<!WebInspector.Script>}
+ */
+ _scriptsForUISourceCode: function(uiSourceCode)
+ {
+ /**
+ * @param {!WebInspector.Script} script
+ * @return {boolean}
+ */
+ function isInlineScript(script)
+ {
+ return script.isInlineScript();
+ }
+
+ if (uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
+ return this._debuggerModel.scriptsForSourceURL(uiSourceCode.url).filter(isInlineScript);
+ if (uiSourceCode.contentType() === WebInspector.resourceTypes.Script) {
+ var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (uiSourceCode.uiLocationToRawLocation(this._debuggerModel.target(), 0, 0));
+ return rawLocation ? [rawLocation.script()] : [];
+ }
+ return [];
+ },
+
+ _init: function()
+ {
+ /** @type {!Map.<!WebInspector.Script, !WebInspector.UISourceCode>} */
+ this._uiSourceCodes = new Map();
+ /** @type {!StringMap.<string>} */
+ this._formattedPaths = new StringMap();
+ /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.FormatterScriptMapping.FormatData>} */
+ this._formatData = new Map();
+ },
+
+ _debuggerReset: function()
+ {
+ var formattedPaths = this._formattedPaths.values();
+ for (var i = 0; i < formattedPaths.length; ++i)
+ this._projectDelegate._removeFormatted(formattedPaths[i]);
+ this._init();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {function(?WebInspector.UISourceCode, !WebInspector.FormatterSourceMapping=)} callback
+ */
+ _performUISourceCodeScriptFormatting: function(uiSourceCode, callback)
+ {
+ var path = this._formattedPaths.get(uiSourceCode.project().id() + ":" + uiSourceCode.path());
+ if (path) {
+ var uiSourceCodePath = path;
+ var formattedUISourceCode = this._workspace.uiSourceCode(this._projectId, uiSourceCodePath);
+ var formatData = formattedUISourceCode ? this._formatData.get(formattedUISourceCode) : null;
+ if (!formatData)
+ callback(null);
+ else
+ callback(formattedUISourceCode, formatData.mapping);
+ return;
+ }
+
+ uiSourceCode.requestContent(contentLoaded.bind(this));
+
+ /**
+ * @this {WebInspector.FormatterScriptMapping}
+ * @param {?string} content
+ */
+ function contentLoaded(content)
+ {
+ var formatter = WebInspector.Formatter.createFormatter(uiSourceCode.contentType());
+ formatter.formatContent(uiSourceCode.highlighterType(), content || "", innerCallback.bind(this));
+ }
+
+ /**
+ * @this {WebInspector.FormatterScriptMapping}
+ * @param {string} formattedContent
+ * @param {!WebInspector.FormatterSourceMapping} formatterMapping
+ */
+ function innerCallback(formattedContent, formatterMapping)
+ {
+ var scripts = this._scriptsForUISourceCode(uiSourceCode);
+ if (!scripts.length) {
+ callback(null);
+ return;
+ }
+ var name;
+ if (uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
+ name = uiSourceCode.displayName();
+ else
+ name = uiSourceCode.name() || scripts[0].scriptId;
+ path = this._projectDelegate._addFormatted(name, uiSourceCode.url, uiSourceCode.contentType(), formattedContent);
+ var formattedUISourceCode = /** @type {!WebInspector.UISourceCode} */ (this._workspace.uiSourceCode(this._projectId, path));
+
+ var formatData = new WebInspector.FormatterScriptMapping.FormatData(uiSourceCode.project().id(), uiSourceCode.path(), formatterMapping, scripts);
+ this._formatData.put(formattedUISourceCode, formatData);
+ this._formattedPaths.put(uiSourceCode.project().id() + ":" + uiSourceCode.path(), path);
+ for (var i = 0; i < scripts.length; ++i) {
+ this._uiSourceCodes.put(scripts[i], formattedUISourceCode);
+ scripts[i].pushSourceMapping(this);
+ }
+ formattedUISourceCode.setSourceMappingForTarget(this._debuggerModel.target(), this);
+ callback(formattedUISourceCode, formatterMapping);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} formattedUISourceCode
+ * @return {?WebInspector.FormatterSourceMapping}
+ */
+ _discardFormattedUISourceCodeScript: function(formattedUISourceCode)
+ {
+ var formatData = this._formatData.get(formattedUISourceCode);
+ if (!formatData)
+ return null;
+
+ this._formatData.remove(formattedUISourceCode);
+ this._formattedPaths.remove(formatData.projectId + ":" + formatData.path);
+ for (var i = 0; i < formatData.scripts.length; ++i) {
+ this._uiSourceCodes.remove(formatData.scripts[i]);
+ formatData.scripts[i].popSourceMapping();
+ }
+ this._projectDelegate._removeFormatted(formattedUISourceCode.path());
+ return formatData.mapping;
+ }
+}
+
+/**
+ * @constructor
+ * @param {string} projectId
+ * @param {string} path
+ * @param {!WebInspector.FormatterSourceMapping} mapping
+ * @param {!Array.<!WebInspector.Script>} scripts
+ */
+WebInspector.FormatterScriptMapping.FormatData = function(projectId, path, mapping, scripts)
+{
+ this.projectId = projectId;
+ this.path = path;
+ this.mapping = mapping;
+ this.scripts = scripts;
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Workspace} workspace
+ * @param {string} id
+ * @extends {WebInspector.ContentProviderBasedProjectDelegate}
+ */
+WebInspector.FormatterProjectDelegate = function(workspace, id)
+{
+ WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, WebInspector.projectTypes.Formatter);
+}
+
+WebInspector.FormatterProjectDelegate.prototype = {
+ /**
+ * @return {string}
+ */
+ displayName: function()
+ {
+ return "formatter";
+ },
+
+ /**
+ * @param {string} name
+ * @param {string} sourceURL
+ * @param {!WebInspector.ResourceType} contentType
+ * @param {string} content
+ * @return {string}
+ */
+ _addFormatted: function(name, sourceURL, contentType, content)
+ {
+ var contentProvider = new WebInspector.StaticContentProvider(contentType, content);
+ return this.addContentProvider(sourceURL, name + ":formatted", "deobfuscated:" + sourceURL, contentProvider);
+ },
+
+ /**
+ * @param {string} path
+ */
+ _removeFormatted: function(path)
+ {
+ this.removeFile(path);
+ },
+
+ __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.SourcesView.EditorAction}
+ */
+WebInspector.ScriptFormatterEditorAction = function()
+{
+ this._scriptMapping = new WebInspector.FormatterScriptMapping(WebInspector.workspace, WebInspector.debuggerModel);
+}
+
+WebInspector.ScriptFormatterEditorAction.prototype = {
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorSelected: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._updateButton(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorClosed: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
+ var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
+
+ if (wasSelected)
+ this._updateButton(null);
+ this._discardFormattedUISourceCodeScript(uiSourceCode);
+ },
+
+ /**
+ * @param {?WebInspector.UISourceCode} uiSourceCode
+ */
+ _updateButton: function(uiSourceCode)
+ {
+ this._button.element.classList.toggle("hidden", !this._isFormatableScript(uiSourceCode));
+ },
+
+ /**
+ * @param {!WebInspector.SourcesView} sourcesView
+ * @return {!Element}
+ */
+ button: function(sourcesView)
+ {
+ if (this._button)
+ return this._button.element;
+
+ this._sourcesView = sourcesView;
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
+
+ this._button = new WebInspector.StatusBarButton(WebInspector.UIString("Pretty print"), "sources-toggle-pretty-print-status-bar-item");
+ this._button.toggled = false;
+ this._button.addEventListener("click", this._toggleFormatScriptSource, this);
+ this._updateButton(null);
+
+ return this._button.element;
+ },
+
+ /**
+ * @param {?WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ _isFormatableScript: function(uiSourceCode)
+ {
+ if (!uiSourceCode)
+ return false;
+ var supportedProjectTypes = [WebInspector.projectTypes.Network, WebInspector.projectTypes.Debugger, WebInspector.projectTypes.ContentScripts];
+ if (supportedProjectTypes.indexOf(uiSourceCode.project().type()) === -1)
+ return false;
+ var contentType = uiSourceCode.contentType();
+ return contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document;
+ },
+
+ _toggleFormatScriptSource: function()
+ {
+ var uiSourceCode = this._sourcesView.currentUISourceCode();
+ if (!this._isFormatableScript(uiSourceCode))
+ return;
+ this._formatUISourceCodeScript(uiSourceCode);
+
+ WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
+ action: WebInspector.UserMetrics.UserActionNames.TogglePrettyPrint,
+ enabled: true,
+ url: uiSourceCode.originURL()
+ });
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _formatUISourceCodeScript: function(uiSourceCode)
+ {
+ this._scriptMapping._performUISourceCodeScriptFormatting(uiSourceCode, innerCallback.bind(this));
+
+ /**
+ * @this {WebInspector.ScriptFormatterEditorAction}
+ * @param {?WebInspector.UISourceCode} formattedUISourceCode
+ * @param {!WebInspector.FormatterSourceMapping=} mapping
+ */
+ function innerCallback(formattedUISourceCode, mapping)
+ {
+ if (!formattedUISourceCode)
+ return;
+ if (uiSourceCode !== this._sourcesView.currentUISourceCode())
+ return;
+ var sourceFrame = this._sourcesView.viewForFile(uiSourceCode);
+ var start = [0, 0];
+ if (sourceFrame) {
+ var selection = sourceFrame.selection();
+ start = mapping.originalToFormatted(selection.startLine, selection.startColumn);
+ }
+ this._sourcesView.showSourceLocation(formattedUISourceCode, start[0], start[1]);
+ this._updateButton(formattedUISourceCode);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _discardFormattedUISourceCodeScript: function(uiSourceCode)
+ {
+ this._scriptMapping._discardFormattedUISourceCodeScript(uiSourceCode);
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/SimpleHistoryManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SimpleHistoryManager.js
new file mode 100644
index 00000000000..5771e7a0e97
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SimpleHistoryManager.js
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @interface
+ */
+WebInspector.HistoryEntry = function() { }
+
+WebInspector.HistoryEntry.prototype = {
+ /**
+ * @return {boolean}
+ */
+ valid: function() { },
+
+ reveal: function() { }
+};
+
+/**
+ * @constructor
+ * @param {number} historyDepth
+ */
+WebInspector.SimpleHistoryManager = function(historyDepth)
+{
+ this._entries = [];
+ this._activeEntryIndex = -1;
+ this._coalescingReadonly = 0;
+ this._historyDepth = historyDepth;
+}
+
+WebInspector.SimpleHistoryManager.prototype = {
+ readOnlyLock: function()
+ {
+ ++this._coalescingReadonly;
+ },
+
+ releaseReadOnlyLock: function()
+ {
+ --this._coalescingReadonly;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ readOnly: function()
+ {
+ return !!this._coalescingReadonly;
+ },
+
+ /**
+ * @param {!function(!WebInspector.HistoryEntry):boolean} filterOutCallback
+ */
+ filterOut: function(filterOutCallback)
+ {
+ if (this.readOnly())
+ return;
+ var filteredEntries = [];
+ var removedBeforeActiveEntry = 0;
+ for (var i = 0; i < this._entries.length; ++i) {
+ if (!filterOutCallback(this._entries[i])) {
+ filteredEntries.push(this._entries[i]);
+ } else if (i <= this._activeEntryIndex)
+ ++removedBeforeActiveEntry;
+ }
+ this._entries = filteredEntries;
+ this._activeEntryIndex = Math.max(0, this._activeEntryIndex - removedBeforeActiveEntry);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ empty: function()
+ {
+ return !this._entries.length;
+ },
+
+ /**
+ * @return {?WebInspector.HistoryEntry}
+ */
+ active: function()
+ {
+ return this.empty() ? null : this._entries[this._activeEntryIndex];
+ },
+
+ /**
+ * @param {!WebInspector.HistoryEntry} entry
+ */
+ push: function(entry)
+ {
+ if (this.readOnly())
+ return;
+ if (!this.empty())
+ this._entries.splice(this._activeEntryIndex + 1);
+ this._entries.push(entry);
+ if (this._entries.length > this._historyDepth)
+ this._entries.shift();
+ this._activeEntryIndex = this._entries.length - 1;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ rollback: function()
+ {
+ if (this.empty())
+ return false;
+
+ var revealIndex = this._activeEntryIndex - 1;
+ while (revealIndex >= 0 && !this._entries[revealIndex].valid())
+ --revealIndex;
+ if (revealIndex < 0)
+ return false;
+
+ this.readOnlyLock();
+ this._entries[revealIndex].reveal();
+ this.releaseReadOnlyLock();
+
+ this._activeEntryIndex = revealIndex;
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ rollover: function()
+ {
+ var revealIndex = this._activeEntryIndex + 1;
+
+ while (revealIndex < this._entries.length && !this._entries[revealIndex].valid())
+ ++revealIndex;
+ if (revealIndex >= this._entries.length)
+ return false;
+
+ this.readOnlyLock();
+ this._entries[revealIndex].reveal();
+ this.releaseReadOnlyLock();
+
+ this._activeEntryIndex = revealIndex;
+ return true;
+ },
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js
new file mode 100644
index 00000000000..ce6a897c9f8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
+ * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.Workspace} workspace
+ */
+WebInspector.SourcesNavigator = function(workspace)
+{
+ WebInspector.Object.call(this);
+ this._workspace = workspace;
+
+ this._tabbedPane = new WebInspector.TabbedPane();
+ this._tabbedPane.shrinkableTabs = true;
+ this._tabbedPane.element.classList.add("navigator-tabbed-pane");
+ new WebInspector.ExtensibleTabbedPaneController(this._tabbedPane, "navigator-view", this._navigatorViewCreated.bind(this));
+ /** @type {!StringMap.<?WebInspector.NavigatorView>} */
+ this._navigatorViews = new StringMap();
+}
+
+WebInspector.SourcesNavigator.Events = {
+ SourceSelected: "SourceSelected",
+ SourceRenamed: "SourceRenamed"
+}
+
+WebInspector.SourcesNavigator.prototype = {
+ /**
+ * @param {string} id
+ * @param {!WebInspector.View} view
+ */
+ _navigatorViewCreated: function(id, view)
+ {
+ var navigatorView = /** @type {!WebInspector.NavigatorView} */ (view);
+ navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemSelected, this._sourceSelected, this);
+ navigatorView.addEventListener(WebInspector.NavigatorView.Events.ItemRenamed, this._sourceRenamed, this);
+ this._navigatorViews.put(id, navigatorView);
+ navigatorView.setWorkspace(this._workspace);
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ get view()
+ {
+ return this._tabbedPane;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {string|null}
+ */
+ _navigatorViewIdForUISourceCode: function(uiSourceCode)
+ {
+ var ids = this._navigatorViews.keys();
+ for (var i = 0; i < ids.length; ++i) {
+ var id = ids[i]
+ var navigatorView = this._navigatorViews.get(id);
+ if (navigatorView.accept(uiSourceCode))
+ return id;
+ }
+ return null;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ revealUISourceCode: function(uiSourceCode)
+ {
+ var id = this._navigatorViewIdForUISourceCode(uiSourceCode);
+ if (!id)
+ return;
+ var navigatorView = this._navigatorViews.get(id);
+ console.assert(navigatorView);
+ navigatorView.revealUISourceCode(uiSourceCode, true);
+ this._tabbedPane.selectTab(id);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sourceSelected: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceSelected, event.data);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sourceRenamed: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.SourcesNavigator.Events.SourceRenamed, event.data);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.NavigatorView}
+ */
+WebInspector.SnippetsNavigatorView = function()
+{
+ WebInspector.NavigatorView.call(this);
+}
+
+WebInspector.SnippetsNavigatorView.prototype = {
+ /**
+ * @override
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ accept: function(uiSourceCode)
+ {
+ if (!WebInspector.NavigatorView.prototype.accept(uiSourceCode))
+ return false;
+ return uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
+ },
+
+ /**
+ * @param {!Event} event
+ */
+ handleContextMenu: function(event)
+ {
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
+ contextMenu.show();
+ },
+
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ handleFileContextMenu: function(event, uiSourceCode)
+ {
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendItem(WebInspector.UIString("Run"), this._handleEvaluateSnippet.bind(this, uiSourceCode));
+ contextMenu.appendItem(WebInspector.UIString("Rename"), this.rename.bind(this, uiSourceCode));
+ contextMenu.appendItem(WebInspector.UIString("Remove"), this._handleRemoveSnippet.bind(this, uiSourceCode));
+ contextMenu.appendSeparator();
+ contextMenu.appendItem(WebInspector.UIString("New"), this._handleCreateSnippet.bind(this));
+ contextMenu.show();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _handleEvaluateSnippet: function(uiSourceCode)
+ {
+ var executionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets || !executionContext)
+ return;
+ WebInspector.scriptSnippetModel.evaluateScriptSnippet(executionContext, uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _handleRemoveSnippet: function(uiSourceCode)
+ {
+ if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
+ return;
+ uiSourceCode.remove();
+ },
+
+ _handleCreateSnippet: function()
+ {
+ this.create(WebInspector.scriptSnippetModel.project(), "")
+ },
+
+ /**
+ * @override
+ */
+ sourceDeleted: function(uiSourceCode)
+ {
+ this._handleRemoveSnippet(uiSourceCode);
+ },
+
+ __proto__: WebInspector.NavigatorView.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
new file mode 100644
index 00000000000..bf570c2b982
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -0,0 +1,1479 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+importScript("Placard.js");
+importScript("BreakpointsSidebarPane.js");
+importScript("CallStackSidebarPane.js");
+importScript("SimpleHistoryManager.js");
+importScript("EditingLocationHistoryManager.js");
+importScript("FilePathScoreFunction.js");
+importScript("FilteredItemSelectionDialog.js");
+importScript("UISourceCodeFrame.js");
+importScript("JavaScriptSourceFrame.js");
+importScript("CSSSourceFrame.js");
+importScript("NavigatorView.js");
+importScript("RevisionHistoryView.js");
+importScript("ScopeChainSidebarPane.js");
+importScript("SourcesNavigator.js");
+importScript("StyleSheetOutlineDialog.js");
+importScript("TabbedEditorContainer.js");
+importScript("WatchExpressionsSidebarPane.js");
+importScript("WorkersSidebarPane.js");
+importScript("TargetsToolbar.js");
+importScript("ScriptFormatterEditorAction.js");
+importScript("InplaceFormatterEditorAction.js");
+importScript("ScriptFormatter.js");
+importScript("SourcesView.js");
+
+/**
+ * @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ * @implements {WebInspector.TargetManager.Observer}
+ * @extends {WebInspector.Panel}
+ * @param {!WebInspector.Workspace=} workspaceForTest
+ */
+WebInspector.SourcesPanel = function(workspaceForTest)
+{
+ WebInspector.Panel.call(this, "sources");
+ this.registerRequiredCSS("sourcesPanel.css");
+ this.registerRequiredCSS("suggestBox.css");
+ new WebInspector.UpgradeFileSystemDropTarget(this.element);
+
+ WebInspector.settings.showEditorInDrawer = WebInspector.settings.createSetting("showEditorInDrawer", true);
+
+ this._workspace = workspaceForTest || WebInspector.workspace;
+
+ var helpSection = WebInspector.shortcutsScreen.section(WebInspector.UIString("Sources Panel"));
+ this.debugToolbar = this._createDebugToolbar();
+ this._debugToolbarDrawer = this._createDebugToolbarDrawer();
+ this._targetsToolbar = new WebInspector.TargetsToolbar();
+
+ const initialDebugSidebarWidth = 225;
+ this._splitView = new WebInspector.SplitView(true, true, "sourcesPanelSplitViewState", initialDebugSidebarWidth);
+ this._splitView.enableShowModeSaving();
+ this._splitView.show(this.element);
+
+ // Create scripts navigator
+ const initialNavigatorWidth = 225;
+ this.editorView = new WebInspector.SplitView(true, false, "sourcesPanelNavigatorSplitViewState", initialNavigatorWidth);
+ this.editorView.enableShowModeSaving();
+ this.editorView.element.id = "scripts-editor-split-view";
+ this.editorView.element.tabIndex = 0;
+ this.editorView.show(this._splitView.mainElement());
+
+ this._navigator = new WebInspector.SourcesNavigator(this._workspace);
+ this._navigator.view.setMinimumSize(100, 25);
+ this._navigator.view.show(this.editorView.sidebarElement());
+ this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceSelected, this._sourceSelected, this);
+ this._navigator.addEventListener(WebInspector.SourcesNavigator.Events.SourceRenamed, this._sourceRenamed, this);
+
+ this._sourcesView = new WebInspector.SourcesView(this._workspace, this);
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorSelected, this._editorSelected.bind(this));
+ this._sourcesView.addEventListener(WebInspector.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
+ this._sourcesView.registerShortcuts(this.registerShortcuts.bind(this));
+
+ if (WebInspector.experimentsSettings.editorInDrawer.isEnabled()) {
+ this._drawerEditorView = new WebInspector.SourcesPanel.DrawerEditorView();
+ this._sourcesView.show(this._drawerEditorView.element);
+ } else {
+ this._sourcesView.show(this.editorView.mainElement());
+ }
+
+ this._debugSidebarResizeWidgetElement = document.createElementWithClass("div", "resizer-widget");
+ this._debugSidebarResizeWidgetElement.id = "scripts-debug-sidebar-resizer-widget";
+ this._splitView.addEventListener(WebInspector.SplitView.Events.ShowModeChanged, this._updateDebugSidebarResizeWidget, this);
+ this._updateDebugSidebarResizeWidget();
+ this._splitView.installResizer(this._debugSidebarResizeWidgetElement);
+
+ this.sidebarPanes = {};
+ this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane();
+ this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane();
+ this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this));
+ this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameRestarted, this._callFrameRestartedInSidebar.bind(this));
+ this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this));
+
+ this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane();
+ this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.debuggerModel, WebInspector.breakpointManager, this.showUISourceCode.bind(this));
+ this.sidebarPanes.domBreakpoints = WebInspector.domBreakpointsSidebarPane.createProxy(this);
+ this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane();
+ this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane();
+
+ if (Capabilities.isMainFrontend)
+ this.sidebarPanes.workerList = new WebInspector.WorkersSidebarPane();
+
+ this._extensionSidebarPanes = [];
+ this._installDebuggerSidebarController();
+
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
+ WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
+ this._dockSideChanged();
+
+ this._updateDebuggerButtons();
+ this._pauseOnExceptionEnabledChanged();
+ WebInspector.settings.pauseOnExceptionEnabled.addChangeListener(this._pauseOnExceptionEnabledChanged, this);
+ WebInspector.targetManager.observeTargets(this);
+ this._setTarget(WebInspector.context.flavor(WebInspector.Target));
+ WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._onCurrentTargetChanged, this);
+}
+
+WebInspector.SourcesPanel.minToolbarWidth = 215;
+
+WebInspector.SourcesPanel.prototype = {
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerReset, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
+ target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerWasDisabled, this._debuggerReset, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.BreakpointsActiveStateChanged, this._breakpointsActiveStateChanged, this);
+ target.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
+ },
+
+ /**
+ * @param {?WebInspector.Target} target
+ */
+ _setTarget: function(target)
+ {
+ if (!target)
+ return;
+
+ if (target.debuggerModel.isPaused()) {
+ this._showDebuggerPausedDetails(/** @type {!WebInspector.DebuggerPausedDetails} */ (target.debuggerModel.debuggerPausedDetails()));
+ var callFrame = target.debuggerModel.selectedCallFrame();
+ if (callFrame)
+ this._selectCallFrame(callFrame);
+ } else {
+ this._paused = false;
+ this._clearInterface();
+ this._toggleDebuggerSidebarButton.setEnabled(true);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onCurrentTargetChanged: function(event)
+ {
+ var target = /** @type {?WebInspector.Target} */ (event.data);
+ this._setTarget(target);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this._sourcesView.defaultFocusedElement() || this._navigator.view.defaultFocusedElement();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ paused: function()
+ {
+ return this._paused;
+ },
+
+ /**
+ * @return {!WebInspector.SourcesPanel.DrawerEditor}
+ */
+ _drawerEditor: function()
+ {
+ var drawerEditorInstance = WebInspector.moduleManager.instance(WebInspector.DrawerEditor);
+ console.assert(drawerEditorInstance instanceof WebInspector.SourcesPanel.DrawerEditor, "WebInspector.DrawerEditor module instance does not use WebInspector.SourcesPanel.DrawerEditor as an implementation. ");
+ return /** @type {!WebInspector.SourcesPanel.DrawerEditor} */ (drawerEditorInstance);
+ },
+
+ wasShown: function()
+ {
+ WebInspector.context.setFlavor(WebInspector.SourcesPanel, this);
+ if (WebInspector.experimentsSettings.editorInDrawer.isEnabled()) {
+ this._drawerEditor()._panelWasShown();
+ this._sourcesView.show(this.editorView.mainElement());
+ }
+ WebInspector.Panel.prototype.wasShown.call(this);
+ },
+
+ willHide: function()
+ {
+ WebInspector.Panel.prototype.willHide.call(this);
+ if (WebInspector.experimentsSettings.editorInDrawer.isEnabled()) {
+ this._drawerEditor()._panelWillHide();
+ this._sourcesView.show(this._drawerEditorView.element);
+ }
+ WebInspector.context.setFlavor(WebInspector.SourcesPanel, null);
+ },
+
+ /**
+ * @return {!WebInspector.SearchableView}
+ */
+ searchableView: function()
+ {
+ return this._sourcesView.searchableView();
+ },
+
+ _consoleCommandEvaluatedInSelectedCallFrame: function(event)
+ {
+ this.sidebarPanes.scopechain.update(WebInspector.debuggerModel.selectedCallFrame());
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _debuggerPaused: function(event)
+ {
+ var details = /** @type {!WebInspector.DebuggerPausedDetails} */ (event.data);
+ if (!this._paused)
+ WebInspector.inspectorView.setCurrentPanel(this);
+
+ if (WebInspector.context.flavor(WebInspector.Target) === details.target())
+ this._showDebuggerPausedDetails(details);
+ else if (!this._paused)
+ WebInspector.context.setFlavor(WebInspector.Target, details.target());
+ },
+
+ /**
+ * @param {!WebInspector.DebuggerPausedDetails} details
+ */
+ _showDebuggerPausedDetails: function(details)
+ {
+ this._paused = true;
+ this._updateDebuggerButtons();
+
+ this.sidebarPanes.callstack.update(details);
+
+ /**
+ * @param {!Element} element
+ * @this {WebInspector.SourcesPanel}
+ */
+ function didCreateBreakpointHitStatusMessage(element)
+ {
+ this.sidebarPanes.callstack.setStatus(element);
+ }
+
+ /**
+ * @param {!WebInspector.UILocation} uiLocation
+ * @this {WebInspector.SourcesPanel}
+ */
+ function didGetUILocation(uiLocation)
+ {
+ var breakpoint = WebInspector.breakpointManager.findBreakpointOnLine(uiLocation.uiSourceCode, uiLocation.lineNumber);
+ if (!breakpoint)
+ return;
+ this.sidebarPanes.jsBreakpoints.highlightBreakpoint(breakpoint);
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a JavaScript breakpoint."));
+ }
+
+ if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) {
+ WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData);
+ WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details, didCreateBreakpointHitStatusMessage.bind(this));
+ } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) {
+ var eventName = details.auxData["eventName"];
+ var targetName = details.auxData["targetName"];
+ this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(eventName, targetName);
+ var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData);
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI));
+ } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) {
+ this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]);
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest."));
+ } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception)
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on exception: '%s'.", details.auxData["description"]));
+ else if (details.reason === WebInspector.DebuggerModel.BreakReason.Assert)
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on assertion."));
+ else if (details.reason === WebInspector.DebuggerModel.BreakReason.CSPViolation)
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a script blocked due to Content Security Policy directive: \"%s\".", details.auxData["directiveText"]));
+ else if (details.reason === WebInspector.DebuggerModel.BreakReason.DebugCommand)
+ this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a debugged function"));
+ else {
+ if (details.callFrames.length)
+ details.callFrames[0].createLiveLocation(didGetUILocation.bind(this));
+ else
+ console.warn("ScriptsPanel paused, but callFrames.length is zero."); // TODO remove this once we understand this case better
+ }
+
+ this._splitView.showBoth(true);
+ this._toggleDebuggerSidebarButton.setEnabled(false);
+ window.focus();
+ InspectorFrontendHost.bringToFront();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _debuggerResumed: function(event)
+ {
+ var target = /** @type {!WebInspector.Target} */ (event.target.target());
+ if (WebInspector.context.flavor(WebInspector.Target) !== target)
+ return;
+ this._paused = false;
+ this._clearInterface();
+ this._toggleDebuggerSidebarButton.setEnabled(true);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _debuggerWasEnabled: function(event)
+ {
+ var target = /** @type {!WebInspector.Target} */ (event.target.target());
+ if (WebInspector.context.flavor(WebInspector.Target) !== target)
+ return;
+
+ this._updateDebuggerButtons();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _debuggerReset: function(event)
+ {
+ this._debuggerResumed(event);
+ delete this._skipExecutionLineRevealing;
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ get visibleView()
+ {
+ return this._sourcesView.visibleView();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number=} lineNumber
+ * @param {number=} columnNumber
+ * @param {boolean=} forceShowInPanel
+ */
+ showUISourceCode: function(uiSourceCode, lineNumber, columnNumber, forceShowInPanel)
+ {
+ this._showEditor(forceShowInPanel);
+ this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
+ },
+
+ _showEditor: function(forceShowInPanel)
+ {
+ if (this._sourcesView.isShowing())
+ return;
+
+ if (this._shouldShowEditorInDrawer() && !forceShowInPanel)
+ this._drawerEditor()._show();
+ else
+ WebInspector.inspectorView.showPanel("sources");
+ },
+
+ /**
+ * @param {!WebInspector.UILocation} uiLocation
+ * @param {boolean=} forceShowInPanel
+ */
+ showUILocation: function(uiLocation, forceShowInPanel)
+ {
+ this.showUISourceCode(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, forceShowInPanel);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _shouldShowEditorInDrawer: function()
+ {
+ return WebInspector.experimentsSettings.editorInDrawer.isEnabled() && WebInspector.settings.showEditorInDrawer.get() && WebInspector.inspectorView.isDrawerEditorShown();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _revealInNavigator: function(uiSourceCode)
+ {
+ this._navigator.revealUISourceCode(uiSourceCode);
+ },
+
+ _executionLineChanged: function(uiLocation)
+ {
+ this._sourcesView.clearCurrentExecutionLine();
+ this._sourcesView.setExecutionLine(uiLocation);
+ if (this._skipExecutionLineRevealing)
+ return;
+ this._skipExecutionLineRevealing = true;
+ this._sourcesView.showSourceLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, 0, undefined, true);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _callFrameSelected: function(event)
+ {
+ var callFrame = /** @type {?WebInspector.DebuggerModel.CallFrame} */ (event.data);
+
+ if (!callFrame || callFrame.target() !== WebInspector.context.flavor(WebInspector.Target))
+ return;
+
+ this._selectCallFrame(callFrame);
+ },
+
+ /**
+ * @param {!WebInspector.DebuggerModel.CallFrame} callFrame
+ */
+ _selectCallFrame: function(callFrame)
+ {
+ this.sidebarPanes.scopechain.update(callFrame);
+ this.sidebarPanes.watchExpressions.refreshExpressions();
+ this.sidebarPanes.callstack.setSelectedCallFrame(callFrame);
+ callFrame.createLiveLocation(this._executionLineChanged.bind(this));
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sourceSelected: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.uiSourceCode);
+ this._sourcesView.showSourceLocation(uiSourceCode, undefined, undefined, !event.data.focusSource)
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sourceRenamed: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._sourcesView.sourceRenamed(uiSourceCode);
+ },
+
+ _pauseOnExceptionEnabledChanged: function()
+ {
+ var enabled = WebInspector.settings.pauseOnExceptionEnabled.get();
+ this._pauseOnExceptionButton.toggled = enabled;
+ this._pauseOnExceptionButton.title = WebInspector.UIString(enabled ? "Don't pause on exceptions." : "Pause on exceptions.");
+ this._debugToolbarDrawer.classList.toggle("expanded", enabled);
+ },
+
+ _updateDebuggerButtons: function()
+ {
+ var currentTarget = WebInspector.context.flavor(WebInspector.Target);
+ if (!currentTarget)
+ return;
+
+ if (this._paused) {
+ this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Resume script execution (%s)."))
+ this._pauseButton.state = true;
+ this._pauseButton.setLongClickOptionsEnabled((function() { return [ this._longResumeButton ] }).bind(this));
+
+ this._pauseButton.setEnabled(true);
+ this._stepOverButton.setEnabled(true);
+ this._stepIntoButton.setEnabled(true);
+ this._stepOutButton.setEnabled(true);
+ } else {
+ this._updateButtonTitle(this._pauseButton, WebInspector.UIString("Pause script execution (%s)."))
+ this._pauseButton.state = false;
+ this._pauseButton.setLongClickOptionsEnabled(null);
+
+ this._pauseButton.setEnabled(!currentTarget.debuggerModel.isPausing());
+ this._stepOverButton.setEnabled(false);
+ this._stepIntoButton.setEnabled(false);
+ this._stepOutButton.setEnabled(false);
+ }
+ },
+
+ _clearInterface: function()
+ {
+ this.sidebarPanes.callstack.update(null);
+ this.sidebarPanes.scopechain.update(null);
+ this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight();
+ WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight();
+ this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight();
+ this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight();
+
+ this._sourcesView.clearCurrentExecutionLine();
+ this._updateDebuggerButtons();
+ },
+
+ _togglePauseOnExceptions: function()
+ {
+ WebInspector.settings.pauseOnExceptionEnabled.set(!this._pauseOnExceptionButton.toggled);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _runSnippet: function()
+ {
+ var uiSourceCode = this._sourcesView.currentUISourceCode();
+ if (uiSourceCode.project().type() !== WebInspector.projectTypes.Snippets)
+ return false;
+
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (!currentExecutionContext)
+ return false;
+
+ WebInspector.scriptSnippetModel.evaluateScriptSnippet(currentExecutionContext, uiSourceCode);
+ return true;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorSelected: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._editorChanged(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _editorClosed: function(event)
+ {
+ var wasSelected = /** @type {boolean} */ (event.data.wasSelected);
+ if (wasSelected)
+ this._editorChanged(null);
+ },
+
+ /**
+ * @param {?WebInspector.UISourceCode} uiSourceCode
+ */
+ _editorChanged: function(uiSourceCode)
+ {
+ var isSnippet = uiSourceCode && uiSourceCode.project().type() === WebInspector.projectTypes.Snippets;
+ this._runSnippetButton.element.classList.toggle("hidden", !isSnippet);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ togglePause: function()
+ {
+ var target = WebInspector.context.flavor(WebInspector.Target);
+ if (!target)
+ return true;
+
+ if (this._paused) {
+ delete this._skipExecutionLineRevealing;
+ this._paused = false;
+ target.debuggerModel.resume();
+ } else {
+ // Make sure pauses didn't stick skipped.
+ target.debuggerModel.pause();
+ }
+
+ this._clearInterface();
+ return true;
+ },
+
+ /**
+ * @return {?WebInspector.DebuggerModel}
+ */
+ _prepareToResume: function()
+ {
+ if (!this._paused)
+ return null;
+
+ delete this._skipExecutionLineRevealing;
+ this._paused = false;
+
+ this._clearInterface();
+ var target = WebInspector.context.flavor(WebInspector.Target);
+ return target ? target.debuggerModel : null;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _longResume: function()
+ {
+ var debuggerModel = this._prepareToResume();
+ if (!debuggerModel)
+ return true;
+
+ debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
+ debuggerModel.resume();
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _stepOverClicked: function()
+ {
+ var debuggerModel = this._prepareToResume();
+ if (!debuggerModel)
+ return true;
+
+ debuggerModel.stepOver();
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _stepIntoClicked: function()
+ {
+ var debuggerModel = this._prepareToResume();
+ if (!debuggerModel)
+ return true;
+
+ debuggerModel.stepInto();
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _stepOutClicked: function()
+ {
+ var debuggerModel = this._prepareToResume();
+ if (!debuggerModel)
+ return true;
+
+ debuggerModel.stepOut();
+ return true;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _callFrameSelectedInSidebar: function(event)
+ {
+ var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data);
+ delete this._skipExecutionLineRevealing;
+ callFrame.target().debuggerModel.setSelectedCallFrame(callFrame);
+ },
+
+ _callFrameRestartedInSidebar: function()
+ {
+ delete this._skipExecutionLineRevealing;
+ },
+
+ /**
+ * @param {!WebInspector.DebuggerModel.Location} rawLocation
+ */
+ continueToLocation: function(rawLocation)
+ {
+ if (!this._prepareToResume())
+ return;
+
+ rawLocation.continueToLocation();
+ },
+
+ _toggleBreakpointsClicked: function(event)
+ {
+ WebInspector.debuggerModel.setBreakpointsActive(!WebInspector.debuggerModel.breakpointsActive());
+ },
+
+ _breakpointsActiveStateChanged: function(event)
+ {
+ var active = event.data;
+ this._toggleBreakpointsButton.toggled = !active;
+ this.sidebarPanes.jsBreakpoints.listElement.classList.toggle("breakpoints-list-deactivated", !active);
+ this._sourcesView.toggleBreakpointsActiveState(active);
+ if (active)
+ this._toggleBreakpointsButton.title = WebInspector.UIString("Deactivate breakpoints.");
+ else
+ this._toggleBreakpointsButton.title = WebInspector.UIString("Activate breakpoints.");
+ },
+
+ _createDebugToolbar: function()
+ {
+ var debugToolbar = document.createElement("div");
+ debugToolbar.className = "scripts-debug-toolbar";
+
+ var title, handler;
+ var platformSpecificModifier = WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta;
+
+ // Run snippet.
+ title = WebInspector.UIString("Run snippet (%s).");
+ handler = this._runSnippet.bind(this);
+ this._runSnippetButton = this._createButtonAndRegisterShortcuts("scripts-run-snippet", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.RunSnippet);
+ debugToolbar.appendChild(this._runSnippetButton.element);
+ this._runSnippetButton.element.classList.add("hidden");
+
+ // Continue.
+ handler = function() { return WebInspector.actionRegistry.execute("debugger.toggle-pause"); };
+ this._pauseButton = this._createButtonAndRegisterShortcuts("scripts-pause", "", handler, []);
+ debugToolbar.appendChild(this._pauseButton.element);
+
+ // Long resume.
+ title = WebInspector.UIString("Resume with all pauses blocked for 500 ms");
+ this._longResumeButton = new WebInspector.StatusBarButton(title, "scripts-long-resume");
+ this._longResumeButton.addEventListener("click", this._longResume.bind(this), this);
+
+ // Step over.
+ title = WebInspector.UIString("Step over next function call (%s).");
+ handler = this._stepOverClicked.bind(this);
+ this._stepOverButton = this._createButtonAndRegisterShortcuts("scripts-step-over", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOver);
+ debugToolbar.appendChild(this._stepOverButton.element);
+
+ // Step into.
+ title = WebInspector.UIString("Step into next function call (%s).");
+ handler = this._stepIntoClicked.bind(this);
+ this._stepIntoButton = this._createButtonAndRegisterShortcuts("scripts-step-into", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepInto);
+ debugToolbar.appendChild(this._stepIntoButton.element);
+
+ // Step out.
+ title = WebInspector.UIString("Step out of current function (%s).");
+ handler = this._stepOutClicked.bind(this);
+ this._stepOutButton = this._createButtonAndRegisterShortcuts("scripts-step-out", title, handler, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.StepOut);
+ debugToolbar.appendChild(this._stepOutButton.element);
+
+ // Toggle Breakpoints
+ this._toggleBreakpointsButton = new WebInspector.StatusBarButton(WebInspector.UIString("Deactivate breakpoints."), "scripts-toggle-breakpoints");
+ this._toggleBreakpointsButton.toggled = false;
+ this._toggleBreakpointsButton.addEventListener("click", this._toggleBreakpointsClicked, this);
+ debugToolbar.appendChild(this._toggleBreakpointsButton.element);
+
+ // Pause on Exception
+ this._pauseOnExceptionButton = new WebInspector.StatusBarButton("", "scripts-pause-on-exceptions-status-bar-item");
+ this._pauseOnExceptionButton.addEventListener("click", this._togglePauseOnExceptions, this);
+ debugToolbar.appendChild(this._pauseOnExceptionButton.element);
+
+ return debugToolbar;
+ },
+
+ _createDebugToolbarDrawer: function()
+ {
+ var debugToolbarDrawer = document.createElement("div");
+ debugToolbarDrawer.className = "scripts-debug-toolbar-drawer";
+
+ var label = WebInspector.UIString("Pause On Caught Exceptions");
+ var setting = WebInspector.settings.pauseOnCaughtException;
+ debugToolbarDrawer.appendChild(WebInspector.SettingsUI.createSettingCheckbox(label, setting, true));
+
+ return debugToolbarDrawer;
+ },
+
+ /**
+ * @param {!WebInspector.StatusBarButton} button
+ * @param {string} buttonTitle
+ */
+ _updateButtonTitle: function(button, buttonTitle)
+ {
+ var hasShortcuts = button.shortcuts && button.shortcuts.length;
+ if (hasShortcuts)
+ button.title = String.vsprintf(buttonTitle, [button.shortcuts[0].name]);
+ else
+ button.title = buttonTitle;
+ },
+
+ /**
+ * @param {string} buttonId
+ * @param {string} buttonTitle
+ * @param {function(?Event=):boolean} handler
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
+ * @return {!WebInspector.StatusBarButton}
+ */
+ _createButtonAndRegisterShortcuts: function(buttonId, buttonTitle, handler, shortcuts)
+ {
+ var button = new WebInspector.StatusBarButton(buttonTitle, buttonId);
+ button.element.addEventListener("click", handler, false);
+ button.shortcuts = shortcuts;
+ this._updateButtonTitle(button, buttonTitle);
+ this.registerShortcuts(shortcuts, handler);
+ return button;
+ },
+
+ addToWatch: function(expression)
+ {
+ this.sidebarPanes.watchExpressions.addExpression(expression);
+ },
+
+ _installDebuggerSidebarController: function()
+ {
+ this._toggleNavigatorSidebarButton = this.editorView.createShowHideSidebarButton("navigator", "scripts-navigator-show-hide-button");
+ this.editorView.mainElement().appendChild(this._toggleNavigatorSidebarButton.element);
+
+ this._toggleDebuggerSidebarButton = this._splitView.createShowHideSidebarButton("debugger", "scripts-debugger-show-hide-button");
+
+ this._splitView.mainElement().appendChild(this._toggleDebuggerSidebarButton.element);
+ this._splitView.mainElement().appendChild(this._debugSidebarResizeWidgetElement);
+ },
+
+ _updateDebugSidebarResizeWidget: function()
+ {
+ this._debugSidebarResizeWidgetElement.classList.toggle("hidden", this._splitView.showMode() !== WebInspector.SplitView.ShowMode.Both);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _showLocalHistory: function(uiSourceCode)
+ {
+ WebInspector.RevisionHistoryView.showHistory(uiSourceCode);
+ },
+
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ this._appendUISourceCodeItems(event, contextMenu, target);
+ this._appendRemoteObjectItems(contextMenu, target);
+ },
+
+ _suggestReload: function()
+ {
+ if (window.confirm(WebInspector.UIString("It is recommended to restart inspector after making these changes. Would you like to restart it?")))
+ WebInspector.reload();
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _mapFileSystemToNetwork: function(uiSourceCode)
+ {
+ WebInspector.SelectUISourceCodeForProjectTypesDialog.show(uiSourceCode.name(), [WebInspector.projectTypes.Network, WebInspector.projectTypes.ContentScripts], mapFileSystemToNetwork.bind(this), this.editorView.mainElement())
+
+ /**
+ * @param {!WebInspector.UISourceCode} networkUISourceCode
+ * @this {WebInspector.SourcesPanel}
+ */
+ function mapFileSystemToNetwork(networkUISourceCode)
+ {
+ this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding);
+ this._suggestReload();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _removeNetworkMapping: function(uiSourceCode)
+ {
+ if (confirm(WebInspector.UIString("Are you sure you want to remove network mapping?"))) {
+ this._workspace.removeMapping(uiSourceCode);
+ this._suggestReload();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} networkUISourceCode
+ */
+ _mapNetworkToFileSystem: function(networkUISourceCode)
+ {
+ WebInspector.SelectUISourceCodeForProjectTypesDialog.show(networkUISourceCode.name(), [WebInspector.projectTypes.FileSystem], mapNetworkToFileSystem.bind(this), this.editorView.mainElement())
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @this {WebInspector.SourcesPanel}
+ */
+ function mapNetworkToFileSystem(uiSourceCode)
+ {
+ this._workspace.addMapping(networkUISourceCode, uiSourceCode, WebInspector.fileSystemWorkspaceBinding);
+ this._suggestReload();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _appendUISourceCodeMappingItems: function(contextMenu, uiSourceCode)
+ {
+ if (uiSourceCode.project().type() === WebInspector.projectTypes.FileSystem) {
+ var hasMappings = !!uiSourceCode.url;
+ if (!hasMappings)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to network resource\u2026" : "Map to Network Resource\u2026"), this._mapFileSystemToNetwork.bind(this, uiSourceCode));
+ else
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove network mapping" : "Remove Network Mapping"), this._removeNetworkMapping.bind(this, uiSourceCode));
+ }
+
+ /**
+ * @param {!WebInspector.Project} project
+ */
+ function filterProject(project)
+ {
+ return project.type() === WebInspector.projectTypes.FileSystem;
+ }
+
+ if (uiSourceCode.project().type() === WebInspector.projectTypes.Network || uiSourceCode.project().type() === WebInspector.projectTypes.ContentScripts) {
+ if (!this._workspace.projects().filter(filterProject).length)
+ return;
+ if (this._workspace.uiSourceCodeForURL(uiSourceCode.url) === uiSourceCode)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Map to file system resource\u2026" : "Map to File System Resource\u2026"), this._mapNetworkToFileSystem.bind(this, uiSourceCode));
+ }
+ },
+
+ /**
+ * @param {?Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ _appendUISourceCodeItems: function(event, contextMenu, target)
+ {
+ if (!(target instanceof WebInspector.UISourceCode))
+ return;
+
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (target);
+ var project = uiSourceCode.project();
+ if (project.type() !== WebInspector.projectTypes.FileSystem)
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Local modifications\u2026" : "Local Modifications\u2026"), this._showLocalHistory.bind(this, uiSourceCode));
+ this._appendUISourceCodeMappingItems(contextMenu, uiSourceCode);
+
+ if (!event.target.isSelfOrDescendant(this.editorView.sidebarElement())) {
+ contextMenu.appendSeparator();
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Reveal in navigator" : "Reveal in Navigator"), this._handleContextMenuReveal.bind(this, uiSourceCode));
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _handleContextMenuReveal: function(uiSourceCode)
+ {
+ this.editorView.showBoth();
+ this._revealInNavigator(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ _appendRemoteObjectItems: function(contextMenu, target)
+ {
+ if (!(target instanceof WebInspector.RemoteObject))
+ return;
+ var remoteObject = /** @type {!WebInspector.RemoteObject} */ (target);
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Store as global variable" : "Store as Global Variable"), this._saveToTempVariable.bind(this, remoteObject));
+ if (remoteObject.type === "function")
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Show function definition" : "Show Function Definition"), this._showFunctionDefinition.bind(this, remoteObject));
+ },
+
+ /**
+ * @param {!WebInspector.RemoteObject} remoteObject
+ */
+ _saveToTempVariable: function(remoteObject)
+ {
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (!currentExecutionContext)
+ return;
+
+ currentExecutionContext.evaluate("window", "", false, true, false, false, didGetGlobalObject.bind(null, currentExecutionContext.target()));
+ /**
+ * @param {!WebInspector.Target} target
+ * @param {?WebInspector.RemoteObject} global
+ * @param {boolean=} wasThrown
+ */
+ function didGetGlobalObject(target, global, wasThrown)
+ {
+ /**
+ * @suppressReceiverCheck
+ * @this {Window}
+ */
+ function remoteFunction(value)
+ {
+ var prefix = "temp";
+ var index = 1;
+ while ((prefix + index) in this)
+ ++index;
+ var name = prefix + index;
+ this[name] = value;
+ return name;
+ }
+
+ if (wasThrown || !global)
+ failedToSave(target, global);
+ else
+ global.callFunction(remoteFunction, [WebInspector.RemoteObject.toCallArgument(remoteObject)], didSave.bind(null, global));
+ }
+
+ /**
+ * @param {!WebInspector.RemoteObject} global
+ * @param {?WebInspector.RemoteObject} result
+ * @param {boolean=} wasThrown
+ */
+ function didSave(global, result, wasThrown)
+ {
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ global.release();
+ if (!currentExecutionContext || wasThrown || !result || result.type !== "string")
+ failedToSave(global.target(), result);
+ else
+ WebInspector.ConsoleModel.evaluateCommandInConsole(currentExecutionContext, result.value);
+ }
+
+ /**
+ * @param {!WebInspector.Target} target
+ * @param {?WebInspector.RemoteObject} result
+ */
+ function failedToSave(target, result)
+ {
+ var message = WebInspector.UIString("Failed to save to temp variable.");
+ if (result) {
+ message += " " + result.description;
+ result.release();
+ }
+ target.consoleModel.showErrorMessage(message);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.RemoteObject} remoteObject
+ */
+ _showFunctionDefinition: function(remoteObject)
+ {
+ var target = remoteObject.target();
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {!DebuggerAgent.FunctionDetails} response
+ * @this {WebInspector.SourcesPanel}
+ */
+ function didGetFunctionDetails(error, response)
+ {
+ if (error) {
+ console.error(error);
+ return;
+ }
+
+ var uiLocation = target.debuggerModel.rawLocationToUILocation(response.location);
+ if (!uiLocation)
+ return;
+
+ this.showUILocation(uiLocation, true);
+ }
+ target.debuggerAgent().getFunctionDetails(remoteObject.objectId, didGetFunctionDetails.bind(this));
+ },
+
+ showGoToSourceDialog: function()
+ {
+ this._sourcesView.showOpenResourceDialog();
+ },
+
+ _dockSideChanged: function()
+ {
+ var vertically = WebInspector.dockController.isVertical() && WebInspector.settings.splitVerticallyWhenDockedToRight.get();
+ this._splitVertically(vertically);
+ },
+
+ /**
+ * @param {boolean} vertically
+ */
+ _splitVertically: function(vertically)
+ {
+ if (this.sidebarPaneView && vertically === !this._splitView.isVertical())
+ return;
+
+ if (this.sidebarPaneView)
+ this.sidebarPaneView.detach();
+
+ this._splitView.setVertical(!vertically);
+
+ if (!vertically)
+ this._splitView.uninstallResizer(this._sourcesView.statusBarContainerElement());
+ else
+ this._splitView.installResizer(this._sourcesView.statusBarContainerElement());
+
+ // Create vertical box with stack.
+ var vbox = new WebInspector.VBox();
+ vbox.element.appendChild(this._debugToolbarDrawer);
+ vbox.element.appendChild(this.debugToolbar);
+ vbox.element.appendChild(this._targetsToolbar.element);
+ vbox.setMinimumAndPreferredSizes(25, 25, WebInspector.SourcesPanel.minToolbarWidth, 100);
+ var sidebarPaneStack = new WebInspector.SidebarPaneStack();
+ sidebarPaneStack.element.classList.add("flex-auto");
+ sidebarPaneStack.show(vbox.element);
+
+ if (!vertically) {
+ // Populate the only stack.
+ for (var pane in this.sidebarPanes)
+ sidebarPaneStack.addPane(this.sidebarPanes[pane]);
+ this._extensionSidebarPanesContainer = sidebarPaneStack;
+
+ this.sidebarPaneView = vbox;
+ } else {
+ var splitView = new WebInspector.SplitView(true, true, "sourcesPanelDebuggerSidebarSplitViewState", 0.5);
+ vbox.show(splitView.mainElement());
+
+ // Populate the left stack.
+ sidebarPaneStack.addPane(this.sidebarPanes.callstack);
+ sidebarPaneStack.addPane(this.sidebarPanes.jsBreakpoints);
+ sidebarPaneStack.addPane(this.sidebarPanes.domBreakpoints);
+ sidebarPaneStack.addPane(this.sidebarPanes.xhrBreakpoints);
+ sidebarPaneStack.addPane(this.sidebarPanes.eventListenerBreakpoints);
+ if (this.sidebarPanes.workerList)
+ sidebarPaneStack.addPane(this.sidebarPanes.workerList);
+
+ var tabbedPane = new WebInspector.SidebarTabbedPane();
+ tabbedPane.show(splitView.sidebarElement());
+ tabbedPane.addPane(this.sidebarPanes.scopechain);
+ tabbedPane.addPane(this.sidebarPanes.watchExpressions);
+ this._extensionSidebarPanesContainer = tabbedPane;
+
+ this.sidebarPaneView = splitView;
+ }
+ for (var i = 0; i < this._extensionSidebarPanes.length; ++i)
+ this._extensionSidebarPanesContainer.addPane(this._extensionSidebarPanes[i]);
+
+ this.sidebarPaneView.show(this._splitView.sidebarElement());
+
+ this.sidebarPanes.scopechain.expand();
+ this.sidebarPanes.jsBreakpoints.expand();
+ this.sidebarPanes.callstack.expand();
+
+ if (WebInspector.settings.watchExpressions.get().length > 0)
+ this.sidebarPanes.watchExpressions.expand();
+ },
+
+ /**
+ * @param {string} id
+ * @param {!WebInspector.SidebarPane} pane
+ */
+ addExtensionSidebarPane: function(id, pane)
+ {
+ this._extensionSidebarPanes.push(pane);
+ this._extensionSidebarPanesContainer.addPane(pane);
+ this.setHideOnDetach();
+ },
+
+ /**
+ * @return {!WebInspector.SourcesView}
+ */
+ sourcesView: function()
+ {
+ return this._sourcesView;
+ },
+
+ __proto__: WebInspector.Panel.prototype
+}
+
+/**
+ * @constructor
+ * @param {!Element} element
+ */
+WebInspector.UpgradeFileSystemDropTarget = function(element)
+{
+ element.addEventListener("dragenter", this._onDragEnter.bind(this), true);
+ element.addEventListener("dragover", this._onDragOver.bind(this), true);
+ this._element = element;
+}
+
+WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType = "Files";
+
+WebInspector.UpgradeFileSystemDropTarget.prototype = {
+ _onDragEnter: function (event)
+ {
+ if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1)
+ return;
+ event.consume(true);
+ },
+
+ _onDragOver: function (event)
+ {
+ if (event.dataTransfer.types.indexOf(WebInspector.UpgradeFileSystemDropTarget.dragAndDropFilesType) === -1)
+ return;
+ event.dataTransfer.dropEffect = "copy";
+ event.consume(true);
+ if (this._dragMaskElement)
+ return;
+ this._dragMaskElement = this._element.createChild("div", "fill drag-mask");
+ this._dragMaskElement.createChild("div", "fill drag-mask-inner").textContent = WebInspector.UIString("Drop workspace folder here");
+ this._dragMaskElement.addEventListener("drop", this._onDrop.bind(this), true);
+ this._dragMaskElement.addEventListener("dragleave", this._onDragLeave.bind(this), true);
+ },
+
+ _onDrop: function (event)
+ {
+ event.consume(true);
+ this._removeMask();
+ var items = /** @type {!Array.<!DataTransferItem>} */ (event.dataTransfer.items);
+ if (!items.length)
+ return;
+ var entry = items[0].webkitGetAsEntry();
+ if (!entry.isDirectory)
+ return;
+ InspectorFrontendHost.upgradeDraggedFileSystemPermissions(entry.filesystem);
+ },
+
+ _onDragLeave: function (event)
+ {
+ event.consume(true);
+ this._removeMask();
+ },
+
+ _removeMask: function ()
+ {
+ this._dragMaskElement.remove();
+ delete this._dragMaskElement;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.DrawerEditor}
+ */
+WebInspector.SourcesPanel.DrawerEditor = function()
+{
+ this._panel = WebInspector.inspectorView.panel("sources");
+}
+
+WebInspector.SourcesPanel.DrawerEditor.prototype = {
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function()
+ {
+ return this._panel._drawerEditorView;
+ },
+
+ installedIntoDrawer: function()
+ {
+ if (this._panel.isShowing())
+ this._panelWasShown();
+ else
+ this._panelWillHide();
+ },
+
+ _panelWasShown: function()
+ {
+ WebInspector.inspectorView.setDrawerEditorAvailable(false);
+ WebInspector.inspectorView.hideDrawerEditor();
+ },
+
+ _panelWillHide: function()
+ {
+ WebInspector.inspectorView.setDrawerEditorAvailable(true);
+ if (WebInspector.inspectorView.isDrawerEditorShown())
+ WebInspector.inspectorView.showDrawerEditor();
+ },
+
+ _show: function()
+ {
+ WebInspector.inspectorView.showDrawerEditor();
+ },
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.SourcesPanel.DrawerEditorView = function()
+{
+ WebInspector.VBox.call(this);
+ this.element.id = "drawer-editor-view";
+}
+
+WebInspector.SourcesPanel.DrawerEditorView.prototype = {
+ __proto__: WebInspector.VBox.prototype
+}
+
+
+/**
+ * @constructor
+ * @implements {WebInspector.ContextMenu.Provider}
+ */
+WebInspector.SourcesPanel.ContextMenuProvider = function()
+{
+}
+
+WebInspector.SourcesPanel.ContextMenuProvider.prototype = {
+ /**
+ * @param {!Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {!Object} target
+ */
+ appendApplicableItems: function(event, contextMenu, target)
+ {
+ WebInspector.inspectorView.panel("sources").appendApplicableItems(event, contextMenu, target);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.SourcesPanel.UILocationRevealer = function()
+{
+}
+
+WebInspector.SourcesPanel.UILocationRevealer.prototype = {
+ /**
+ * @param {!Object} uiLocation
+ */
+ reveal: function(uiLocation)
+ {
+ if (uiLocation instanceof WebInspector.UILocation)
+ /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUILocation(uiLocation);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.Revealer}
+ */
+WebInspector.SourcesPanel.UISourceCodeRevealer = function()
+{
+}
+
+WebInspector.SourcesPanel.UISourceCodeRevealer.prototype = {
+ /**
+ * @param {!Object} uiSourceCode
+ */
+ reveal: function(uiSourceCode)
+ {
+ if (uiSourceCode instanceof WebInspector.UISourceCode)
+ /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.panel("sources")).showUISourceCode(uiSourceCode);
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate = function() {}
+
+WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.showPanel("sources")).showGoToSourceDialog();
+ return true;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.UISettingDelegate}
+ */
+WebInspector.SourcesPanel.SkipStackFramePatternSettingDelegate = function()
+{
+ WebInspector.UISettingDelegate.call(this);
+}
+
+WebInspector.SourcesPanel.SkipStackFramePatternSettingDelegate.prototype = {
+ /**
+ * @override
+ * @return {!Element}
+ */
+ settingElement: function()
+ {
+ return WebInspector.SettingsUI.createSettingInputField(WebInspector.UIString("Pattern"), WebInspector.settings.skipStackFramesPattern, false, 1000, "100px", WebInspector.SettingsUI.regexValidator);
+ },
+
+ __proto__: WebInspector.UISettingDelegate.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.UISettingDelegate}
+ */
+WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate = function()
+{
+ WebInspector.UISettingDelegate.call(this);
+}
+
+WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate.prototype = {
+ /**
+ * @override
+ * @return {!Element}
+ */
+ settingElement: function()
+ {
+ var disableJSElement = WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Disable JavaScript"), WebInspector.settings.javaScriptDisabled);
+ this._disableJSCheckbox = disableJSElement.getElementsByTagName("input")[0];
+ WebInspector.settings.javaScriptDisabled.addChangeListener(this._settingChanged, this);
+ var disableJSInfoParent = this._disableJSCheckbox.parentElement.createChild("span", "monospace");
+ this._disableJSInfo = disableJSInfoParent.createChild("span", "object-info-state-note hidden");
+ this._disableJSInfo.title = WebInspector.UIString("JavaScript is blocked on the inspected page (may be disabled in browser settings).");
+
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._updateScriptDisabledCheckbox, this);
+ this._updateScriptDisabledCheckbox();
+ return disableJSElement;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _settingChanged: function(event)
+ {
+ PageAgent.setScriptExecutionDisabled(event.data, this._updateScriptDisabledCheckbox.bind(this));
+ },
+
+ _updateScriptDisabledCheckbox: function()
+ {
+ PageAgent.getScriptExecutionStatus(executionStatusCallback.bind(this));
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {string} status
+ * @this {WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate}
+ */
+ function executionStatusCallback(error, status)
+ {
+ if (error || !status)
+ return;
+
+ var forbidden = (status === "forbidden");
+ var disabled = forbidden || (status === "disabled");
+
+ this._disableJSInfo.classList.toggle("hidden", !forbidden);
+ this._disableJSCheckbox.checked = disabled;
+ this._disableJSCheckbox.disabled = forbidden;
+ }
+ },
+
+ __proto__: WebInspector.UISettingDelegate.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ActionDelegate}
+ */
+WebInspector.SourcesPanel.TogglePauseActionDelegate = function()
+{
+}
+
+WebInspector.SourcesPanel.TogglePauseActionDelegate.prototype = {
+ /**
+ * @return {boolean}
+ */
+ handleAction: function()
+ {
+ /** @type {!WebInspector.SourcesPanel} */ (WebInspector.inspectorView.showPanel("sources")).togglePause();
+ return true;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
new file mode 100644
index 00000000000..12257d2b3d0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
@@ -0,0 +1,708 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.TabbedEditorContainerDelegate}
+ * @implements {WebInspector.Searchable}
+ * @implements {WebInspector.Replaceable}
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.Workspace} workspace
+ * @param {!WebInspector.SourcesPanel} sourcesPanel
+ */
+WebInspector.SourcesView = function(workspace, sourcesPanel)
+{
+ WebInspector.VBox.call(this);
+ this.registerRequiredCSS("sourcesView.css");
+ this.element.id = "sources-panel-sources-view";
+ this.setMinimumAndPreferredSizes(50, 25, 150, 100);
+
+ this._workspace = workspace;
+ this._sourcesPanel = sourcesPanel;
+
+ this._searchableView = new WebInspector.SearchableView(this);
+ this._searchableView.setMinimalSearchQuerySize(0);
+ this._searchableView.show(this.element);
+
+ /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.UISourceCodeFrame>} */
+ this._sourceFramesByUISourceCode = new Map();
+
+ var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIString("Hit Cmd+P to open a file") : WebInspector.UIString("Hit Ctrl+P to open a file");
+ this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previouslyViewedFiles", tabbedEditorPlaceholderText);
+ this._editorContainer.show(this._searchableView.element);
+ this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
+ this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);
+
+ this._historyManager = new WebInspector.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));
+
+ this._scriptViewStatusBarItemsContainer = document.createElement("div");
+ this._scriptViewStatusBarItemsContainer.className = "inline-block";
+
+ this._scriptViewStatusBarTextContainer = document.createElement("div");
+ this._scriptViewStatusBarTextContainer.className = "hbox";
+
+ this._statusBarContainerElement = this.element.createChild("div", "sources-status-bar");
+
+ /**
+ * @this {WebInspector.SourcesView}
+ * @param {!WebInspector.SourcesView.EditorAction} EditorAction
+ */
+ function appendButtonForExtension(EditorAction)
+ {
+ this._statusBarContainerElement.appendChild(EditorAction.button(this));
+ }
+ var editorActions = /** @type {!Array.<!WebInspector.SourcesView.EditorAction>} */ (WebInspector.moduleManager.instances(WebInspector.SourcesView.EditorAction));
+ editorActions.forEach(appendButtonForExtension.bind(this));
+
+ this._statusBarContainerElement.appendChild(this._scriptViewStatusBarItemsContainer);
+ this._statusBarContainerElement.appendChild(this._scriptViewStatusBarTextContainer);
+
+ WebInspector.startBatchUpdate();
+ this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
+ WebInspector.endBatchUpdate();
+
+ this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
+ this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);
+
+ function handleBeforeUnload(event)
+ {
+ if (event.returnValue)
+ return;
+ var unsavedSourceCodes = WebInspector.workspace.unsavedSourceCodes();
+ if (!unsavedSourceCodes.length)
+ return;
+
+ event.returnValue = WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");
+ WebInspector.inspectorView.showPanel("sources");
+ for (var i = 0; i < unsavedSourceCodes.length; ++i)
+ WebInspector.Revealer.reveal(unsavedSourceCodes[i]);
+ }
+ window.addEventListener("beforeunload", handleBeforeUnload, true);
+
+ this._shortcuts = {};
+ this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
+}
+
+WebInspector.SourcesView.Events = {
+ EditorClosed: "EditorClosed",
+ EditorSelected: "EditorSelected",
+}
+
+WebInspector.SourcesView.prototype = {
+ /**
+ * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(?Event=):boolean)} registerShortcutDelegate
+ */
+ registerShortcuts: function(registerShortcutDelegate)
+ {
+ /**
+ * @this {WebInspector.SourcesView}
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts
+ * @param {function(?Event=):boolean} handler
+ */
+ function registerShortcut(shortcuts, handler)
+ {
+ registerShortcutDelegate(shortcuts, handler);
+ this._registerShortcuts(shortcuts, handler);
+ }
+
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousLocation, this._onJumpToPreviousLocation.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocation, this._onJumpToNextLocation.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab, this._onCloseEditorTab.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, this._showGoToLineDialog.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, this._showOutlineDialog.bind(this));
+ registerShortcut.call(this, [WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift)], this._showOutlineDialog.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.Save, this._save.bind(this));
+ registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.SaveAll, this._saveAll.bind(this));
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys
+ * @param {function(?Event=):boolean} handler
+ */
+ _registerShortcuts: function(keys, handler)
+ {
+ for (var i = 0; i < keys.length; ++i)
+ this._shortcuts[keys[i].key] = handler;
+ },
+
+ _handleKeyDown: function(event)
+ {
+ var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
+ var handler = this._shortcuts[shortcutKey];
+ if (handler && handler())
+ event.consume(true);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ statusBarContainerElement: function()
+ {
+ return this._statusBarContainerElement;
+ },
+
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this._editorContainer.view.defaultFocusedElement();
+ },
+
+ /**
+ * @return {!WebInspector.SearchableView}
+ */
+ searchableView: function()
+ {
+ return this._searchableView;
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ visibleView: function()
+ {
+ return this._editorContainer.visibleView;
+ },
+
+ /**
+ * @return {?WebInspector.SourceFrame}
+ */
+ currentSourceFrame: function()
+ {
+ var view = this.visibleView();
+ if (!(view instanceof WebInspector.SourceFrame))
+ return null;
+ return /** @type {!WebInspector.SourceFrame} */ (view);
+ },
+
+ /**
+ * @return {?WebInspector.UISourceCode}
+ */
+ currentUISourceCode: function()
+ {
+ return this._currentUISourceCode;
+ },
+
+ /**
+ * @param {?Event=} event
+ */
+ _onCloseEditorTab: function(event)
+ {
+ var uiSourceCode = this.currentUISourceCode();
+ if (!uiSourceCode)
+ return false;
+ this._editorContainer.closeFile(uiSourceCode);
+ return true;
+ },
+
+ /**
+ * @param {?Event=} event
+ */
+ _onJumpToPreviousLocation: function(event)
+ {
+ this._historyManager.rollback();
+ return true;
+ },
+
+ /**
+ * @param {?Event=} event
+ */
+ _onJumpToNextLocation: function(event)
+ {
+ this._historyManager.rollover();
+ return true;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _uiSourceCodeAdded: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._addUISourceCode(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _addUISourceCode: function(uiSourceCode)
+ {
+ if (uiSourceCode.project().isServiceProject())
+ return;
+ this._editorContainer.addUISourceCode(uiSourceCode);
+ // Replace debugger script-based uiSourceCode with a network-based one.
+ var currentUISourceCode = this._currentUISourceCode;
+ if (currentUISourceCode && currentUISourceCode.project().isServiceProject() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSourceCode.url) {
+ this._showFile(uiSourceCode);
+ this._editorContainer.removeUISourceCode(currentUISourceCode);
+ }
+ },
+
+ _uiSourceCodeRemoved: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._removeUISourceCodes([uiSourceCode]);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes
+ */
+ _removeUISourceCodes: function(uiSourceCodes)
+ {
+ this._editorContainer.removeUISourceCodes(uiSourceCodes);
+ for (var i = 0; i < uiSourceCodes.length; ++i) {
+ this._removeSourceFrame(uiSourceCodes[i]);
+ this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
+ }
+ },
+
+ _projectRemoved: function(event)
+ {
+ var project = event.data;
+ var uiSourceCodes = project.uiSourceCodes();
+ this._removeUISourceCodes(uiSourceCodes);
+ if (project.type() === WebInspector.projectTypes.Network)
+ this._editorContainer.reset();
+ },
+
+ _updateScriptViewStatusBarItems: function()
+ {
+ this._scriptViewStatusBarItemsContainer.removeChildren();
+ this._scriptViewStatusBarTextContainer.removeChildren();
+ var sourceFrame = this.currentSourceFrame();
+ if (!sourceFrame)
+ return;
+
+ var statusBarItems = sourceFrame.statusBarItems() || [];
+ for (var i = 0; i < statusBarItems.length; ++i)
+ this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
+ var statusBarText = sourceFrame.statusBarText();
+ if (statusBarText)
+ this._scriptViewStatusBarTextContainer.appendChild(statusBarText);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @param {number=} lineNumber
+ * @param {number=} columnNumber
+ * @param {boolean=} omitFocus
+ * @param {boolean=} omitHighlight
+ */
+ showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHighlight)
+ {
+ this._historyManager.updateCurrentState();
+ var sourceFrame = this._showFile(uiSourceCode);
+ if (typeof lineNumber === "number")
+ sourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight);
+ this._historyManager.pushNewState();
+ if (!omitFocus)
+ sourceFrame.focus();
+ WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
+ action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
+ url: uiSourceCode.originURL(),
+ lineNumber: lineNumber
+ });
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {!WebInspector.SourceFrame}
+ */
+ _showFile: function(uiSourceCode)
+ {
+ var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
+ if (this._currentUISourceCode === uiSourceCode)
+ return sourceFrame;
+
+ this._currentUISourceCode = uiSourceCode;
+ this._editorContainer.showFile(uiSourceCode);
+ this._updateScriptViewStatusBarItems();
+ return sourceFrame;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {!WebInspector.UISourceCodeFrame}
+ */
+ _createSourceFrame: function(uiSourceCode)
+ {
+ var sourceFrame;
+ switch (uiSourceCode.contentType()) {
+ case WebInspector.resourceTypes.Script:
+ sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode);
+ break;
+ case WebInspector.resourceTypes.Document:
+ sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPanel, uiSourceCode);
+ break;
+ case WebInspector.resourceTypes.Stylesheet:
+ sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode);
+ break;
+ default:
+ sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
+ break;
+ }
+ sourceFrame.setHighlighterType(uiSourceCode.highlighterType());
+ this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
+ this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
+ return sourceFrame;
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {!WebInspector.UISourceCodeFrame}
+ */
+ _getOrCreateSourceFrame: function(uiSourceCode)
+ {
+ return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._createSourceFrame(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.SourceFrame} sourceFrame
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {boolean}
+ */
+ _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode)
+ {
+ switch (uiSourceCode.contentType()) {
+ case WebInspector.resourceTypes.Script:
+ case WebInspector.resourceTypes.Document:
+ return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;
+ case WebInspector.resourceTypes.Stylesheet:
+ return sourceFrame instanceof WebInspector.CSSSourceFrame;
+ default:
+ return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _recreateSourceFrameIfNeeded: function(uiSourceCode)
+ {
+ var oldSourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
+ if (!oldSourceFrame)
+ return;
+ if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
+ oldSourceFrame.setHighlighterType(uiSourceCode.highlighterType());
+ } else {
+ this._editorContainer.removeUISourceCode(uiSourceCode);
+ this._removeSourceFrame(uiSourceCode);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ * @return {!WebInspector.SourceFrame}
+ */
+ viewForFile: function(uiSourceCode)
+ {
+ return this._getOrCreateSourceFrame(uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ _removeSourceFrame: function(uiSourceCode)
+ {
+ var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
+ if (!sourceFrame)
+ return;
+ this._sourceFramesByUISourceCode.remove(uiSourceCode);
+ sourceFrame.dispose();
+ },
+
+ clearCurrentExecutionLine: function()
+ {
+ if (this._executionSourceFrame)
+ this._executionSourceFrame.clearExecutionLine();
+ delete this._executionSourceFrame;
+ },
+
+ setExecutionLine: function(uiLocation)
+ {
+ var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
+ sourceFrame.setExecutionLine(uiLocation.lineNumber);
+ this._executionSourceFrame = sourceFrame;
+ },
+
+ _editorClosed: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
+ this._historyManager.removeHistoryForSourceCode(uiSourceCode);
+
+ var wasSelected = false;
+ if (this._currentUISourceCode === uiSourceCode) {
+ delete this._currentUISourceCode;
+ wasSelected = true;
+ }
+
+ // SourcesNavigator does not need to update on EditorClosed.
+ this._updateScriptViewStatusBarItems();
+ this._searchableView.resetSearch();
+
+ var data = {};
+ data.uiSourceCode = uiSourceCode;
+ data.wasSelected = wasSelected;
+ this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClosed, data);
+ },
+
+ _editorSelected: function(event)
+ {
+ var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data.currentFile);
+ var shouldUseHistoryManager = uiSourceCode !== this._currentUISourceCode && event.data.userGesture;
+ if (shouldUseHistoryManager)
+ this._historyManager.updateCurrentState();
+ var sourceFrame = this._showFile(uiSourceCode);
+ if (shouldUseHistoryManager)
+ this._historyManager.pushNewState();
+
+ this._searchableView.setReplaceable(!!sourceFrame && sourceFrame.canEditSource());
+ this._searchableView.resetSearch();
+
+ this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSelected, uiSourceCode);
+ },
+
+ /**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ sourceRenamed: function(uiSourceCode)
+ {
+ this._recreateSourceFrameIfNeeded(uiSourceCode);
+ },
+
+ searchCanceled: function()
+ {
+ if (this._searchView)
+ this._searchView.searchCanceled();
+
+ delete this._searchView;
+ delete this._searchQuery;
+ },
+
+ /**
+ * @param {string} query
+ * @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
+ */
+ performSearch: function(query, shouldJump, jumpBackwards)
+ {
+ this._searchableView.updateSearchMatchesCount(0);
+
+ var sourceFrame = this.currentSourceFrame();
+ if (!sourceFrame)
+ return;
+
+ this._searchView = sourceFrame;
+ this._searchQuery = query;
+
+ /**
+ * @param {!WebInspector.View} view
+ * @param {number} searchMatches
+ * @this {WebInspector.SourcesView}
+ */
+ function finishedCallback(view, searchMatches)
+ {
+ if (!searchMatches)
+ return;
+
+ this._searchableView.updateSearchMatchesCount(searchMatches);
+ }
+
+ /**
+ * @param {number} currentMatchIndex
+ * @this {WebInspector.SourcesView}
+ */
+ function currentMatchChanged(currentMatchIndex)
+ {
+ this._searchableView.updateCurrentMatchIndex(currentMatchIndex);
+ }
+
+ /**
+ * @this {WebInspector.SourcesView}
+ */
+ function searchResultsChanged()
+ {
+ this._searchableView.cancelSearch();
+ }
+
+ this._searchView.performSearch(query, shouldJump, !!jumpBackwards, finishedCallback.bind(this), currentMatchChanged.bind(this), searchResultsChanged.bind(this));
+ },
+
+ jumpToNextSearchResult: function()
+ {
+ if (!this._searchView)
+ return;
+
+ if (this._searchView !== this.currentSourceFrame()) {
+ this.performSearch(this._searchQuery, true);
+ return;
+ }
+
+ this._searchView.jumpToNextSearchResult();
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ if (!this._searchView)
+ return;
+
+ if (this._searchView !== this.currentSourceFrame()) {
+ this.performSearch(this._searchQuery, true);
+ if (this._searchView)
+ this._searchView.jumpToLastSearchResult();
+ return;
+ }
+
+ this._searchView.jumpToPreviousSearchResult();
+ },
+
+ /**
+ * @param {string} text
+ */
+ replaceSelectionWith: function(text)
+ {
+ var sourceFrame = this.currentSourceFrame();
+ if (!sourceFrame) {
+ console.assert(sourceFrame);
+ return;
+ }
+ sourceFrame.replaceSelectionWith(text);
+ },
+
+ /**
+ * @param {string} query
+ * @param {string} text
+ */
+ replaceAllWith: function(query, text)
+ {
+ var sourceFrame = this.currentSourceFrame();
+ if (!sourceFrame) {
+ console.assert(sourceFrame);
+ return;
+ }
+ sourceFrame.replaceAllWith(query, text);
+ },
+
+ /**
+ * @param {?Event=} event
+ * @return {boolean}
+ */
+ _showOutlineDialog: function(event)
+ {
+ var uiSourceCode = this._editorContainer.currentFile();
+ if (!uiSourceCode)
+ return false;
+
+ switch (uiSourceCode.contentType()) {
+ case WebInspector.resourceTypes.Document:
+ case WebInspector.resourceTypes.Script:
+ WebInspector.JavaScriptOutlineDialog.show(this, uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
+ return true;
+ case WebInspector.resourceTypes.Stylesheet:
+ WebInspector.StyleSheetOutlineDialog.show(this, uiSourceCode, this.showSourceLocation.bind(this, uiSourceCode));
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * @param {string=} query
+ */
+ showOpenResourceDialog: function(query)
+ {
+ var uiSourceCodes = this._editorContainer.historyUISourceCodes();
+ /** @type {!Map.<!WebInspector.UISourceCode, number>} */
+ var defaultScores = new Map();
+ for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
+ defaultScores.put(uiSourceCodes[i], uiSourceCodes.length - i);
+ WebInspector.OpenResourceDialog.show(this, this.element, query, defaultScores);
+ },
+
+ /**
+ * @param {?Event=} event
+ * @return {boolean}
+ */
+ _showGoToLineDialog: function(event)
+ {
+ if (this._currentUISourceCode)
+ this.showOpenResourceDialog(":");
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _save: function()
+ {
+ this._saveSourceFrame(this.currentSourceFrame());
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _saveAll: function()
+ {
+ var sourceFrames = this._editorContainer.fileViews();
+ sourceFrames.forEach(this._saveSourceFrame.bind(this));
+ return true;
+ },
+
+ /**
+ * @param {?WebInspector.SourceFrame} sourceFrame
+ */
+ _saveSourceFrame: function(sourceFrame)
+ {
+ if (!sourceFrame)
+ return;
+ if (!(sourceFrame instanceof WebInspector.UISourceCodeFrame))
+ return;
+ var uiSourceCodeFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (sourceFrame);
+ uiSourceCodeFrame.commitEditing();
+ },
+ /**
+ * @return {boolean}
+ */
+ _toggleBreakpoint: function()
+ {
+ var sourceFrame = this.currentSourceFrame();
+ if (!sourceFrame)
+ return false;
+
+ if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
+ var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourceFrame} */ (sourceFrame);
+ javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * @param {boolean} active
+ */
+ toggleBreakpointsActiveState: function(active)
+ {
+ this._editorContainer.view.element.classList.toggle("breakpoints-deactivated", !active);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @interface
+ */
+WebInspector.SourcesView.EditorAction = function()
+{
+}
+
+WebInspector.SourcesView.EditorAction.prototype = {
+ /**
+ * @param {!WebInspector.SourcesView} sourcesView
+ * @return {!Element}
+ */
+ button: function(sourcesView) { }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/StyleSheetOutlineDialog.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/StyleSheetOutlineDialog.js
index b7f21e5e0e8..05b5f9a6ea0 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/StyleSheetOutlineDialog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/StyleSheetOutlineDialog.js
@@ -29,18 +29,16 @@
/**
* @constructor
* @extends {WebInspector.SelectionDialogContentProvider}
- * @param {!WebInspector.View} view
* @param {!WebInspector.UISourceCode} uiSourceCode
* @param {function(number, number)} selectItemCallback
*/
-WebInspector.StyleSheetOutlineDialog = function(view, uiSourceCode, selectItemCallback)
+WebInspector.StyleSheetOutlineDialog = function(uiSourceCode, selectItemCallback)
{
WebInspector.SelectionDialogContentProvider.call(this);
this._selectItemCallback = selectItemCallback;
- this._rules = [];
- this._view = view;
- this._uiSourceCode = uiSourceCode;
- this._requestItems();
+ this._cssParser = new WebInspector.CSSParser();
+ this._cssParser.addEventListener(WebInspector.CSSParser.Events.RulesParsed, this.refresh.bind(this));
+ this._cssParser.parse(uiSourceCode.workingCopy());
}
/**
@@ -51,8 +49,8 @@ WebInspector.StyleSheetOutlineDialog = function(view, uiSourceCode, selectItemCa
WebInspector.StyleSheetOutlineDialog.show = function(view, uiSourceCode, selectItemCallback)
{
if (WebInspector.Dialog.currentInstance())
- return null;
- var delegate = new WebInspector.StyleSheetOutlineDialog(view, uiSourceCode, selectItemCallback);
+ return;
+ var delegate = new WebInspector.StyleSheetOutlineDialog(uiSourceCode, selectItemCallback);
var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(delegate);
WebInspector.Dialog.show(view.element, filteredItemSelectionDialog);
}
@@ -63,7 +61,7 @@ WebInspector.StyleSheetOutlineDialog.prototype = {
*/
itemCount: function()
{
- return this._rules.length;
+ return this._cssParser.rules().length;
},
/**
@@ -72,7 +70,8 @@ WebInspector.StyleSheetOutlineDialog.prototype = {
*/
itemKeyAt: function(itemIndex)
{
- return this._rules[itemIndex].selectorText;
+ var rule = this._cssParser.rules()[itemIndex];
+ return rule.selectorText || rule.atRule;
},
/**
@@ -82,8 +81,8 @@ WebInspector.StyleSheetOutlineDialog.prototype = {
*/
itemScoreAt: function(itemIndex, query)
{
- var rule = this._rules[itemIndex];
- return -rule.rawLocation.lineNumber;
+ var rule = this._cssParser.rules()[itemIndex];
+ return -rule.lineNumber;
},
/**
@@ -94,47 +93,10 @@ WebInspector.StyleSheetOutlineDialog.prototype = {
*/
renderItem: function(itemIndex, query, titleElement, subtitleElement)
{
- var rule = this._rules[itemIndex];
- titleElement.textContent = rule.selectorText;
+ var rule = this._cssParser.rules()[itemIndex];
+ titleElement.textContent = rule.selectorText || rule.atRule;
this.highlightRanges(titleElement, query);
- subtitleElement.textContent = ":" + (rule.rawLocation.lineNumber + 1);
- },
-
- _requestItems: function()
- {
- /**
- * @param {?Protocol.Error} error
- * @param {!Array.<!CSSAgent.CSSStyleSheetHeader>} infos
- * @this {WebInspector.StyleSheetOutlineDialog}
- */
- function didGetAllStyleSheets(error, infos)
- {
- if (error)
- return;
-
- for (var i = 0; i < infos.length; ++i) {
- var info = infos[i];
- if (info.sourceURL === this._uiSourceCode.url) {
- WebInspector.CSSStyleSheet.createForId(info.styleSheetId, didGetStyleSheet.bind(this));
- return;
- }
- }
- }
-
- CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this));
-
- /**
- * @param {?WebInspector.CSSStyleSheet} styleSheet
- * @this {WebInspector.StyleSheetOutlineDialog}
- */
- function didGetStyleSheet(styleSheet)
- {
- if (!styleSheet)
- return;
-
- this._rules = styleSheet.rules;
- this.refresh();
- }
+ subtitleElement.textContent = ":" + (rule.lineNumber + 1);
},
/**
@@ -143,10 +105,15 @@ WebInspector.StyleSheetOutlineDialog.prototype = {
*/
selectItem: function(itemIndex, promptValue)
{
- var rule = this._rules[itemIndex];
- var lineNumber = rule.rawLocation.lineNumber;
+ var rule = this._cssParser.rules()[itemIndex];
+ var lineNumber = rule.lineNumber;
if (!isNaN(lineNumber) && lineNumber >= 0)
- this._selectItemCallback(lineNumber, rule.rawLocation.columnNumber);
+ this._selectItemCallback(lineNumber, rule.columnNumber);
+ },
+
+ dispose: function()
+ {
+ this._cssParser.dispose();
},
__proto__: WebInspector.SelectionDialogContentProvider.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TabbedEditorContainer.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js
index 931154512c7..b7de95086c4 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TabbedEditorContainer.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/TabbedEditorContainer.js
@@ -36,7 +36,7 @@ WebInspector.TabbedEditorContainerDelegate.prototype = {
* @param {!WebInspector.UISourceCode} uiSourceCode
* @return {!WebInspector.SourceFrame}
*/
- viewForFile: function(uiSourceCode) { }
+ viewForFile: function(uiSourceCode) { },
}
/**
@@ -95,6 +95,14 @@ WebInspector.TabbedEditorContainer.prototype = {
},
/**
+ * @return {!Array.<!WebInspector.SourceFrame>}
+ */
+ fileViews: function()
+ {
+ return /** @type {!Array.<!WebInspector.SourceFrame>} */ (this._tabbedPane.tabViews());
+ },
+
+ /**
* @param {!Element} parentElement
*/
show: function(parentElement)
@@ -111,6 +119,17 @@ WebInspector.TabbedEditorContainer.prototype = {
},
/**
+ * @param {!WebInspector.UISourceCode} uiSourceCode
+ */
+ closeFile: function(uiSourceCode)
+ {
+ var tabId = this._tabIds.get(uiSourceCode);
+ if (!tabId)
+ return;
+ this._closeTabs([tabId]);
+ },
+
+ /**
* @return {!Array.<!WebInspector.UISourceCode>}
*/
historyUISourceCodes: function()
@@ -132,7 +151,7 @@ WebInspector.TabbedEditorContainer.prototype = {
return result;
},
- _addScrollAndSelectionListeners: function()
+ _addViewListeners: function()
{
if (!this._currentView)
return;
@@ -140,7 +159,7 @@ WebInspector.TabbedEditorContainer.prototype = {
this._currentView.addEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this);
},
- _removeScrollAndSelectionListeners: function()
+ _removeViewListeners: function()
{
if (!this._currentView)
return;
@@ -148,6 +167,9 @@ WebInspector.TabbedEditorContainer.prototype = {
this._currentView.removeEventListener(WebInspector.SourceFrame.Events.SelectionChanged, this._selectionChanged, this);
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
_scrollChanged: function(event)
{
var lineNumber = /** @type {number} */ (event.data);
@@ -155,6 +177,9 @@ WebInspector.TabbedEditorContainer.prototype = {
this._history.save(this._previouslyViewedFilesSetting);
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
_selectionChanged: function(event)
{
var range = /** @type {!WebInspector.TextRange} */ (event.data);
@@ -171,19 +196,20 @@ WebInspector.TabbedEditorContainer.prototype = {
if (this._currentFile === uiSourceCode)
return;
- this._removeScrollAndSelectionListeners();
+ this._removeViewListeners();
this._currentFile = uiSourceCode;
var tabId = this._tabIds.get(uiSourceCode) || this._appendFileTab(uiSourceCode, userGesture);
-
+
this._tabbedPane.selectTab(tabId, userGesture);
if (userGesture)
this._editorSelectedByUserAction();
-
+
this._currentView = this.visibleView;
- this._addScrollAndSelectionListeners();
+ this._addViewListeners();
- this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorSelected, this._currentFile);
+ var eventData = { currentFile: this._currentFile, userGesture: userGesture };
+ this.dispatchEventToListeners(WebInspector.TabbedEditorContainer.Events.EditorSelected, eventData);
},
/**
@@ -325,7 +351,7 @@ WebInspector.TabbedEditorContainer.prototype = {
{
return this._files[tabId].uri();
}
-
+
this._history.update(tabIds.map(tabIdToURI.bind(this)));
this._history.save(this._previouslyViewedFilesSetting);
},
@@ -378,7 +404,7 @@ WebInspector.TabbedEditorContainer.prototype = {
var uiSourceCode = this._files[tabId];
if (this._currentFile === uiSourceCode) {
- this._removeScrollAndSelectionListeners();
+ this._removeViewListeners();
delete this._currentView;
delete this._currentFile;
}
@@ -414,7 +440,6 @@ WebInspector.TabbedEditorContainer.prototype = {
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this);
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this);
uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.SavedStateUpdated, this._uiSourceCodeSavedStateUpdated, this);
- uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormattedChanged, this);
},
/**
@@ -426,7 +451,6 @@ WebInspector.TabbedEditorContainer.prototype = {
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._uiSourceCodeWorkingCopyChanged, this);
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._uiSourceCodeWorkingCopyCommitted, this);
uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.SavedStateUpdated, this._uiSourceCodeSavedStateUpdated, this);
- uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._uiSourceCodeFormattedChanged, this);
},
/**
@@ -470,12 +494,6 @@ WebInspector.TabbedEditorContainer.prototype = {
this._updateFileTitle(uiSourceCode);
},
- _uiSourceCodeFormattedChanged: function(event)
- {
- var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
- this._updateFileTitle(uiSourceCode);
- },
-
reset: function()
{
delete this._userSelectedFiles;
@@ -539,9 +557,7 @@ WebInspector.TabbedEditorContainer.HistoryItem.prototype = {
serializedHistoryItem.selectionRange = this.selectionRange;
serializedHistoryItem.scrollLineNumber = this.scrollLineNumber;
return serializedHistoryItem;
- },
-
- __proto__: WebInspector.Object.prototype
+ }
}
/**
@@ -663,7 +679,7 @@ WebInspector.TabbedEditorContainer.History.prototype = {
this._rebuildItemIndex();
}
},
-
+
/**
* @param {!WebInspector.Setting} setting
*/
@@ -671,7 +687,7 @@ WebInspector.TabbedEditorContainer.History.prototype = {
{
setting.set(this._serializeToObject());
},
-
+
/**
* @return {!Array.<!Object>}
*/
@@ -698,9 +714,7 @@ WebInspector.TabbedEditorContainer.History.prototype = {
for (var i = 0; i < this._items.length; ++i)
result.push(this._items[i].url);
return result;
- },
-
- __proto__: WebInspector.Object.prototype
+ }
}
/**
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/TargetsToolbar.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/TargetsToolbar.js
new file mode 100644
index 00000000000..5b0a4a9db1f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/TargetsToolbar.js
@@ -0,0 +1,78 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @implements {WebInspector.TargetManager.Observer}
+ */
+WebInspector.TargetsToolbar = function()
+{
+ this.element = document.createElement("div");
+ this.element.className = "status-bar scripts-debug-toolbar targets-toolbar hidden";
+ this._comboBox = new WebInspector.StatusBarComboBox(this._onComboBoxSelectionChange.bind(this));
+ this.element.appendChild(this._comboBox.element);
+
+ /** @type {!Map.<!WebInspector.Target, !Element>} */
+ this._targetToOption = new Map();
+ if (!WebInspector.experimentsSettings.workersInMainWindow.isEnabled())
+ return;
+
+ WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._targetChangedExternally, this);
+ WebInspector.targetManager.observeTargets(this);
+}
+
+WebInspector.TargetsToolbar.prototype = {
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetAdded: function(target)
+ {
+ var option = this._comboBox.createOption(target.name());
+ option.__target = target;
+ this._targetToOption.put(target, option);
+ if (WebInspector.context.flavor(WebInspector.Target) === target)
+ this._comboBox.select(option);
+
+ this._updateVisibility();
+ },
+
+ /**
+ * @param {!WebInspector.Target} target
+ */
+ targetRemoved: function(target)
+ {
+ var option = this._targetToOption.remove(target);
+ this._comboBox.removeOption(option);
+ this._updateVisibility();
+ },
+
+ _onComboBoxSelectionChange: function()
+ {
+ var selectedOption = this._comboBox.selectedOption();
+ if (!selectedOption)
+ return;
+
+ WebInspector.context.setFlavor(WebInspector.Target, selectedOption.__target);
+ },
+
+ _updateVisibility: function()
+ {
+ var hidden = this._comboBox.size() === 1;
+ this.element.classList.toggle("hidden", hidden);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _targetChangedExternally: function(event)
+ {
+ var target = /** @type {?WebInspector.Target} */ (event.data);
+ if (target) {
+ var option = /** @type {!Element} */ (this._targetToOption.get(target));
+ this._comboBox.select(option);
+ }
+ }
+
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/UISourceCodeFrame.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
index 76a49112246..782325215ac 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/UISourceCodeFrame.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/UISourceCodeFrame.js
@@ -38,13 +38,20 @@ WebInspector.UISourceCodeFrame = function(uiSourceCode)
WebInspector.settings.textEditorAutocompletion.addChangeListener(this._enableAutocompletionIfNeeded, this);
this._enableAutocompletionIfNeeded();
- this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._onFormattedChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
this._updateStyle();
}
WebInspector.UISourceCodeFrame.prototype = {
+ /**
+ * @return {!WebInspector.UISourceCode}
+ */
+ uiSourceCode: function()
+ {
+ return this._uiSourceCode;
+ },
+
_enableAutocompletionIfNeeded: function()
{
this.textEditor.setCompletionDictionary(WebInspector.settings.textEditorAutocompletion.get() ? new WebInspector.SampleCompletionDictionary() : null);
@@ -71,7 +78,12 @@ WebInspector.UISourceCodeFrame.prototype = {
*/
canEditSource: function()
{
- return this._uiSourceCode.isEditable();
+ var projectType = this._uiSourceCode.project().type();
+ if (projectType === WebInspector.projectTypes.Debugger || projectType === WebInspector.projectTypes.Formatter)
+ return false;
+ if (projectType === WebInspector.projectTypes.Network && this._uiSourceCode.contentType() === WebInspector.resourceTypes.Document)
+ return false;
+ return true;
},
_windowFocused: function(event)
@@ -86,10 +98,7 @@ WebInspector.UISourceCodeFrame.prototype = {
this._uiSourceCode.checkContentUpdated();
},
- /**
- * @param {string} text
- */
- commitEditing: function(text)
+ commitEditing: function()
{
if (!this._uiSourceCode.isDirty())
return;
@@ -115,7 +124,7 @@ WebInspector.UISourceCodeFrame.prototype = {
_didEditContent: function(error)
{
if (error) {
- WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
+ WebInspector.messageSink.addErrorMessage(error, true);
return;
}
},
@@ -123,29 +132,6 @@ WebInspector.UISourceCodeFrame.prototype = {
/**
* @param {!WebInspector.Event} event
*/
- _onFormattedChanged: function(event)
- {
- var content = /** @type {string} */ (event.data.content);
- this._textEditor.setReadOnly(this._uiSourceCode.formatted());
- var selection = this._textEditor.selection();
- this._innerSetContent(content);
- var start = null;
- var end = null;
- if (this._uiSourceCode.formatted()) {
- start = event.data.newFormatter.originalToFormatted(selection.startLine, selection.startColumn);
- end = event.data.newFormatter.originalToFormatted(selection.endLine, selection.endColumn);
- } else {
- start = event.data.oldFormatter.formattedToOriginal(selection.startLine, selection.startColumn);
- end = event.data.oldFormatter.formattedToOriginal(selection.endLine, selection.endColumn);
- }
- this.textEditor.setSelection(new WebInspector.TextRange(start[0], start[1],
- end[0], end[1]));
- this.textEditor.revealLine(start[0]);
- },
-
- /**
- * @param {!WebInspector.Event} event
- */
_onWorkingCopyChanged: function(event)
{
if (this._muteSourceCodeEvents)
@@ -169,7 +155,7 @@ WebInspector.UISourceCodeFrame.prototype = {
_updateStyle: function()
{
- this.element.enableStyleClass("source-frame-unsaved-committed-changes", this._uiSourceCode.hasUnsavedCommittedChanges());
+ this.element.classList.toggle("source-frame-unsaved-committed-changes", this._uiSourceCode.hasUnsavedCommittedChanges());
},
onUISourceCodeContentChanged: function()
@@ -195,6 +181,8 @@ WebInspector.UISourceCodeFrame.prototype = {
dispose: function()
{
+ WebInspector.settings.textEditorAutocompletion.removeChangeListener(this._enableAutocompletionIfNeeded, this);
+ this._textEditor.dispose();
this.detach();
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/WatchExpressionsSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
index 8023096ad8d..80b97689bed 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/WatchExpressionsSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -52,6 +52,7 @@ WebInspector.WatchExpressionsSidebarPane = function()
addButton.title = WebInspector.UIString("Add watch expression");
this._requiresUpdate = true;
+ WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext ,this.refreshExpressions, this);
}
WebInspector.WatchExpressionsSidebarPane.prototype = {
@@ -60,11 +61,6 @@ WebInspector.WatchExpressionsSidebarPane.prototype = {
this._refreshExpressionsIfNeeded();
},
- reset: function()
- {
- this.refreshExpressions();
- },
-
refreshExpressions: function()
{
this._requiresUpdate = true;
@@ -110,7 +106,7 @@ WebInspector.WatchExpressionsSection = function()
{
this._watchObjectGroupId = "watch-group";
- WebInspector.ObjectPropertiesSection.call(this, WebInspector.RemoteObject.fromPrimitiveValue(""));
+ WebInspector.ObjectPropertiesSection.call(this, WebInspector.runtimeModel.createRemoteObjectFromPrimitiveValue(""));
this.treeElementConstructor = WebInspector.WatchedPropertyTreeElement;
this._expandedExpressions = {};
@@ -189,7 +185,7 @@ WebInspector.WatchExpressionsSection.prototype = {
}
// TODO: pass exact injected script id.
- RuntimeAgent.releaseObjectGroup(this._watchObjectGroupId)
+ WebInspector.targetManager.targets().forEach(function(target) {target.runtimeAgent().releaseObjectGroup(this._watchObjectGroupId)}, this);
var properties = [];
// Count the properties, so we known when to call this.updateProperties()
@@ -203,12 +199,15 @@ WebInspector.WatchExpressionsSection.prototype = {
// Now process all the expressions, since we have the actual count,
// which is checked in the appendResult inner function.
- for (var i = 0; i < this.watchExpressions.length; ++i) {
- var expression = this.watchExpressions[i];
- if (!expression)
- continue;
-
- WebInspector.runtimeModel.evaluate(expression, this._watchObjectGroupId, false, true, false, false, appendResult.bind(this, expression, i));
+ var currentExecutionContext = WebInspector.context.flavor(WebInspector.ExecutionContext);
+ if (currentExecutionContext) {
+ for (var i = 0; i < this.watchExpressions.length; ++i) {
+ var expression = this.watchExpressions[i];
+ if (!expression)
+ continue;
+
+ currentExecutionContext.evaluate(expression, this._watchObjectGroupId, false, true, false, false, appendResult.bind(this, expression, i));
+ }
}
if (!propertyCount) {
@@ -258,7 +257,7 @@ WebInspector.WatchExpressionsSection.prototype = {
this.saveExpressions();
this.update();
},
-
+
_deleteAllExpressions: function()
{
this.watchExpressions = [];
@@ -266,6 +265,9 @@ WebInspector.WatchExpressionsSection.prototype = {
this.update();
},
+ /**
+ * @return {?TreeElement}
+ */
findAddedTreeElement: function()
{
var children = this.propertiesTreeOutline.children;
@@ -273,8 +275,12 @@ WebInspector.WatchExpressionsSection.prototype = {
if (children[i].property.name === WebInspector.WatchExpressionsSection.NewWatchExpression)
return children[i];
}
+ return null;
},
+ /**
+ * @return {number}
+ */
saveExpressions: function()
{
var toSave = [];
@@ -334,6 +340,11 @@ WebInspector.WatchExpressionsSection.prototype = {
__proto__: WebInspector.ObjectPropertiesSection.prototype
}
+/**
+ * @param {!WebInspector.RemoteObjectProperty} propertyA
+ * @param {!WebInspector.RemoteObjectProperty} propertyB
+ * @return {number}
+ */
WebInspector.WatchExpressionsSection.CompareProperties = function(propertyA, propertyB)
{
if (propertyA.watchIndex == propertyB.watchIndex)
@@ -430,19 +441,26 @@ WebInspector.WatchExpressionTreeElement.prototype = {
this.treeOutline.section.updateExpression(this, null);
},
+ /**
+ * @return {boolean}
+ */
renderPromptAsBlock: function()
{
return true;
},
/**
- * @param {!Event=} event
+ * @override
+ * @return {{element: !Element, value: (string|undefined)}}
*/
- elementAndValueToEdit: function(event)
+ elementAndValueToEdit: function()
{
- return [this.nameElement, this.property.name.trim()];
+ return { element: this.nameElement, value: this.property.name.trim() };
},
+ /**
+ * @override
+ */
editingCancelled: function(element, context)
{
if (!context.elementToEdit.textContent)
@@ -451,14 +469,14 @@ WebInspector.WatchExpressionTreeElement.prototype = {
WebInspector.ObjectPropertyTreeElement.prototype.editingCancelled.call(this, element, context);
},
- applyExpression: function(expression, updateInterface)
+ /**
+ * @override
+ * @param {string} expression
+ */
+ applyExpression: function(expression)
{
expression = expression.trim();
-
- if (!expression)
- expression = null;
-
- this.property.name = expression;
+ this.property.name = expression || null;
this.treeOutline.section.updateExpression(this, expression);
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/WorkersSidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/sources/WorkersSidebarPane.js
index bf16b7a99c3..73eb9b30df7 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/WorkersSidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/WorkersSidebarPane.js
@@ -30,19 +30,9 @@
/**
* @constructor
- */
-WebInspector.Worker = function(id, url, shared)
-{
- this.id = id;
- this.url = url;
- this.shared = shared;
-}
-
-/**
- * @constructor
* @extends {WebInspector.SidebarPane}
*/
-WebInspector.WorkersSidebarPane = function(workerManager)
+WebInspector.WorkersSidebarPane = function()
{
WebInspector.SidebarPane.call(this, WebInspector.UIString("Workers"));
@@ -70,17 +60,25 @@ WebInspector.WorkersSidebarPane = function(workerManager)
this.bodyElement.appendChild(this._workerListElement);
this._idToWorkerItem = {};
- this._workerManager = workerManager;
- workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerAdded, this._workerAdded, this);
- workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerRemoved, this._workerRemoved, this);
- workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkersCleared, this._workersCleared, this);
+ var threadList = WebInspector.workerManager.threadsList();
+ for (var i = 0; i < threadList.length; ++i) {
+ var threadId = threadList[i];
+ if (threadId === WebInspector.WorkerManager.MainThreadId)
+ continue;
+
+ this._addWorker(threadId, WebInspector.workerManager.threadUrl(threadId));
+ }
+
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerAdded, this._workerAdded, this);
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkerRemoved, this._workerRemoved, this);
+ WebInspector.workerManager.addEventListener(WebInspector.WorkerManager.Events.WorkersCleared, this._workersCleared, this);
}
WebInspector.WorkersSidebarPane.prototype = {
_workerAdded: function(event)
{
- this._addWorker(event.data.workerId, event.data.url, event.data.inspectorConnected);
+ this._addWorker(event.data.workerId, event.data.url);
},
_workerRemoved: function(event)
@@ -95,7 +93,7 @@ WebInspector.WorkersSidebarPane.prototype = {
this._workerListElement.removeChildren();
},
- _addWorker: function(workerId, url, inspectorConnected)
+ _addWorker: function(workerId, url)
{
var item = this._workerListElement.createChild("div", "dedicated-worker-item");
var link = item.createChild("a");
@@ -108,8 +106,8 @@ WebInspector.WorkersSidebarPane.prototype = {
_workerItemClicked: function(workerId, event)
{
- event.preventDefault();
- this._workerManager.openWorkerInspector(workerId);
+ event.consume(true);
+ WebInspector.workerFrontendManager.openWorkerInspector(workerId);
},
_autoattachToWorkersClicked: function(event)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sources/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/sources/module.json
new file mode 100644
index 00000000000..81fd9276f85
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sources/module.json
@@ -0,0 +1,173 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "sources",
+ "title": "Sources",
+ "order": 2,
+ "className": "WebInspector.SourcesPanel"
+ },
+ {
+ "type": "@WebInspector.ContextMenu.Provider",
+ "contextTypes": ["WebInspector.UISourceCode", "WebInspector.RemoteObject"],
+ "className": "WebInspector.SourcesPanel.ContextMenuProvider"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "debugger.toggle-pause",
+ "className": "WebInspector.SourcesPanel.TogglePauseActionDelegate",
+ "contextTypes": ["WebInspector.SourcesPanel", "WebInspector.ShortcutRegistry.ForwardedShortcut"],
+ "bindings": [
+ {
+ "platform": "windows,linux",
+ "shortcut": "F8 Ctrl+\\"
+ },
+ {
+ "platform": "mac",
+ "shortcut": "F8 Meta+\\"
+ }
+ ]
+ },
+ {
+ "type": "@WebInspector.SearchScope",
+ "className": "WebInspector.SourcesSearchScope"
+ },
+ {
+ "type": "@WebInspector.DrawerEditor",
+ "className": "WebInspector.SourcesPanel.DrawerEditor"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.UILocation"],
+ "className": "WebInspector.SourcesPanel.UILocationRevealer"
+ },
+ {
+ "type": "@WebInspector.Revealer",
+ "contextTypes": ["WebInspector.UISourceCode"],
+ "className": "WebInspector.SourcesPanel.UISourceCodeRevealer"
+ },
+ {
+ "type": "@WebInspector.SourcesView.EditorAction",
+ "className": "WebInspector.InplaceFormatterEditorAction"
+ },
+ {
+ "type": "@WebInspector.SourcesView.EditorAction",
+ "className": "WebInspector.ScriptFormatterEditorAction"
+ },
+ {
+ "type": "navigator-view",
+ "name": "sources",
+ "title": "Sources",
+ "order": 1,
+ "className": "WebInspector.SourcesNavigatorView"
+ },
+ {
+ "type": "navigator-view",
+ "name": "contentScripts",
+ "title": "Content scripts",
+ "order": 2,
+ "className": "WebInspector.ContentScriptsNavigatorView"
+ },
+ {
+ "type": "navigator-view",
+ "name": "snippets",
+ "title": "Snippets",
+ "order": 3,
+ "className": "WebInspector.SnippetsNavigatorView"
+ },
+ {
+ "type": "@WebInspector.ActionDelegate",
+ "actionId": "sources.go-to-source",
+ "className": "WebInspector.SourcesPanel.ShowGoToSourceDialogActionDelegate",
+ "bindings": [
+ {
+ "platform": "mac",
+ "shortcut": "Meta+O Meta+P"
+ },
+ {
+ "platform": "windows,linux",
+ "shortcut": "Ctrl+O Ctrl+P"
+ }
+ ]
+ },
+ {
+ "type": "ui-setting",
+ "settingName": "javaScriptDisabled",
+ "settingType": "custom",
+ "className": "WebInspector.SourcesPanel.DisableJavaScriptSettingDelegate"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Search in content scripts",
+ "settingName": "searchInContentScripts",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Enable JavaScript source maps",
+ "settingName": "jsSourceMapsEnabled",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Detect indentation",
+ "settingName": "textEditorAutoDetectIndent",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Autocompletion",
+ "settingName": "textEditorAutocompletion",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Bracket matching",
+ "settingName": "textEditorBracketMatching",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Show whitespace characters",
+ "settingName": "showWhitespacesInEditor",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "title": "Enable CSS source maps",
+ "settingName": "cssSourceMapsEnabled",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "title": "Auto-reload generated CSS",
+ "parentSettingName": "cssSourceMapsEnabled",
+ "settingName": "cssReloadEnabled",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "section": "Sources",
+ "experiment": "frameworksDebuggingSupport",
+ "title": "Skip stepping through sources with particular names",
+ "settingName": "skipStackFramesSwitch",
+ "settingType": "checkbox"
+ },
+ {
+ "type": "ui-setting",
+ "experiment": "frameworksDebuggingSupport",
+ "parentSettingName": "skipStackFramesSwitch",
+ "settingType": "custom",
+ "className": "WebInspector.SourcesPanel.SkipStackFramePatternSettingDelegate"
+ }
+ ],
+ "dependencies": [ "source_frame" ],
+ "scripts": [ "SourcesPanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sourcesPanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/sourcesPanel.css
index 45c3e074a24..12bad85bab2 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/sourcesPanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sourcesPanel.css
@@ -31,14 +31,10 @@
-webkit-mask-position: -256px 0;
}
-.scripts-pause-on-exceptions-status-bar-item.toggled-all .glyph {
+.scripts-pause-on-exceptions-status-bar-item.toggled-on .glyph {
background-color: rgb(66, 129, 235);
}
-.scripts-pause-on-exceptions-status-bar-item.toggled-uncaught .glyph {
- background-color: purple;
-}
-
.evaluate-snippet-status-bar-item .glyph {
-webkit-mask-position: -64px -48px;
}
@@ -47,12 +43,34 @@
background-color: rgb(66, 129, 235);
}
-#scripts-debug-toolbar {
- position: relative;
- margin-top: -1px;
- height: 24px;
- border-bottom: 1px solid rgb(202, 202, 202);
+.scripts-debug-toolbar {
+ position: absolute;
+ top: 0;
+ width: 100%;
background-color: rgb(236, 236, 236);
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.scripts-debug-toolbar-drawer {
+ flex: 0 0 46px;
+ -webkit-transition: margin-top 0.1s ease-in-out;
+ margin-top: -23px;
+ line-height: 23px;
+ padding-top: 22px;
+ border-bottom: 1px solid rgb(202, 202, 202);
+ background-color: white;
+ overflow: hidden;
+}
+
+.scripts-debug-toolbar-drawer.expanded {
+ margin-top: 0;
+}
+
+.scripts-debug-toolbar-drawer > label {
+ display: flex;
+ padding-left: 3px;
+ border-top: 1px solid rgb(196,196,196);
}
#scripts-editor-toolbar {
@@ -97,63 +115,54 @@
-webkit-mask-position: 0 -24px;
}
-.status-bar-item.scripts-navigator-show-hide-button,
-.status-bar-item.scripts-debugger-show-hide-button {
- opacity: 0.9;
-}
-
-.panel.sources .tabbed-pane-header {
- background-color: rgb(236, 236, 236);
+.dedicated-worker-item {
+ margin: 5px 0 5px 1px;
}
-button.status-bar-item.scripts-navigator-show-hide-button {
- left: 0;
+#shared-workers-list {
+ margin: 5px 0 5px 20px;
+ font-style:italic;
}
-button.status-bar-item.scripts-navigator-show-hide-button.toggled-overlay {
- left: auto;
- right: 15px;
+#pause-workers-checkbox > input {
+ position: relative;
+ top: 2px;
}
-.scripts-views-container {
- position: absolute;
- top: 23px;
- right: 0;
- bottom: 0;
- left: 0;
+.panel.sources #sources-editor-container-tabbed-pane .tabbed-pane-header-contents {
+ margin-left: 22px;
+ margin-right: 36px;
}
-.script-view {
- display: none;
- overflow: hidden;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
+.panel.sources .split-view button.scripts-debugger-show-hide-button.right-sidebar-show-hide-button.toggled-hide {
+ margin-right: 15px;
}
-.script-view.visible {
- display: block;
+.panel.sources .split-view #scripts-debug-sidebar-resizer-widget.ns-resizer-widget {
+ -webkit-transform: rotate(90deg);
+ right: 17px;
+ bottom: 4px;
+ top: auto;
+ height: 10px;
+ width: 18px;
}
-.dedicated-worker-item {
- margin: 5px 0 5px 1px;
+.panel.sources .split-view.hbox #scripts-debug-sidebar-resizer-widget {
+ bottom: 0;
}
-#shared-workers-list {
- margin: 5px 0 5px 20px;
- font-style:italic;
+.panel.sources .scripts-debugger-show-hide-button {
+ display: block;
}
-#pause-workers-checkbox > input {
- position: relative;
- top: 2px;
+.panel.sources button.status-bar-item.scripts-navigator-show-hide-button {
+ display: block;
+ top: 4px;
+ left: 4px;
}
-.panel.sources #sources-editor-container-tabbed-pane .tabbed-pane-header-contents {
- margin-left: 20px;
- margin-right: 36px;
+.panel.sources .navigator-tabbed-pane .tabbed-pane-header {
+ background-color: rgb(236, 236, 236);
}
.function-location-link {
@@ -171,20 +180,6 @@ button.status-bar-item.scripts-navigator-show-hide-button.toggled-overlay {
font-weight: bold;
}
-button.status-bar-item.scripts-debugger-show-hide-button {
- right: 15px;
-}
-
-button.status-bar-item.scripts-debugger-show-hide-button.toggled-left {
- right: 0;
-}
-
-div.sidebar-pane-stack#scripts-debug-sidebar-contents,
-#scripts-sidebar-stack-pane {
- top: 23px;
- overflow: auto;
-}
-
.workers-list > li {
overflow: hidden;
text-overflow: ellipsis;
@@ -203,47 +198,27 @@ a.worker-item:hover {
color: rgb(15%, 15%, 15%);
}
-.source-frame-debugger-script {
- background-color: rgba(255, 255, 194, 0.5);
-}
-
-.source-frame-unsaved-committed-changes {
- background-color: rgba(255, 225, 205, 0.40);
-}
-
-.tabbed-pane-placeholder {
- font-size: 14px;
- text-align: center;
- margin-top: 20px;
- text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
-}
-
-.tabbed-pane-header-tab-icon {
- width: 11px;
- height: 10px;
- margin-top: 3px;
- float: left;
- display: block;
- margin-right: 1px;
+.panel.sources .sidebar-pane-stack {
+ overflow: auto;
}
-.editor-container-unsaved-committed-changes-icon {
- background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
- background-position: -202px -107px;
+.targets-toolbar {
+ padding-left: 10px;
+ margin-top: -1px;
}
-.sources-status-bar div.resizer-widget {
- width: 18px;
- height: 16px;
- -webkit-transform: rotate(90deg);
- top: 2px;
- right: 17px;
+.panel.sources .drag-mask {
+ background-color: rgba(255,255,255,0.8);
+ z-index: 1000;
}
-.sources-status-bar .scripts-debugger-show-hide-button {
- margin-top: 1px !important;
- height: 16px !important;
- -webkit-transform: rotate(90deg);
- right: 0 !important;
+.panel.sources .drag-mask-inner {
+ font-size: 30px;
+ color: #999;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin: 20px;
+ border: 4px dashed #ddd;
+ pointer-events: none;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/sourcesView.css b/chromium/third_party/WebKit/Source/devtools/front_end/sourcesView.css
index 84a02002b8c..8de6724503c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/sourcesView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/sourcesView.css
@@ -41,7 +41,12 @@
border-bottom: 1px solid #BBB;
}
+#sources-panel-sources-view .tabbed-pane-header {
+ background-color: rgb(236, 236, 236);
+}
+
#sources-panel-sources-view .sources-status-bar {
+ display: flex;
position: relative;
flex: 0 0 20px;
background-color: rgb(236, 236, 236);
@@ -53,6 +58,11 @@
height: 20px;
}
+#sources-panel-sources-view .sources-status-bar .status-bar-item.status-bar-text {
+ margin: auto 0;
+ height: auto;
+}
+
#sources-panel-sources-view .source-frame-cursor-position {
-webkit-user-select: text;
}
@@ -65,7 +75,80 @@
background-color: rgb(66, 129, 235);
}
-#sources-panel-sources-view .drag-mask
- background-color: transparent;
- z-index: 1000;
+.source-frame-debugger-script {
+ background-color: rgba(255, 255, 194, 0.5);
+}
+
+.source-frame-unsaved-committed-changes {
+ background-color: rgba(255, 225, 205, 0.40);
+}
+
+.editor-container-unsaved-committed-changes-icon {
+ background-image: url(Images/statusbarButtonGlyphs.png);
+ background-size: 320px 144px;
+ background-position: -202px -107px;
+}
+
+button.status-bar-item.scripts-debugger-show-hide-button {
+ display: none;
+}
+
+button.status-bar-item.scripts-navigator-show-hide-button {
+ display: none;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar {
+ border-bottom: 1px solid rgb(187, 187, 187);
+ display: flex;
+ flex-direction: column;
+ flex: 0 1 auto;
+ background-color: rgb(255, 255, 194);
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-warning-icon {
+ background-image: url(Images/statusbarButtonGlyphs.png);
+ background-size: 320px 144px;
+ background-position: -202px -107px;
+ width: 11px;
+ height: 10px;
+ margin-right: 4px;
+ display: inline-block;
+ margin-top: 1px;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-main-row {
+ display: flex;
+ flex: 0 0 17px;
+ overflow: hidden;
+ margin: 5px 10px 0px;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-details-container {
+ display: flex;
+ flex-direction: column;
+ padding: 5px 0;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-details-row {
+ display: flex;
+ flex: 0 0 15px;
+ margin: auto 10px;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-row-message {
+ flex: 0 1 auto;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-toggle {
+ flex: auto;
+ text-decoration: underline;
+ color: rgb(50, 50, 200);
+}
+
+#sources-panel-sources-view .java-script-source-frame-infobar-details-url {
+ flex: 0 1000 auto;
+ color: rgb(50, 50, 200);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/spectrum.css b/chromium/third_party/WebKit/Source/devtools/front_end/spectrum.css
index e5aae8c6158..b9331fb3132 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/spectrum.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/spectrum.css
@@ -75,15 +75,15 @@
}
.spectrum-sat {
- background-image: -webkit-linear-gradient(left, white, rgba(204, 154, 129, 0));
+ background-image: linear-gradient(to right, white, rgba(204, 154, 129, 0));
}
.spectrum-val {
- background-image: -webkit-linear-gradient(bottom, black, rgba(204, 154, 129, 0));
+ background-image: linear-gradient(to top, black, rgba(204, 154, 129, 0));
}
.spectrum-hue {
- background: -webkit-linear-gradient(bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
+ background: linear-gradient(to top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
}
.spectrum-dragger {
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/splitView.css b/chromium/third_party/WebKit/Source/devtools/front_end/splitView.css
index eef9641cba7..f735ebdd020 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/splitView.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/splitView.css
@@ -27,13 +27,15 @@
*/
.split-view {
+ display: flex;
overflow: hidden;
}
.split-view-contents {
overflow: auto;
- cursor: default;
+ display: flex;
position: relative;
+ flex-direction: column;
}
.split-view-sidebar {
@@ -44,55 +46,113 @@
flex: auto;
}
-.split-view.hbox > .split-view-sidebar.split-view-contents-first:not(.maximized) {
- border-right: 1px solid rgb(64%, 64%, 64%);
+.split-view.hbox > .split-view-resizer {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 6px;
+ z-index: 500;
}
-.split-view.hbox > .split-view-sidebar.split-view-contents-second:not(.maximized) {
- border-left: 1px solid rgb(64%, 64%, 64%);
+.split-view.vbox > .split-view-resizer {
+ position: absolute;
+ left: 0;
+ right: 0;
+ height: 6px;
+ z-index: 500;
}
-.split-view.vbox > .split-view-sidebar.split-view-contents-first:not(.maximized) {
- border-bottom: 1px solid rgb(64%, 64%, 64%);
+.split-view-resizer-border {
+ pointer-events: none;
}
-.split-view.vbox > .split-view-sidebar.split-view-contents-second:not(.maximized) {
+.split-view.vbox > .split-view-resizer > .split-view-resizer-border {
+ width: 100%;
+ margin-top: 3px;
+ height: 1px;
border-top: 1px solid rgb(64%, 64%, 64%);
}
-.split-view.hbox > .split-view-resizer {
- position: absolute;
- top: 0;
- bottom: 0;
- width: 5px;
- z-index: 1500;
+.split-view.hbox > .split-view-resizer > .split-view-resizer-border {
+ height: 100%;
+ margin-left: 3px;
+ width: 1px;
+ border-left: 1px solid rgb(64%, 64%, 64%);
}
-.split-view.vbox > .split-view-resizer {
+.split-view button.sidebar-show-hide-button {
position: absolute;
- left: 0;
- right: 0;
- height: 5px;
- z-index: 1500;
+ background-image: none;
+ height: 16px;
+ width: 16px;
+ border: none;
+ z-index: 10;
}
-.sidebar-overlay {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- z-index: 12;
- background-color: white;
- border-right: 1px solid gray;
- box-shadow: rgb(90,90,90) 20px 0 50px -25px;
- display: -webkit-flex;
- -webkit-flex-direction: column;
+.split-view button.left-sidebar-show-hide-button,
+.split-view button.top-sidebar-show-hide-button {
+ top: 4px;
+ left: 4px;
}
-.sidebar-overlay-resizer {
- position: absolute;
- top: 0;
+.split-view button.left-sidebar-show-hide-button:active,
+.split-view button.top-sidebar-show-hide-button:active {
+ top: 5px;
+ left: 3px;
+}
+
+.split-view button.right-sidebar-show-hide-button {
+ top: 4px;
+ right:2px;
+}
+
+.split-view button.right-sidebar-show-hide-button:active {
+ top: 5px;
+ right: 1px;
+}
+
+.split-view button.bottom-sidebar-show-hide-button {
+ bottom: 0px;
+ right: 1px;
+}
+
+.split-view button.bottom-sidebar-show-hide-button:active {
bottom: 0;
- width: 5px;
- z-index: 500;
+ right: 0;
+}
+
+.split-view button.left-sidebar-show-hide-button.toggled-show > .glyph {
+ -webkit-mask-position: -168px -76px; /* |> */
+}
+
+.split-view button.left-sidebar-show-hide-button.toggled-hide > .glyph {
+ -webkit-mask-position: -199px -76px; /* |< */
+}
+
+.split-view button.right-sidebar-show-hide-button.toggled-show > .glyph {
+ -webkit-mask-position: -296px -76px; /* <| */
+}
+
+.split-view button.right-sidebar-show-hide-button.toggled-hide > .glyph {
+ -webkit-mask-position: -264px -76px; /* >| */
+}
+
+.split-view button.top-sidebar-show-hide-button.toggled-show > .glyph {
+ -webkit-mask-position: -168px -76px; /* |> */
+ -webkit-transform: rotate(90deg);
+}
+
+.split-view button.top-sidebar-show-hide-button.toggled-hide > .glyph {
+ -webkit-mask-position: -199px -76px; /* |< */
+ -webkit-transform: rotate(90deg);
+}
+
+.split-view button.bottom-sidebar-show-hide-button.toggled-show > .glyph {
+ -webkit-mask-position: -296px -76px; /* <| */
+ -webkit-transform: rotate(90deg);
+}
+
+.split-view button.bottom-sidebar-show-hide-button.toggled-hide > .glyph {
+ -webkit-mask-position: -264px -76px; /* >| */
+ -webkit-transform: rotate(90deg);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/textPrompt.css b/chromium/third_party/WebKit/Source/devtools/front_end/suggestBox.css
index ca4ba07ce73..0b68e653e9f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/textPrompt.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/suggestBox.css
@@ -28,42 +28,77 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-.suggest-box {
+.suggest-box-overlay {
position: absolute;
- background-color: #FFFFFF;
- display: block;
- border: 1px solid black;
- padding: 2px;
- z-index: 100;
+ background-color: transparent;
+ z-index: 1000;
+ pointer-events: none;
+ overflow: hidden;
+ display: flex;
+ flex-direction: row;
}
-.suggest-box .container {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
+.suggest-box-overlay .suggest-box-left-spacer {
+ flex: 0 1 auto;
+}
+
+.suggest-box-overlay .suggest-box-horizontal {
+ display: flex;
+ flex-direction: column;
+ flex: 0 0 auto;
+ max-width: 300px;
+}
+
+.suggest-box-overlay .suggest-box-top-spacer {
+ flex: auto;
+}
+
+.suggest-box-overlay.under-anchor .suggest-box-top-spacer,
+.suggest-box-overlay:not(.under-anchor) .suggest-box-bottom-spacer {
+ flex: 0 0 auto;
+}
+
+.suggest-box-overlay .suggest-box {
+ background-color: #FFFFFF;
+ border: 1px solid rgb(66%, 66%, 66%);
+ pointer-events: auto;
+ margin-left: -3px;
overflow-x: hidden;
overflow-y: auto;
+ display: flex;
+ flex-direction: column;
+ flex: 0 0 auto;
+ border-radius: 5px 5px 5px 0;
}
-.suggest-box-content-item {
+.suggest-box-overlay.under-anchor .suggest-box {
+ border-radius: 0 5px 5px 5px;
+}
+
+.suggest-box-overlay .suggest-box .suggest-box-content-item {
padding: 1px;
margin: 0;
- font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid transparent;
+ flex: 0 0 auto;
+ padding-right: 0px;
+ white-space: nowrap;
}
-.suggest-box-content-item .prefix {
+.suggest-box-overlay .suggest-box .suggest-box-content-item .prefix {
font-weight: bold;
}
-.suggest-box-content-item.selected {
- background-color: rgb(212, 212, 212);
+.suggest-box-overlay .suggest-box .suggest-box-content-item .spacer {
+ display: inline-block;
+ width: 20px;
+}
+
+.suggest-box-overlay .suggest-box .suggest-box-content-item.selected {
+ background-color: rgba(56, 121, 217, 0.1);
}
-.suggest-box-content-item:hover:not(.selected) {
+.suggest-box-overlay .suggest-box .suggest-box-content-item:hover:not(.selected) {
border: 1px solid rgb(204, 204, 204);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/tabbedPane.css b/chromium/third_party/WebKit/Source/devtools/front_end/tabbedPane.css
index 164e28f017d..fcf8378facf 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/tabbedPane.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/tabbedPane.css
@@ -30,6 +30,7 @@
.tabbed-pane {
flex: auto;
+ overflow: hidden;
}
.tabbed-pane-content {
@@ -37,12 +38,20 @@
overflow: auto;
flex: auto;
display: flex;
+ flex-direction: column;
}
.tabbed-pane-content.has-no-tabs {
background-color: lightgray;
}
+.tabbed-pane-placeholder {
+ font-size: 14px;
+ text-align: center;
+ margin-top: 20px;
+ text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
+}
+
.tabbed-pane-header {
flex: 0 0 23px;
border-bottom: 1px solid rgb(163, 163, 163);
@@ -66,7 +75,6 @@
border: 1px solid transparent;
border-bottom: none;
line-height: 15px;
-
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
@@ -101,6 +109,15 @@
visibility: visible;
}
+.tabbed-pane-header-tab-icon {
+ width: 11px;
+ height: 10px;
+ margin-top: 3px;
+ float: left;
+ display: block;
+ margin-right: 1px;
+}
+
.tabbed-pane-header-tabs-drop-down-container {
float: left;
position: relative;
@@ -129,16 +146,13 @@
opacity: 0.8;
}
-select.tabbed-pane-header-tabs-drop-down-select {
+.tabbed-pane-header-tabs-drop-down > select.drop-down-menu {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
- border: none;
- margin: 0;
font-size: 75%;
- -webkit-appearance: none;
width: 20px;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/temp_storage_shared_worker/TempStorageSharedWorker.js b/chromium/third_party/WebKit/Source/devtools/front_end/temp_storage_shared_worker/TempStorageSharedWorker.js
new file mode 100644
index 00000000000..beda63125f2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/temp_storage_shared_worker/TempStorageSharedWorker.js
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var ports = [];
+var isTempStorageCleared = false;
+/**
+ * @type {string}
+ */
+var tempStorageError;
+
+/**
+ * @param {!MessageEvent} event
+ */
+self.onconnect = function(event)
+{
+ var newPort = /** @type {!MessagePort} */ (event.ports[0]);
+ if (isTempStorageCleared) {
+ notifyTempStorageCleared(newPort);
+ return;
+ }
+
+ newPort.onmessage = handleMessage;
+ newPort.onerror = handleError;
+ ports.push(newPort);
+
+ if (ports.length === 1)
+ clearTempStorage();
+}
+
+function clearTempStorage()
+{
+ function didFail(e)
+ {
+ tempStorageError = "Failed to clear temp storage: " + e.message + " " + e.name;
+ console.error(tempStorageError);
+ didClearTempStorage();
+ }
+ /**
+ * @param {!FileSystem} fs
+ */
+ function didGetFS(fs)
+ {
+ fs.root.createReader().readEntries(didReadEntries, didFail);
+ }
+ /**
+ * @param {!Array.<!Entry>} entries
+ */
+ function didReadEntries(entries)
+ {
+ var remainingEntries = entries.length;
+ if (!remainingEntries) {
+ didClearTempStorage();
+ return;
+ }
+ function didDeleteEntry()
+ {
+ if (!--remainingEntries)
+ didClearTempStorage();
+ }
+ function failedToDeleteEntry(e)
+ {
+ tempStorageError = "Failed to delete entry: " + e.message + " " + e.name;
+ console.error(tempStorageError);
+ didDeleteEntry();
+ }
+ for (var i = 0; i < entries.length; i++) {
+ var entry = entries[i];
+ if (entry.isFile)
+ entry.remove(didDeleteEntry, failedToDeleteEntry);
+ else
+ entry.removeRecursively(didDeleteEntry, failedToDeleteEntry);
+ }
+ }
+ self.webkitRequestFileSystem(self.TEMPORARY, 10, didGetFS, didFail);
+}
+
+function didClearTempStorage()
+{
+ isTempStorageCleared = true;
+ for (var i = 0; i < ports.length; i++)
+ notifyTempStorageCleared(ports[i]);
+ ports = null;
+}
+
+/**
+ * @param {!MessagePort} port
+ */
+function notifyTempStorageCleared(port)
+{
+ port.postMessage({
+ type: "tempStorageCleared",
+ error: tempStorageError
+ });
+}
+
+function handleMessage(event)
+{
+ if (event.data.type === "disconnect")
+ removePort(event.target);
+}
+
+function handleError(event)
+{
+ console.error("Error: " + event.data);
+ removePort(event.target);
+}
+
+function removePort(port)
+{
+ if (!ports)
+ return;
+ var index = ports.indexOf(port);
+ ports.splice(index, 1);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/test-runner.html b/chromium/third_party/WebKit/Source/devtools/front_end/test-runner.html
deleted file mode 100644
index bdbe4bb4af2..00000000000
--- a/chromium/third_party/WebKit/Source/devtools/front_end/test-runner.html
+++ /dev/null
@@ -1,366 +0,0 @@
-<html>
-<script src="jsdifflib.js"></script>
-<script src="utilities.js"></script>
-<script src="DOMExtension.js"></script>
-<script src="treeoutline.js"></script>
-
-<link rel="stylesheet" type="text/css" href="inspector.css">
-<style>
-:focus {
- outline: none;
-}
-
-.failed {
- color: red;
-}
-
-.timeout {
- color: brown;
-}
-
-iframe {
- width: 0;
- height: 0;
- opacity: 0;
-}
-
-</style>
-
-<script>
-
-var layoutTestsServer = "http://localhost:8002/";
-var scannerServer = "http://localhost:8002/";
-var remoteDebuggingServer = "http://localhost:9222/";
-
-var tests = [];
-var skipList = [
- // HALT
- "inspector/console/console-api-on-call-frame.html",
-
- // FAILED
- "inspector/console/console-dir-global.html",
- "inspector/console/console-log-toString-object.html",
- "inspector/console/console-uncaught-exception-in-eval.html",
- "inspector/elements/edit-dom-actions.html",
- "inspector/elements/highlight-node-scaled.html",
- "inspector/elements/highlight-node-scroll.html",
- "inspector/elements/highlight-node.html",
- "inspector/elements/highlight-svg-root.html",
- "inspector/network-status-non-http.html",
- "inspector/storage-panel-dom-storage-update.html",
- "inspector/styles/inject-stylesheet.html",
- "inspector/styles/protocol-css-regions-commands.html",
- "inspector/styles/region-style-crash.html",
- "inspector/styles/styles-disable-then-enable-overriden-ua.html",
- "inspector/styles/styles-url-linkify.html",
- "inspector/styles/vendor-prefixes.html",
- "inspector/timeline/timeline-event-dispatch.html",
- "inspector/timeline/timeline-frames.html",
- "inspector/timeline/timeline-network-resource.html",
- "inspector/timeline/timeline-paint.html",
- "inspector/timeline/timeline-receive-response-event.html",
-
- // TIMEOUT
- "inspector/profiler/cpu-profiler-profiling-without-inspector.html",
- "inspector/profiler/heap-snapshot-inspect-dom-wrapper.html",
- "inspector/timeline/timeline-network-received-data.html",
-];
-var treeOutline = null;
-
-function run(debug)
-{
- if (window.runner && debug) {
- window.runner.continueDebugging();
- return;
- }
-
- if (window.testScannerIframe)
- document.body.removeChild(window.testScannerIframe);
-
- if (window.runner)
- window.runner.cleanup();
-
- window.testScannerIframe = document.createElement("iframe");
- window.testScannerIframe.src = scannerServer + "LayoutTests/http/tests/inspector/resources/test-scanner.html";
- document.body.appendChild(window.testScannerIframe);
- window.debug = debug;
-}
-
-function runTests()
-{
- document.getElementById("outline").removeChildren();
- treeOutline = new TreeOutline(document.getElementById("outline"));
-
- document.getElementById("pass").textContent = 0;
- document.getElementById("skip").textContent = 0;
- document.getElementById("fail").textContent = 0;
- document.getElementById("timeout").textContent = 0;
- document.getElementById("remaining").textContent = tests.length;
-
- runNextTest();
-}
-
-function interrupt()
-{
- tests = [];
-}
-
-function runNextTest(lastResult)
-{
- if (lastResult) {
- var element = document.getElementById(lastResult);
- element.textContent = parseInt(element.textContent) + 1;
-
- element = document.getElementById("remaining");
- element.textContent = parseInt(element.textContent) - 1;
- if (window.debug) {
- document.getElementById("debug").textContent = "Debug";
- return;
- }
- }
-
- var test;
- var filter = document.getElementById("filter").value;
- while (test = tests.shift()) {
- if (!filter || test[0].match(filter)) {
- new StandaloneTestRunner(layoutTestsServer + test[0], test[1], runNextTest.bind(null));
- return;
- }
- }
-}
-
-function StandaloneTestRunner(testPath, expected, next)
-{
- this._testPath = testPath;
- this._next = next;
- this._expected = expected;
- this._pendingMessages = [];
-
- this._treeElement = new TreeElement(testPath);
- treeOutline.appendChild(this._treeElement);
-
- for (var i = 0; !window.debug && i < skipList.length; ++i) {
- if (testPath.indexOf(skipList[i]) !== -1) {
- this._treeElement.title = testPath + ": SKIPPED";
- this._next("skip");
- return;
- }
- }
- window.runner = this;
- this._testPage = window.open("about:blank", "inspected", "width=800,height=600");
-
- window.remoteDebuggingHandshake = this._remoteDebuggingHandshake.bind(this);
- var script = document.createElement("script");
- script.src = remoteDebuggingServer + "json?jsonp=remoteDebuggingHandshake";
- document.head.appendChild(script);
-}
-
-StandaloneTestRunner.FrontendLocation = "inspector.html";
-
-StandaloneTestRunner.prototype = {
- _remoteDebuggingHandshake: function(data)
- {
- for (var i = 0; i < data.length; ++i) {
- if (data[i].url !== "about:blank")
- continue;
- this._debuggerURL = data[i].webSocketDebuggerUrl.replace("://", "=");
- this._navigateTestPage();
- break;
- }
- },
-
- _navigateTestPage: function()
- {
- this._testPage.location.href = this._testPath;
- var width = localStorage.getItem('inspectorWidth') || 600;
- var height = localStorage.getItem('inspectorHeight') || 400;
- var features = "width=" + Math.max(width , 600) + ",height=" + Math.max(height, 400);
- this._inspectorWindowLoading = window.open(StandaloneTestRunner.FrontendLocation + "?" + this._debuggerURL, "inspector", features);
- this._inspectorWindowLoading.dispatchStandaloneTestRunnerMessages = true;
-
- window.addEventListener('unload', this.cleanup.bind(this));
-
- if (!window.debug)
- this._watchDog = setTimeout(this._timeout.bind(this), 10000);
- },
-
- loadCompleted: function()
- {
- if (!window.debug) {
- this._loadCompleted(this);
- return;
- }
- document.getElementById("debug").textContent = "Continue";
- },
-
- continueDebugging: function()
- {
- this._loadCompleted();
- },
-
- _loadCompleted: function()
- {
- this._inspectorWindow = this._inspectorWindowLoading;
- for (var i = 0; i < this._pendingMessages.length; ++i)
- this._inspectorWindow.postMessage(this._pendingMessages[i], "*");
- this._pendingMessages = [];
- },
-
- closeWebInspector: function()
- {
- if (!window.debug)
- this._inspectorWindow.close();
- },
-
- notifyDone: function(actual)
- {
- if (this._done)
- return;
- this._done = true;
-
- if (!window.debug)
- this.cleanup()
-
- clearTimeout(this._watchDog);
-
- this._treeElement.onselect = this.onTreeElementSelect.bind(this);
-
- // TODO pavel is the RHS || condition wanted?
- if (actual === this._expected || actual === this._expected + "\n") {
- this._treeElement.title = this._testPath + ": SUCCESS";
- this._next("pass");
- return;
- }
-
- this._treeElement.title = this._testPath + ": FAILED";
- this._treeElement.listItemElement.classList.add("failed");
-
- var baseLines = difflib.stringAsLines(this._expected);
- var newLines = difflib.stringAsLines(actual);
- var sm = new difflib.SequenceMatcher(baseLines, newLines);
- var opcodes = sm.get_opcodes();
- var lastWasSeparator = false;
-
- for (var idx = 0; idx < opcodes.length; idx++) {
- var code = opcodes[idx];
- var change = code[0];
- var b = code[1];
- var be = code[2];
- var n = code[3];
- var ne = code[4];
- var rowCount = Math.max(be - b, ne - n);
- var topRows = [];
- var bottomRows = [];
- for (var i = 0; i < rowCount; i++) {
- if (change === "delete" || (change === "replace" && b < be)) {
- var lineNumber = b++;
- this._treeElement.appendChild(new TreeElement("- [" + lineNumber + "] " + baseLines[lineNumber]));
- }
-
- if (change === "insert" || (change === "replace" && n < ne)) {
- var lineNumber = n++;
- this._treeElement.appendChild(new TreeElement("+ [" + lineNumber + "] " + newLines[lineNumber]));
- }
-
- if (change === "equal") {
- b++;
- n++;
- }
- }
- }
-
- this._next("fail");
- },
-
- evaluateInWebInspector: function(callId, script)
- {
- if (this._inspectorWindow)
- this._inspectorWindow.postMessage(["evaluateForTest", callId, script], "*");
- else
- this._pendingMessages.push(["evaluateForTest", callId, script]);
- },
-
- _timeout: function()
- {
- this._treeElement.title = this._testPath + ": TIMEOUT";
- this._treeElement.listItemElement.classList.add("timeout");
- this._done = true;
- this.cleanup();
- this._next("timeout");
- },
-
- cleanup: function ()
- {
- localStorage.setItem('inspectorWidth', this._inspectorWindowLoading.outerWidth);
- localStorage.setItem('inspectorHeight', this._inspectorWindowLoading.outerHeight);
- this._inspectorWindowLoading.close();
- this._testPage.close();
- delete window.runner;
- },
-
- onTreeElementSelect: function ()
- {
- var baseEndSentinel = '/inspector/';
- var baseChars = this._testPath.indexOf(baseEndSentinel) + baseEndSentinel.length;
- if (baseChars > 0)
- document.getElementById("filter").value = this._testPath.substr(baseChars);
- },
-
- display: function() { }
-}
-
-function onMessageFromTestPage(event)
-{
- var signature = event.data;
- var method = signature.shift();
- if (method === "tests") {
- tests = signature[0];
- runTests();
- return;
- }
-
- if (window.runner)
- window.runner[method].apply(window.runner, signature);
-}
-
-function onload()
-{
- var queryParamsObject = {};
- var queryParams = window.location.search;
- if (!queryParams)
- return;
- var params = queryParams.substring(1).split("&");
- for (var i = 0; i < params.length; ++i) {
- var pair = params[i].split("=");
- queryParamsObject[pair[0]] = pair[1];
- }
- if ("filter" in queryParamsObject)
- document.getElementById("filter").value = queryParamsObject["filter"];
-}
-
-window.addEventListener("message", onMessageFromTestPage, true);
-
-</script>
-<body onload="onload()">
-This is a standalone test suite for inspector front-end. Here is how you run it:
-<ul>
-<li>Check out WebKit source tree: git clone http://git.chromium.org/external/Webkit.git</li>
-<li>Run "Tools/Scripts/new-run-webkit-httpd --root=. --port=8002 --server=start"</li>
-<li>Run Chrome Canary (ToT Chromium) with following flags: "--remote-debugging-port=9222 --user-data-dir=testProfile http://localhost:8002/Source/devtools/front_end/test-runner.html"</li>
-</ul>
-
-<button onclick="run()">Run</button>
-<button id="debug" onclick="run(true)">Debug</button>
-<button onclick="interrupt()">Interrupt</button>
-Filter: <input id="filter" type="text" size="40"></input><small><i>Click on results to load filter</i></small><br>
-
-<span>Passed: <span id="pass">0</span></span>
-<span>Failed: <span id="fail">0</span></span>
-<span>Timeout: <span id="timeout">0</span></span>
-<span>Skipped: <span id="skip">0</span></span>
-<span>Remaining: <span id="remaining">0</span><br>
-
-<ol id="outline" style="font-size: 12px !important" class="source-code outline-disclosure"></ol>
-
-</body>
-</html>
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/CountersGraph.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/CountersGraph.js
new file mode 100644
index 00000000000..a63f9dd9a73
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/CountersGraph.js
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.SplitView}
+ * @param {string} title
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TimelineModel} model
+ */
+WebInspector.CountersGraph = function(title, delegate, model)
+{
+ WebInspector.SplitView.call(this, true, false);
+
+ this.element.id = "memory-graphs-container";
+
+ this._delegate = delegate;
+ this._model = model;
+ this._calculator = new WebInspector.TimelineCalculator(this._model);
+
+ this._graphsContainer = this.mainElement();
+ this._createCurrentValuesBar();
+ this._canvasView = new WebInspector.VBoxWithResizeCallback(this._resize.bind(this));
+ this._canvasView.show(this._graphsContainer);
+ this._canvasContainer = this._canvasView.element;
+ this._canvasContainer.id = "memory-graphs-canvas-container";
+ this._canvas = this._canvasContainer.createChild("canvas");
+ this._canvas.id = "memory-counters-graph";
+
+ this._canvasContainer.addEventListener("mouseover", this._onMouseMove.bind(this), true);
+ this._canvasContainer.addEventListener("mousemove", this._onMouseMove.bind(this), true);
+ this._canvasContainer.addEventListener("mouseout", this._onMouseOut.bind(this), true);
+ this._canvasContainer.addEventListener("click", this._onClick.bind(this), true);
+ // We create extra timeline grid here to reuse its event dividers.
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
+
+ // Populate sidebar
+ this.sidebarElement().createChild("div", "sidebar-tree sidebar-tree-section").textContent = title;
+ this._counters = [];
+ this._counterUI = [];
+}
+
+WebInspector.CountersGraph.prototype = {
+ _createCurrentValuesBar: function()
+ {
+ this._currentValuesBar = this._graphsContainer.createChild("div");
+ this._currentValuesBar.id = "counter-values-bar";
+ },
+
+ /**
+ * @param {string} uiName
+ * @param {string} uiValueTemplate
+ * @param {string} color
+ * @return {!WebInspector.CountersGraph.Counter}
+ */
+ createCounter: function(uiName, uiValueTemplate, color)
+ {
+ var counter = new WebInspector.CountersGraph.Counter();
+ this._counters.push(counter);
+ this._counterUI.push(new WebInspector.CountersGraph.CounterUI(this, uiName, uiValueTemplate, color, counter));
+ return counter;
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function()
+ {
+ return this;
+ },
+
+ dispose: function()
+ {
+ },
+
+ reset: function()
+ {
+ for (var i = 0; i < this._counters.length; ++i) {
+ this._counters[i].reset();
+ this._counterUI[i].reset();
+ }
+ this.refresh();
+ },
+
+ _resize: function()
+ {
+ var parentElement = this._canvas.parentElement;
+ this._canvas.width = parentElement.clientWidth * window.devicePixelRatio;
+ this._canvas.height = parentElement.clientHeight * window.devicePixelRatio;
+ var timelinePaddingLeft = 15;
+ this._calculator.setDisplayWindow(timelinePaddingLeft, this._canvas.width);
+ this.refresh();
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._calculator.setWindow(startTime, endTime);
+ this.scheduleRefresh();
+ },
+
+ scheduleRefresh: function()
+ {
+ WebInspector.invokeOnceAfterBatchUpdate(this, this.refresh);
+ },
+
+ draw: function()
+ {
+ for (var i = 0; i < this._counters.length; ++i) {
+ this._counters[i]._calculateVisibleIndexes(this._calculator);
+ this._counters[i]._calculateXValues(this._canvas.width);
+ }
+ this._clear();
+
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._counterUI[i]._drawGraph(this._canvas);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onClick: function(event)
+ {
+ var x = event.x - this._canvasContainer.totalOffsetLeft();
+ var minDistance = Infinity;
+ var bestTime;
+ for (var i = 0; i < this._counterUI.length; ++i) {
+ var counterUI = this._counterUI[i];
+ if (!counterUI.counter.times.length)
+ continue;
+ var index = counterUI._recordIndexAt(x);
+ var distance = Math.abs(x * window.devicePixelRatio - counterUI.counter.x[index]);
+ if (distance < minDistance) {
+ minDistance = distance;
+ bestTime = counterUI.counter.times[index];
+ }
+ }
+ if (bestTime !== undefined)
+ this._revealRecordAt(bestTime);
+ },
+
+ /**
+ * @param {number} time
+ */
+ _revealRecordAt: function(time)
+ {
+ var recordToReveal;
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ * @this {WebInspector.CountersGraph}
+ */
+ function findRecordToReveal(record)
+ {
+ if (!this._model.isVisible(record))
+ return false;
+ if (record.startTime() <= time && time <= record.endTime()) {
+ recordToReveal = record;
+ return true;
+ }
+ // If there is no record containing the time than use the latest one before that time.
+ if (!recordToReveal || record.endTime() < time && recordToReveal.endTime() < record.endTime())
+ recordToReveal = record;
+ return false;
+ }
+ this._model.forAllRecords(null, findRecordToReveal.bind(this));
+ this._delegate.select(recordToReveal ? WebInspector.TimelineSelection.fromRecord(recordToReveal) : null);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOut: function(event)
+ {
+ delete this._markerXPosition;
+ this._clearCurrentValueAndMarker();
+ },
+
+ _clearCurrentValueAndMarker: function()
+ {
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._counterUI[i]._clearCurrentValueAndMarker();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseMove: function(event)
+ {
+ var x = event.x - this._canvasContainer.totalOffsetLeft();
+ this._markerXPosition = x;
+ this._refreshCurrentValues();
+ },
+
+ _refreshCurrentValues: function()
+ {
+ if (this._markerXPosition === undefined)
+ return;
+ for (var i = 0; i < this._counterUI.length; ++i)
+ this._counterUI[i].updateCurrentValue(this._markerXPosition);
+ },
+
+ refresh: function()
+ {
+ this._timelineGrid.updateDividers(this._calculator);
+ this.draw();
+ this._refreshCurrentValues();
+ },
+
+ refreshRecords: function()
+ {
+ },
+
+ _clear: function()
+ {
+ var ctx = this._canvas.getContext("2d");
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord)
+ {
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ setSelection: function(selection)
+ {
+ },
+
+ __proto__: WebInspector.SplitView.prototype
+}
+
+/**
+ * @constructor
+ */
+WebInspector.CountersGraph.Counter = function()
+{
+ this.times = [];
+ this.values = [];
+}
+
+WebInspector.CountersGraph.Counter.prototype = {
+ /**
+ * @param {number} time
+ * @param {number} value
+ */
+ appendSample: function(time, value)
+ {
+ if (this.values.length && this.values.peekLast() === value)
+ return;
+ this.times.push(time);
+ this.values.push(value);
+ },
+
+ reset: function()
+ {
+ this.times = [];
+ this.values = [];
+ },
+
+ /**
+ * @param {number} value
+ */
+ setLimit: function(value)
+ {
+ this._limitValue = value;
+ },
+
+ /**
+ * @return {!{min: number, max: number}}
+ */
+ _calculateBounds: function()
+ {
+ var maxValue;
+ var minValue;
+ for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
+ var value = this.values[i];
+ if (minValue === undefined || value < minValue)
+ minValue = value;
+ if (maxValue === undefined || value > maxValue)
+ maxValue = value;
+ }
+ minValue = minValue || 0;
+ maxValue = maxValue || 1;
+ if (this._limitValue) {
+ if (maxValue > this._limitValue * 0.5)
+ maxValue = Math.max(maxValue, this._limitValue);
+ minValue = Math.min(minValue, this._limitValue);
+ }
+ return { min: minValue, max: maxValue };
+ },
+
+ /**
+ * @param {!WebInspector.TimelineCalculator} calculator
+ */
+ _calculateVisibleIndexes: function(calculator)
+ {
+ var start = calculator.minimumBoundary();
+ var end = calculator.maximumBoundary();
+
+ // Maximum index of element whose time <= start.
+ this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, this.times.length - 1);
+
+ // Minimum index of element whose time >= end.
+ this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, this.times.length - 1);
+
+ // Current window bounds.
+ this._minTime = start;
+ this._maxTime = end;
+ },
+
+ /**
+ * @param {number} width
+ */
+ _calculateXValues: function(width)
+ {
+ if (!this.values.length)
+ return;
+
+ var xFactor = width / (this._maxTime - this._minTime);
+
+ this.x = new Array(this.values.length);
+ for (var i = this._minimumIndex + 1; i <= this._maximumIndex; i++)
+ this.x[i] = xFactor * (this.times[i] - this._minTime);
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.CountersGraph} memoryCountersPane
+ * @param {string} title
+ * @param {string} currentValueLabel
+ * @param {string} graphColor
+ * @param {!WebInspector.CountersGraph.Counter} counter
+ */
+WebInspector.CountersGraph.CounterUI = function(memoryCountersPane, title, currentValueLabel, graphColor, counter)
+{
+ this._memoryCountersPane = memoryCountersPane;
+ this.counter = counter;
+ var container = memoryCountersPane.sidebarElement().createChild("div", "memory-counter-sidebar-info");
+ var swatchColor = graphColor;
+ this._swatch = new WebInspector.SwatchCheckbox(WebInspector.UIString(title), swatchColor);
+ this._swatch.addEventListener(WebInspector.SwatchCheckbox.Events.Changed, this._toggleCounterGraph.bind(this));
+ container.appendChild(this._swatch.element);
+ this._range = this._swatch.element.createChild("span");
+
+ this._value = memoryCountersPane._currentValuesBar.createChild("span", "memory-counter-value");
+ this._value.style.color = graphColor;
+ this.graphColor = graphColor;
+ this.limitColor = WebInspector.Color.parse(graphColor).setAlpha(0.3).toString(WebInspector.Color.Format.RGBA);
+ this.graphYValues = [];
+ this._verticalPadding = 10;
+
+ this._currentValueLabel = currentValueLabel;
+ this._marker = memoryCountersPane._canvasContainer.createChild("div", "memory-counter-marker");
+ this._marker.style.backgroundColor = graphColor;
+ this._clearCurrentValueAndMarker();
+}
+
+WebInspector.CountersGraph.CounterUI.prototype = {
+ reset: function()
+ {
+ this._range.textContent = "";
+ },
+
+ /**
+ * @param {number} minValue
+ * @param {number} maxValue
+ */
+ setRange: function(minValue, maxValue)
+ {
+ this._range.textContent = WebInspector.UIString("[%.0f:%.0f]", minValue, maxValue);
+ },
+
+ _toggleCounterGraph: function(event)
+ {
+ this._value.classList.toggle("hidden", !this._swatch.checked);
+ this._memoryCountersPane.refresh();
+ },
+
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ _recordIndexAt: function(x)
+ {
+ return this.counter.x.upperBound(x * window.devicePixelRatio, null, this.counter._minimumIndex + 1, this.counter._maximumIndex + 1) - 1;
+ },
+
+ /**
+ * @param {number} x
+ */
+ updateCurrentValue: function(x)
+ {
+ if (!this.visible() || !this.counter.values.length)
+ return;
+ var index = this._recordIndexAt(x);
+ this._value.textContent = WebInspector.UIString(this._currentValueLabel, this.counter.values[index]);
+ var y = this.graphYValues[index] / window.devicePixelRatio;
+ this._marker.style.left = x + "px";
+ this._marker.style.top = y + "px";
+ this._marker.classList.remove("hidden");
+ },
+
+ _clearCurrentValueAndMarker: function()
+ {
+ this._value.textContent = "";
+ this._marker.classList.add("hidden");
+ },
+
+ /**
+ * @param {!HTMLCanvasElement} canvas
+ */
+ _drawGraph: function(canvas)
+ {
+ var ctx = canvas.getContext("2d");
+ var width = canvas.width;
+ var height = canvas.height - 2 * this._verticalPadding;
+ if (height <= 0) {
+ this.graphYValues = [];
+ return;
+ }
+ var originY = this._verticalPadding;
+ var counter = this.counter;
+ var values = counter.values;
+
+ if (!values.length)
+ return;
+
+ var bounds = counter._calculateBounds();
+ var minValue = bounds.min;
+ var maxValue = bounds.max;
+ this.setRange(minValue, maxValue);
+
+ if (!this.visible())
+ return;
+
+ var yValues = this.graphYValues;
+ var maxYRange = maxValue - minValue;
+ var yFactor = maxYRange ? height / (maxYRange) : 1;
+
+ ctx.save();
+ ctx.lineWidth = window.devicePixelRatio;
+ if (ctx.lineWidth % 2)
+ ctx.translate(0.5, 0.5);
+ ctx.beginPath();
+ var value = values[counter._minimumIndex];
+ var currentY = Math.round(originY + height - (value - minValue) * yFactor);
+ ctx.moveTo(0, currentY);
+ for (var i = counter._minimumIndex; i <= counter._maximumIndex; i++) {
+ var x = Math.round(counter.x[i]);
+ ctx.lineTo(x, currentY);
+ var currentValue = values[i];
+ if (typeof currentValue !== "undefined")
+ value = currentValue;
+ currentY = Math.round(originY + height - (value - minValue) * yFactor);
+ ctx.lineTo(x, currentY);
+ yValues[i] = currentY;
+ }
+ yValues.length = i;
+ ctx.lineTo(width, currentY);
+ ctx.strokeStyle = this.graphColor;
+ ctx.stroke();
+ if (counter._limitValue) {
+ var limitLineY = Math.round(originY + height - (counter._limitValue - minValue) * yFactor);
+ ctx.moveTo(0, limitLineY);
+ ctx.lineTo(width, limitLineY);
+ ctx.strokeStyle = this.limitColor;
+ ctx.stroke();
+ }
+ ctx.closePath();
+ ctx.restore();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ visible: function()
+ {
+ return this._swatch.checked;
+ }
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.SwatchCheckbox = function(title, color)
+{
+ this.element = document.createElement("div");
+ this._swatch = this.element.createChild("div", "swatch");
+ this.element.createChild("span", "title").textContent = title;
+ this._color = color;
+ this.checked = true;
+
+ this.element.addEventListener("click", this._toggleCheckbox.bind(this), true);
+}
+
+WebInspector.SwatchCheckbox.Events = {
+ Changed: "Changed"
+}
+
+WebInspector.SwatchCheckbox.prototype = {
+ get checked()
+ {
+ return this._checked;
+ },
+
+ set checked(v)
+ {
+ this._checked = v;
+ if (this._checked)
+ this._swatch.style.backgroundColor = this._color;
+ else
+ this._swatch.style.backgroundColor = "";
+ },
+
+ _toggleCheckbox: function(event)
+ {
+ this.checked = !this.checked;
+ this.dispatchEventToListeners(WebInspector.SwatchCheckbox.Events.Changed);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
new file mode 100644
index 00000000000..90dd25d0be6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/Layers3DView.js
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.Layers3DView = function()
+{
+ WebInspector.VBox.call(this);
+ this.element.classList.add("layers-3d-view");
+ this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in the composited mode.\nConsider forcing composited mode in Settings."));
+ this._canvasElement = this.element.createChild("canvas");
+ this._transformController = new WebInspector.TransformController(this._canvasElement);
+ this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged, this._update, this);
+ this._canvasElement.addEventListener("dblclick", this._onDoubleClick.bind(this), false);
+ this._canvasElement.addEventListener("mousedown", this._onMouseDown.bind(this), false);
+ this._canvasElement.addEventListener("mouseup", this._onMouseUp.bind(this), false);
+ this._canvasElement.addEventListener("mouseout", this._onMouseMove.bind(this), false);
+ this._canvasElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
+ this._canvasElement.addEventListener("contextmenu", this._onContextMenu.bind(this), false);
+ this._lastActiveObject = {};
+ this._picturesForLayer = {};
+ this._scrollRectQuadsForLayer = {};
+ this._isVisible = {};
+ this._layerTree = null;
+ WebInspector.settings.showPaintRects.addChangeListener(this._update, this);
+}
+
+/** @typedef {{layer: !WebInspector.Layer, scrollRectIndex: number}|{layer: !WebInspector.Layer}} */
+WebInspector.Layers3DView.ActiveObject;
+
+/** @typedef {{color: !Array.<number>, borderColor: !Array.<number>, borderWidth: number}} */
+WebInspector.Layers3DView.LayerStyle;
+
+/** @typedef {{layerId: string, rect: !Array.<number>, imageURL: string}} */
+WebInspector.Layers3DView.Tile;
+
+/**
+ * @enum {string}
+ */
+WebInspector.Layers3DView.OutlineType = {
+ Hovered: "hovered",
+ Selected: "selected"
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.Layers3DView.Events = {
+ ObjectHovered: "ObjectHovered",
+ ObjectSelected: "ObjectSelected",
+ LayerSnapshotRequested: "LayerSnapshotRequested"
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.Layers3DView.ScrollRectTitles = {
+ RepaintsOnScroll: WebInspector.UIString("repaints on scroll"),
+ TouchEventHandler: WebInspector.UIString("touch event listener"),
+ WheelEventHandler: WebInspector.UIString("mousewheel event listener")
+}
+
+WebInspector.Layers3DView.FragmentShader = "\
+ precision mediump float;\
+ varying vec4 vColor;\
+ varying vec2 vTextureCoord;\
+ uniform sampler2D uSampler;\
+ void main(void)\
+ {\
+ gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\
+ }";
+
+WebInspector.Layers3DView.VertexShader = "\
+ attribute vec3 aVertexPosition;\
+ attribute vec2 aTextureCoord;\
+ attribute vec4 aVertexColor;\
+ uniform mat4 uPMatrix;\
+ varying vec2 vTextureCoord;\
+ varying vec4 vColor;\
+ void main(void)\
+ {\
+ gl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\
+ vColor = aVertexColor;\
+ vTextureCoord = aTextureCoord;\
+ }";
+
+WebInspector.Layers3DView.SelectedBackgroundColor = [20, 40, 110, 0.66];
+WebInspector.Layers3DView.BackgroundColor = [0, 0, 0, 0];
+WebInspector.Layers3DView.HoveredBorderColor = [0, 0, 255, 1];
+WebInspector.Layers3DView.SelectedBorderColor = [0, 255, 0, 1];
+WebInspector.Layers3DView.BorderColor = [0, 0, 0, 1];
+WebInspector.Layers3DView.ScrollRectBackgroundColor = [178, 0, 0, 0.4];
+WebInspector.Layers3DView.SelectedScrollRectBackgroundColor = [178, 0, 0, 0.6];
+WebInspector.Layers3DView.ScrollRectBorderColor = [178, 0, 0, 1];
+WebInspector.Layers3DView.BorderWidth = 1;
+WebInspector.Layers3DView.SelectedBorderWidth = 2;
+
+WebInspector.Layers3DView.LayerSpacing = 20;
+WebInspector.Layers3DView.ScrollRectSpacing = 4;
+
+WebInspector.Layers3DView.prototype = {
+ /**
+ * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(?Event=))} registerShortcutDelegate
+ */
+ registerShortcuts: function(registerShortcutDelegate)
+ {
+ this._transformController.registerShortcuts(registerShortcutDelegate);
+ },
+
+ onResize: function()
+ {
+ this._update();
+ },
+
+ willHide: function()
+ {
+ },
+
+ wasShown: function()
+ {
+ if (this._needsUpdate)
+ this._update();
+ },
+
+ /**
+ * @param {!WebInspector.Layers3DView.OutlineType} type
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ _setOutline: function(type, activeObject)
+ {
+ this._lastActiveObject[type] = activeObject;
+ this._update();
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ hoverObject: function(activeObject)
+ {
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, activeObject);
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ selectObject: function(activeObject)
+ {
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {string=} imageURL
+ */
+ showImageForLayer: function(layer, imageURL)
+ {
+ this.setTiles([{layerId: layer.id(), rect: [0, 0, layer.width(), layer.height()], imageURL: imageURL}])
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.Layers3DView.Tile>} tiles
+ */
+ setTiles: function(tiles)
+ {
+ this._picturesForLayer = {};
+ tiles.forEach(this._setTile, this);
+ },
+
+ /**
+ * @param {!WebInspector.Layers3DView.Tile} tile
+ */
+ _setTile: function(tile)
+ {
+ var texture = this._gl.createTexture();
+ texture.image = new Image();
+ texture.image.addEventListener("load", this._handleLoadedTexture.bind(this, texture, tile.layerId, tile.rect), false);
+ texture.image.src = tile.imageURL;
+ },
+
+ /**
+ * @param {!Element} canvas
+ * @return {!Object}
+ */
+ _initGL: function(canvas)
+ {
+ var gl = canvas.getContext("webgl");
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+ gl.enable(gl.BLEND);
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.enable(gl.DEPTH_TEST);
+ return gl;
+ },
+
+ /**
+ * @param {!Object} type
+ * @param {string} script
+ */
+ _createShader: function(type, script)
+ {
+ var shader = this._gl.createShader(type);
+ this._gl.shaderSource(shader, script);
+ this._gl.compileShader(shader);
+ this._gl.attachShader(this._shaderProgram, shader);
+ },
+
+ /**
+ * @param {string} attributeName
+ * @param {string} glName
+ */
+ _enableVertexAttribArray: function(attributeName, glName)
+ {
+ this._shaderProgram[attributeName] = this._gl.getAttribLocation(this._shaderProgram, glName);
+ this._gl.enableVertexAttribArray(this._shaderProgram[attributeName]);
+ },
+
+ _initShaders: function()
+ {
+ this._shaderProgram = this._gl.createProgram();
+ this._createShader(this._gl.FRAGMENT_SHADER, WebInspector.Layers3DView.FragmentShader);
+ this._createShader(this._gl.VERTEX_SHADER, WebInspector.Layers3DView.VertexShader);
+ this._gl.linkProgram(this._shaderProgram);
+ this._gl.useProgram(this._shaderProgram);
+
+ this._shaderProgram.vertexPositionAttribute = this._gl.getAttribLocation(this._shaderProgram, "aVertexPosition");
+ this._gl.enableVertexAttribArray(this._shaderProgram.vertexPositionAttribute);
+ this._shaderProgram.vertexColorAttribute = this._gl.getAttribLocation(this._shaderProgram, "aVertexColor");
+ this._gl.enableVertexAttribArray(this._shaderProgram.vertexColorAttribute);
+ this._shaderProgram.textureCoordAttribute = this._gl.getAttribLocation(this._shaderProgram, "aTextureCoord");
+ this._gl.enableVertexAttribArray(this._shaderProgram.textureCoordAttribute);
+
+ this._shaderProgram.pMatrixUniform = this._gl.getUniformLocation(this._shaderProgram, "uPMatrix");
+ this._shaderProgram.samplerUniform = this._gl.getUniformLocation(this._shaderProgram, "uSampler");
+ },
+
+ _resizeCanvas: function()
+ {
+ this._canvasElement.width = this._canvasElement.offsetWidth * window.devicePixelRatio;
+ this._canvasElement.height = this._canvasElement.offsetHeight * window.devicePixelRatio;
+ this._gl.viewportWidth = this._canvasElement.width;
+ this._gl.viewportHeight = this._canvasElement.height;
+ },
+
+ /**
+ * @return {!CSSMatrix}
+ */
+ _calculateProjectionMatrix: function()
+ {
+ var scaleFactorForMargins = 1.2;
+ var viewport = this._layerTree.viewportSize();
+ var baseWidth = viewport ? viewport.width : this._layerTree.contentRoot().width();
+ var baseHeight = viewport ? viewport.height : this._layerTree.contentRoot().height();
+ var canvasWidth = this._canvasElement.width;
+ var canvasHeight = this._canvasElement.height;
+ var scaleX = canvasWidth / baseWidth / scaleFactorForMargins;
+ var scaleY = canvasHeight / baseHeight / scaleFactorForMargins;
+ var viewScale = Math.min(scaleX, scaleY);
+ var scale = this._transformController.scale();
+ var offsetX = this._transformController.offsetX() * window.devicePixelRatio;
+ var offsetY = this._transformController.offsetY() * window.devicePixelRatio;
+ var rotateX = this._transformController.rotateX();
+ var rotateY = this._transformController.rotateY();
+ return new WebKitCSSMatrix().translate(offsetX, offsetY, 0).scale(scale, scale, scale).translate(canvasWidth / 2, canvasHeight / 2, 0)
+ .rotate(rotateX, rotateY, 0).scale(viewScale, viewScale, viewScale).translate(-baseWidth / 2, -baseHeight / 2, 0);
+ },
+
+ _initProjectionMatrix: function()
+ {
+ this._pMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0)
+ .scale(2 / this._canvasElement.width, 2 / this._canvasElement.height, 1 / 1000000).multiply(this._calculateProjectionMatrix());
+ this._gl.uniformMatrix4fv(this._shaderProgram.pMatrixUniform, false, this._arrayFromMatrix(this._pMatrix));
+ },
+
+ /**
+ * @param {!Object} texture
+ * @param {string} layerId
+ * @param {!Array.<number>} rect
+ */
+ _handleLoadedTexture: function(texture, layerId, rect)
+ {
+ this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
+ this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, true);
+ this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture.image);
+ this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);
+ this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);
+ this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
+ this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
+ this._gl.bindTexture(this._gl.TEXTURE_2D, null);
+ if (!this._picturesForLayer[layerId])
+ this._picturesForLayer[layerId] = [];
+ this._picturesForLayer[layerId].push({texture: texture, rect: rect});
+ this._update();
+ },
+
+ _initWhiteTexture: function()
+ {
+ this._whiteTexture = this._gl.createTexture();
+ this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
+ var whitePixel = new Uint8Array([255, 255, 255, 255]);
+ this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, 1, 1, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, whitePixel);
+ },
+
+ _initGLIfNecessary: function()
+ {
+ if (this._gl)
+ return this._gl;
+ this._gl = this._initGL(this._canvasElement);
+ this._initShaders();
+ this._initWhiteTexture();
+ return this._gl;
+ },
+
+ /**
+ * @param {!CSSMatrix} m
+ * @return {!Float32Array}
+ */
+ _arrayFromMatrix: function(m)
+ {
+ return new Float32Array([m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44]);
+ },
+
+ /**
+ * @param {!Array.<number>} color
+ * @return {!Array.<number>}
+ */
+ _makeColorsArray: function(color)
+ {
+ var colors = [];
+ var normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
+ for (var i = 0; i < 4; i++) {
+ colors = colors.concat(normalizedColor);
+ }
+ return colors;
+ },
+
+ /**
+ * @param {!Object} attribute
+ * @param {!Array.<number>} array
+ * @param {!number} length
+ */
+ _setVertexAttribute: function(attribute, array, length)
+ {
+ var gl = this._gl;
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(attribute, length, gl.FLOAT, false, 0, 0);
+ },
+
+ /**
+ * @param {!Array.<number>} vertices
+ * @param {!Array.<number>} color
+ * @param {!Object} glMode
+ * @param {!Object=} texture
+ */
+ _drawRectangle: function(vertices, color, glMode, texture)
+ {
+ this._setVertexAttribute(this._shaderProgram.vertexPositionAttribute, vertices, 3);
+ this._setVertexAttribute(this._shaderProgram.textureCoordAttribute, [0, 1, 1, 1, 1, 0, 0, 0], 2);
+
+ if (texture) {
+ var white = [255, 255, 255, 1];
+ this._setVertexAttribute(this._shaderProgram.vertexColorAttribute, this._makeColorsArray(white), white.length);
+ this._gl.activeTexture(this._gl.TEXTURE0);
+ this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
+ this._gl.uniform1i(this._shaderProgram.samplerUniform, 0);
+ } else {
+ this._setVertexAttribute(this._shaderProgram.vertexColorAttribute, this._makeColorsArray(color), color.length);
+ this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
+ }
+
+ var numberOfVertices = 4;
+ this._gl.drawArrays(glMode, 0, numberOfVertices);
+ },
+
+ /**
+ * @param {!WebInspector.Layers3DView.OutlineType} type
+ * @param {!WebInspector.Layer} layer
+ * @param {number=} scrollRectIndex
+ */
+ _isObjectActive: function(type, layer, scrollRectIndex)
+ {
+ var activeObject = this._lastActiveObject[type];
+ return activeObject && activeObject.layer && activeObject.layer.id() === layer.id() && (typeof scrollRectIndex !== "number" || activeObject.scrollRectIndex === scrollRectIndex);
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @return {!WebInspector.Layers3DView.LayerStyle}
+ */
+ _styleForLayer: function(layer)
+ {
+ var isSelected = this._isObjectActive(WebInspector.Layers3DView.OutlineType.Selected, layer);
+ var isHovered = this._isObjectActive(WebInspector.Layers3DView.OutlineType.Hovered, layer);
+ var color = isSelected ? WebInspector.Layers3DView.SelectedBackgroundColor : WebInspector.Layers3DView.BackgroundColor;
+ var borderColor;
+ if (isSelected)
+ borderColor = WebInspector.Layers3DView.SelectedBorderColor;
+ else if (isHovered)
+ borderColor = WebInspector.Layers3DView.HoveredBorderColor;
+ else
+ borderColor = WebInspector.Layers3DView.BorderColor;
+ var borderWidth = isSelected ? WebInspector.Layers3DView.SelectedBorderWidth : WebInspector.Layers3DView.BorderWidth;
+ return {color: color, borderColor: borderColor, borderWidth: borderWidth};
+ },
+
+ /**
+ * @param {!Array.<number>} quad
+ * @param {number} z
+ * @return {!Array.<number>}
+ */
+ _calculateVerticesForQuad: function(quad, z)
+ {
+ return [quad[0], quad[1], z, quad[2], quad[3], z, quad[4], quad[5], z, quad[6], quad[7], z];
+ },
+
+ /**
+ * Finds coordinates of point on layer quad, having offsets (ratioX * width) and (ratioY * height)
+ * from the left corner of the initial layer rect, where width and heigth are layer bounds.
+ * @param {!Array.<number>} quad
+ * @param {number} ratioX
+ * @param {number} ratioY
+ * @return {!Array.<number>}
+ */
+ _calculatePointOnQuad: function(quad, ratioX, ratioY)
+ {
+ var x0 = quad[0];
+ var y0 = quad[1];
+ var x1 = quad[2];
+ var y1 = quad[3];
+ var x2 = quad[4];
+ var y2 = quad[5];
+ var x3 = quad[6];
+ var y3 = quad[7];
+ // Point on the first quad side clockwise
+ var firstSidePointX = x0 + ratioX * (x1 - x0);
+ var firstSidePointY = y0 + ratioX * (y1 - y0);
+ // Point on the third quad side clockwise
+ var thirdSidePointX = x3 + ratioX * (x2 - x3);
+ var thirdSidePointY = y3 + ratioX * (y2 - y3);
+ var x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
+ var y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
+ return [x, y];
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {!DOMAgent.Rect} rect
+ * @return {!Array.<number>}
+ */
+ _calculateRectQuad: function(layer, rect)
+ {
+ var quad = layer.quad();
+ var rx1 = rect.x / layer.width();
+ var rx2 = (rect.x + rect.width) / layer.width();
+ var ry1 = rect.y / layer.height();
+ var ry2 = (rect.y + rect.height) / layer.height();
+ return this._calculatePointOnQuad(quad, rx1, ry1).concat(this._calculatePointOnQuad(quad, rx2, ry1))
+ .concat(this._calculatePointOnQuad(quad, rx2, ry2)).concat(this._calculatePointOnQuad(quad, rx1, ry2));
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @return {!Array.<!Array.<number>>}
+ */
+ _calculateScrollRectQuadsForLayer: function(layer)
+ {
+ var quads = [];
+ for (var i = 0; i < layer.scrollRects().length; ++i)
+ quads.push(this._calculateRectQuad(layer, layer.scrollRects()[i].rect));
+ return quads;
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {number} index
+ * @return {number}
+ */
+ _calculateScrollRectDepth: function(layer, index)
+ {
+ return this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing + index * WebInspector.Layers3DView.ScrollRectSpacing + 1;
+ },
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ */
+ _drawLayer: function(layer)
+ {
+ var gl = this._gl;
+ var vertices;
+ var style = this._styleForLayer(layer);
+ var layerDepth = this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing;
+ if (this._isVisible[layer.id()]) {
+ vertices = this._calculateVerticesForQuad(layer.quad(), layerDepth);
+ gl.lineWidth(style.borderWidth);
+ this._drawRectangle(vertices, style.borderColor, gl.LINE_LOOP);
+ gl.lineWidth(1);
+ }
+ this._scrollRectQuadsForLayer[layer.id()] = this._calculateScrollRectQuadsForLayer(layer);
+ var scrollRectQuads = this._scrollRectQuadsForLayer[layer.id()];
+ for (var i = 0; i < scrollRectQuads.length; ++i) {
+ vertices = this._calculateVerticesForQuad(scrollRectQuads[i], this._calculateScrollRectDepth(layer, i));
+ var isSelected = this._isObjectActive(WebInspector.Layers3DView.OutlineType.Selected, layer, i);
+ var color = isSelected ? WebInspector.Layers3DView.SelectedScrollRectBackgroundColor : WebInspector.Layers3DView.ScrollRectBackgroundColor;
+ this._drawRectangle(vertices, color, gl.TRIANGLE_FAN);
+ this._drawRectangle(vertices, WebInspector.Layers3DView.ScrollRectBorderColor, gl.LINE_LOOP);
+ }
+ var tiles = this._picturesForLayer[layer.id()] || [];
+ for (var i = 0; i < tiles.length; ++i) {
+ var tile = tiles[i];
+ var quad = this._calculateRectQuad(layer, {x: tile.rect[0], y: tile.rect[1], width: tile.rect[2] - tile.rect[0], height: tile.rect[3] - tile.rect[1]});
+ vertices = this._calculateVerticesForQuad(quad, layerDepth);
+ this._drawRectangle(vertices, style.color, gl.TRIANGLE_FAN, tile.texture);
+ }
+ },
+
+ _drawViewport: function()
+ {
+ var viewport = this._layerTree.viewportSize();
+ var vertices = [0, 0, 0, viewport.width, 0, 0, viewport.width, viewport.height, 0, 0, viewport.height, 0];
+ var color = [0, 0, 0, 1];
+ this._gl.lineWidth(3.0);
+ this._drawRectangle(vertices, color, this._gl.LINE_LOOP);
+ this._gl.lineWidth(1.0);
+ },
+
+ _calculateDepths: function()
+ {
+ this._depthByLayerId = {};
+ this._isVisible = {};
+ var depth = 0;
+ var root = this._layerTree.root();
+ var queue = [root];
+ this._depthByLayerId[root.id()] = 0;
+ this._isVisible[root.id()] = false;
+ while (queue.length > 0) {
+ var layer = queue.shift();
+ var children = layer.children();
+ for (var i = 0; i < children.length; ++i) {
+ this._depthByLayerId[children[i].id()] = ++depth;
+ this._isVisible[children[i].id()] = children[i] === this._layerTree.contentRoot() || this._isVisible[layer.id()];
+ queue.push(children[i]);
+ }
+ }
+ },
+
+
+ /**
+ * @param {?WebInspector.LayerTreeBase} layerTree
+ */
+ setLayerTree: function(layerTree)
+ {
+ this._layerTree = layerTree;
+ this._update();
+ },
+
+ _update: function()
+ {
+ if (!this.isShowing()) {
+ this._needsUpdate = true;
+ return;
+ }
+ var contentRoot = this._layerTree && this._layerTree.contentRoot();
+ if (!contentRoot || !this._layerTree.root()) {
+ this._emptyView.show(this.element);
+ return;
+ }
+ this._emptyView.detach();
+
+ var gl = this._initGLIfNecessary();
+ this._resizeCanvas();
+ this._initProjectionMatrix();
+ this._calculateDepths();
+
+ gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ if (this._layerTree.viewportSize())
+ this._drawViewport();
+ this._layerTree.forEachLayer(this._drawLayer.bind(this));
+ },
+
+ /**
+ * Intersects quad with given transform matrix and line l(t) = (x0, y0, t)
+ * @param {!Array.<number>} vertices
+ * @param {!CSSMatrix} matrix
+ * @param {!number} x0
+ * @param {!number} y0
+ * @return {(number|undefined)}
+ */
+ _intersectLineAndRect: function(vertices, matrix, x0, y0)
+ {
+ var epsilon = 1e-8;
+ var i;
+ // Vertices of the quad with transform matrix applied
+ var points = [];
+ for (i = 0; i < 4; ++i)
+ points[i] = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]), matrix);
+ // Calculating quad plane normal
+ var normal = WebInspector.Geometry.crossProduct(WebInspector.Geometry.subtract(points[1], points[0]), WebInspector.Geometry.subtract(points[2], points[1]));
+ // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
+ var A = normal.x;
+ var B = normal.y;
+ var C = normal.z;
+ var D = -(A * points[0].x + B * points[0].y + C * points[0].z);
+ // Finding t from the equation
+ var t = -(D + A * x0 + B * y0) / C;
+ // Point of the intersection
+ var pt = new WebInspector.Geometry.Vector(x0, y0, t);
+ // Vectors from the intersection point to vertices of the quad
+ var tVects = points.map(WebInspector.Geometry.subtract.bind(null, pt));
+ // Intersection point lies inside of the polygon if scalar products of normal of the plane and
+ // cross products of successive tVects are all nonstrictly above or all nonstrictly below zero
+ for (i = 0; i < tVects.length; ++i) {
+ var product = WebInspector.Geometry.scalarProduct(normal, WebInspector.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
+ if (product < 0)
+ return undefined;
+ }
+ return t;
+ },
+
+ /**
+ * @param {?Event} event
+ * @return {?WebInspector.Layers3DView.ActiveObject}
+ */
+ _activeObjectFromEventPoint: function(event)
+ {
+ if (!this._layerTree)
+ return null;
+ var closestIntersectionPoint = Infinity;
+ var closestLayer = null;
+ var projectionMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._calculateProjectionMatrix());
+ var x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
+ var y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @this {WebInspector.Layers3DView}
+ */
+ function checkIntersection(layer)
+ {
+ var t;
+ if (this._isVisible[layer.id()]) {
+ t = this._intersectLineAndRect(this._calculateVerticesForQuad(layer.quad(), this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing), projectionMatrix, x0, y0);
+ if (t < closestIntersectionPoint) {
+ closestIntersectionPoint = t;
+ closestLayer = {layer: layer};
+ }
+ }
+ var scrollRectQuads = this._scrollRectQuadsForLayer[layer.id()];
+ for (var i = 0; i < scrollRectQuads.length; ++i) {
+ t = this._intersectLineAndRect(this._calculateVerticesForQuad(scrollRectQuads[i], this._calculateScrollRectDepth(layer, i)), projectionMatrix, x0, y0);
+ if (t < closestIntersectionPoint) {
+ closestIntersectionPoint = t;
+ closestLayer = {layer: layer, scrollRectIndex: i};
+ }
+ }
+ }
+
+ this._layerTree.forEachLayer(checkIntersection.bind(this));
+ return closestLayer;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onContextMenu: function(event)
+ {
+ var activeObject = this._activeObjectFromEventPoint(event);
+ var node = activeObject && activeObject.layer && activeObject.layer.nodeForSelfOrAncestor();
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendItem("Reset view", this._transformController._resetAndNotify.bind(this._transformController), false);
+ if (node)
+ contextMenu.appendApplicableItems(node);
+ contextMenu.show();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseMove: function(event)
+ {
+ if (event.which)
+ return;
+ this.dispatchEventToListeners(WebInspector.Layers3DView.Events.ObjectHovered, this._activeObjectFromEventPoint(event));
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseDown: function(event)
+ {
+ this._mouseDownX = event.clientX;
+ this._mouseDownY = event.clientY;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseUp: function(event)
+ {
+ const maxDistanceInPixels = 6;
+ if (this._mouseDownX && Math.abs(event.clientX - this._mouseDownX) < maxDistanceInPixels && Math.abs(event.clientY - this._mouseDownY) < maxDistanceInPixels)
+ this.dispatchEventToListeners(WebInspector.Layers3DView.Events.ObjectSelected, this._activeObjectFromEventPoint(event));
+ delete this._mouseDownX;
+ delete this._mouseDownY;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onDoubleClick: function(event)
+ {
+ var object = this._activeObjectFromEventPoint(event);
+ if (object && object.layer)
+ this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSnapshotRequested, object.layer);
+ event.stopPropagation();
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/MemoryCountersGraph.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/MemoryCountersGraph.js
new file mode 100644
index 00000000000..055733d2a58
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/MemoryCountersGraph.js
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.CountersGraph}
+ * @implements {WebInspector.TimelineModeView}
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
+ */
+WebInspector.MemoryCountersGraph = function(delegate, model, uiUtils)
+{
+ WebInspector.CountersGraph.call(this, WebInspector.UIString("MEMORY"), delegate, model);
+ this._uiUtils = uiUtils;
+ this._countersByName = {};
+ this._countersByName["jsHeapSizeUsed"] = this.createCounter(WebInspector.UIString("Used JS Heap"), WebInspector.UIString("JS Heap Size: %d"), "hsl(220, 90%, 43%)");
+ this._countersByName["documents"] = this.createCounter(WebInspector.UIString("Documents"), WebInspector.UIString("Documents: %d"), "hsl(0, 90%, 43%)");
+ this._countersByName["nodes"] = this.createCounter(WebInspector.UIString("Nodes"), WebInspector.UIString("Nodes: %d"), "hsl(120, 90%, 43%)");
+ this._countersByName["jsEventListeners"] = this.createCounter(WebInspector.UIString("Listeners"), WebInspector.UIString("Listeners: %d"), "hsl(38, 90%, 43%)");
+ if (WebInspector.experimentsSettings.gpuTimeline.isEnabled()) {
+ this._gpuMemoryCounter = this.createCounter(WebInspector.UIString("GPU Memory"), WebInspector.UIString("GPU Memory [KB]: %d"), "hsl(300, 90%, 43%)");
+ this._countersByName["gpuMemoryUsedKB"] = this._gpuMemoryCounter;
+ }
+}
+
+WebInspector.MemoryCountersGraph.prototype = {
+ timelineStarted: function()
+ {
+ },
+
+ timelineStopped: function()
+ {
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @this {!WebInspector.MemoryCountersGraph}
+ */
+ function addStatistics(record)
+ {
+ var counters = this._uiUtils.countersForRecord(record);
+ if (!counters)
+ return;
+ for (var name in counters) {
+ var counter = this._countersByName[name];
+ if (counter)
+ counter.appendSample(record.endTime() || record.startTime(), counters[name]);
+ }
+
+ var gpuMemoryLimitCounterName = "gpuMemoryLimitKB";
+ if (this._gpuMemoryCounter && (gpuMemoryLimitCounterName in counters))
+ this._gpuMemoryCounter.setLimit(counters[gpuMemoryLimitCounterName]);
+ }
+ WebInspector.TimelineModel.forAllRecords([record], null, addStatistics.bind(this));
+ this.scheduleRefresh();
+ },
+
+ refreshRecords: function()
+ {
+ this.reset();
+ var records = this._model.records();
+ for (var i = 0; i < records.length; ++i)
+ this.addRecord(records[i]);
+ },
+
+ __proto__: WebInspector.CountersGraph.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineEventOverview.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js
index f75e474f6fa..1ad996560db 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineEventOverview.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineEventOverview.js
@@ -32,22 +32,23 @@
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
* @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
-WebInspector.TimelineEventOverview = function(model)
+WebInspector.TimelineEventOverview = function(model, uiUtils)
{
WebInspector.TimelineOverviewBase.call(this, model);
-
+ this._uiUtils = uiUtils;
this.element.id = "timeline-overview-events";
this._fillStyles = {};
- var categories = WebInspector.TimelinePresentationModel.categories();
+ var categories = WebInspector.TimelineUIUtils.categories();
for (var category in categories) {
- this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, 0, WebInspector.TimelineEventOverview._stripGradientHeight, categories[category]);
+ this._fillStyles[category] = WebInspector.TimelineUIUtils.createFillStyleForCategory(this._context, 0, WebInspector.TimelineEventOverview._stripGradientHeight, categories[category]);
categories[category].addEventListener(WebInspector.TimelineCategory.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
}
- this._disabledCategoryFillStyle = WebInspector.TimelinePresentationModel.createFillStyle(this._context, 0, WebInspector.TimelineEventOverview._stripGradientHeight,
- "rgb(218, 218, 218)", "rgb(170, 170, 170)", "rgb(143, 143, 143)");
+ this._disabledCategoryFillStyle = WebInspector.TimelineUIUtils.createFillStyle(this._context, 0, WebInspector.TimelineEventOverview._stripGradientHeight,
+ "hsl(0, 0%, 85%)", "hsl(0, 0%, 67%)", "hsl(0, 0%, 56%)");
this._disabledCategoryBorderStyle = "rgb(143, 143, 143)";
}
@@ -59,6 +60,13 @@ WebInspector.TimelineEventOverview._numberOfStrips = 3;
WebInspector.TimelineEventOverview._stripGradientHeight = 120;
WebInspector.TimelineEventOverview.prototype = {
+ dispose: function()
+ {
+ var categories = WebInspector.TimelineUIUtils.categories();
+ for (var category in categories)
+ categories[category].removeEventListener(WebInspector.TimelineCategory.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
+ },
+
update: function()
{
this.resetCanvas();
@@ -75,30 +83,33 @@ WebInspector.TimelineEventOverview.prototype = {
this._context.fillRect(0.5, i * stripHeight + 0.5, this._canvas.width, stripHeight);
/**
+ * @param {!WebInspector.TimelineModel.Record} record
* @this {WebInspector.TimelineEventOverview}
*/
function appendRecord(record)
{
- if (record.type === WebInspector.TimelineModel.RecordType.BeginFrame)
+ if (this._uiUtils.isBeginFrame(record))
return;
- var recordStart = Math.floor((WebInspector.TimelineModel.startTimeInSeconds(record) - timeOffset) * scale);
- var recordEnd = Math.ceil((WebInspector.TimelineModel.endTimeInSeconds(record) - timeOffset) * scale);
- var category = WebInspector.TimelinePresentationModel.categoryForRecord(record);
+ var recordStart = Math.floor((record.startTime() - timeOffset) * scale);
+ var recordEnd = Math.ceil((record.endTime() - timeOffset) * scale);
+ var category = record.category();
if (category.overviewStripGroupIndex < 0)
return;
var bar = lastBarByGroup[category.overviewStripGroupIndex];
// This bar may be merged with previous -- so just adjust the previous bar.
- const barsMergeThreshold = 2;
- if (bar && bar.category === category && bar.end + barsMergeThreshold >= recordStart) {
- if (recordEnd > bar.end)
+ if (bar) {
+ // If record fits entirely into previous bar just absorb it ignoring the category match.
+ if (recordEnd <= bar.end)
+ return;
+ if (bar.category === category && recordStart <= bar.end) {
bar.end = recordEnd;
- return;
- }
- if (bar)
+ return;
+ }
this._renderBar(bar.start, bar.end, stripHeight, bar.category);
+ }
lastBarByGroup[category.overviewStripGroupIndex] = { start: recordStart, end: recordEnd, category: category };
}
- WebInspector.TimelinePresentationModel.forAllRecords(this._model.records, appendRecord.bind(this));
+ this._model.forAllRecords(appendRecord.bind(this));
for (var i = 0; i < lastBarByGroup.length; ++i) {
if (lastBarByGroup[i])
this._renderBar(lastBarByGroup[i].start, lastBarByGroup[i].end, stripHeight, lastBarByGroup[i].category);
@@ -121,17 +132,22 @@ WebInspector.TimelineEventOverview.prototype = {
const stripPadding = 4 * window.devicePixelRatio;
const innerStripHeight = height - 2 * stripPadding;
- var x = begin + 0.5;
+ var x = begin;
var y = category.overviewStripGroupIndex * height + stripPadding + 0.5;
var width = Math.max(end - begin, 1);
this._context.save();
this._context.translate(x, y);
+ this._context.beginPath();
this._context.scale(1, innerStripHeight / WebInspector.TimelineEventOverview._stripGradientHeight);
this._context.fillStyle = category.hidden ? this._disabledCategoryFillStyle : this._fillStyles[category.name];
this._context.fillRect(0, 0, width, WebInspector.TimelineEventOverview._stripGradientHeight);
this._context.strokeStyle = category.hidden ? this._disabledCategoryBorderStyle : category.borderColor;
- this._context.strokeRect(0, 0, width, WebInspector.TimelineEventOverview._stripGradientHeight);
+ this._context.moveTo(0, 0);
+ this._context.lineTo(width, 0);
+ this._context.moveTo(0, WebInspector.TimelineEventOverview._stripGradientHeight);
+ this._context.lineTo(width, WebInspector.TimelineEventOverview._stripGradientHeight);
+ this._context.stroke();
this._context.restore();
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
new file mode 100644
index 00000000000..97f697f505f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChart.js
@@ -0,0 +1,980 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @implements {WebInspector.FlameChartDataProvider}
+ * @implements {WebInspector.TimelineFlameChart.SelectionProvider}
+ * @param {!WebInspector.TimelineModelImpl} model
+ * @param {!WebInspector.TimelineFrameModelBase} frameModel
+ */
+WebInspector.TimelineFlameChartDataProvider = function(model, frameModel)
+{
+ WebInspector.FlameChartDataProvider.call(this);
+ this._model = model;
+ this._frameModel = frameModel;
+ this._font = "12px " + WebInspector.fontFamily();
+ this._linkifier = new WebInspector.Linkifier();
+}
+
+WebInspector.TimelineFlameChartDataProvider.prototype = {
+ /**
+ * @return {number}
+ */
+ barHeight: function()
+ {
+ return 20;
+ },
+
+ /**
+ * @return {number}
+ */
+ textBaseline: function()
+ {
+ return 6;
+ },
+
+ /**
+ * @return {number}
+ */
+ textPadding: function()
+ {
+ return 5;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryFont: function(entryIndex)
+ {
+ return this._font;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryTitle: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (record === this._cpuThreadRecord)
+ return WebInspector.UIString("CPU");
+ else if (record === this._gpuThreadRecord)
+ return WebInspector.UIString("GPU");
+ var details = WebInspector.TimelineUIUtilsImpl.buildDetailsNode(record, this._linkifier, this._model.loadedFromFile());
+ var title = WebInspector.TimelineUIUtilsImpl.recordTitle(record);
+ return details ? WebInspector.UIString("%s (%s)", title, details.textContent) : title;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {?Array.<number>}
+ */
+ dividerOffsets: function(startTime, endTime)
+ {
+ // While we have tracing and timeline flame chart on screen at a time,
+ // we don't want to render frame-based grid.
+ return null;
+ },
+
+ reset: function()
+ {
+ this._timelineData = null;
+ },
+
+ /**
+ * @return {!WebInspector.FlameChart.TimelineData}
+ */
+ timelineData: function()
+ {
+ if (this._timelineData)
+ return this._timelineData;
+
+ this._linkifier.reset();
+
+ /**
+ * @type {?WebInspector.FlameChart.TimelineData}
+ */
+ this._timelineData = {
+ entryLevels: [],
+ entryTotalTimes: [],
+ entryStartTimes: []
+ };
+
+ this._records = [];
+ this._entryThreadDepths = {};
+ this._minimumBoundary = this._model.minimumRecordTime();
+
+ var cpuThreadRecordPayload = { type: WebInspector.TimelineModel.RecordType.Program };
+ this._cpuThreadRecord = new WebInspector.TimelineModel.RecordImpl(this._model, /** @type {!TimelineAgent.TimelineEvent} */ (cpuThreadRecordPayload), null);
+ this._pushRecord(this._cpuThreadRecord, 0, this.minimumBoundary(), Math.max(this._model.maximumRecordTime(), this.totalTime() + this.minimumBoundary()));
+
+ this._gpuThreadRecord = null;
+
+ var records = this._model.records();
+ for (var i = 0; i < records.length; ++i) {
+ var record = records[i];
+ var thread = record.thread();
+ if (thread === "gpu")
+ continue;
+ if (!thread) {
+ for (var j = 0; j < record.children().length; ++j)
+ this._appendRecord(record.children()[j], 1);
+ } else {
+ var visible = this._appendRecord(records[i], 1);
+ if (visible && !this._gpuThreadRecord) {
+ var gpuThreadRecordPayload = { type: WebInspector.TimelineModel.RecordType.Program };
+ this._gpuThreadRecord = new WebInspector.TimelineModel.RecordImpl(this._model, /** @type {!TimelineAgent.TimelineEvent} */ (gpuThreadRecordPayload), null);
+ this._pushRecord(this._gpuThreadRecord, 0, this.minimumBoundary(), Math.max(this._model.maximumRecordTime(), this.totalTime() + this.minimumBoundary()));
+ }
+ }
+ }
+
+ var cpuStackDepth = Math.max(4, this._entryThreadDepths[undefined]);
+ delete this._entryThreadDepths[undefined];
+ this._maxStackDepth = cpuStackDepth;
+
+ if (this._gpuThreadRecord) {
+ // We have multiple threads, update levels.
+ var threadBaselines = {};
+ var threadBaseline = cpuStackDepth + 2;
+
+ for (var thread in this._entryThreadDepths) {
+ threadBaselines[thread] = threadBaseline;
+ threadBaseline += this._entryThreadDepths[thread];
+ }
+ this._maxStackDepth = threadBaseline;
+
+ for (var i = 0; i < this._records.length; ++i) {
+ var record = this._records[i];
+ var level = this._timelineData.entryLevels[i];
+ if (record === this._cpuThreadRecord)
+ level = 0;
+ else if (record === this._gpuThreadRecord)
+ level = cpuStackDepth + 2;
+ else if (record.thread())
+ level += threadBaselines[record.thread()];
+ this._timelineData.entryLevels[i] = level;
+ }
+ }
+
+ return this._timelineData;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundary;
+ },
+
+ /**
+ * @return {number}
+ */
+ totalTime: function()
+ {
+ return Math.max(1000, this._model.maximumRecordTime() - this._model.minimumRecordTime());
+ },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function()
+ {
+ return this._maxStackDepth;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {number} level
+ * @return {boolean}
+ */
+ _appendRecord: function(record, level)
+ {
+ var result = false;
+ if (!this._model.isVisible(record)) {
+ for (var i = 0; i < record.children().length; ++i)
+ result = this._appendRecord(record.children()[i], level) || result;
+ return result;
+ }
+
+ this._pushRecord(record, level, record.startTime(), record.endTime());
+ for (var i = 0; i < record.children().length; ++i)
+ this._appendRecord(record.children()[i], level + 1);
+ return true;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {number} level
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {number}
+ */
+ _pushRecord: function(record, level, startTime, endTime)
+ {
+ var index = this._records.length;
+ this._records.push(record);
+ this._timelineData.entryStartTimes[index] = startTime;
+ this._timelineData.entryLevels[index] = level;
+ this._timelineData.entryTotalTimes[index] = endTime - startTime;
+ this._entryThreadDepths[record.thread()] = Math.max(level, this._entryThreadDepths[record.thread()] || 0);
+ return index;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?Array.<!{title: string, text: string}>}
+ */
+ prepareHighlightedEntryInfo: function(entryIndex)
+ {
+ return null;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ canJumpToEntry: function(entryIndex)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryColor: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (record === this._cpuThreadRecord || record === this._gpuThreadRecord)
+ return "#555";
+
+ if (record.type() === WebInspector.TimelineModel.RecordType.JSFrame)
+ return WebInspector.TimelineFlameChartDataProvider.jsFrameColorGenerator().colorForID(record.data()["functionName"]);
+
+ return record.category().fillColorStop1;
+ },
+
+
+ /**
+ * @param {number} entryIndex
+ * @param {!CanvasRenderingContext2D} context
+ * @param {?string} text
+ * @param {number} barX
+ * @param {number} barY
+ * @param {number} barWidth
+ * @param {number} barHeight
+ * @param {function(number):number} offsetToPosition
+ * @return {boolean}
+ */
+ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, offsetToPosition)
+ {
+ if (barWidth < 5)
+ return false;
+
+ var record = this._records[entryIndex];
+ var timelineData = this._timelineData;
+
+ var category = record.category();
+ // Paint text using white color on dark background.
+ if (text) {
+ context.save();
+ context.fillStyle = "white";
+ context.shadowColor = "rgba(0, 0, 0, 0.1)";
+ context.shadowOffsetX = 1;
+ context.shadowOffsetY = 1;
+ context.font = this._font;
+ context.fillText(text, barX + this.textPadding(), barY + barHeight - this.textBaseline());
+ context.restore();
+ }
+
+ if (record.children().length) {
+ var entryStartTime = timelineData.entryStartTimes[entryIndex];
+ var barSelf = offsetToPosition(entryStartTime + record.selfTime())
+
+ context.beginPath();
+ context.fillStyle = category.backgroundColor;
+ context.rect(barSelf, barY, barX + barWidth - barSelf, barHeight);
+ context.fill();
+
+ // Paint text using dark color on light background.
+ if (text) {
+ context.save();
+ context.clip();
+ context.fillStyle = category.borderColor;
+ context.shadowColor = "rgba(0, 0, 0, 0.1)";
+ context.shadowOffsetX = 1;
+ context.shadowOffsetY = 1;
+ context.fillText(text, barX + this.textPadding(), barY + barHeight - this.textBaseline());
+ context.restore();
+ }
+ }
+
+ if (record.warnings()) {
+ context.save();
+
+ context.rect(barX, barY, barWidth, this.barHeight());
+ context.clip();
+
+ context.beginPath();
+ context.fillStyle = record.warnings() ? "red" : "rgba(255, 0, 0, 0.5)";
+ context.moveTo(barX + barWidth - 15, barY + 1);
+ context.lineTo(barX + barWidth - 1, barY + 1);
+ context.lineTo(barX + barWidth - 1, barY + 15);
+ context.fill();
+
+ context.restore();
+ }
+
+ return true;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ forceDecoration: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ return !!record.warnings();
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?{startTime: number, endTime: number}}
+ */
+ highlightTimeRange: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (record === this._cpuThreadRecord || record === this._gpuThreadRecord)
+ return null;
+ return {
+ startTime: record.startTime(),
+ endTime: record.endTime()
+ };
+ },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ textColor: function(entryIndex)
+ {
+ return "white";
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?WebInspector.TimelineSelection}
+ */
+ createSelection: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (record instanceof WebInspector.TimelineModel.RecordImpl) {
+ this._lastSelection = new WebInspector.TimelineFlameChart.Selection(WebInspector.TimelineSelection.fromRecord(record), entryIndex);
+ return this._lastSelection.timelineSelection;
+ }
+ return null;
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ * @return {number}
+ */
+ entryIndexForSelection: function(selection)
+ {
+ if (!selection || selection.type() !== WebInspector.TimelineSelection.Type.Record)
+ return -1;
+ var record = /** @type{!WebInspector.TimelineModel.Record} */ (selection.object());
+ if (this._lastSelection && this._lastSelection.timelineSelection.object() === record)
+ return this._lastSelection.entryIndex;
+ var entryRecords = this._records;
+ for (var entryIndex = 0; entryIndex < entryRecords.length; ++entryIndex) {
+ if (entryRecords[entryIndex] === record) {
+ this._lastSelection = new WebInspector.TimelineFlameChart.Selection(WebInspector.TimelineSelection.fromRecord(record), entryIndex);
+ return entryIndex;
+ }
+ }
+ return -1;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.FlameChartDataProvider}
+ * @implements {WebInspector.TimelineFlameChart.SelectionProvider}
+ * @param {!WebInspector.TracingTimelineModel} model
+ * @param {!WebInspector.TimelineFrameModelBase} frameModel
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TracingBasedTimelineFlameChartDataProvider = function(model, frameModel, target)
+{
+ WebInspector.FlameChartDataProvider.call(this);
+ this._model = model;
+ this._frameModel = frameModel;
+ this._target = target;
+ this._font = "12px " + WebInspector.fontFamily();
+ this._linkifier = new WebInspector.Linkifier();
+ this._palette = new WebInspector.TraceViewPalette();
+ this._entryIndexToTitle = {};
+}
+
+WebInspector.TracingBasedTimelineFlameChartDataProvider.prototype = {
+ /**
+ * @return {number}
+ */
+ barHeight: function()
+ {
+ return 20;
+ },
+
+ /**
+ * @return {number}
+ */
+ textBaseline: function()
+ {
+ return 6;
+ },
+
+ /**
+ * @return {number}
+ */
+ textPadding: function()
+ {
+ return 5;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryFont: function(entryIndex)
+ {
+ return this._font;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryTitle: function(entryIndex)
+ {
+ var event = this._entryEvents[entryIndex];
+ if (event) {
+ var name = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(event.name).title;
+ // TODO(yurys): support event dividers
+ var details = WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent(event, this._linkifier, false, this._target);
+ return details ? WebInspector.UIString("%s (%s)", name, details.textContent) : name;
+ }
+ var title = this._entryIndexToTitle[entryIndex];
+ if (!title) {
+ title = WebInspector.UIString("Unexpected entryIndex %d", entryIndex);
+ console.error(title);
+ }
+ return title;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {?Array.<number>}
+ */
+ dividerOffsets: function(startTime, endTime)
+ {
+ return null;
+ },
+
+ reset: function()
+ {
+ this._timelineData = null;
+ /** @type {!Array.<!WebInspector.TracingModel.Event>} */
+ this._entryEvents = [];
+ this._entryIndexToTitle = {};
+ },
+
+ /**
+ * @return {!WebInspector.FlameChart.TimelineData}
+ */
+ timelineData: function()
+ {
+ if (this._timelineData)
+ return this._timelineData;
+
+ /**
+ * @type {?WebInspector.FlameChart.TimelineData}
+ */
+ this._timelineData = {
+ entryLevels: [],
+ entryTotalTimes: [],
+ entryStartTimes: []
+ };
+
+ this._currentLevel = 0;
+ this._minimumBoundary = this._model.minimumRecordTime();
+ this._timeSpan = Math.max(this._model.maximumRecordTime() - this._minimumBoundary, 1000);
+ this._appendHeaderRecord("CPU");
+ var events = this._model.mainThreadEvents();
+ var maxStackDepth = 0;
+ for (var eventIndex = 0; eventIndex < events.length; ++eventIndex) {
+ var event = events[eventIndex];
+ var category = event.category;
+ if (category !== "disabled-by-default-devtools.timeline" && category !== "devtools")
+ continue;
+ if (event.duration || event.phase === WebInspector.TracingModel.Phase.Instant) {
+ this._appendEvent(event);
+ if (maxStackDepth < event.level)
+ maxStackDepth = event.level;
+ }
+ }
+ this._currentLevel += maxStackDepth + 1;
+
+ this._appendHeaderRecord("GPU");
+ return this._timelineData;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundary;
+ },
+
+ /**
+ * @return {number}
+ */
+ totalTime: function()
+ {
+ return this._timeSpan;
+ },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function()
+ {
+ return this._currentLevel;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?Array.<!{title: string, text: string}>}
+ */
+ prepareHighlightedEntryInfo: function(entryIndex)
+ {
+ return null;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ canJumpToEntry: function(entryIndex)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryColor: function(entryIndex)
+ {
+ var event = this._entryEvents[entryIndex];
+ if (!event)
+ return "#555";
+ var style = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(event.name);
+ return style.category.fillColorStop1;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @param {!CanvasRenderingContext2D} context
+ * @param {?string} text
+ * @param {number} barX
+ * @param {number} barY
+ * @param {number} barWidth
+ * @param {number} barHeight
+ * @param {function(number):number} offsetToPosition
+ * @return {boolean}
+ */
+ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, offsetToPosition)
+ {
+ if (barWidth < 5)
+ return false;
+
+ var timelineData = this._timelineData;
+
+ // Paint text using white color on dark background.
+ if (text) {
+ context.save();
+ context.fillStyle = "white";
+ context.shadowColor = "rgba(0, 0, 0, 0.1)";
+ context.shadowOffsetX = 1;
+ context.shadowOffsetY = 1;
+ context.font = this._font;
+ context.fillText(text, barX + this.textPadding(), barY + barHeight - this.textBaseline());
+ context.restore();
+ }
+
+ var event = this._entryEvents[entryIndex];
+ if (event && event.warning) {
+ context.save();
+
+ context.rect(barX, barY, barWidth, this.barHeight());
+ context.clip();
+
+ context.beginPath();
+ context.fillStyle = "red";
+ context.moveTo(barX + barWidth - 15, barY + 1);
+ context.lineTo(barX + barWidth - 1, barY + 1);
+ context.lineTo(barX + barWidth - 1, barY + 15);
+ context.fill();
+
+ context.restore();
+ }
+
+ return true;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ forceDecoration: function(entryIndex)
+ {
+ var event = this._entryEvents[entryIndex];
+ if (!event)
+ return false;
+ return !!event.warning;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?{startTime: number, endTime: number}}
+ */
+ highlightTimeRange: function(entryIndex)
+ {
+ var event = this._entryEvents[entryIndex];
+ if (!event)
+ return null;
+ return {
+ startTime: event.startTime,
+ endTime: event.endTime
+ }
+ },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ textColor: function(entryIndex)
+ {
+ return "white";
+ },
+
+ /**
+ * @param {string} title
+ */
+ _appendHeaderRecord: function(title)
+ {
+ var index = this._entryEvents.length;
+ this._entryIndexToTitle[index] = title;
+ this._entryEvents.push(null);
+ this._timelineData.entryLevels[index] = this._currentLevel++;
+ this._timelineData.entryTotalTimes[index] = this._timeSpan;
+ this._timelineData.entryStartTimes[index] = this._minimumBoundary;
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ _appendEvent: function(event)
+ {
+ var index = this._entryEvents.length;
+ this._entryEvents.push(event);
+ this._timelineData.entryLevels[index] = this._currentLevel + event.level;
+ this._timelineData.entryTotalTimes[index] = event.duration || 1;
+ this._timelineData.entryStartTimes[index] = event.startTime;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?WebInspector.TimelineSelection}
+ */
+ createSelection: function(entryIndex)
+ {
+ var event = this._entryEvents[entryIndex];
+ if (!event)
+ return null;
+ this._lastSelection = new WebInspector.TimelineFlameChart.Selection(WebInspector.TimelineSelection.fromTraceEvent(event), entryIndex);
+ return this._lastSelection.timelineSelection;
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ * @return {number}
+ */
+ entryIndexForSelection: function(selection)
+ {
+ if (!selection || selection.type() !== WebInspector.TimelineSelection.Type.TraceEvent)
+ return -1;
+ var event = /** @type{!WebInspector.TracingModel.Event} */ (selection.object());
+ if (this._lastSelection && this._lastSelection.timelineSelection.object() === event)
+ return this._lastSelection.entryIndex;
+ var entryEvents = this._entryEvents;
+ for (var entryIndex = 0; entryIndex < entryEvents.length; ++entryIndex) {
+ if (entryEvents[entryIndex] === event) {
+ this._lastSelection = new WebInspector.TimelineFlameChart.Selection(WebInspector.TimelineSelection.fromTraceEvent(event), entryIndex);
+ return entryIndex;
+ }
+ }
+ return -1;
+ }
+}
+
+/**
+ * @return {!WebInspector.FlameChart.ColorGenerator}
+ */
+WebInspector.TimelineFlameChartDataProvider.jsFrameColorGenerator = function()
+{
+ if (!WebInspector.TimelineFlameChartDataProvider._jsFrameColorGenerator) {
+ var hueSpace = { min: 30, max: 55, count: 5 };
+ var satSpace = { min: 70, max: 100, count: 6 };
+ var colorGenerator = new WebInspector.FlameChart.ColorGenerator(hueSpace, satSpace, 50);
+ colorGenerator.setColorForID("(idle)", "hsl(0, 0%, 60%)");
+ colorGenerator.setColorForID("(program)", "hsl(0, 0%, 60%)");
+ colorGenerator.setColorForID("(garbage collector)", "hsl(0, 0%, 60%)");
+ WebInspector.TimelineFlameChartDataProvider._jsFrameColorGenerator = colorGenerator;
+ }
+ return WebInspector.TimelineFlameChartDataProvider._jsFrameColorGenerator;
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @implements {WebInspector.TimelineModeView}
+ * @implements {WebInspector.FlameChartDelegate}
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TimelineModel} model
+ * @param {?WebInspector.TracingTimelineModel} tracingModel
+ * @param {!WebInspector.TimelineFrameModelBase} frameModel
+ */
+WebInspector.TimelineFlameChart = function(delegate, model, tracingModel, frameModel)
+{
+ WebInspector.VBox.call(this);
+ this.element.classList.add("timeline-flamechart");
+ this.registerRequiredCSS("flameChart.css");
+ this._delegate = delegate;
+ this._model = model;
+ this._dataProvider = tracingModel
+ ? new WebInspector.TracingBasedTimelineFlameChartDataProvider(tracingModel, frameModel, model.target())
+ : new WebInspector.TimelineFlameChartDataProvider(/** @type {!WebInspector.TimelineModelImpl} */(model), frameModel);
+ this._mainView = new WebInspector.FlameChart(this._dataProvider, this, true);
+ this._mainView.show(this.element);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
+ this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
+}
+
+WebInspector.TimelineFlameChart.prototype = {
+ dispose: function()
+ {
+ this._model.removeEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
+ this._mainView.removeEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
+ },
+
+ /**
+ * @param {number} windowStartTime
+ * @param {number} windowEndTime
+ */
+ requestWindowTimes: function(windowStartTime, windowEndTime)
+ {
+ this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
+ },
+
+ /**
+ * @param {?RegExp} textFilter
+ */
+ refreshRecords: function(textFilter)
+ {
+ this._dataProvider.reset();
+ this._mainView._scheduleUpdate();
+ },
+
+ wasShown: function()
+ {
+ this._mainView._scheduleUpdate();
+ },
+
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function()
+ {
+ return this;
+ },
+
+ reset: function()
+ {
+ this._automaticallySizeWindow = true;
+ this._dataProvider.reset();
+ this._mainView.reset();
+ this._mainView.setWindowTimes(0, Infinity);
+ },
+
+ _onRecordingStarted: function()
+ {
+ this._automaticallySizeWindow = true;
+ this._mainView.reset();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ this._dataProvider.reset();
+ if (this._automaticallySizeWindow) {
+ var minimumRecordTime = this._model.minimumRecordTime();
+ if (record.startTime() > (minimumRecordTime + 1000)) {
+ this._automaticallySizeWindow = false;
+ this._delegate.requestWindowTimes(minimumRecordTime, minimumRecordTime + 1000);
+ }
+ this._mainView._scheduleUpdate();
+ } else {
+ if (!this._pendingUpdateTimer)
+ this._pendingUpdateTimer = window.setTimeout(this._updateOnAddRecord.bind(this), 300);
+ }
+ },
+
+ _updateOnAddRecord: function()
+ {
+ delete this._pendingUpdateTimer;
+ this._mainView._scheduleUpdate();
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._mainView.setWindowTimes(startTime, endTime);
+ this._delegate.select(null);
+ },
+
+ /**
+ * @param {number} width
+ */
+ setSidebarSize: function(width)
+ {
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord)
+ {
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ setSelection: function(selection)
+ {
+ var index = this._dataProvider.entryIndexForSelection(selection);
+ this._mainView.setSelectedEntry(index);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onEntrySelected: function(event)
+ {
+ var entryIndex = /** @type{number} */ (event.data);
+ var timelineSelection = this._dataProvider.createSelection(entryIndex);
+ if (timelineSelection)
+ this._delegate.select(timelineSelection);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TimelineSelection} selection
+ * @param {number} entryIndex
+ */
+WebInspector.TimelineFlameChart.Selection = function(selection, entryIndex)
+{
+ this.timelineSelection = selection;
+ this.entryIndex = entryIndex;
+}
+
+/**
+ * @interface
+ */
+WebInspector.TimelineFlameChart.SelectionProvider = function() { }
+
+WebInspector.TimelineFlameChart.SelectionProvider.prototype = {
+ /**
+ * @param {number} entryIndex
+ * @return {?WebInspector.TimelineSelection}
+ */
+ createSelection: function(entryIndex) { },
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ * @return {number}
+ */
+ entryIndexForSelection: function(selection) { }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js
new file mode 100644
index 00000000000..2a7e7a55aad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameModel.js
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TimelineFrameModelBase = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+
+ this.reset();
+}
+
+WebInspector.TimelineFrameModelBase.prototype = {
+ /**
+ * @return {!Array.<!WebInspector.TimelineFrame>}
+ */
+ frames: function()
+ {
+ return this._frames;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {!Array.<!WebInspector.TimelineFrame>}
+ */
+ filteredFrames: function(startTime, endTime)
+ {
+ /**
+ * @param {number} value
+ * @param {!WebInspector.TimelineFrame} object
+ * @return {number}
+ */
+ function compareStartTime(value, object)
+ {
+ return value - object.startTime;
+ }
+ /**
+ * @param {number} value
+ * @param {!WebInspector.TimelineFrame} object
+ * @return {number}
+ */
+ function compareEndTime(value, object)
+ {
+ return value - object.endTime;
+ }
+ var frames = this._frames;
+ var firstFrame = insertionIndexForObjectInListSortedByFunction(startTime, frames, compareEndTime);
+ var lastFrame = insertionIndexForObjectInListSortedByFunction(endTime, frames, compareStartTime);
+ return frames.slice(firstFrame, lastFrame);
+ },
+
+ reset: function()
+ {
+ this._minimumRecordTime = Infinity;
+ this._frames = [];
+ this._lastFrame = null;
+ this._lastLayerTree = null;
+ this._hasThreadedCompositing = false;
+ this._mainFrameCommitted = false;
+ this._mainFrameRequested = false;
+ this._aggregatedMainThreadWork = null;
+ },
+
+ /**
+ * @param {number} startTime
+ */
+ handleBeginFrame: function(startTime)
+ {
+ if (!this._lastFrame)
+ this._startBackgroundFrame(startTime);
+ },
+
+ /**
+ * @param {number} startTime
+ */
+ handleDrawFrame: function(startTime)
+ {
+ if (!this._lastFrame) {
+ this._startBackgroundFrame(startTime);
+ return;
+ }
+
+ // - if it wasn't drawn, it didn't happen!
+ // - only show frames that either did not wait for the main thread frame or had one committed.
+ if (this._mainFrameCommitted || !this._mainFrameRequested)
+ this._startBackgroundFrame(startTime);
+ this._mainFrameCommitted = false;
+ },
+
+ handleActivateLayerTree: function()
+ {
+ if (!this._lastFrame)
+ return;
+ this._mainFrameRequested = false;
+ this._mainFrameCommitted = true;
+ this._lastFrame._addTimeForCategories(this._aggregatedMainThreadWorkToAttachToBackgroundFrame);
+ this._aggregatedMainThreadWorkToAttachToBackgroundFrame = {};
+ },
+
+ handleRequestMainThreadFrame: function()
+ {
+ if (!this._lastFrame)
+ return;
+ this._mainFrameRequested = true;
+ },
+
+ handleCompositeLayers: function()
+ {
+ if (!this._hasThreadedCompositing || !this._aggregatedMainThreadWork)
+ return;
+ this._aggregatedMainThreadWorkToAttachToBackgroundFrame = this._aggregatedMainThreadWork;
+ this._aggregatedMainThreadWork = null;
+ },
+
+ /**
+ * @param {!WebInspector.DeferredLayerTree} layerTree
+ */
+ handleLayerTreeSnapshot: function(layerTree)
+ {
+ this._lastLayerTree = layerTree;
+ },
+
+ /**
+ * @param {number} startTime
+ */
+ _startBackgroundFrame: function(startTime)
+ {
+ if (!this._hasThreadedCompositing) {
+ this._lastFrame = null;
+ this._hasThreadedCompositing = true;
+ }
+ if (this._lastFrame)
+ this._flushFrame(this._lastFrame, startTime);
+
+ this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this._minimumRecordTime);
+ },
+
+ /**
+ * @param {number} startTime
+ */
+ _startMainThreadFrame: function(startTime)
+ {
+ if (this._lastFrame)
+ this._flushFrame(this._lastFrame, startTime);
+ this._lastFrame = new WebInspector.TimelineFrame(startTime, startTime - this._minimumRecordTime);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineFrame} frame
+ * @param {number} endTime
+ */
+ _flushFrame: function(frame, endTime)
+ {
+ frame._setLayerTree(this._lastLayerTree);
+ frame._setEndTime(endTime);
+ this._frames.push(frame);
+ },
+
+ /**
+ * @param {!Array.<string>} types
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?WebInspector.TimelineModel.Record} record
+ */
+ _findRecordRecursively: function(types, record)
+ {
+ if (types.indexOf(record.type()) >= 0)
+ return record;
+ if (!record.children())
+ return null;
+ for (var i = 0; i < record.children().length; ++i) {
+ var result = this._findRecordRecursively(types, record.children()[i]);
+ if (result)
+ return result;
+ }
+ return null;
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Target} target
+ * @extends {WebInspector.TimelineFrameModelBase}
+ */
+WebInspector.TimelineFrameModel = function(target)
+{
+ WebInspector.TimelineFrameModelBase.call(this, target);
+}
+
+WebInspector.TimelineFrameModel._mainFrameMarkers = [
+ WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation,
+ WebInspector.TimelineModel.RecordType.InvalidateLayout,
+ WebInspector.TimelineModel.RecordType.BeginFrame,
+ WebInspector.TimelineModel.RecordType.ScrollLayer
+];
+
+WebInspector.TimelineFrameModel.prototype = {
+ reset: function()
+ {
+ this._mergeRecords = true;
+ this._mergingBuffer = new WebInspector.TimelineMergingRecordBuffer();
+ WebInspector.TimelineFrameModelBase.prototype.reset.call(this);
+ },
+
+ /**
+ * @param {boolean} value
+ */
+ setMergeRecords: function(value)
+ {
+ this._mergeRecords = value;
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} records
+ */
+ addRecords: function(records)
+ {
+ if (!records.length)
+ return;
+ if (records[0].startTime() < this._minimumRecordTime)
+ this._minimumRecordTime = records[0].startTime();
+ for (var i = 0; i < records.length; ++i)
+ this.addRecord(records[i]);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ var programRecord = record.type() === recordTypes.Program ? record : null;
+
+ // Start collecting main frame
+ if (programRecord) {
+ if (!this._aggregatedMainThreadWork && this._findRecordRecursively(WebInspector.TimelineFrameModel._mainFrameMarkers, programRecord))
+ this._aggregatedMainThreadWork = {};
+ }
+ /** type {Array.<!WebInspector.TimelineModel.Record>} */
+ var records = [];
+ if (!this._mergeRecords)
+ records = [record];
+ else
+ records = this._mergingBuffer.process(record.thread(), /** type {Array.<!WebInspector.TimelineModel.Record>} */(programRecord ? record.children() || [] : [record]));
+ for (var i = 0; i < records.length; ++i) {
+ if (records[i].thread())
+ this._addBackgroundRecord(records[i]);
+ else
+ this._addMainThreadRecord(programRecord, records[i]);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _addBackgroundRecord: function(record)
+ {
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ if (record.type() === recordTypes.BeginFrame)
+ this.handleBeginFrame(record.startTime());
+ else if (record.type() === recordTypes.DrawFrame)
+ this.handleDrawFrame(record.startTime());
+ else if (record.type() === recordTypes.RequestMainThreadFrame)
+ this.handleRequestMainThreadFrame();
+ else if (record.type() === recordTypes.ActivateLayerTree)
+ this.handleActivateLayerTree();
+
+ if (this._lastFrame)
+ this._lastFrame._addTimeFromRecord(record);
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} programRecord
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _addMainThreadRecord: function(programRecord, record)
+ {
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ if (record.type() === recordTypes.UpdateLayerTree && record.data()["layerTree"])
+ this.handleLayerTreeSnapshot(new WebInspector.DeferredAgentLayerTree(this.target(), record.data()["layerTree"]));
+ if (!this._hasThreadedCompositing) {
+ if (record.type() === recordTypes.BeginFrame)
+ this._startMainThreadFrame(record.startTime());
+
+ if (!this._lastFrame)
+ return;
+
+ this._lastFrame._addTimeFromRecord(record);
+
+ // Account for "other" time at the same time as the first child.
+ if (programRecord.children()[0] === record)
+ this._lastFrame._addTimeForCategory("other", this._deriveOtherTime(programRecord));
+ return;
+ }
+
+ if (!this._aggregatedMainThreadWork)
+ return;
+
+ WebInspector.TimelineUIUtils.aggregateTimeForRecord(this._aggregatedMainThreadWork, record);
+ if (programRecord.children()[0] === record)
+ this._aggregatedMainThreadWork["other"] = (this._aggregatedMainThreadWork["other"] || 0) + this._deriveOtherTime(programRecord);
+
+ if (record.type() === recordTypes.CompositeLayers)
+ this.handleCompositeLayers();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} programRecord
+ * @return {number}
+ */
+ _deriveOtherTime: function(programRecord)
+ {
+ var accounted = 0;
+ for (var i = 0; i < programRecord.children().length; ++i)
+ accounted += programRecord.children()[i].endTime() - programRecord.children()[i].startTime();
+ return programRecord.endTime() - programRecord.startTime() - accounted;
+ },
+
+ __proto__: WebInspector.TimelineFrameModelBase.prototype,
+};
+
+/**
+ * @constructor
+ * @param {!WebInspector.Target} target
+ * @extends {WebInspector.TimelineFrameModelBase}
+ */
+WebInspector.TracingTimelineFrameModel = function(target)
+{
+ WebInspector.TimelineFrameModelBase.call(this, target);
+}
+
+WebInspector.TracingTimelineFrameModel._mainFrameMarkers = [
+ WebInspector.TracingTimelineModel.RecordType.ScheduleStyleRecalculation,
+ WebInspector.TracingTimelineModel.RecordType.InvalidateLayout,
+ WebInspector.TracingTimelineModel.RecordType.BeginMainThreadFrame,
+ WebInspector.TracingTimelineModel.RecordType.ScrollLayer
+];
+
+WebInspector.TracingTimelineFrameModel.prototype = {
+ /**
+ * @param {!Array.<!WebInspector.TracingModel.Event>} events
+ * @param {string} sessionId
+ */
+ addTraceEvents: function(events, sessionId)
+ {
+ this._sessionId = sessionId;
+ if (!events.length)
+ return;
+ if (events[0].startTime < this._minimumRecordTime)
+ this._minimumRecordTime = events[0].startTime;
+ for (var i = 0; i < events.length; ++i)
+ this._addTraceEvent(events[i]);
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ _addTraceEvent: function(event)
+ {
+ var eventNames = WebInspector.TracingTimelineModel.RecordType;
+
+ if (event.name === eventNames.SetLayerTreeId) {
+ if (this._sessionId === event.args["sessionId"])
+ this._layerTreeId = event.args["layerTreeId"];
+ return;
+ }
+ if (event.name === eventNames.TracingStartedInPage) {
+ this._mainThread = event.thread;
+ return;
+ }
+ if (event.thread === this._mainThread)
+ this._addMainThreadTraceEvent(event);
+ else
+ this._addBackgroundTraceEvent(event);
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ _addBackgroundTraceEvent: function(event)
+ {
+ var eventNames = WebInspector.TracingTimelineModel.RecordType;
+
+ if (event.phase === WebInspector.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0) === this._layerTreeId) {
+ this.handleLayerTreeSnapshot(new WebInspector.DeferredTracingLayerTree(this.target(), event.args["snapshot"]["active_tree"]["root_layer"], event.args["snapshot"]["device_viewport_size"]));
+ return;
+ }
+ if (this._lastFrame && event.selfTime)
+ this._lastFrame._addTimeForCategory(WebInspector.TracingTimelineUIUtils.eventStyle(event).category.name, event.selfTime);
+
+ if (event.args["layerTreeId"] !== this._layerTreeId)
+ return;
+
+ var timestamp = event.startTime;
+ if (event.name === eventNames.BeginFrame)
+ this.handleBeginFrame(timestamp);
+ else if (event.name === eventNames.DrawFrame)
+ this.handleDrawFrame(timestamp);
+ else if (event.name === eventNames.ActivateLayerTree)
+ this.handleActivateLayerTree();
+ else if (event.name === eventNames.RequestMainThreadFrame)
+ this.handleRequestMainThreadFrame();
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ _addMainThreadTraceEvent: function(event)
+ {
+ var eventNames = WebInspector.TracingTimelineModel.RecordType;
+ var timestamp = event.startTime;
+ var selfTime = event.selfTime || 0;
+
+ if (!this._hasThreadedCompositing) {
+ if (event.name === eventNames.BeginMainThreadFrame)
+ this._startMainThreadFrame(timestamp);
+ if (!this._lastFrame)
+ return;
+ if (!selfTime)
+ return;
+
+ var categoryName = WebInspector.TracingTimelineUIUtils.eventStyle(event).category.name;
+ this._lastFrame._addTimeForCategory(categoryName, selfTime);
+ return;
+ }
+
+ if (!this._aggregatedMainThreadWork && WebInspector.TracingTimelineFrameModel._mainFrameMarkers.indexOf(event.name) >= 0)
+ this._aggregatedMainThreadWork = {};
+ if (!this._aggregatedMainThreadWork)
+ return;
+
+ if (selfTime) {
+ var categoryName = WebInspector.TracingTimelineUIUtils.eventStyle(event).category.name;
+ this._aggregatedMainThreadWork[categoryName] = (this._aggregatedMainThreadWork[categoryName] || 0) + selfTime;
+ }
+ if (event.name === eventNames.CompositeLayers && event.args["layerTreeId"] === this._layerTreeId)
+ this.handleCompositeLayers();
+ },
+
+ __proto__: WebInspector.TimelineFrameModelBase.prototype
+}
+
+/**
+ * @constructor
+ * @param {!Array.<!WebInspector.TimelineFrame>} frames
+ */
+WebInspector.FrameStatistics = function(frames)
+{
+ this.frameCount = frames.length;
+ this.minDuration = Infinity;
+ this.maxDuration = 0;
+ this.timeByCategory = {};
+ this.startOffset = frames[0].startTimeOffset;
+ var lastFrame = frames[this.frameCount - 1];
+ this.endOffset = lastFrame.startTimeOffset + lastFrame.duration;
+
+ var totalDuration = 0;
+ var sumOfSquares = 0;
+ for (var i = 0; i < this.frameCount; ++i) {
+ var duration = frames[i].duration;
+ totalDuration += duration;
+ sumOfSquares += duration * duration;
+ this.minDuration = Math.min(this.minDuration, duration);
+ this.maxDuration = Math.max(this.maxDuration, duration);
+ WebInspector.TimelineUIUtils.aggregateTimeByCategory(this.timeByCategory, frames[i].timeByCategory);
+ }
+ this.average = totalDuration / this.frameCount;
+ var variance = sumOfSquares / this.frameCount - this.average * this.average;
+ this.stddev = Math.sqrt(variance);
+}
+
+/**
+ * @constructor
+ * @param {number} startTime
+ * @param {number} startTimeOffset
+ */
+WebInspector.TimelineFrame = function(startTime, startTimeOffset)
+{
+ this.startTime = startTime;
+ this.startTimeOffset = startTimeOffset;
+ this.endTime = this.startTime;
+ this.duration = 0;
+ this.timeByCategory = {};
+ this.cpuTime = 0;
+ /** @type {?WebInspector.DeferredLayerTree} */
+ this.layerTree = null;
+}
+
+WebInspector.TimelineFrame.prototype = {
+ /**
+ * @param {number} endTime
+ */
+ _setEndTime: function(endTime)
+ {
+ this.endTime = endTime;
+ this.duration = this.endTime - this.startTime;
+ },
+
+ /**
+ * @param {?WebInspector.DeferredLayerTree} layerTree
+ */
+ _setLayerTree: function(layerTree)
+ {
+ this.layerTree = layerTree;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _addTimeFromRecord: function(record)
+ {
+ if (!record.endTime())
+ return;
+ var timeByCategory = {};
+ WebInspector.TimelineUIUtils.aggregateTimeForRecord(timeByCategory, record);
+ this._addTimeForCategories(timeByCategory);
+ },
+
+ /**
+ * @param {!Object} timeByCategory
+ */
+ _addTimeForCategories: function(timeByCategory)
+ {
+ for (var category in timeByCategory)
+ this._addTimeForCategory(category, timeByCategory[category]);
+ },
+
+ /**
+ * @param {string} category
+ * @param {number} time
+ */
+ _addTimeForCategory: function(category, time)
+ {
+ this.timeByCategory[category] = (this.timeByCategory[category] || 0) + time;
+ this.cpuTime += time;
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameOverview.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameOverview.js
index 5030de3c671..0672b6b281e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineFrameOverview.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFrameOverview.js
@@ -32,11 +32,13 @@
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
* @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineFrameModelBase} frameModel
*/
-WebInspector.TimelineFrameOverview = function(model)
+WebInspector.TimelineFrameOverview = function(model, frameModel)
{
WebInspector.TimelineOverviewBase.call(this, model);
this.element.id = "timeline-overview-frames";
+ this._frameModel = frameModel;
this.reset();
this._outerPadding = 4 * window.devicePixelRatio;
@@ -48,23 +50,35 @@ WebInspector.TimelineFrameOverview = function(model)
this._actualOuterBarWidth = this._maxInnerBarWidth + this._actualPadding;
this._fillStyles = {};
- var categories = WebInspector.TimelinePresentationModel.categories();
+ var categories = WebInspector.TimelineUIUtils.categories();
for (var category in categories)
- this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[category]);
+ this._fillStyles[category] = WebInspector.TimelineUIUtils.createFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[category]);
+
this._frameTopShadeGradient = this._context.createLinearGradient(0, 0, 0, this._topPadding);
this._frameTopShadeGradient.addColorStop(0, "rgba(255, 255, 255, 0.9)");
this._frameTopShadeGradient.addColorStop(1, "rgba(255, 255, 255, 0.2)");
}
WebInspector.TimelineFrameOverview.prototype = {
+ /**
+ * @param {!WebInspector.OverviewGrid} grid
+ */
+ setOverviewGrid: function(grid)
+ {
+ this._overviewGrid = grid;
+ this._overviewGrid.element.classList.add("timeline-overview-frames-mode");
+ },
+
+ dispose: function()
+ {
+ this._overviewGrid.element.classList.remove("timeline-overview-frames-mode");
+ },
+
reset: function()
{
this._recordsPerBar = 1;
- /** @type {!Array.<{startTime:number, endTime:number}>} */
+ /** @type {!Array.<!{startTime:number, endTime:number}>} */
this._barTimes = [];
- this._mainThreadFrames = [];
- this._backgroundFrames = [];
- this._framesById = {};
},
update: function()
@@ -72,79 +86,18 @@ WebInspector.TimelineFrameOverview.prototype = {
this.resetCanvas();
this._barTimes = [];
- var backgroundFramesHeight = 15;
- var mainThreadFramesHeight = this._canvas.height - backgroundFramesHeight;
const minBarWidth = 4 * window.devicePixelRatio;
- var frameCount = this._backgroundFrames.length || this._mainThreadFrames.length;
- var framesPerBar = Math.max(1, frameCount * minBarWidth / this._canvas.width);
-
- var mainThreadVisibleFrames;
- var backgroundVisibleFrames;
- if (this._backgroundFrames.length) {
- backgroundVisibleFrames = this._aggregateFrames(this._backgroundFrames, framesPerBar);
- mainThreadVisibleFrames = new Array(backgroundVisibleFrames.length);
- for (var i = 0; i < backgroundVisibleFrames.length; ++i) {
- var frameId = backgroundVisibleFrames[i].mainThreadFrameId;
- mainThreadVisibleFrames[i] = frameId && this._framesById[frameId];
- }
- } else {
- mainThreadVisibleFrames = this._aggregateFrames(this._mainThreadFrames, framesPerBar);
- }
+ var frames = this._frameModel.frames();
+ var framesPerBar = Math.max(1, frames.length * minBarWidth / this._canvas.width);
+ var visibleFrames = this._aggregateFrames(frames, framesPerBar);
this._context.save();
- this._setCanvasWindow(0, backgroundFramesHeight, this._canvas.width, mainThreadFramesHeight);
- var scale = (mainThreadFramesHeight - this._topPadding) / this._computeTargetFrameLength(mainThreadVisibleFrames);
- this._renderBars(mainThreadVisibleFrames, scale, mainThreadFramesHeight);
+ var scale = (this._canvas.height - this._topPadding) / this._computeTargetFrameLength(visibleFrames);
+ this._renderBars(visibleFrames, scale, this._canvas.height);
this._context.fillStyle = this._frameTopShadeGradient;
this._context.fillRect(0, 0, this._canvas.width, this._topPadding);
- this._drawFPSMarks(scale, mainThreadFramesHeight);
+ this._drawFPSMarks(scale, this._canvas.height);
this._context.restore();
-
- var bottom = backgroundFramesHeight + 0.5;
- this._context.strokeStyle = "rgba(120, 120, 120, 0.8)";
- this._context.beginPath();
- this._context.moveTo(0, bottom);
- this._context.lineTo(this._canvas.width, bottom);
- this._context.stroke();
-
- if (backgroundVisibleFrames) {
- const targetFPS = 30.0;
- scale = (backgroundFramesHeight - this._topPadding) / (1.0 / targetFPS);
- this._renderBars(backgroundVisibleFrames, scale, backgroundFramesHeight);
- }
- },
-
- /**
- * @param {!WebInspector.TimelineFrame} frame
- */
- addFrame: function(frame)
- {
- var frames;
- if (frame.isBackground) {
- frames = this._backgroundFrames;
- } else {
- frames = this._mainThreadFrames;
- this._framesById[frame.id] = frame;
- }
- frames.push(frame);
- },
-
- /**
- * @param {number} x0
- * @param {number} y0
- * @param {number} width
- * @param {number} height
- */
- _setCanvasWindow: function(x0, y0, width, height)
- {
- this._context.translate(x0, y0);
- this._context.beginPath();
- this._context.moveTo(0, 0);
- this._context.lineTo(width, 0);
- this._context.lineTo(width, height);
- this._context.lineTo(0, height);
- this._context.lineTo(0, 0);
- this._context.clip();
},
/**
@@ -162,7 +115,7 @@ WebInspector.TimelineFrameOverview.prototype = {
for (var lastFrame = Math.min(Math.floor((barNumber + 1) * framesPerBar), frames.length);
currentFrame < lastFrame; ++currentFrame) {
- var duration = this._frameDuration(frames[currentFrame]);
+ var duration = frames[currentFrame].duration;
if (!longestFrame || longestDuration < duration) {
longestFrame = frames[currentFrame];
longestDuration = duration;
@@ -178,15 +131,6 @@ WebInspector.TimelineFrameOverview.prototype = {
},
/**
- * @param {!WebInspector.TimelineFrame} frame
- */
- _frameDuration: function(frame)
- {
- var relatedFrame = frame.mainThreadFrameId && this._framesById[frame.mainThreadFrameId];
- return frame.duration + (relatedFrame ? relatedFrame.duration : 0);
- },
-
- /**
* @param {!Array.<!WebInspector.TimelineFrame>} frames
* @return {number}
*/
@@ -199,10 +143,10 @@ WebInspector.TimelineFrameOverview.prototype = {
}
var medianFrameLength = durations.qselect(Math.floor(durations.length / 2));
- // Optimize appearance for 30fps. However, if at least half frames won't fit at this scale,
- // fall back to using autoscale.
- const targetFPS = 30;
- var result = 1.0 / targetFPS;
+ // Optimize appearance for 30fps, but leave some space so it's evident when a frame overflows.
+ // However, if at least half frames won't fit at this scale, fall back to using autoscale.
+ const targetFPS = 20;
+ var result = 1000.0 / targetFPS;
if (result >= medianFrameLength)
return result;
@@ -259,7 +203,7 @@ WebInspector.TimelineFrameOverview.prototype = {
for (var i = 0; i < fpsMarks.length; ++i) {
var fps = fpsMarks[i];
// Draw lines one pixel above they need to be, so 60pfs line does not cross most of the frames tops.
- var y = height - Math.floor(1.0 / fps * scale) - 0.5;
+ var y = height - Math.floor(1000.0 / fps * scale) - 0.5;
var label = WebInspector.UIString("%d\u2009fps", fps);
var labelWidth = this._context.measureText(label).width + 2 * labelPadding;
var labelX = this._canvas.width;
@@ -293,19 +237,21 @@ WebInspector.TimelineFrameOverview.prototype = {
*/
_renderBar: function(left, width, windowHeight, frame, scale)
{
- var categories = Object.keys(WebInspector.TimelinePresentationModel.categories());
- if (!categories.length)
- return;
+ var categories = Object.keys(WebInspector.TimelineUIUtils.categories());
var x = Math.floor(left) + 0.5;
width = Math.floor(width);
+ var totalCPUTime = frame.cpuTime;
+ var normalizedScale = scale;
+ if (totalCPUTime > frame.duration)
+ normalizedScale *= frame.duration / totalCPUTime;
+
for (var i = 0, bottomOffset = windowHeight; i < categories.length; ++i) {
var category = categories[i];
var duration = frame.timeByCategory[category];
-
if (!duration)
continue;
- var height = Math.round(duration * scale);
+ var height = Math.round(duration * normalizedScale);
var y = Math.floor(bottomOffset - height) + 0.5;
this._context.save();
@@ -313,7 +259,7 @@ WebInspector.TimelineFrameOverview.prototype = {
this._context.scale(width / this._maxInnerBarWidth, 1);
this._context.fillStyle = this._fillStyles[category];
this._context.fillRect(0, y, this._maxInnerBarWidth, Math.floor(height));
- this._context.strokeStyle = WebInspector.TimelinePresentationModel.categories()[category].borderColor;
+ this._context.strokeStyle = WebInspector.TimelineUIUtils.categories()[category].borderColor;
this._context.beginPath();
this._context.moveTo(0, y);
this._context.lineTo(this._maxInnerBarWidth, y);
@@ -338,29 +284,31 @@ WebInspector.TimelineFrameOverview.prototype = {
/**
* @param {number} windowLeft
* @param {number} windowRight
+ * @return {!{startTime: number, endTime: number}}
*/
windowTimes: function(windowLeft, windowRight)
{
if (!this._barTimes.length)
return WebInspector.TimelineOverviewBase.prototype.windowTimes.call(this, windowLeft, windowRight);
var windowSpan = this._canvas.width;
- var leftOffset = windowLeft * windowSpan - this._outerPadding + this._actualPadding;
- var rightOffset = windowRight * windowSpan - this._outerPadding;
- var firstBar = Math.floor(Math.max(leftOffset, 0) / this._actualOuterBarWidth);
- var lastBar = Math.min(Math.floor(rightOffset / this._actualOuterBarWidth), this._barTimes.length - 1);
+ var leftOffset = windowLeft * windowSpan;
+ var rightOffset = windowRight * windowSpan;
+ var firstBar = Math.floor(Math.max(leftOffset - this._outerPadding + this._actualPadding, 0) / this._actualOuterBarWidth);
+ var lastBar = Math.min(Math.floor(Math.max(rightOffset - this._outerPadding, 0)/ this._actualOuterBarWidth), this._barTimes.length - 1);
if (firstBar >= this._barTimes.length)
return {startTime: Infinity, endTime: Infinity};
- const snapToRightTolerancePixels = 3;
+ const snapTolerancePixels = 3;
return {
- startTime: this._barTimes[firstBar].startTime,
- endTime: (rightOffset + snapToRightTolerancePixels > windowSpan) || (lastBar >= this._barTimes.length) ? Infinity : this._barTimes[lastBar].endTime
+ startTime: leftOffset > snapTolerancePixels ? this._barTimes[firstBar].startTime : this._model.minimumRecordTime(),
+ endTime: (rightOffset + snapTolerancePixels > windowSpan) || (lastBar >= this._barTimes.length) ? this._model.maximumRecordTime() : this._barTimes[lastBar].endTime
}
},
/**
* @param {number} startTime
* @param {number} endTime
+ * @return {!{left: number, right: number}}
*/
windowBoundaries: function(startTime, endTime)
{
@@ -368,7 +316,7 @@ WebInspector.TimelineFrameOverview.prototype = {
return {left: 0, right: 1};
/**
* @param {number} time
- * @param {{startTime:number, endTime:number}} barTime
+ * @param {!{startTime:number, endTime:number}} barTime
* @return {number}
*/
function barStartComparator(time, barTime)
@@ -377,7 +325,7 @@ WebInspector.TimelineFrameOverview.prototype = {
}
/**
* @param {number} time
- * @param {{startTime:number, endTime:number}} barTime
+ * @param {!{startTime:number, endTime:number}} barTime
* @return {number}
*/
function barEndComparator(time, barTime)
@@ -395,7 +343,7 @@ WebInspector.TimelineFrameOverview.prototype = {
/**
* @param {number} time
- * @param {function(number, {startTime:number, endTime:number}):number} comparator
+ * @param {function(number, !{startTime:number, endTime:number}):number} comparator
*/
_windowBoundaryFromTime: function(time, comparator)
{
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js
new file mode 100644
index 00000000000..5af54ed1e2d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineJSProfile.js
@@ -0,0 +1,92 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+WebInspector.TimelineJSProfileProcessor = { };
+
+/**
+ * @param {!WebInspector.TimelineModelImpl} timelineModel
+ * @param {!ProfilerAgent.CPUProfile} jsProfile
+ */
+WebInspector.TimelineJSProfileProcessor.mergeJSProfileIntoTimeline = function(timelineModel, jsProfile)
+{
+ if (!jsProfile.samples)
+ return;
+ var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
+ var idleNode = jsProfileModel.idleNode;
+ var programNode = jsProfileModel.programNode;
+ var gcNode = jsProfileModel.gcNode;
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ function processRecord(record)
+ {
+ if (record.type() !== WebInspector.TimelineModel.RecordType.FunctionCall &&
+ record.type() !== WebInspector.TimelineModel.RecordType.EvaluateScript)
+ return;
+ var recordStartTime = record.startTime();
+ var recordEndTime = record.endTime();
+ var originalChildren = record.children().splice(0);
+ var childIndex = 0;
+
+ /**
+ * @param {number} depth
+ * @param {!ProfilerAgent.CPUProfileNode} node
+ * @param {number} startTime
+ */
+ function onOpenFrame(depth, node, startTime)
+ {
+ if (node === idleNode || node === programNode || node === gcNode)
+ return;
+ var event = {
+ type: "JSFrame",
+ data: node,
+ startTime: startTime
+ };
+ putOriginalChildrenUpToTime(startTime);
+ record = new WebInspector.TimelineModel.RecordImpl(timelineModel, event, record);
+ }
+
+ /**
+ * @param {number} depth
+ * @param {!ProfilerAgent.CPUProfileNode} node
+ * @param {number} startTime
+ * @param {number} totalTime
+ * @param {number} selfTime
+ */
+ function onCloseFrame(depth, node, startTime, totalTime, selfTime)
+ {
+ if (node === idleNode || node === programNode || node === gcNode)
+ return;
+ record.setEndTime(Math.min(startTime + totalTime, recordEndTime));
+ record._selfTime = record.endTime() - record.startTime();
+ putOriginalChildrenUpToTime(record.endTime());
+ var deoptReason = node.deoptReason;
+ if (deoptReason && deoptReason !== "no reason")
+ record.addWarning(deoptReason);
+ record = record.parent;
+ }
+
+ /**
+ * @param {number} endTime
+ */
+ function putOriginalChildrenUpToTime(endTime)
+ {
+ for (; childIndex < originalChildren.length; ++childIndex) {
+ var child = originalChildren[childIndex];
+ var midTime = (child.startTime() + child.endTime()) / 2;
+ if (midTime >= endTime)
+ break;
+ child.parent = record;
+ record.children().push(child);
+ }
+ }
+
+ jsProfileModel.forEachFrame(onOpenFrame, onCloseFrame, recordStartTime, recordEndTime);
+ putOriginalChildrenUpToTime(recordEndTime);
+ }
+
+ timelineModel.forAllRecords(processRecord);
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLayersView.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLayersView.js
new file mode 100644
index 00000000000..3d45c986a67
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLayersView.js
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ */
+WebInspector.TimelineLayersView = function()
+{
+ WebInspector.VBox.call(this);
+ this._layers3DView = new WebInspector.Layers3DView();
+ this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectSelected, this._onObjectSelected, this);
+ this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectHovered, this._onObjectHovered, this);
+ this._layers3DView.show(this.element);
+}
+
+WebInspector.TimelineLayersView.prototype = {
+ /**
+ * @param {!WebInspector.DeferredLayerTree} deferredLayerTree
+ */
+ showLayerTree: function(deferredLayerTree)
+ {
+ this._target = deferredLayerTree.target();
+ deferredLayerTree.resolve(onLayersReady.bind(this));
+ /**
+ * @param {!WebInspector.LayerTreeBase} layerTree
+ * @this {WebInspector.TimelineLayersView} this
+ */
+ function onLayersReady(layerTree)
+ {
+ this._layers3DView.setLayerTree(layerTree);
+ }
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ _selectObject: function(activeObject)
+ {
+ var layer = activeObject && activeObject.layer;
+ if (this._currentlySelectedLayer === activeObject)
+ return;
+ this._currentlySelectedLayer = activeObject;
+ var node = layer ? layer.nodeForSelfOrAncestor() : null;
+ if (node)
+ node.highlightForTwoSeconds();
+ else
+ this._target.domModel.hideDOMNodeHighlight();
+ this._layers3DView.selectObject(activeObject);
+ },
+
+ /**
+ * @param {?WebInspector.Layers3DView.ActiveObject} activeObject
+ */
+ _hoverObject: function(activeObject)
+ {
+ var layer = activeObject && activeObject.layer;
+ if (this._currentlyHoveredLayer === activeObject)
+ return;
+ this._currentlyHoveredLayer = activeObject;
+ var node = layer ? layer.nodeForSelfOrAncestor() : null;
+ if (node)
+ node.highlight();
+ else
+ this._target.domModel.hideDOMNodeHighlight();
+ this._layers3DView.hoverObject(activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onObjectSelected: function(event)
+ {
+ var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data);
+ this._selectObject(activeObject);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onObjectHovered: function(event)
+ {
+ var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data);
+ this._hoverObject(activeObject);
+ },
+
+ __proto__: WebInspector.VBox.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineMemoryOverview.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineMemoryOverview.js
index a99edfaeb29..f0c1a91f76a 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineMemoryOverview.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineMemoryOverview.js
@@ -32,83 +32,111 @@
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
* @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
-WebInspector.TimelineMemoryOverview = function(model)
+WebInspector.TimelineMemoryOverview = function(model, uiUtils)
{
WebInspector.TimelineOverviewBase.call(this, model);
+ this._uiUtils = uiUtils;
this.element.id = "timeline-overview-memory";
- this._maxHeapSizeLabel = this.element.createChild("div", "max memory-graph-label");
- this._minHeapSizeLabel = this.element.createChild("div", "min memory-graph-label");
+ this._heapSizeLabel = this.element.createChild("div", "memory-graph-label");
}
WebInspector.TimelineMemoryOverview.prototype = {
+ resetHeapSizeLabels: function()
+ {
+ this._heapSizeLabel.textContent = "";
+ },
+
update: function()
{
this.resetCanvas();
+ var ratio = window.devicePixelRatio;
- var records = this._model.records;
- if (!records.length)
+ var records = this._model.records();
+ if (!records.length) {
+ this.resetHeapSizeLabels();
return;
+ }
- const lowerOffset = 3;
+ var lowerOffset = 3 * ratio;
var maxUsedHeapSize = 0;
var minUsedHeapSize = 100000000000;
var minTime = this._model.minimumRecordTime();
var maxTime = this._model.maximumRecordTime();
- WebInspector.TimelinePresentationModel.forAllRecords(records, function(r) {
- maxUsedHeapSize = Math.max(maxUsedHeapSize, r.usedHeapSize || maxUsedHeapSize);
- minUsedHeapSize = Math.min(minUsedHeapSize, r.usedHeapSize || minUsedHeapSize);
- });
+ var uiUtils = this._uiUtils;
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ function calculateMinMaxSizes(record)
+ {
+ var counters = uiUtils.countersForRecord(record);
+ if (!counters || !counters.jsHeapSizeUsed)
+ return;
+ maxUsedHeapSize = Math.max(maxUsedHeapSize, counters.jsHeapSizeUsed);
+ minUsedHeapSize = Math.min(minUsedHeapSize, counters.jsHeapSizeUsed);
+ }
+ this._model.forAllRecords(calculateMinMaxSizes);
minUsedHeapSize = Math.min(minUsedHeapSize, maxUsedHeapSize);
+ var lineWidth = 1;
var width = this._canvas.width;
var height = this._canvas.height - lowerOffset;
var xFactor = width / (maxTime - minTime);
- var yFactor = height / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
+ var yFactor = (height - lineWidth) / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
var histogram = new Array(width);
- WebInspector.TimelinePresentationModel.forAllRecords(records, function(r) {
- if (!r.usedHeapSize)
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ function buildHistogram(record)
+ {
+ var counters = uiUtils.countersForRecord(record);
+ if (!counters || !counters.jsHeapSizeUsed)
return;
- var x = Math.round((WebInspector.TimelineModel.endTimeInSeconds(r) - minTime) * xFactor);
- var y = Math.round((r.usedHeapSize - minUsedHeapSize) * yFactor);
+ var x = Math.round((record.endTime() - minTime) * xFactor);
+ var y = Math.round((counters.jsHeapSizeUsed - minUsedHeapSize) * yFactor);
histogram[x] = Math.max(histogram[x] || 0, y);
- });
+ }
+ this._model.forAllRecords(buildHistogram);
- height++; // +1 so that the border always fit into the canvas area.
+ var ctx = this._context;
+ var heightBeyondView = height + lowerOffset + lineWidth;
+ ctx.translate(0.5, 0.5);
+ ctx.beginPath();
+ ctx.moveTo(-lineWidth, heightBeyondView);
var y = 0;
var isFirstPoint = true;
- var ctx = this._context;
- ctx.beginPath();
- ctx.moveTo(0, this._canvas.height);
+ var lastX = 0;
for (var x = 0; x < histogram.length; x++) {
if (typeof histogram[x] === "undefined")
continue;
if (isFirstPoint) {
isFirstPoint = false;
y = histogram[x];
- ctx.lineTo(0, height - y);
+ ctx.lineTo(-lineWidth, height - y);
}
+ var nextY = histogram[x];
+ if (Math.abs(nextY - y) > 2 && Math.abs(x - lastX) > 1)
+ ctx.lineTo(x, height - y);
+ y = nextY;
ctx.lineTo(x, height - y);
- y = histogram[x];
- ctx.lineTo(x, height - y);
+ lastX = x;
}
- ctx.lineTo(width, height - y);
- ctx.lineTo(width, this._canvas.height);
- ctx.lineTo(0, this._canvas.height);
+ ctx.lineTo(width + lineWidth, height - y);
+ ctx.lineTo(width + lineWidth, heightBeyondView);
ctx.closePath();
- ctx.lineWidth = 0.5;
- ctx.strokeStyle = "rgba(20,0,0,0.8)";
- ctx.stroke();
-
- ctx.fillStyle = "rgba(214,225,254, 0.8);";
+ ctx.fillStyle = "hsla(220, 90%, 70%, 0.2)";
ctx.fill();
+ ctx.lineWidth = lineWidth;
+ ctx.strokeStyle = "hsl(220, 90%, 70%)";
+ ctx.stroke();
- this._maxHeapSizeLabel.textContent = Number.bytesToString(maxUsedHeapSize);
- this._minHeapSizeLabel.textContent = Number.bytesToString(minUsedHeapSize);
+ this._heapSizeLabel.textContent = WebInspector.UIString("%s \u2013 %s", Number.bytesToString(minUsedHeapSize), Number.bytesToString(maxUsedHeapSize));
},
__proto__: WebInspector.TimelineOverviewBase.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
new file mode 100644
index 00000000000..4a98603bcfd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModel.js
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TimelineModel = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+ this._filters = [];
+}
+
+WebInspector.TimelineModel.RecordType = {
+ Root: "Root",
+ Program: "Program",
+ EventDispatch: "EventDispatch",
+
+ GPUTask: "GPUTask",
+
+ RequestMainThreadFrame: "RequestMainThreadFrame",
+ BeginFrame: "BeginFrame",
+ ActivateLayerTree: "ActivateLayerTree",
+ DrawFrame: "DrawFrame",
+ ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
+ RecalculateStyles: "RecalculateStyles",
+ InvalidateLayout: "InvalidateLayout",
+ Layout: "Layout",
+ UpdateLayerTree: "UpdateLayerTree",
+ PaintSetup: "PaintSetup",
+ Paint: "Paint",
+ Rasterize: "Rasterize",
+ ScrollLayer: "ScrollLayer",
+ DecodeImage: "DecodeImage",
+ ResizeImage: "ResizeImage",
+ CompositeLayers: "CompositeLayers",
+
+ ParseHTML: "ParseHTML",
+
+ TimerInstall: "TimerInstall",
+ TimerRemove: "TimerRemove",
+ TimerFire: "TimerFire",
+
+ XHRReadyStateChange: "XHRReadyStateChange",
+ XHRLoad: "XHRLoad",
+ EvaluateScript: "EvaluateScript",
+
+ MarkLoad: "MarkLoad",
+ MarkDOMContent: "MarkDOMContent",
+ MarkFirstPaint: "MarkFirstPaint",
+
+ TimeStamp: "TimeStamp",
+ ConsoleTime: "ConsoleTime",
+
+ ResourceSendRequest: "ResourceSendRequest",
+ ResourceReceiveResponse: "ResourceReceiveResponse",
+ ResourceReceivedData: "ResourceReceivedData",
+ ResourceFinish: "ResourceFinish",
+
+ FunctionCall: "FunctionCall",
+ GCEvent: "GCEvent",
+ JSFrame: "JSFrame",
+
+ UpdateCounters: "UpdateCounters",
+
+ RequestAnimationFrame: "RequestAnimationFrame",
+ CancelAnimationFrame: "CancelAnimationFrame",
+ FireAnimationFrame: "FireAnimationFrame",
+
+ WebSocketCreate : "WebSocketCreate",
+ WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
+ WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
+ WebSocketDestroy : "WebSocketDestroy",
+
+ EmbedderCallback : "EmbedderCallback",
+}
+
+WebInspector.TimelineModel.Events = {
+ RecordAdded: "RecordAdded",
+ RecordsCleared: "RecordsCleared",
+ RecordingStarted: "RecordingStarted",
+ RecordingStopped: "RecordingStopped",
+ RecordingProgress: "RecordingProgress",
+ RecordFilterChanged: "RecordFilterChanged"
+}
+
+/**
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray
+ * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector.TimelineModel.Record,number)} preOrderCallback
+ * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)=} postOrderCallback
+ * @return {boolean}
+ */
+WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallback, postOrderCallback)
+{
+ /**
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} records
+ * @param {number} depth
+ * @return {boolean}
+ */
+ function processRecords(records, depth)
+ {
+ for (var i = 0; i < records.length; ++i) {
+ var record = records[i];
+ if (preOrderCallback && preOrderCallback(record, depth))
+ return true;
+ if (processRecords(record.children(), depth + 1))
+ return true;
+ if (postOrderCallback && postOrderCallback(record, depth))
+ return true;
+ }
+ return false;
+ }
+ return processRecords(recordsArray, 0);
+}
+
+WebInspector.TimelineModel.prototype = {
+ /**
+ * @param {boolean} captureStacks
+ * @param {boolean} captureMemory
+ * @param {boolean} capturePictures
+ */
+ startRecording: function(captureStacks, captureMemory, capturePictures)
+ {
+ },
+
+ stopRecording: function()
+ {
+ },
+
+ /**
+ * @return {boolean}
+ */
+ loadedFromFile: function()
+ {
+ return false;
+ },
+
+ /**
+ * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector.TimelineModel.Record,number)} preOrderCallback
+ * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)=} postOrderCallback
+ */
+ forAllRecords: function(preOrderCallback, postOrderCallback)
+ {
+ WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback, postOrderCallback);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Filter} filter
+ */
+ addFilter: function(filter)
+ {
+ this._filters.push(filter);
+ filter._model = this;
+ },
+
+ /**
+ * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.TimelineModel.Record,number)} callback
+ */
+ forAllFilteredRecords: function(callback)
+ {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {number} depth
+ * @this {WebInspector.TimelineModel}
+ * @return {boolean}
+ */
+ function processRecord(record, depth)
+ {
+ var visible = this.isVisible(record);
+ if (visible) {
+ if (callback(record, depth))
+ return true;
+ }
+
+ for (var i = 0; i < record.children().length; ++i) {
+ if (processRecord.call(this, record.children()[i], visible ? depth + 1 : depth))
+ return true;
+ }
+ return false;
+ }
+
+ for (var i = 0; i < this._records.length; ++i)
+ processRecord.call(this, this._records[i], 0);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isVisible: function(record)
+ {
+ for (var i = 0; i < this._filters.length; ++i) {
+ if (!this._filters[i].accept(record))
+ return false;
+ }
+ return true;
+ },
+
+ _filterChanged: function()
+ {
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFilterChanged);
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ records: function()
+ {
+ return this._records;
+ },
+
+ /**
+ * @param {!Blob} file
+ * @param {!WebInspector.Progress} progress
+ */
+ loadFromFile: function(file, progress)
+ {
+ throw new Error("Not implemented");
+ },
+
+ /**
+ * @param {string} url
+ * @param {!WebInspector.Progress} progress
+ */
+ loadFromURL: function(url, progress)
+ {
+ throw new Error("Not implemented");
+ },
+
+ saveToFile: function()
+ {
+ throw new Error("Not implemented");
+ },
+
+ reset: function()
+ {
+ this._loadedFromFile = false;
+ this._records = [];
+ this._minimumRecordTime = 0;
+ this._maximumRecordTime = 0;
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
+ this._mainThreadTasks = [];
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
+ this._gpuThreadTasks = [];
+ /** @type {!Array.<!WebInspector.TimelineModel.Record>} */
+ this._eventDividerRecords = [];
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsCleared);
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRecordTime: function()
+ {
+ return this._minimumRecordTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumRecordTime: function()
+ {
+ return this._maximumRecordTime;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _updateBoundaries: function(record)
+ {
+ var startTime = record.startTime();
+ var endTime = record.endTime();
+
+ if (!this._minimumRecordTime || startTime < this._minimumRecordTime)
+ this._minimumRecordTime = startTime;
+ if (endTime > this._maximumRecordTime)
+ this._maximumRecordTime = endTime;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ mainThreadTasks: function()
+ {
+ return this._mainThreadTasks;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ gpuThreadTasks: function()
+ {
+ return this._gpuThreadTasks;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ eventDividerRecords: function()
+ {
+ return this._eventDividerRecords;
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @interface
+ */
+WebInspector.TimelineModel.Record = function()
+{
+}
+
+WebInspector.TimelineModel.Record.prototype = {
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ callSiteStackTrace: function() { },
+
+ /**
+ * @return {?WebInspector.TimelineModel.Record}
+ */
+ initiator: function() { },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function() { },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function() { },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ children: function() { },
+
+ /**
+ * @return {!WebInspector.TimelineCategory}
+ */
+ category: function() { },
+
+ /**
+ * @return {number}
+ */
+ startTime: function() { },
+
+ /**
+ * @return {string|undefined}
+ */
+ thread: function() { },
+
+ /**
+ * @return {number}
+ */
+ endTime: function() { },
+
+ /**
+ * @param {number} endTime
+ */
+ setEndTime: function(endTime) { },
+
+ /**
+ * @return {!Object}
+ */
+ data: function() { },
+
+ /**
+ * @return {string}
+ */
+ type: function() { },
+
+ /**
+ * @return {string}
+ */
+ frameId: function() { },
+
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ stackTrace: function() { },
+
+ /**
+ * @param {string} key
+ * @return {?Object}
+ */
+ getUserObject: function(key) { },
+
+ /**
+ * @param {string} key
+ * @param {?Object|undefined} value
+ */
+ setUserObject: function(key, value) { },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ aggregatedStats: function() { },
+
+ /**
+ * @return {?Array.<string>}
+ */
+ warnings: function() { }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineModel.Filter = function()
+{
+ /** @type {!WebInspector.TimelineModel} */
+ this._model;
+}
+
+WebInspector.TimelineModel.Filter.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return true;
+ },
+
+ notifyFilterChanged: function()
+ {
+ this._model._filterChanged();
+ }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineMergingRecordBuffer = function()
+{
+ this._backgroundRecordsBuffer = [];
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineMergingRecordBuffer.prototype = {
+ /**
+ * @param {string} thread
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} records
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ process: function(thread, records)
+ {
+ if (thread) {
+ this._backgroundRecordsBuffer = this._backgroundRecordsBuffer.concat(records);
+ return [];
+ }
+ /**
+ * @param {!WebInspector.TimelineModel.Record} a
+ * @param {!WebInspector.TimelineModel.Record} b
+ */
+ function recordTimestampComparator(a, b)
+ {
+ // Never return 0, as the merge function will squash identical entries.
+ return a.startTime() < b.startTime() ? -1 : 1;
+ }
+ var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordTimestampComparator);
+ this._backgroundRecordsBuffer = [];
+ return result;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModelImpl.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModelImpl.js
new file mode 100644
index 00000000000..a18efee6063
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineModelImpl.js
@@ -0,0 +1,739 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineModel}
+ * @param {!WebInspector.TimelineManager} timelineManager
+ */
+WebInspector.TimelineModelImpl = function(timelineManager)
+{
+ WebInspector.TimelineModel.call(this, timelineManager.target());
+ this._timelineManager = timelineManager;
+ this._filters = [];
+ this._bindings = new WebInspector.TimelineModelImpl.InterRecordBindings();
+
+ this.reset();
+
+ this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onRecordAdded, this);
+ this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStarted, this._onStarted, this);
+ this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineStopped, this._onStopped, this);
+ this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineProgress, this._onProgress, this);
+}
+
+WebInspector.TimelineModelImpl.TransferChunkLengthBytes = 5000000;
+
+WebInspector.TimelineModelImpl.prototype = {
+ /**
+ * @return {boolean}
+ */
+ loadedFromFile: function()
+ {
+ return this._loadedFromFile;
+ },
+
+ /**
+ * @param {boolean} captureStacks
+ * @param {boolean} captureMemory
+ * @param {boolean} capturePictures
+ */
+ startRecording: function(captureStacks, captureMemory, capturePictures)
+ {
+ console.assert(!capturePictures, "Legacy timeline does not support capturing pictures");
+ this._clientInitiatedRecording = true;
+ this.reset();
+ var maxStackFrames = captureStacks ? 30 : 0;
+ var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEnabled();
+ var liveEvents = [ WebInspector.TimelineModel.RecordType.BeginFrame,
+ WebInspector.TimelineModel.RecordType.DrawFrame,
+ WebInspector.TimelineModel.RecordType.RequestMainThreadFrame,
+ WebInspector.TimelineModel.RecordType.ActivateLayerTree ];
+ this._timelineManager.start(maxStackFrames, WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled(), liveEvents.join(","), captureMemory, includeGPUEvents, this._fireRecordingStarted.bind(this));
+ },
+
+ stopRecording: function()
+ {
+ if (!this._clientInitiatedRecording) {
+ this._timelineManager.start(undefined, undefined, undefined, undefined, undefined, stopTimeline.bind(this));
+ return;
+ }
+
+ /**
+ * Console started this one and we are just sniffing it. Initiate recording so that we
+ * could stop it.
+ * @this {WebInspector.TimelineModelImpl}
+ */
+ function stopTimeline()
+ {
+ this._timelineManager.stop(this._fireRecordingStopped.bind(this));
+ }
+
+ this._clientInitiatedRecording = false;
+ this._timelineManager.stop(this._fireRecordingStopped.bind(this));
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ records: function()
+ {
+ return this._records;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onRecordAdded: function(event)
+ {
+ if (this._collectionEnabled)
+ this._addRecord(/** @type {!TimelineAgent.TimelineEvent} */(event.data));
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onStarted: function(event)
+ {
+ if (event.data) {
+ // Started from console.
+ this._fireRecordingStarted();
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onStopped: function(event)
+ {
+ // If we were buffering events, discard those that got through, the real ones are coming!
+ if (WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled())
+ this.reset();
+ if (event.data) {
+ // Stopped from console.
+ this._fireRecordingStopped(null, null);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onProgress: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingProgress, event.data);
+ },
+
+ _fireRecordingStarted: function()
+ {
+ this._collectionEnabled = true;
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted);
+ },
+
+ /**
+ * @param {?Protocol.Error} error
+ * @param {?ProfilerAgent.CPUProfile} cpuProfile
+ */
+ _fireRecordingStopped: function(error, cpuProfile)
+ {
+ this._collectionEnabled = false;
+ if (cpuProfile)
+ WebInspector.TimelineJSProfileProcessor.mergeJSProfileIntoTimeline(this, cpuProfile);
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
+ },
+
+ /**
+ * @param {!TimelineAgent.TimelineEvent} payload
+ */
+ _addRecord: function(payload)
+ {
+ this._internStrings(payload);
+ this._payloads.push(payload);
+
+ var record = this._innerAddRecord(payload, null);
+ this._updateBoundaries(record);
+ this._records.push(record);
+ if (record.type() === WebInspector.TimelineModel.RecordType.Program)
+ this._mainThreadTasks.push(record);
+ if (record.type() === WebInspector.TimelineModel.RecordType.GPUTask)
+ this._gpuThreadTasks.push(record);
+
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAdded, record);
+ },
+
+ /**
+ * @param {!TimelineAgent.TimelineEvent} payload
+ * @param {?WebInspector.TimelineModel.Record} parentRecord
+ * @return {!WebInspector.TimelineModel.Record}
+ */
+ _innerAddRecord: function(payload, parentRecord)
+ {
+ var record = new WebInspector.TimelineModel.RecordImpl(this, payload, parentRecord);
+ if (WebInspector.TimelineUIUtilsImpl.isEventDivider(record))
+ this._eventDividerRecords.push(record);
+
+ for (var i = 0; payload.children && i < payload.children.length; ++i)
+ this._innerAddRecord.call(this, payload.children[i], record);
+
+ record._calculateAggregatedStats();
+ if (parentRecord)
+ parentRecord._selfTime -= record.endTime() - record.startTime();
+ return record;
+ },
+
+ /**
+ * @param {!Blob} file
+ * @param {!WebInspector.Progress} progress
+ */
+ loadFromFile: function(file, progress)
+ {
+ var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
+ var fileReader = this._createFileReader(file, delegate);
+ var loader = new WebInspector.TimelineModelLoader(this, fileReader, progress);
+ fileReader.start(loader);
+ },
+
+ /**
+ * @param {string} url
+ * @param {!WebInspector.Progress} progress
+ */
+ loadFromURL: function(url, progress)
+ {
+ var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress);
+ var urlReader = new WebInspector.ChunkedXHRReader(url, delegate);
+ var loader = new WebInspector.TimelineModelLoader(this, urlReader, progress);
+ urlReader.start(loader);
+ },
+
+ _createFileReader: function(file, delegate)
+ {
+ return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModelImpl.TransferChunkLengthBytes, delegate);
+ },
+
+ _createFileWriter: function()
+ {
+ return new WebInspector.FileOutputStream();
+ },
+
+ saveToFile: function()
+ {
+ var now = new Date();
+ var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json";
+ var stream = this._createFileWriter();
+
+ /**
+ * @param {boolean} accepted
+ * @this {WebInspector.TimelineModelImpl}
+ */
+ function callback(accepted)
+ {
+ if (!accepted)
+ return;
+ var saver = new WebInspector.TimelineSaver(stream);
+ saver.save(this._payloads, window.navigator.appVersion);
+ }
+ stream.open(fileName, callback.bind(this));
+ },
+
+ reset: function()
+ {
+ this._loadedFromFile = false;
+ this._payloads = [];
+ this._stringPool = {};
+ this._bindings._reset();
+ WebInspector.TimelineModel.prototype.reset.call(this);
+ },
+
+ /**
+ * @param {!TimelineAgent.TimelineEvent} record
+ */
+ _internStrings: function(record)
+ {
+ for (var name in record) {
+ var value = record[name];
+ if (typeof value !== "string")
+ continue;
+
+ var interned = this._stringPool[value];
+ if (typeof interned === "string")
+ record[name] = interned;
+ else
+ this._stringPool[value] = value;
+ }
+
+ var children = record.children;
+ for (var i = 0; children && i < children.length; ++i)
+ this._internStrings(children[i]);
+ },
+
+ __proto__: WebInspector.TimelineModel.prototype
+}
+
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineModelImpl.InterRecordBindings = function() {
+ this._reset();
+}
+
+WebInspector.TimelineModelImpl.InterRecordBindings.prototype = {
+ _reset: function()
+ {
+ this._sendRequestRecords = {};
+ this._timerRecords = {};
+ this._requestAnimationFrameRecords = {};
+ this._layoutInvalidate = {};
+ this._lastScheduleStyleRecalculation = {};
+ this._webSocketCreateRecords = {};
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineModel.Record}
+ * @param {!WebInspector.TimelineModelImpl} model
+ * @param {!TimelineAgent.TimelineEvent} timelineEvent
+ * @param {?WebInspector.TimelineModel.Record} parentRecord
+ */
+WebInspector.TimelineModel.RecordImpl = function(model, timelineEvent, parentRecord)
+{
+ this._model = model;
+ var bindings = this._model._bindings;
+ this._aggregatedStats = {};
+ this._record = timelineEvent;
+ this._children = [];
+ if (parentRecord) {
+ this.parent = parentRecord;
+ parentRecord.children().push(this);
+ }
+
+ this._selfTime = this.endTime() - this.startTime();
+
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ switch (timelineEvent.type) {
+ case recordTypes.ResourceSendRequest:
+ // Make resource receive record last since request was sent; make finish record last since response received.
+ bindings._sendRequestRecords[timelineEvent.data["requestId"]] = this;
+ break;
+
+ case recordTypes.ResourceReceiveResponse:
+ case recordTypes.ResourceReceivedData:
+ case recordTypes.ResourceFinish:
+ this._initiator = bindings._sendRequestRecords[timelineEvent.data["requestId"]];
+ break;
+
+ case recordTypes.TimerInstall:
+ bindings._timerRecords[timelineEvent.data["timerId"]] = this;
+ break;
+
+ case recordTypes.TimerFire:
+ this._initiator = bindings._timerRecords[timelineEvent.data["timerId"]];
+ break;
+
+ case recordTypes.RequestAnimationFrame:
+ bindings._requestAnimationFrameRecords[timelineEvent.data["id"]] = this;
+ break;
+
+ case recordTypes.FireAnimationFrame:
+ this._initiator = bindings._requestAnimationFrameRecords[timelineEvent.data["id"]];
+ break;
+
+ case recordTypes.ScheduleStyleRecalculation:
+ bindings._lastScheduleStyleRecalculation[this.frameId()] = this;
+ break;
+
+ case recordTypes.RecalculateStyles:
+ this._initiator = bindings._lastScheduleStyleRecalculation[this.frameId()];
+ break;
+
+ case recordTypes.InvalidateLayout:
+ // Consider style recalculation as a reason for layout invalidation,
+ // but only if we had no earlier layout invalidation records.
+ var layoutInitator = this;
+ if (!bindings._layoutInvalidate[this.frameId()] && parentRecord.type() === recordTypes.RecalculateStyles)
+ layoutInitator = parentRecord._initiator;
+ bindings._layoutInvalidate[this.frameId()] = layoutInitator;
+ break;
+
+ case recordTypes.Layout:
+ this._initiator = bindings._layoutInvalidate[this.frameId()];
+ bindings._layoutInvalidate[this.frameId()] = null;
+ if (this.stackTrace())
+ this.addWarning(WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck."));
+ break;
+
+ case recordTypes.WebSocketCreate:
+ bindings._webSocketCreateRecords[timelineEvent.data["identifier"]] = this;
+ break;
+
+ case recordTypes.WebSocketSendHandshakeRequest:
+ case recordTypes.WebSocketReceiveHandshakeResponse:
+ case recordTypes.WebSocketDestroy:
+ this._initiator = bindings._webSocketCreateRecords[timelineEvent.data["identifier"]];
+ break;
+ }
+}
+
+WebInspector.TimelineModel.RecordImpl.prototype = {
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ callSiteStackTrace: function()
+ {
+ return this._initiator ? this._initiator.stackTrace() : null;
+ },
+
+ /**
+ * @return {?WebInspector.TimelineModel.Record}
+ */
+ initiator: function()
+ {
+ return this._initiator;
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._model.target();
+ },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function()
+ {
+ return this._selfTime;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ children: function()
+ {
+ return this._children;
+ },
+
+ /**
+ * @return {!WebInspector.TimelineCategory}
+ */
+ category: function()
+ {
+ return WebInspector.TimelineUIUtils.recordStyle(this).category;
+ },
+
+ /**
+ * @return {number}
+ */
+ startTime: function()
+ {
+ return this._record.startTime;
+ },
+
+ /**
+ * @return {string|undefined}
+ */
+ thread: function()
+ {
+ return this._record.thread;
+ },
+
+ /**
+ * @return {number}
+ */
+ endTime: function()
+ {
+ return this._endTime || this._record.endTime || this._record.startTime;
+ },
+
+ /**
+ * @param {number} endTime
+ */
+ setEndTime: function(endTime)
+ {
+ this._endTime = endTime;
+ },
+
+ /**
+ * @return {!Object}
+ */
+ data: function()
+ {
+ return this._record.data;
+ },
+
+ /**
+ * @return {string}
+ */
+ type: function()
+ {
+ return this._record.type;
+ },
+
+ /**
+ * @return {string}
+ */
+ frameId: function()
+ {
+ return this._record.frameId || "";
+ },
+
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ stackTrace: function()
+ {
+ if (this._record.stackTrace && this._record.stackTrace.length)
+ return this._record.stackTrace;
+ return null;
+ },
+
+ /**
+ * @param {string} key
+ * @return {?Object}
+ */
+ getUserObject: function(key)
+ {
+ if (!this._userObjects)
+ return null;
+ return this._userObjects.get(key);
+ },
+
+ /**
+ * @param {string} key
+ * @param {?Object|undefined} value
+ */
+ setUserObject: function(key, value)
+ {
+ if (!this._userObjects)
+ this._userObjects = new StringMap();
+ this._userObjects.put(key, value);
+ },
+
+ _calculateAggregatedStats: function()
+ {
+ this._aggregatedStats = {};
+
+ for (var index = this._children.length; index; --index) {
+ var child = this._children[index - 1];
+ for (var category in child._aggregatedStats)
+ this._aggregatedStats[category] = (this._aggregatedStats[category] || 0) + child._aggregatedStats[category];
+ }
+ this._aggregatedStats[this.category().name] = (this._aggregatedStats[this.category().name] || 0) + this._selfTime;
+ },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ aggregatedStats: function()
+ {
+ return this._aggregatedStats;
+ },
+
+ /**
+ * @param {string} message
+ */
+ addWarning: function(message)
+ {
+ if (!this._warnings)
+ this._warnings = [];
+ this._warnings.push(message);
+ },
+
+ /**
+ * @return {?Array.<string>}
+ */
+ warnings: function()
+ {
+ return this._warnings;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.OutputStream}
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!{cancel: function()}} reader
+ * @param {!WebInspector.Progress} progress
+ */
+WebInspector.TimelineModelLoader = function(model, reader, progress)
+{
+ this._model = model;
+ this._reader = reader;
+ this._progress = progress;
+ this._buffer = "";
+ this._firstChunk = true;
+}
+
+WebInspector.TimelineModelLoader.prototype = {
+ /**
+ * @param {string} chunk
+ */
+ write: function(chunk)
+ {
+ var data = this._buffer + chunk;
+ var lastIndex = 0;
+ var index;
+ do {
+ index = lastIndex;
+ lastIndex = WebInspector.TextUtils.findBalancedCurlyBrackets(data, index);
+ } while (lastIndex !== -1)
+
+ var json = data.slice(0, index) + "]";
+ this._buffer = data.slice(index);
+
+ if (!index)
+ return;
+
+ // Prepending "0" to turn string into valid JSON.
+ if (!this._firstChunk)
+ json = "[0" + json;
+
+ var items;
+ try {
+ items = /** @type {!Array.<!TimelineAgent.TimelineEvent>} */ (JSON.parse(json));
+ } catch (e) {
+ WebInspector.messageSink.addErrorMessage("Malformed timeline data.", true);
+ this._model.reset();
+ this._reader.cancel();
+ this._progress.done();
+ return;
+ }
+
+ if (this._firstChunk) {
+ this._version = items[0];
+ this._firstChunk = false;
+ this._model.reset();
+ }
+
+ // Skip 0-th element - it is either version or 0.
+ for (var i = 1, size = items.length; i < size; ++i)
+ this._model._addRecord(items[i]);
+ },
+
+ close: function()
+ {
+ this._model._loadedFromFile = true;
+ }
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.OutputStreamDelegate}
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Progress} progress
+ */
+WebInspector.TimelineModelLoadFromFileDelegate = function(model, progress)
+{
+ this._model = model;
+ this._progress = progress;
+}
+
+WebInspector.TimelineModelLoadFromFileDelegate.prototype = {
+ onTransferStarted: function()
+ {
+ this._progress.setTitle(WebInspector.UIString("Loading\u2026"));
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ */
+ onChunkTransferred: function(reader)
+ {
+ if (this._progress.isCanceled()) {
+ reader.cancel();
+ this._progress.done();
+ this._model.reset();
+ return;
+ }
+
+ var totalSize = reader.fileSize();
+ if (totalSize) {
+ this._progress.setTotalWork(totalSize);
+ this._progress.setWorked(reader.loadedSize());
+ }
+ },
+
+ onTransferFinished: function()
+ {
+ this._progress.done();
+ },
+
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ * @param {!Event} event
+ */
+ onError: function(reader, event)
+ {
+ this._progress.done();
+ this._model.reset();
+ switch (event.target.error.code) {
+ case FileError.NOT_FOUND_ERR:
+ WebInspector.messageSink.addErrorMessage(WebInspector.UIString("File \"%s\" not found.", reader.fileName()), true);
+ break;
+ case FileError.NOT_READABLE_ERR:
+ WebInspector.messageSink.addErrorMessage(WebInspector.UIString("File \"%s\" is not readable", reader.fileName()), true);
+ break;
+ case FileError.ABORT_ERR:
+ break;
+ default:
+ WebInspector.messageSink.addErrorMessage(WebInspector.UIString("An error occurred while reading the file \"%s\"", reader.fileName()), true);
+ }
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.OutputStream} stream
+ */
+WebInspector.TimelineSaver = function(stream)
+{
+ this._stream = stream;
+}
+
+WebInspector.TimelineSaver.prototype = {
+ /**
+ * @param {!Array.<*>} payloads
+ * @param {string} version
+ */
+ save: function(payloads, version)
+ {
+ this._payloads = payloads;
+ this._recordIndex = 0;
+ this._prologue = "[" + JSON.stringify(version);
+
+ this._writeNextChunk(this._stream);
+ },
+
+ _writeNextChunk: function(stream)
+ {
+ const separator = ",\n";
+ var data = [];
+ var length = 0;
+
+ if (this._prologue) {
+ data.push(this._prologue);
+ length += this._prologue.length;
+ delete this._prologue;
+ } else {
+ if (this._recordIndex === this._payloads.length) {
+ stream.close();
+ return;
+ }
+ data.push("");
+ }
+ while (this._recordIndex < this._payloads.length) {
+ var item = JSON.stringify(this._payloads[this._recordIndex]);
+ var itemLength = item.length + separator.length;
+ if (length + itemLength > WebInspector.TimelineModelImpl.TransferChunkLengthBytes)
+ break;
+ length += itemLength;
+ data.push(item);
+ ++this._recordIndex;
+ }
+ if (this._recordIndex === this._payloads.length)
+ data.push(data.pop() + "]");
+ stream.write(data.join(separator), this._writeNextChunk.bind(this));
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineOverviewPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineOverviewPane.js
index a47ea36f17b..80228c8816e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TimelineOverviewPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineOverviewPane.js
@@ -30,16 +30,16 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
*/
-WebInspector.TimelineOverviewPane = function(model)
+WebInspector.TimelineOverviewPane = function(model, uiUtils)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
+ this._uiUtils = uiUtils;
this.element.id = "timeline-overview-pane";
- this._windowStartTime = 0;
- this._windowEndTime = Infinity;
this._eventDividers = [];
this._model = model;
@@ -49,9 +49,9 @@ WebInspector.TimelineOverviewPane = function(model)
this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();
- model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._reset, this);
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
+ this._overviewControls = [];
}
WebInspector.TimelineOverviewPane.Events = {
@@ -61,52 +61,44 @@ WebInspector.TimelineOverviewPane.Events = {
WebInspector.TimelineOverviewPane.prototype = {
wasShown: function()
{
- this._update();
+ this.update();
},
onResize: function()
{
- this._update();
+ this.update();
},
/**
- * @param {!WebInspector.TimelineOverviewBase} overviewControl
+ * @param {!Array.<!WebInspector.TimelineOverview>} overviewControls
*/
- willSetOverviewControl: function(overviewControl)
+ setOverviewControls: function(overviewControls)
{
- this._sameOverviewControl = this._overviewControl === overviewControl;
- if (this._sameOverviewControl)
- return;
- this._windowTimes = null;
- if (this._overviewControl) {
- this._windowTimes = this._overviewControl.windowTimes(this.windowLeft(), this.windowRight());
- this._overviewControl.detach();
+ for (var i = 0; i < this._overviewControls.length; ++i) {
+ var overviewControl = this._overviewControls[i];
+ overviewControl.detach();
+ overviewControl.dispose();
}
- this._overviewControl = overviewControl;
- this._overviewControl.show(this._overviewGrid.element);
- this._update();
- },
- didSetOverviewControl: function()
- {
- if (this._sameOverviewControl)
- return;
- if (this._windowTimes && this._windowTimes.startTime >= 0)
- this.setWindowTimes(this._windowTimes.startTime, this._windowTimes.endTime);
- this._update();
+ for (var i = 0; i < overviewControls.length; ++i) {
+ overviewControls[i].setOverviewGrid(this._overviewGrid);
+ overviewControls[i].show(this._overviewGrid.element);
+ }
+ this._overviewControls = overviewControls;
+ this.update();
},
- _update: function()
+ update: function()
{
delete this._refreshTimeout;
- this._updateWindow();
- this._overviewCalculator.setWindow(this._model.minimumRecordTime(), this._model.maximumRecordTime());
- this._overviewCalculator.setDisplayWindow(0, this._overviewGrid.clientWidth());
-
- this._overviewControl.update();
+ this._overviewCalculator._setWindow(this._model.minimumRecordTime(), this._model.maximumRecordTime());
+ this._overviewCalculator._setDisplayWindow(0, this._overviewGrid.clientWidth());
+ for (var i = 0; i < this._overviewControls.length; ++i)
+ this._overviewControls[i].update();
this._overviewGrid.updateDividers(this._overviewCalculator);
this._updateEventDividers();
+ this._updateWindow();
},
_updateEventDividers: function()
@@ -120,7 +112,7 @@ WebInspector.TimelineOverviewPane.prototype = {
var dividerPosition = Math.round(positions.start * 10);
if (dividers[dividerPosition])
continue;
- var divider = WebInspector.TimelinePresentationModel.createEventDivider(record.type);
+ var divider = this._uiUtils.createEventDivider(record.type());
divider.style.left = positions.start + "%";
dividers[dividerPosition] = divider;
}
@@ -128,88 +120,72 @@ WebInspector.TimelineOverviewPane.prototype = {
},
/**
- * @param {!WebInspector.TimelineFrame} frame
+ * @param {!WebInspector.TimelineModel.Record} record
*/
- zoomToFrame: function(frame)
- {
- this.setWindowTimes(frame.startTime, frame.endTime);
- this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged);
- },
-
- _onRecordAdded: function(event)
+ addRecord: function(record)
{
- var record = event.data;
var eventDividers = this._eventDividers;
+ var uiUtils = this._uiUtils;
function addEventDividers(record)
{
- if (WebInspector.TimelinePresentationModel.isEventDivider(record))
+ if (uiUtils.isEventDivider(record))
eventDividers.push(record);
}
- WebInspector.TimelinePresentationModel.forAllRecords([record], addEventDividers);
+ WebInspector.TimelineModel.forAllRecords([record], addEventDividers);
this._scheduleRefresh();
},
_reset: function()
{
- this._windowStartTime = 0;
- this._windowEndTime = Infinity;
this._overviewCalculator.reset();
this._overviewGrid.reset();
this._overviewGrid.setResizeEnabled(false);
this._eventDividers = [];
this._overviewGrid.updateDividers(this._overviewCalculator);
- this._overviewControl.reset();
- this._update();
- },
-
- windowStartTime: function()
- {
- return this._windowStartTime || this._model.minimumRecordTime();
- },
-
- windowEndTime: function()
- {
- return this._windowEndTime < Infinity ? this._windowEndTime : this._model.maximumRecordTime();
- },
-
- windowLeft: function()
- {
- return this._overviewGrid.windowLeft();
- },
-
- windowRight: function()
- {
- return this._overviewGrid.windowRight();
+ for (var i = 0; i < this._overviewControls.length; ++i)
+ this._overviewControls[i].reset();
+ this.update();
},
- _onWindowChanged: function()
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onWindowChanged: function(event)
{
- if (this._ignoreWindowChangedEvent)
+ if (this._muteOnWindowChanged)
+ return;
+ // Always use first control as a time converter.
+ if (!this._overviewControls.length)
return;
- var times = this._overviewControl.windowTimes(this.windowLeft(), this.windowRight());
- this._windowStartTime = times.startTime;
- this._windowEndTime = times.endTime;
- this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged);
+ var windowTimes = this._overviewControls[0].windowTimes(this._overviewGrid.windowLeft(), this._overviewGrid.windowRight());
+ this._windowStartTime = windowTimes.startTime;
+ this._windowEndTime = windowTimes.endTime;
+ this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged, windowTimes);
},
/**
- * @param {!Number} startTime
- * @param {!Number} endTime
+ * @param {number} startTime
+ * @param {number} endTime
*/
- setWindowTimes: function(startTime, endTime)
+ requestWindowTimes: function(startTime, endTime)
{
+ if (startTime === this._windowStartTime && endTime === this._windowEndTime)
+ return;
this._windowStartTime = startTime;
this._windowEndTime = endTime;
this._updateWindow();
+ this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged, { startTime: startTime, endTime: endTime });
},
_updateWindow: function()
{
- var windowBoundaries = this._overviewControl.windowBoundaries(this._windowStartTime, this._windowEndTime);
- this._ignoreWindowChangedEvent = true;
+ if (!this._overviewControls.length)
+ return;
+ var windowBoundaries = this._overviewControls[0].windowBoundaries(this._windowStartTime, this._windowEndTime);
+ this._muteOnWindowChanged = true;
this._overviewGrid.setWindow(windowBoundaries.left, windowBoundaries.right);
- this._overviewGrid.setResizeEnabled(this._model.records.length);
- this._ignoreWindowChangedEvent = false;
+ this._overviewGrid.setResizeEnabled(!!this._model.records().length);
+ this._muteOnWindowChanged = false;
},
_scheduleRefresh: function()
@@ -218,10 +194,10 @@ WebInspector.TimelineOverviewPane.prototype = {
return;
if (!this.isShowing())
return;
- this._refreshTimeout = setTimeout(this._update.bind(this), 300);
+ this._refreshTimeout = setTimeout(this.update.bind(this), 300);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
/**
@@ -234,70 +210,94 @@ WebInspector.TimelineOverviewCalculator = function()
WebInspector.TimelineOverviewCalculator.prototype = {
/**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return this._paddingLeft;
+ },
+
+ /**
* @param {number} time
+ * @return {number}
*/
computePosition: function(time)
{
- return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this.paddingLeft;
+ return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this._paddingLeft;
},
+ /**
+ * @return {!{start: number, end: number}}
+ */
computeBarGraphPercentages: function(record)
{
- var start = (WebInspector.TimelineModel.startTimeInSeconds(record) - this._minimumBoundary) / this.boundarySpan() * 100;
- var end = (WebInspector.TimelineModel.endTimeInSeconds(record) - this._minimumBoundary) / this.boundarySpan() * 100;
+ var start = (record.startTime() - this._minimumBoundary) / this.boundarySpan() * 100;
+ var end = (record.endTime() - this._minimumBoundary) / this.boundarySpan() * 100;
return {start: start, end: end};
},
/**
- * @param {number=} minimum
- * @param {number=} maximum
+ * @param {number=} minimumRecordTime
+ * @param {number=} maximumRecordTime
*/
- setWindow: function(minimum, maximum)
+ _setWindow: function(minimumRecordTime, maximumRecordTime)
{
- this._minimumBoundary = minimum >= 0 ? minimum : undefined;
- this._maximumBoundary = maximum >= 0 ? maximum : undefined;
+ this._minimumBoundary = minimumRecordTime;
+ this._maximumBoundary = maximumRecordTime;
},
/**
* @param {number} paddingLeft
* @param {number} clientWidth
*/
- setDisplayWindow: function(paddingLeft, clientWidth)
+ _setDisplayWindow: function(paddingLeft, clientWidth)
{
this._workingArea = clientWidth - paddingLeft;
- this.paddingLeft = paddingLeft;
+ this._paddingLeft = paddingLeft;
},
reset: function()
{
- this.setWindow();
+ this._setWindow(0, 1000);
},
/**
* @param {number} value
- * @param {boolean=} hires
+ * @param {number=} precision
* @return {string}
*/
- formatTime: function(value, hires)
+ formatTime: function(value, precision)
{
- return Number.secondsToString(value, hires);
+ return Number.preciseMillisToString(value - this.zeroTime(), precision);
},
+ /**
+ * @return {number}
+ */
maximumBoundary: function()
{
return this._maximumBoundary;
},
+ /**
+ * @return {number}
+ */
minimumBoundary: function()
{
return this._minimumBoundary;
},
+ /**
+ * @return {number}
+ */
zeroTime: function()
{
return this._minimumBoundary;
},
+ /**
+ * @return {number}
+ */
boundarySpan: function()
{
return this._maximumBoundary - this._minimumBoundary;
@@ -305,14 +305,54 @@ WebInspector.TimelineOverviewCalculator.prototype = {
}
/**
+ * @interface
+ */
+WebInspector.TimelineOverview = function(model)
+{
+}
+
+WebInspector.TimelineOverview.prototype = {
+ /**
+ * @param {?Element} parentElement
+ * @param {!Element=} insertBefore
+ */
+ show: function(parentElement, insertBefore) { },
+
+ /**
+ * @param {!WebInspector.OverviewGrid} grid
+ */
+ setOverviewGrid: function(grid) { },
+
+ update: function() { },
+
+ dispose: function() { },
+
+ reset: function() { },
+
+ /**
+ * @param {number} windowLeft
+ * @param {number} windowRight
+ * @return {!{startTime: number, endTime: number}}
+ */
+ windowTimes: function(windowLeft, windowRight) { },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {!{left: number, right: number}}
+ */
+ windowBoundaries: function(startTime, endTime) { },
+}
+
+/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
+ * @implements {WebInspector.TimelineOverview}
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.TimelineOverviewBase = function(model)
{
- WebInspector.View.call(this);
- this.element.classList.add("fill");
+ WebInspector.VBox.call(this);
this._model = model;
this._canvas = this.element.createChild("canvas", "fill");
@@ -320,12 +360,38 @@ WebInspector.TimelineOverviewBase = function(model)
}
WebInspector.TimelineOverviewBase.prototype = {
- update: function() { },
- reset: function() { },
+ /**
+ * @param {!WebInspector.OverviewGrid} grid
+ */
+ setOverviewGrid: function(grid)
+ {
+ },
+
+ update: function()
+ {
+ this.resetCanvas();
+ },
+
+ dispose: function()
+ {
+ },
+
+ reset: function()
+ {
+ },
+
+ timelineStarted: function()
+ {
+ },
+
+ timelineStopped: function()
+ {
+ },
/**
* @param {number} windowLeft
* @param {number} windowRight
+ * @return {!{startTime: number, endTime: number}}
*/
windowTimes: function(windowLeft, windowRight)
{
@@ -340,12 +406,13 @@ WebInspector.TimelineOverviewBase.prototype = {
/**
* @param {number} startTime
* @param {number} endTime
+ * @return {!{left: number, right: number}}
*/
windowBoundaries: function(startTime, endTime)
{
var absoluteMin = this._model.minimumRecordTime();
var timeSpan = this._model.maximumRecordTime() - absoluteMin;
- var haveRecords = absoluteMin >= 0;
+ var haveRecords = absoluteMin > 0;
return {
left: haveRecords && startTime ? Math.min((startTime - absoluteMin) / timeSpan, 1) : 0,
right: haveRecords && endTime < Infinity ? (endTime - absoluteMin) / timeSpan : 1
@@ -358,5 +425,5 @@ WebInspector.TimelineOverviewBase.prototype = {
this._canvas.height = this.element.clientHeight * window.devicePixelRatio;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
new file mode 100644
index 00000000000..e55890fee1a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -0,0 +1,1453 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Intel Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+importScript("../sdk/CPUProfileModel.js");
+importScript("CountersGraph.js");
+importScript("Layers3DView.js");
+importScript("MemoryCountersGraph.js");
+importScript("TimelineModel.js");
+importScript("TimelineModelImpl.js");
+importScript("TimelineJSProfile.js");
+importScript("TimelineOverviewPane.js");
+importScript("TimelinePresentationModel.js");
+importScript("TracingTimelineModel.js");
+importScript("TimelineFrameModel.js");
+importScript("TimelineEventOverview.js");
+importScript("TimelineFrameOverview.js");
+importScript("TimelineMemoryOverview.js");
+importScript("TimelinePowerGraph.js");
+importScript("TimelinePowerOverview.js");
+importScript("TimelineFlameChart.js");
+importScript("TimelineUIUtils.js");
+importScript("TimelineUIUtilsImpl.js");
+importScript("TimelineView.js");
+importScript("TimelineTracingView.js");
+importScript("TimelineLayersView.js");
+importScript("TracingModel.js");
+importScript("TracingTimelineUIUtils.js");
+importScript("TransformController.js");
+
+/**
+ * @constructor
+ * @extends {WebInspector.Panel}
+ * @implements {WebInspector.TimelineModeViewDelegate}
+ * @implements {WebInspector.Searchable}
+ */
+WebInspector.TimelinePanel = function()
+{
+ WebInspector.Panel.call(this, "timeline");
+ this.registerRequiredCSS("timelinePanel.css");
+ this.registerRequiredCSS("layersPanel.css");
+ this.registerRequiredCSS("filter.css");
+ this.element.addEventListener("contextmenu", this._contextMenu.bind(this), false);
+
+ this._detailsLinkifier = new WebInspector.Linkifier();
+ this._windowStartTime = 0;
+ this._windowEndTime = Infinity;
+
+ // Create model.
+ if (WebInspector.experimentsSettings.timelineTracingMode.isEnabled() ||
+ WebInspector.experimentsSettings.timelineOnTraceEvents.isEnabled()) {
+ this._tracingModel = new WebInspector.TracingModel(WebInspector.targetManager.activeTarget());
+ this._tracingModel.addEventListener(WebInspector.TracingModel.Events.BufferUsage, this._onTracingBufferUsage, this);
+
+ this._tracingTimelineModel = new WebInspector.TracingTimelineModel(this._tracingModel);
+ this._model = this._tracingTimelineModel;
+ this._uiUtils = new WebInspector.TracingTimelineUIUtils();
+ } else {
+ this._model = new WebInspector.TimelineModelImpl(WebInspector.timelineManager);
+ this._uiUtils = new WebInspector.TimelineUIUtilsImpl();
+ }
+
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStopped, this._onRecordingStopped, this);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, this._onRecordsCleared, this);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingProgress, this._onRecordingProgress, this);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordFilterChanged, this._refreshViews, this);
+ this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
+
+ this._model.target().profilingLock.addEventListener(WebInspector.Lock.Events.StateChanged, this._onProfilingStateChanged, this);
+
+ this._categoryFilter = new WebInspector.TimelineCategoryFilter();
+ this._durationFilter = new WebInspector.TimelineIsLongFilter();
+ this._textFilter = new WebInspector.TimelineTextFilter(this._uiUtils);
+
+ this._model.addFilter(new WebInspector.TimelineHiddenFilter());
+ this._model.addFilter(this._categoryFilter);
+ this._model.addFilter(this._durationFilter);
+ this._model.addFilter(this._textFilter);
+
+ /** @type {!Array.<!WebInspector.TimelineModeView>} */
+ this._currentViews = [];
+
+ this._overviewModeSetting = WebInspector.settings.createSetting("timelineOverviewMode", WebInspector.TimelinePanel.OverviewMode.Events);
+ this._flameChartEnabledSetting = WebInspector.settings.createSetting("timelineFlameChartEnabled", false);
+ this._createStatusBarItems();
+
+ this._topPane = new WebInspector.SplitView(true, false);
+ this._topPane.element.id = "timeline-overview-panel";
+ this._topPane.show(this.element);
+ this._topPane.addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._sidebarResized, this);
+ this._topPane.setResizable(false);
+ this._createRecordingOptions();
+
+ // Create top overview component.
+ this._overviewPane = new WebInspector.TimelineOverviewPane(this._model, this._uiUtils);
+ this._overviewPane.addEventListener(WebInspector.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
+ this._overviewPane.show(this._topPane.mainElement());
+
+ this._createFileSelector();
+ this._registerShortcuts();
+
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage, this._willReloadPage, this);
+ WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.Load, this._loadEventFired, this);
+
+ // Create top level properties splitter.
+ this._detailsSplitView = new WebInspector.SplitView(false, true, "timelinePanelDetailsSplitViewState");
+ this._detailsSplitView.element.classList.add("timeline-details-split");
+ this._detailsSplitView.sidebarElement().classList.add("timeline-details");
+ this._detailsView = new WebInspector.TimelineDetailsView();
+ this._detailsSplitView.installResizer(this._detailsView.headerElement());
+ this._detailsView.show(this._detailsSplitView.sidebarElement());
+
+ this._searchableView = new WebInspector.SearchableView(this);
+ this._searchableView.setMinimumSize(0, 25);
+ this._searchableView.element.classList.add("searchable-view");
+ this._searchableView.show(this._detailsSplitView.mainElement());
+
+ this._stackView = new WebInspector.StackView(false);
+ this._stackView.show(this._searchableView.element);
+ this._stackView.element.classList.add("timeline-view-stack");
+
+ WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this));
+ WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this));
+ this._dockSideChanged();
+
+ this._onModeChanged();
+ this._detailsSplitView.show(this.element);
+}
+
+WebInspector.TimelinePanel.OverviewMode = {
+ Events: "Events",
+ Frames: "Frames"
+};
+
+// Define row and header height, should be in sync with styles for timeline graphs.
+WebInspector.TimelinePanel.rowHeight = 18;
+WebInspector.TimelinePanel.headerHeight = 20;
+
+WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15];
+
+WebInspector.TimelinePanel.prototype = {
+ /**
+ * @return {?WebInspector.SearchableView}
+ */
+ searchableView: function()
+ {
+ return this._searchableView;
+ },
+
+ wasShown: function()
+ {
+ if (!WebInspector.TimelinePanel._categoryStylesInitialized) {
+ WebInspector.TimelinePanel._categoryStylesInitialized = true;
+ var style = document.createElement("style");
+ var categories = WebInspector.TimelineUIUtils.categories();
+ style.textContent = Object.values(categories).map(WebInspector.TimelineUIUtils.createStyleRuleForCategory).join("\n");
+ document.head.appendChild(style);
+ }
+ },
+
+ _dockSideChanged: function()
+ {
+ var dockSide = WebInspector.dockController.dockSide();
+ var vertically = false;
+ if (dockSide === WebInspector.DockController.State.DockedToBottom)
+ vertically = true;
+ else
+ vertically = !WebInspector.settings.splitVerticallyWhenDockedToRight.get();
+ this._detailsSplitView.setVertical(vertically);
+ this._detailsView.setVertical(vertically);
+ },
+
+ /**
+ * @return {number}
+ */
+ windowStartTime: function()
+ {
+ if (this._windowStartTime)
+ return this._windowStartTime;
+ return this._model.minimumRecordTime();
+ },
+
+ /**
+ * @return {number}
+ */
+ windowEndTime: function()
+ {
+ if (this._windowEndTime < Infinity)
+ return this._windowEndTime;
+ return this._model.maximumRecordTime() || Infinity;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sidebarResized: function(event)
+ {
+ var width = /** @type {number} */ (event.data);
+ this._topPane.setSidebarSize(width);
+ for (var i = 0; i < this._currentViews.length; ++i)
+ this._currentViews[i].setSidebarSize(width);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onWindowChanged: function(event)
+ {
+ this._windowStartTime = event.data.startTime;
+ this._windowEndTime = event.data.endTime;
+
+ for (var i = 0; i < this._currentViews.length; ++i)
+ this._currentViews[i].setWindowTimes(this._windowStartTime, this._windowEndTime);
+ this._updateSelectedRangeStats();
+ },
+
+ /**
+ * @param {number} windowStartTime
+ * @param {number} windowEndTime
+ */
+ requestWindowTimes: function(windowStartTime, windowEndTime)
+ {
+ this._overviewPane.requestWindowTimes(windowStartTime, windowEndTime);
+ },
+
+ /**
+ * @return {!WebInspector.TimelineFrameModelBase}
+ */
+ _frameModel: function()
+ {
+ if (this._lazyFrameModel)
+ return this._lazyFrameModel;
+ if (this._tracingModel) {
+ var tracingFrameModel = new WebInspector.TracingTimelineFrameModel(this._model.target());
+ tracingFrameModel.addTraceEvents(this._tracingTimelineModel.inspectedTargetEvents(), this._tracingModel.sessionId() || "");
+ this._lazyFrameModel = tracingFrameModel;
+ } else {
+ var frameModel = new WebInspector.TimelineFrameModel(this._model.target());
+ frameModel.setMergeRecords(!WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled() || !this._recordingInProgress);
+ frameModel.addRecords(this._model.records());
+ this._lazyFrameModel = frameModel;
+ }
+ return this._lazyFrameModel;
+ },
+
+ /**
+ * @return {!WebInspector.TimelineView}
+ */
+ _timelineView: function()
+ {
+ if (!this._lazyTimelineView)
+ this._lazyTimelineView = new WebInspector.TimelineView(this, this._model, this._uiUtils);
+ return this._lazyTimelineView;
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ _layersView: function()
+ {
+ if (this._lazyLayersView)
+ return this._lazyLayersView;
+ this._lazyLayersView = new WebInspector.TimelineLayersView();
+ return this._lazyLayersView;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModeView} modeView
+ */
+ _addModeView: function(modeView)
+ {
+ modeView.setWindowTimes(this.windowStartTime(), this.windowEndTime());
+ modeView.refreshRecords(this._textFilter._regex);
+ modeView.view().setSidebarSize(this._topPane.sidebarSize());
+ this._stackView.appendView(modeView.view(), "timelinePanelTimelineStackSplitViewState");
+ modeView.view().addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._sidebarResized, this);
+ this._currentViews.push(modeView);
+ },
+
+ _removeAllModeViews: function()
+ {
+ for (var i = 0; i < this._currentViews.length; ++i) {
+ this._currentViews[i].removeEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._sidebarResized, this);
+ this._currentViews[i].dispose();
+ }
+ this._currentViews = [];
+ this._stackView.detachChildViews();
+ },
+
+ _createRecordingOptions: function()
+ {
+ var topPaneSidebarElement = this._topPane.sidebarElement();
+
+ this._captureStacksSetting = WebInspector.settings.createSetting("timelineCaptureStacks", true);
+ topPaneSidebarElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Capture stacks"),
+ this._captureStacksSetting, true, undefined,
+ WebInspector.UIString("Capture JavaScript stack on every timeline event")));
+
+ this._captureMemorySetting = WebInspector.settings.createSetting("timelineCaptureMemory", false);
+ topPaneSidebarElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Capture memory"),
+ this._captureMemorySetting, true, undefined,
+ WebInspector.UIString("Capture memory information on every timeline event")));
+ this._captureMemorySetting.addChangeListener(this._onModeChanged, this);
+
+ if (Capabilities.canProfilePower) {
+ this._capturePowerSetting = WebInspector.settings.createSetting("timelineCapturePower", false);
+ topPaneSidebarElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Capture power"),
+ this._capturePowerSetting, true, undefined,
+ WebInspector.UIString("Capture power information")));
+ this._capturePowerSetting.addChangeListener(this._onModeChanged, this);
+ }
+
+ if (WebInspector.experimentsSettings.timelineTracingMode.isEnabled()) {
+ this._captureTracingSetting = WebInspector.settings.createSetting("timelineCaptureTracing", false);
+ topPaneSidebarElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Capture tracing"),
+ this._captureTracingSetting, true, undefined,
+ WebInspector.UIString("Capture tracing information")));
+ this._captureTracingSetting.addChangeListener(this._onModeChanged, this);
+ } else if (WebInspector.experimentsSettings.timelineOnTraceEvents.isEnabled()) {
+ this._captureLayersAndPicturesSetting = WebInspector.settings.createSetting("timelineCaptureLayersAndPictures", false);
+ topPaneSidebarElement.appendChild(WebInspector.SettingsUI.createSettingCheckbox(WebInspector.UIString("Capture pictures"),
+ this._captureLayersAndPicturesSetting, true, undefined,
+ WebInspector.UIString("Capture graphics layer positions and painted pictures")));
+ }
+ },
+
+ _createStatusBarItems: function()
+ {
+ var panelStatusBarElement = this.element.createChild("div", "panel-status-bar");
+ this._statusBarButtons = /** @type {!Array.<!WebInspector.StatusBarItem>} */ ([]);
+
+ this.toggleTimelineButton = new WebInspector.StatusBarButton("", "record-profile-status-bar-item");
+ this.toggleTimelineButton.addEventListener("click", this._toggleTimelineButtonClicked, this);
+ this._statusBarButtons.push(this.toggleTimelineButton);
+ panelStatusBarElement.appendChild(this.toggleTimelineButton.element);
+ this._updateToggleTimelineButton(false);
+
+ var clearButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear"), "clear-status-bar-item");
+ clearButton.addEventListener("click", this._onClearButtonClick, this);
+ this._statusBarButtons.push(clearButton);
+ panelStatusBarElement.appendChild(clearButton.element);
+
+ this._filterBar = this._createFilterBar();
+ panelStatusBarElement.appendChild(this._filterBar.filterButton().element);
+
+ var garbageCollectButton = new WebInspector.StatusBarButton(WebInspector.UIString("Collect Garbage"), "timeline-garbage-collect-status-bar-item");
+ garbageCollectButton.addEventListener("click", this._garbageCollectButtonClicked, this);
+ this._statusBarButtons.push(garbageCollectButton);
+ panelStatusBarElement.appendChild(garbageCollectButton.element);
+
+ var framesToggleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Frames mode"), "timeline-frames-status-bar-item");
+ framesToggleButton.toggled = this._overviewModeSetting.get() === WebInspector.TimelinePanel.OverviewMode.Frames;
+ framesToggleButton.addEventListener("click", this._overviewModeChanged.bind(this, framesToggleButton));
+ this._statusBarButtons.push(framesToggleButton);
+ panelStatusBarElement.appendChild(framesToggleButton.element);
+
+ if (WebInspector.experimentsSettings.timelineFlameChart.isEnabled()) {
+ var flameChartToggleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Tracing mode"), "timeline-flame-chart-status-bar-item");
+ flameChartToggleButton.toggled = this._flameChartEnabledSetting.get();
+ flameChartToggleButton.addEventListener("click", this._flameChartEnabledChanged.bind(this, flameChartToggleButton));
+ this._statusBarButtons.push(flameChartToggleButton);
+ panelStatusBarElement.appendChild(flameChartToggleButton.element);
+ }
+
+ this._miscStatusBarItems = panelStatusBarElement.createChild("div", "status-bar-item");
+
+ this._filtersContainer = this.element.createChild("div", "timeline-filters-header hidden");
+ this._filtersContainer.appendChild(this._filterBar.filtersElement());
+ this._filterBar.addEventListener(WebInspector.FilterBar.Events.FiltersToggled, this._onFiltersToggled, this);
+ this._filterBar.setName("timelinePanel");
+ },
+
+ /**
+ * @return {!WebInspector.FilterBar}
+ */
+ _createFilterBar: function()
+ {
+ this._filterBar = new WebInspector.FilterBar();
+ this._filters = {};
+ this._filters._textFilterUI = new WebInspector.TextFilterUI();
+ this._filters._textFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._textFilterChanged, this);
+ this._filterBar.addFilter(this._filters._textFilterUI);
+
+ var durationOptions = [];
+ for (var presetIndex = 0; presetIndex < WebInspector.TimelinePanel.durationFilterPresetsMs.length; ++presetIndex) {
+ var durationMs = WebInspector.TimelinePanel.durationFilterPresetsMs[presetIndex];
+ var durationOption = {};
+ if (!durationMs) {
+ durationOption.label = WebInspector.UIString("All");
+ durationOption.title = WebInspector.UIString("Show all records");
+ } else {
+ durationOption.label = WebInspector.UIString("\u2265 %dms", durationMs);
+ durationOption.title = WebInspector.UIString("Hide records shorter than %dms", durationMs);
+ }
+ durationOption.value = durationMs;
+ durationOptions.push(durationOption);
+ }
+ this._filters._durationFilterUI = new WebInspector.ComboBoxFilterUI(durationOptions);
+ this._filters._durationFilterUI.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._durationFilterChanged, this);
+ this._filterBar.addFilter(this._filters._durationFilterUI);
+
+ this._filters._categoryFiltersUI = {};
+ var categoryTypes = [];
+ var categories = WebInspector.TimelineUIUtils.categories();
+ for (var categoryName in categories) {
+ var category = categories[categoryName];
+ if (category.overviewStripGroupIndex < 0)
+ continue;
+ var filter = new WebInspector.CheckboxFilterUI(category.name, category.title);
+ this._filters._categoryFiltersUI[category.name] = filter;
+ filter.addEventListener(WebInspector.FilterUI.Events.FilterChanged, this._categoriesFilterChanged.bind(this, categoryName), this);
+ this._filterBar.addFilter(filter);
+ }
+ return this._filterBar;
+ },
+
+ _textFilterChanged: function(event)
+ {
+ var searchQuery = this._filters._textFilterUI.value();
+ this.searchCanceled();
+ this._textFilter.setRegex(searchQuery ? createPlainTextSearchRegex(searchQuery, "i") : null);
+ },
+
+ _durationFilterChanged: function()
+ {
+ var duration = this._filters._durationFilterUI.value();
+ var minimumRecordDuration = parseInt(duration, 10);
+ this._durationFilter.setMinimumRecordDuration(minimumRecordDuration);
+ },
+
+ _categoriesFilterChanged: function(name, event)
+ {
+ var categories = WebInspector.TimelineUIUtils.categories();
+ categories[name].hidden = !this._filters._categoryFiltersUI[name].checked();
+ this._categoryFilter.notifyFilterChanged();
+ },
+
+ /**
+ * @return {!Element}
+ */
+ defaultFocusedElement: function()
+ {
+ return this.element;
+ },
+
+ _onFiltersToggled: function(event)
+ {
+ var toggled = /** @type {boolean} */ (event.data);
+ this._filtersContainer.classList.toggle("hidden", !toggled);
+ this.doResize();
+ },
+
+ /**
+ * @return {?WebInspector.ProgressIndicator}
+ */
+ _prepareToLoadTimeline: function()
+ {
+ if (this._operationInProgress)
+ return null;
+ if (this._recordingInProgress()) {
+ this._updateToggleTimelineButton(false);
+ this._stopRecording();
+ }
+ var progressIndicator = new WebInspector.ProgressIndicator();
+ progressIndicator.addEventListener(WebInspector.Progress.Events.Done, this._setOperationInProgress.bind(this, null));
+ this._setOperationInProgress(progressIndicator);
+ return progressIndicator;
+ },
+
+ /**
+ * @param {?WebInspector.ProgressIndicator} indicator
+ */
+ _setOperationInProgress: function(indicator)
+ {
+ this._operationInProgress = !!indicator;
+ for (var i = 0; i < this._statusBarButtons.length; ++i)
+ this._statusBarButtons[i].setEnabled(!this._operationInProgress);
+ this._miscStatusBarItems.removeChildren();
+ if (indicator)
+ this._miscStatusBarItems.appendChild(indicator.element);
+ },
+
+ _registerShortcuts: function()
+ {
+ this.registerShortcuts(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.StartStopRecording, this._toggleTimelineButtonClicked.bind(this));
+ this.registerShortcuts(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.SaveToFile, this._saveToFile.bind(this));
+ this.registerShortcuts(WebInspector.ShortcutsScreen.TimelinePanelShortcuts.LoadFromFile, this._selectFileToLoad.bind(this));
+ },
+
+ _createFileSelector: function()
+ {
+ if (this._fileSelectorElement)
+ this._fileSelectorElement.remove();
+
+ this._fileSelectorElement = WebInspector.createFileSelectorElement(this._loadFromFile.bind(this));
+ this.element.appendChild(this._fileSelectorElement);
+ },
+
+ _contextMenu: function(event)
+ {
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Save Timeline data\u2026" : "Save Timeline Data\u2026"), this._saveToFile.bind(this), this._operationInProgress);
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Load Timeline data\u2026" : "Load Timeline Data\u2026"), this._selectFileToLoad.bind(this), this._operationInProgress);
+ contextMenu.show();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _saveToFile: function()
+ {
+ if (this._operationInProgress)
+ return true;
+ this._model.saveToFile();
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _selectFileToLoad: function() {
+ this._fileSelectorElement.click();
+ return true;
+ },
+
+ /**
+ * @param {!File} file
+ */
+ _loadFromFile: function(file)
+ {
+ var progressIndicator = this._prepareToLoadTimeline();
+ if (!progressIndicator)
+ return;
+ this._model.loadFromFile(file, progressIndicator);
+ this._createFileSelector();
+ },
+
+ /**
+ * @param {string} url
+ */
+ loadFromURL: function(url)
+ {
+ var progressIndicator = this._prepareToLoadTimeline();
+ if (!progressIndicator)
+ return;
+ this._model.loadFromURL(url, progressIndicator);
+ },
+
+ _refreshViews: function()
+ {
+ for (var i = 0; i < this._currentViews.length; ++i) {
+ var view = this._currentViews[i];
+ view.refreshRecords(this._textFilter._regex);
+ }
+ this._updateSelectedRangeStats();
+ },
+
+ /**
+ * @param {!WebInspector.StatusBarButton} button
+ */
+ _overviewModeChanged: function(button)
+ {
+ var oldMode = this._overviewModeSetting.get();
+ if (oldMode === WebInspector.TimelinePanel.OverviewMode.Events) {
+ this._overviewModeSetting.set(WebInspector.TimelinePanel.OverviewMode.Frames);
+ button.toggled = true;
+ } else {
+ this._overviewModeSetting.set(WebInspector.TimelinePanel.OverviewMode.Events);
+ button.toggled = false;
+ }
+ this._onModeChanged();
+ },
+
+ /**
+ * @param {!WebInspector.StatusBarButton} button
+ */
+ _flameChartEnabledChanged: function(button)
+ {
+ var oldValue = this._flameChartEnabledSetting.get();
+ var newValue = !oldValue;
+ this._flameChartEnabledSetting.set(newValue);
+ button.toggled = newValue;
+ this._onModeChanged();
+ },
+
+ _onModeChanged: function()
+ {
+ this._stackView.detach();
+
+ var isFrameMode = this._overviewModeSetting.get() === WebInspector.TimelinePanel.OverviewMode.Frames;
+ this._removeAllModeViews();
+ this._overviewControls = [];
+
+ if (isFrameMode)
+ this._overviewControls.push(new WebInspector.TimelineFrameOverview(this._model, this._frameModel()));
+ else
+ this._overviewControls.push(new WebInspector.TimelineEventOverview(this._model, this._uiUtils));
+
+ if (WebInspector.experimentsSettings.timelineFlameChart.isEnabled() && this._flameChartEnabledSetting.get()) {
+ var tracingTimelineModel = WebInspector.experimentsSettings.timelineOnTraceEvents.isEnabled() ? this._tracingTimelineModel : null;
+ this._addModeView(new WebInspector.TimelineFlameChart(this, this._model, tracingTimelineModel, this._frameModel()));
+ } else {
+ this._addModeView(this._timelineView());
+ }
+
+ if (this._captureMemorySetting.get()) {
+ if (!isFrameMode) // Frame mode skews time, don't render aux overviews.
+ this._overviewControls.push(new WebInspector.TimelineMemoryOverview(this._model, this._uiUtils));
+ this._addModeView(new WebInspector.MemoryCountersGraph(this, this._model, this._uiUtils));
+ }
+
+ if (this._capturePowerSetting && this._capturePowerSetting.get()) {
+ if (!isFrameMode) // Frame mode skews time, don't render aux overviews.
+ this._overviewControls.push(new WebInspector.TimelinePowerOverview(this._model));
+ this._addModeView(new WebInspector.TimelinePowerGraph(this, this._model));
+ }
+
+ if (this._captureTracingSetting && this._captureTracingSetting.get())
+ this._addModeView(new WebInspector.TimelineTracingView(this, this._tracingModel, this._model));
+
+ this._timelineView().setFrameModel(isFrameMode ? this._frameModel() : null);
+ this._overviewPane.setOverviewControls(this._overviewControls);
+ this.doResize();
+ this._updateSelectedRangeStats();
+
+ this._stackView.show(this._searchableView.element);
+ },
+
+ /**
+ * @param {boolean} userInitiated
+ */
+ _startRecording: function(userInitiated)
+ {
+ this._userInitiatedRecording = userInitiated;
+ this._model.startRecording(this._captureStacksSetting.get(), this._captureMemorySetting.get(), this._captureLayersAndPicturesSetting && this._captureLayersAndPicturesSetting.get());
+ if (WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled() && this._lazyFrameModel)
+ this._lazyFrameModel.setMergeRecords(false);
+
+ for (var i = 0; i < this._overviewControls.length; ++i)
+ this._overviewControls[i].timelineStarted();
+
+ if (userInitiated)
+ WebInspector.userMetrics.TimelineStarted.record();
+ },
+
+ _stopRecording: function()
+ {
+ this._stopPending = true;
+ this._updateToggleTimelineButton(false);
+ this._userInitiatedRecording = false;
+ this._model.stopRecording();
+ if (this._progressElement)
+ this._updateProgress(WebInspector.UIString("Retrieving events\u2026"));
+
+ for (var i = 0; i < this._overviewControls.length; ++i)
+ this._overviewControls[i].timelineStopped();
+ },
+
+ _onProfilingStateChanged: function()
+ {
+ this._updateToggleTimelineButton(this.toggleTimelineButton.toggled);
+ },
+
+ /**
+ * @param {boolean} toggled
+ */
+ _updateToggleTimelineButton: function(toggled)
+ {
+ this.toggleTimelineButton.toggled = toggled;
+ if (toggled) {
+ this.toggleTimelineButton.title = WebInspector.UIString("Stop");
+ this.toggleTimelineButton.setEnabled(true);
+ } else if (this._stopPending) {
+ this.toggleTimelineButton.title = WebInspector.UIString("Stop pending");
+ this.toggleTimelineButton.setEnabled(false);
+ } else if (this._model.target().profilingLock.isAcquired()) {
+ this.toggleTimelineButton.title = WebInspector.UIString("Another profiler is already active");
+ this.toggleTimelineButton.setEnabled(false);
+ } else {
+ this.toggleTimelineButton.title = WebInspector.UIString("Record");
+ this.toggleTimelineButton.setEnabled(true);
+ }
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _toggleTimelineButtonClicked: function()
+ {
+ if (!this.toggleTimelineButton.enabled())
+ return true;
+ if (this._operationInProgress)
+ return true;
+ if (this._recordingInProgress())
+ this._stopRecording();
+ else
+ this._startRecording(true);
+ return true;
+ },
+
+ _garbageCollectButtonClicked: function()
+ {
+ HeapProfilerAgent.collectGarbage();
+ },
+
+ _onClearButtonClick: function()
+ {
+ if (this._tracingModel)
+ this._tracingModel.reset();
+ this._model.reset();
+ },
+
+ _onRecordsCleared: function()
+ {
+ this.requestWindowTimes(0, Infinity);
+ delete this._selection;
+ if (this._lazyFrameModel)
+ this._lazyFrameModel.reset();
+ for (var i = 0; i < this._currentViews.length; ++i)
+ this._currentViews[i].reset();
+ for (var i = 0; i < this._overviewControls.length; ++i)
+ this._overviewControls[i].reset();
+ this._updateSelectedRangeStats();
+ },
+
+ _onRecordingStarted: function()
+ {
+ this._updateToggleTimelineButton(true);
+ if (WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled())
+ this._updateProgress(WebInspector.UIString("%d events collected", 0));
+ },
+
+ _recordingInProgress: function()
+ {
+ return this.toggleTimelineButton.toggled;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onRecordingProgress: function(event)
+ {
+ if (!WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled())
+ return;
+ this._updateProgress(WebInspector.UIString("%d events collected", event.data));
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onTracingBufferUsage: function(event)
+ {
+ var usage = /** @type {number} */ (event.data);
+ this._updateProgress(WebInspector.UIString("Buffer usage %d%", Math.round(usage * 100)));
+ },
+
+ /**
+ * @param {string} progressMessage
+ */
+ _updateProgress: function(progressMessage)
+ {
+ if (!this._progressElement)
+ this._showProgressPane();
+ this._progressElement.textContent = progressMessage;
+ },
+
+ _showProgressPane: function()
+ {
+ this._hideProgressPane();
+ this._progressElement = this._detailsSplitView.mainElement().createChild("div", "timeline-progress-pane");
+ },
+
+ _hideProgressPane: function()
+ {
+ if (this._progressElement)
+ this._progressElement.remove();
+ delete this._progressElement;
+ },
+
+ _onRecordingStopped: function()
+ {
+ this._stopPending = false;
+ this._updateToggleTimelineButton(false);
+ if (this._lazyFrameModel) {
+ if (this._tracingTimelineModel) {
+ this._lazyFrameModel.reset();
+ this._lazyFrameModel.addTraceEvents(this._tracingTimelineModel.inspectedTargetEvents(), this._tracingModel.sessionId());
+ this._overviewPane.update();
+ } else if (WebInspector.experimentsSettings.timelineNoLiveUpdate.isEnabled()) {
+ this._lazyFrameModel.reset();
+ this._lazyFrameModel.addRecords(this._model.records());
+ }
+ }
+ if (this._tracingTimelineModel) {
+ this.requestWindowTimes(this._tracingTimelineModel.minimumRecordTime(), this._tracingTimelineModel.maximumRecordTime());
+ this._refreshViews();
+ }
+ this._hideProgressPane();
+ },
+
+ _onRecordAdded: function(event)
+ {
+ this._addRecord(/** @type {!WebInspector.TimelineModel.Record} */(event.data));
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _addRecord: function(record)
+ {
+ if (this._lazyFrameModel && !this._tracingModel)
+ this._lazyFrameModel.addRecord(record);
+ for (var i = 0; i < this._currentViews.length; ++i)
+ this._currentViews[i].addRecord(record);
+ this._overviewPane.addRecord(record);
+ this._updateSearchHighlight(false, true);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _willReloadPage: function(event)
+ {
+ if (this._operationInProgress || this._userInitiatedRecording || !this.isShowing())
+ return;
+ this._startRecording(false);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _loadEventFired: function(event)
+ {
+ if (!this._recordingInProgress() || this._userInitiatedRecording)
+ return;
+ this._stopRecording();
+ },
+
+ // WebInspector.Searchable implementation
+
+ jumpToNextSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : -1;
+ this._jumpToSearchResult(index + 1);
+ },
+
+ jumpToPreviousSearchResult: function()
+ {
+ if (!this._searchResults || !this._searchResults.length)
+ return;
+ var index = this._selectedSearchResult ? this._searchResults.indexOf(this._selectedSearchResult) : 0;
+ this._jumpToSearchResult(index - 1);
+ },
+
+ _jumpToSearchResult: function(index)
+ {
+ this._selectSearchResult((index + this._searchResults.length) % this._searchResults.length);
+ this._currentViews[0].highlightSearchResult(this._selectedSearchResult, this._searchRegex, true);
+ },
+
+ _selectSearchResult: function(index)
+ {
+ this._selectedSearchResult = this._searchResults[index];
+ this._searchableView.updateCurrentMatchIndex(index);
+ },
+
+ _clearHighlight: function()
+ {
+ this._currentViews[0].highlightSearchResult(null);
+ },
+
+ /**
+ * @param {boolean} revealRecord
+ * @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
+ */
+ _updateSearchHighlight: function(revealRecord, shouldJump, jumpBackwards)
+ {
+ if (!this._textFilter.isEmpty() || !this._searchRegex) {
+ this._clearHighlight();
+ return;
+ }
+
+ if (!this._searchResults)
+ this._updateSearchResults(shouldJump, jumpBackwards);
+ this._currentViews[0].highlightSearchResult(this._selectedSearchResult, this._searchRegex, revealRecord);
+ },
+
+ /**
+ * @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
+ */
+ _updateSearchResults: function(shouldJump, jumpBackwards)
+ {
+ var searchRegExp = this._searchRegex;
+ if (!searchRegExp)
+ return;
+
+ var matches = [];
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @this {WebInspector.TimelinePanel}
+ */
+ function processRecord(record)
+ {
+ if (record.endTime() < this._windowStartTime ||
+ record.startTime() > this._windowEndTime)
+ return;
+ if (this._uiUtils.testContentMatching(record, searchRegExp))
+ matches.push(record);
+ }
+ this._model.forAllFilteredRecords(processRecord.bind(this));
+
+ var matchesCount = matches.length;
+ if (matchesCount) {
+ this._searchResults = matches;
+ this._searchableView.updateSearchMatchesCount(matchesCount);
+
+ var selectedIndex = matches.indexOf(this._selectedSearchResult);
+ if (shouldJump && selectedIndex === -1)
+ selectedIndex = jumpBackwards ? this._searchResults.length - 1 : 0;
+ this._selectSearchResult(selectedIndex);
+ } else {
+ this._searchableView.updateSearchMatchesCount(0);
+ delete this._selectedSearchResult;
+ }
+ },
+
+ searchCanceled: function()
+ {
+ this._clearHighlight();
+ delete this._searchResults;
+ delete this._selectedSearchResult;
+ delete this._searchRegex;
+ },
+
+ /**
+ * @param {string} query
+ * @param {boolean} shouldJump
+ * @param {boolean=} jumpBackwards
+ */
+ performSearch: function(query, shouldJump, jumpBackwards)
+ {
+ this._searchRegex = createPlainTextSearchRegex(query, "i");
+ delete this._searchResults;
+ this._updateSearchHighlight(true, shouldJump, jumpBackwards);
+ },
+
+ _updateSelectionDetails: function()
+ {
+ if (!this._selection) {
+ this._updateSelectedRangeStats();
+ return;
+ }
+ switch (this._selection.type()) {
+ case WebInspector.TimelineSelection.Type.Record:
+ var record = /** @type {!WebInspector.TimelineModel.Record} */ (this._selection.object());
+ var title = this._uiUtils.titleForRecord(record);
+ this._uiUtils.generateDetailsContent(record, this._model, this._detailsLinkifier, this.showInDetails.bind(this, title), this._model.loadedFromFile());
+ break;
+ case WebInspector.TimelineSelection.Type.TraceEvent:
+ var event = /** @type {!WebInspector.TracingModel.Event} */ (this._selection.object());
+ var title = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(event.name).title;
+ WebInspector.TracingTimelineUIUtils.buildTraceEventDetails(event, this._tracingTimelineModel, this._detailsLinkifier, this.showInDetails.bind(this, title), false, this._model.target());
+ break;
+ case WebInspector.TimelineSelection.Type.Frame:
+ var frame = /** @type {!WebInspector.TimelineFrame} */ (this._selection.object());
+ this.showInDetails(WebInspector.UIString("Frame Statistics"), WebInspector.TimelineUIUtils.generateDetailsContentForFrame(this._lazyFrameModel, frame));
+ if (frame.layerTree) {
+ var layersView = this._layersView();
+ layersView.showLayerTree(frame.layerTree);
+ this._detailsView.appendTab("layers", WebInspector.UIString("Layers"), layersView);
+ }
+ break;
+ }
+ },
+
+ _updateSelectedRangeStats: function()
+ {
+ if (this._selection)
+ return;
+
+ var startTime = this._windowStartTime;
+ var endTime = this._windowEndTime;
+
+ // Return early in case 0 selection window.
+ if (startTime < 0)
+ return;
+
+ var aggregatedStats = {};
+
+ /**
+ * @param {number} value
+ * @param {!WebInspector.TimelineModel.Record} task
+ * @return {number}
+ */
+ function compareEndTime(value, task)
+ {
+ return value < task.endTime() ? -1 : 1;
+ }
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ function aggregateTimeForRecordWithinWindow(record)
+ {
+ if (!record.endTime() || record.endTime() < startTime || record.startTime() > endTime)
+ return;
+
+ var childrenTime = 0;
+ var children = record.children() || [];
+ for (var i = 0; i < children.length; ++i) {
+ var child = children[i];
+ if (!child.endTime() || child.endTime() < startTime || child.startTime() > endTime)
+ continue;
+ childrenTime += Math.min(endTime, child.endTime()) - Math.max(startTime, child.startTime());
+ aggregateTimeForRecordWithinWindow(child);
+ }
+ var categoryName = record.category().name;
+ var ownTime = Math.min(endTime, record.endTime()) - Math.max(startTime, record.startTime()) - childrenTime;
+ aggregatedStats[categoryName] = (aggregatedStats[categoryName] || 0) + ownTime;
+ }
+
+ var mainThreadTasks = this._model.mainThreadTasks();
+ var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, mainThreadTasks, compareEndTime);
+ for (; taskIndex < mainThreadTasks.length; ++taskIndex) {
+ var task = mainThreadTasks[taskIndex];
+ if (task.startTime() > endTime)
+ break;
+ aggregateTimeForRecordWithinWindow(task);
+ }
+
+ var aggregatedTotal = 0;
+ for (var categoryName in aggregatedStats)
+ aggregatedTotal += aggregatedStats[categoryName];
+ aggregatedStats["idle"] = Math.max(0, endTime - startTime - aggregatedTotal);
+
+ var pieChartContainer = document.createElement("div");
+ pieChartContainer.classList.add("vbox", "timeline-range-summary");
+ var startOffset = startTime - this._model.minimumRecordTime();
+ var endOffset = endTime - this._model.minimumRecordTime();
+ var title = WebInspector.UIString("Range: %s \u2013 %s", Number.millisToString(startOffset), Number.millisToString(endOffset));
+
+ for (var i = 0; i < this._overviewControls.length; ++i) {
+ if (this._overviewControls[i] instanceof WebInspector.TimelinePowerOverview) {
+ var energy = this._overviewControls[i].calculateEnergy(startTime, endTime);
+ title += WebInspector.UIString(" Energy: %.2f Joules", energy);
+ break;
+ }
+ }
+ pieChartContainer.createChild("div").textContent = title;
+ pieChartContainer.appendChild(WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats));
+ this.showInDetails(WebInspector.UIString("Selected Range"), pieChartContainer);
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ select: function(selection)
+ {
+ this._detailsLinkifier.reset();
+ this._selection = selection;
+
+ for (var i = 0; i < this._currentViews.length; ++i) {
+ var view = this._currentViews[i];
+ view.setSelection(selection);
+ }
+ this._updateSelectionDetails();
+ },
+
+ /**
+ * @param {string} title
+ * @param {!Node} node
+ */
+ showInDetails: function(title, node)
+ {
+ this._detailsView.setContent(title, node);
+ },
+
+ __proto__: WebInspector.Panel.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TabbedPane}
+ */
+WebInspector.TimelineDetailsView = function()
+{
+ WebInspector.TabbedPane.call(this);
+
+ this._defaultDetailsView = new WebInspector.VBox();
+ this._defaultDetailsView.element.classList.add("timeline-details-view");
+ this._defaultDetailsContentElement = this._defaultDetailsView.element.createChild("div", "timeline-details-view-body");
+
+ this.appendTab("default", WebInspector.UIString("Details"), this._defaultDetailsView);
+
+ this.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+}
+
+WebInspector.TimelineDetailsView.prototype = {
+ /**
+ * @param {string} title
+ * @param {!Node} node
+ */
+ setContent: function(title, node)
+ {
+ this.changeTabTitle("default", WebInspector.UIString("Details: %s", title));
+ var otherTabs = this.otherTabs("default");
+ for (var i = 0; i < otherTabs.length; ++i)
+ this.closeTab(otherTabs[i]);
+ this._defaultDetailsContentElement.removeChildren();
+ this._defaultDetailsContentElement.appendChild(node);
+ },
+
+ /**
+ * @param {boolean} vertical
+ */
+ setVertical: function(vertical)
+ {
+ this._defaultDetailsContentElement.classList.toggle("hbox", !vertical);
+ this._defaultDetailsContentElement.classList.toggle("vbox", vertical);
+ },
+
+ /**
+ * @param {string} id
+ * @param {string} tabTitle
+ * @param {!WebInspector.View} view
+ * @param {string=} tabTooltip
+ */
+ appendTab: function(id, tabTitle, view, tabTooltip)
+ {
+ WebInspector.TabbedPane.prototype.appendTab.call(this, id, tabTitle, view, tabTooltip);
+ if (this._lastUserSelectedTabId === id)
+ this.selectTab(id);
+ },
+
+ _tabSelected: function(event)
+ {
+ if (!event.data.isUserGesture)
+ return;
+
+ this._lastUserSelectedTabId = event.data.tabId;
+ },
+
+ __proto__: WebInspector.TabbedPane.prototype
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineSelection = function()
+{
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.TimelineSelection.Type = {
+ Record: "Record",
+ Frame: "Frame",
+ TraceEvent: "TraceEvent",
+};
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {!WebInspector.TimelineSelection}
+ */
+WebInspector.TimelineSelection.fromRecord = function(record)
+{
+ var selection = new WebInspector.TimelineSelection();
+ selection._type = WebInspector.TimelineSelection.Type.Record;
+ selection._object = record;
+ return selection;
+}
+
+/**
+ * @param {!WebInspector.TimelineFrame} frame
+ * @return {!WebInspector.TimelineSelection}
+ */
+WebInspector.TimelineSelection.fromFrame = function(frame)
+{
+ var selection = new WebInspector.TimelineSelection();
+ selection._type = WebInspector.TimelineSelection.Type.Frame;
+ selection._object = frame;
+ return selection;
+}
+
+/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {!WebInspector.TimelineSelection}
+ */
+WebInspector.TimelineSelection.fromTraceEvent = function(event)
+{
+ var selection = new WebInspector.TimelineSelection();
+ selection._type = WebInspector.TimelineSelection.Type.TraceEvent;
+ selection._object = event;
+ return selection;
+}
+
+WebInspector.TimelineSelection.prototype = {
+ /**
+ * @return {!WebInspector.TimelineSelection.Type}
+ */
+ type: function()
+ {
+ return this._type;
+ },
+
+ /**
+ * @return {!Object}
+ */
+ object: function()
+ {
+ return this._object;
+ }
+};
+
+/**
+ * @interface
+ * @extends {WebInspector.EventTarget}
+ */
+WebInspector.TimelineModeView = function()
+{
+}
+
+WebInspector.TimelineModeView.prototype = {
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function() {},
+
+ dispose: function() {},
+
+ reset: function() {},
+
+ /**
+ * @param {?RegExp} textFilter
+ */
+ refreshRecords: function(textFilter) {},
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record) {},
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord) {},
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime) {},
+
+ /**
+ * @param {number} width
+ */
+ setSidebarSize: function(width) {},
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ setSelection: function(selection) {},
+}
+
+/**
+ * @interface
+ */
+WebInspector.TimelineModeViewDelegate = function() {}
+
+WebInspector.TimelineModeViewDelegate.prototype = {
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ requestWindowTimes: function(startTime, endTime) {},
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ select: function(selection) {},
+
+ /**
+ * @param {string} title
+ * @param {!Node} node
+ */
+ showInDetails: function(title, node) {},
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineModel.Filter}
+ */
+WebInspector.TimelineCategoryFilter = function()
+{
+ WebInspector.TimelineModel.Filter.call(this);
+}
+
+WebInspector.TimelineCategoryFilter.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return !record.category().hidden;
+ },
+
+ __proto__: WebInspector.TimelineModel.Filter.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineModel.Filter}
+ */
+WebInspector.TimelineIsLongFilter = function()
+{
+ WebInspector.TimelineModel.Filter.call(this);
+ this._minimumRecordDuration = 0;
+}
+
+WebInspector.TimelineIsLongFilter.prototype = {
+ /**
+ * @param {number} value
+ */
+ setMinimumRecordDuration: function(value)
+ {
+ this._minimumRecordDuration = value;
+ this.notifyFilterChanged();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return this._minimumRecordDuration ? ((record.endTime() - record.startTime()) >= this._minimumRecordDuration) : true;
+ },
+
+ __proto__: WebInspector.TimelineModel.Filter.prototype
+
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineModel.Filter}
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
+ */
+WebInspector.TimelineTextFilter = function(uiUtils)
+{
+ WebInspector.TimelineModel.Filter.call(this);
+ this._uiUtils = uiUtils;
+}
+
+WebInspector.TimelineTextFilter.prototype = {
+ /**
+ * @return {boolean}
+ */
+ isEmpty: function()
+ {
+ return !this._regex;
+ },
+
+ /**
+ * @param {?RegExp} regex
+ */
+ setRegex: function(regex)
+ {
+ this._regex = regex;
+ this.notifyFilterChanged();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return !this._regex || this._uiUtils.testContentMatching(record, this._regex);
+ },
+
+ __proto__: WebInspector.TimelineModel.Filter.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineModel.Filter}
+ */
+WebInspector.TimelineHiddenFilter = function()
+{
+ WebInspector.TimelineModel.Filter.call(this);
+ this._hiddenRecords = {};
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkDOMContent] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkLoad] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.MarkFirstPaint] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.GPUTask] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.ScheduleStyleRecalculation] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.InvalidateLayout] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.RequestMainThreadFrame] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.ActivateLayerTree] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.DrawFrame] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.BeginFrame] = 1;
+ this._hiddenRecords[WebInspector.TimelineModel.RecordType.UpdateCounters] = 1;
+}
+
+WebInspector.TimelineHiddenFilter.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ accept: function(record)
+ {
+ return !this._hiddenRecords[record.type()];
+ },
+
+ __proto__: WebInspector.TimelineModel.Filter.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerGraph.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerGraph.js
new file mode 100644
index 00000000000..dbe20d7d61d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerGraph.js
@@ -0,0 +1,50 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.CountersGraph}
+ * @implements {WebInspector.TimelineModeView}
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TimelineModel} model
+ */
+WebInspector.TimelinePowerGraph = function(delegate, model)
+{
+ WebInspector.CountersGraph.call(this, WebInspector.UIString("POWER"), delegate, model);
+
+ this._counter = this.createCounter(WebInspector.UIString("Power"), WebInspector.UIString("Power: %.2f\u2009watts"), "#d00");
+ WebInspector.powerProfiler.addEventListener(WebInspector.PowerProfiler.EventTypes.PowerEventRecorded, this._onRecordAdded, this);
+}
+
+WebInspector.TimelinePowerGraph.prototype = {
+ dispose: function()
+ {
+ WebInspector.CountersGraph.prototype.dispose.call(this);
+ WebInspector.powerProfiler.removeEventListener(WebInspector.PowerProfiler.EventTypes.PowerEventRecorded, this._onRecordAdded, this);
+ },
+
+ _onRecordAdded: function(event)
+ {
+ var record = event.data;
+ if (!this._previousRecord) {
+ this._previousRecord = record;
+ return;
+ }
+
+ // "value" of original PowerEvent means the average power between previous sampling to current one.
+ // Here, it is converted to average power between current sampling to next one.
+ this._counter.appendSample(this._previousRecord.timestamp, record.value);
+ this._previousRecord = record;
+ this.scheduleRefresh();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ },
+
+ __proto__: WebInspector.CountersGraph.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerOverview.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerOverview.js
new file mode 100644
index 00000000000..b6bfe15b53a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePowerOverview.js
@@ -0,0 +1,217 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.TimelinePowerOverviewDataProvider = function()
+{
+ this._records = [];
+ this._energies = [];
+ this._times = [];
+ WebInspector.powerProfiler.addEventListener(WebInspector.PowerProfiler.EventTypes.PowerEventRecorded, this._onRecordAdded, this);
+}
+
+WebInspector.TimelinePowerOverviewDataProvider.prototype = {
+ dispose: function()
+ {
+ WebInspector.powerProfiler.removeEventListener(WebInspector.PowerProfiler.EventTypes.PowerEventRecorded, this._onRecordAdded, this);
+ },
+
+ /**
+ * @return {!Array.<!PowerAgent.PowerEvent>}
+ */
+ records : function()
+ {
+ // The last record is not used, as its "value" is not set.
+ return this._records.slice(0, this._records.length - 1);
+ },
+
+ /**
+ * @param {number} minTime
+ * @param {number} maxTime
+ * @return {number} energy in joules.
+ */
+ _calculateEnergy : function(minTime, maxTime)
+ {
+ var times = this._times;
+ var energies = this._energies;
+ var last = times.length - 1;
+
+ if (last < 1 || minTime >= times[last] || maxTime <= times[0])
+ return 0;
+
+ // Maximum index of element whose time <= minTime.
+ var start = Number.constrain(times.upperBound(minTime) - 1, 0, last);
+
+ // Minimum index of element whose time >= maxTime.
+ var end = Number.constrain(times.lowerBound(maxTime), 0, last);
+
+ var startTime = minTime < times[0] ? times[0] : minTime;
+ var endTime = maxTime > times[last] ? times[last] : maxTime;
+
+ if (start + 1 === end)
+ return (endTime - startTime) / (times[end] - times[start]) * (energies[end] - energies[start]) / 1000;
+
+ var totalEnergy = 0;
+ totalEnergy += energies[end - 1] - energies[start + 1];
+ totalEnergy += (times[start + 1] - startTime) / (times[start + 1] - times[start]) * (energies[start + 1] - energies[start]);
+ totalEnergy += (endTime - times[end - 1]) / (times[end] - times[end - 1]) * (energies[end] - energies[end - 1]);
+ return totalEnergy / 1000;
+ },
+
+ _onRecordAdded: function(event)
+ {
+ // "value" of original PowerEvent means the average power between previous sampling to current one.
+ // Here, it is converted to average power between current sampling to next one.
+ var record = event.data;
+ var curTime = record.timestamp;
+ var length = this._records.length;
+ var accumulatedEnergy = 0;
+ if (length) {
+ this._records[length - 1].value = record.value;
+
+ var prevTime = this._records[length - 1].timestamp;
+ accumulatedEnergy = this._energies[length - 1];
+ accumulatedEnergy += (curTime - prevTime) * record.value;
+ }
+ this._energies.push(accumulatedEnergy);
+ this._records.push(record);
+ this._times.push(curTime);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineOverviewBase}
+ * @param {!WebInspector.TimelineModel} model
+ */
+WebInspector.TimelinePowerOverview = function(model)
+{
+ WebInspector.TimelineOverviewBase.call(this, model);
+ this.element.id = "timeline-overview-power";
+ this._dataProvider = new WebInspector.TimelinePowerOverviewDataProvider();
+
+ this._maxPowerLabel = this.element.createChild("div", "max memory-graph-label");
+ this._minPowerLabel = this.element.createChild("div", "min memory-graph-label");
+}
+
+WebInspector.TimelinePowerOverview.prototype = {
+ dispose: function()
+ {
+ this._dataProvider.dispose();
+ },
+
+ timelineStarted: function()
+ {
+ if (Capabilities.canProfilePower)
+ WebInspector.powerProfiler.startProfile();
+ },
+
+ timelineStopped: function()
+ {
+ if (Capabilities.canProfilePower)
+ WebInspector.powerProfiler.stopProfile();
+ },
+
+ _resetPowerLabels: function()
+ {
+ this._maxPowerLabel.textContent = "";
+ this._minPowerLabel.textContent = "";
+ },
+
+ update: function()
+ {
+ this.resetCanvas();
+
+ var records = this._dataProvider.records();
+ if (!records.length) {
+ this._resetPowerLabels();
+ return;
+ }
+
+ const lowerOffset = 3;
+ var maxPower = 0;
+ var minPower = 100000000000;
+ var minTime = this._model.minimumRecordTime();
+ var maxTime = this._model.maximumRecordTime();
+ for (var i = 0; i < records.length; i++) {
+ var record = records[i];
+ if (record.timestamp < minTime || record.timestamp > maxTime)
+ continue;
+ maxPower = Math.max(maxPower, record.value);
+ minPower = Math.min(minPower, record.value);
+ }
+ minPower = Math.min(minPower, maxPower);
+
+
+ var width = this._canvas.width;
+ var height = this._canvas.height - lowerOffset;
+ var xFactor = width / (maxTime - minTime);
+ var yFactor = height / Math.max(maxPower - minPower, 1);
+
+ var histogram = new Array(width);
+ for (var i = 0; i < records.length - 1; i++) {
+ var record = records[i];
+ if (record.timestamp < minTime || record.timestamp > maxTime)
+ continue;
+ var x = Math.round((record.timestamp - minTime) * xFactor);
+ var y = Math.round((record.value- minPower ) * yFactor);
+ histogram[x] = Math.max(histogram[x] || 0, y);
+ }
+
+ var y = 0;
+ var isFirstPoint = true;
+ var ctx = this._context;
+ ctx.save();
+ ctx.translate(0.5, 0.5);
+ ctx.beginPath();
+ ctx.moveTo(-1, this._canvas.height);
+ for (var x = 0; x < histogram.length; x++) {
+ if (typeof histogram[x] === "undefined")
+ continue;
+ if (isFirstPoint) {
+ isFirstPoint = false;
+ y = histogram[x];
+ ctx.lineTo(-1, height - y);
+ }
+ ctx.lineTo(x, height - y);
+ y = histogram[x];
+ ctx.lineTo(x, height - y);
+ }
+
+ ctx.lineTo(width, height - y);
+ ctx.lineTo(width, this._canvas.height);
+ ctx.lineTo(-1, this._canvas.height);
+ ctx.closePath();
+
+ ctx.fillStyle = "rgba(255,192,0, 0.8);";
+ ctx.fill();
+
+ ctx.lineWidth = 0.5;
+ ctx.strokeStyle = "rgba(20,0,0,0.8)";
+ ctx.stroke();
+ ctx.restore();
+
+ this._maxPowerLabel.textContent = WebInspector.UIString("%.2f\u2009watts", maxPower);
+ this._minPowerLabel.textContent = WebInspector.UIString("%.2f\u2009watts", minPower);
+ },
+
+ /**
+ * @param {number} minTime
+ * @param {number} maxTime
+ * @return {number} energy in joules.
+ */
+ calculateEnergy: function(minTime, maxTime)
+ {
+ return this._dataProvider._calculateEnergy(minTime, maxTime);
+ },
+
+ __proto__: WebInspector.TimelineOverviewBase.prototype
+}
+
+
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePresentationModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePresentationModel.js
new file mode 100644
index 00000000000..b5b23bcd054
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePresentationModel.js
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Intel Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
+ */
+WebInspector.TimelinePresentationModel = function(model, uiUtils)
+{
+ this._model = model;
+ this._uiUtils = uiUtils;
+ this._filters = [];
+ /**
+ * @type {!Map.<!WebInspector.TimelineModel.Record, !WebInspector.TimelinePresentationModel.Record>}
+ */
+ this._recordToPresentationRecord = new Map();
+ this.reset();
+}
+
+WebInspector.TimelinePresentationModel.prototype = {
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._windowStartTime = startTime;
+ this._windowEndTime = endTime;
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @return {?WebInspector.TimelinePresentationModel.Record}
+ */
+ toPresentationRecord: function(record)
+ {
+ return record ? this._recordToPresentationRecord.get(record) || null : null;
+ },
+
+ /**
+ * @return {!WebInspector.TimelinePresentationModel.Record}
+ */
+ rootRecord: function()
+ {
+ return this._rootRecord;
+ },
+
+ reset: function()
+ {
+ this._recordToPresentationRecord.clear();
+ this._rootRecord = new WebInspector.TimelinePresentationModel.RootRecord();
+ /** @type {!Object.<string, !WebInspector.TimelinePresentationModel.Record>} */
+ this._coalescingBuckets = {};
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ if (this._uiUtils.isProgram(record)) {
+ var records = record.children();
+ for (var i = 0; i < records.length; ++i)
+ this._innerAddRecord(this._rootRecord, records[i]);
+ } else {
+ this._innerAddRecord(this._rootRecord, record);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} parentRecord
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ _innerAddRecord: function(parentRecord, record)
+ {
+ var coalescingBucket;
+
+ // On main thread, only coalesce if the last event is of same type.
+ if (parentRecord === this._rootRecord)
+ coalescingBucket = record.thread() ? record.type() : "mainThread";
+ var coalescedRecord = this._findCoalescedParent(record, parentRecord, coalescingBucket);
+ if (coalescedRecord)
+ parentRecord = coalescedRecord;
+
+ var formattedRecord = new WebInspector.TimelinePresentationModel.ActualRecord(record, parentRecord);
+ this._recordToPresentationRecord.put(record, formattedRecord);
+
+ formattedRecord._collapsed = parentRecord === this._rootRecord;
+ if (coalescingBucket)
+ this._coalescingBuckets[coalescingBucket] = formattedRecord;
+
+ for (var i = 0; record.children() && i < record.children().length; ++i)
+ this._innerAddRecord(formattedRecord, record.children()[i]);
+
+ if (parentRecord.coalesced())
+ this._updateCoalescingParent(formattedRecord);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelinePresentationModel.Record} newParent
+ * @param {string=} bucket
+ * @return {?WebInspector.TimelinePresentationModel.Record}
+ */
+ _findCoalescedParent: function(record, newParent, bucket)
+ {
+ const coalescingThresholdMillis = 5;
+
+ var lastRecord = bucket ? this._coalescingBuckets[bucket] : newParent._presentationChildren.peekLast();
+ if (lastRecord && lastRecord.coalesced())
+ lastRecord = lastRecord._presentationChildren.peekLast();
+ var startTime = record.startTime();
+ var endTime = record.endTime();
+ if (!lastRecord)
+ return null;
+ if (lastRecord.record().type() !== record.type())
+ return null;
+ if (!this._uiUtils.isCoalescable(record.type()))
+ return null;
+ if (lastRecord.record().endTime() + coalescingThresholdMillis < startTime)
+ return null;
+ if (endTime + coalescingThresholdMillis < lastRecord.record().startTime())
+ return null;
+ if (lastRecord.presentationParent().coalesced())
+ return lastRecord.presentationParent();
+ return this._replaceWithCoalescedRecord(lastRecord);
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} presentationRecord
+ * @return {!WebInspector.TimelinePresentationModel.Record}
+ */
+ _replaceWithCoalescedRecord: function(presentationRecord)
+ {
+ var record = presentationRecord.record();
+ var parent = presentationRecord._presentationParent;
+ var coalescedRecord = new WebInspector.TimelinePresentationModel.CoalescedRecord(record);
+
+ coalescedRecord._collapsed = true;
+ coalescedRecord._presentationChildren.push(presentationRecord);
+ presentationRecord._presentationParent = coalescedRecord;
+ if (presentationRecord.hasWarnings() || presentationRecord.childHasWarnings())
+ coalescedRecord._childHasWarnings = true;
+
+ coalescedRecord._presentationParent = parent;
+ parent._presentationChildren[parent._presentationChildren.indexOf(presentationRecord)] = coalescedRecord;
+ WebInspector.TimelineUIUtils.aggregateTimeByCategory(coalescedRecord.presentationAggregatedStats(), presentationRecord.presentationAggregatedStats());
+
+ return coalescedRecord;
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} presentationRecord
+ */
+ _updateCoalescingParent: function(presentationRecord)
+ {
+ var parentRecord = presentationRecord._presentationParent;
+ WebInspector.TimelineUIUtils.aggregateTimeByCategory(parentRecord.presentationAggregatedStats(), presentationRecord.presentationAggregatedStats());
+ if (parentRecord.endTime() < presentationRecord.endTime())
+ parentRecord._endTime = presentationRecord.endTime();
+ },
+
+ /**
+ * @param {?RegExp} textFilter
+ */
+ setTextFilter: function(textFilter)
+ {
+ this._textFilter = textFilter;
+ },
+
+ invalidateFilteredRecords: function()
+ {
+ delete this._filteredRecords;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
+ */
+ filteredRecords: function()
+ {
+ if (this._filteredRecords)
+ return this._filteredRecords;
+
+ var recordsInWindow = [];
+
+ var stack = [{children: this._rootRecord._presentationChildren, index: 0, parentIsCollapsed: false, parentRecord: {}}];
+ var revealedDepth = 0;
+
+ function revealRecordsInStack() {
+ for (var depth = revealedDepth + 1; depth < stack.length; ++depth) {
+ if (stack[depth - 1].parentIsCollapsed) {
+ stack[depth].parentRecord._presentationParent._expandable = true;
+ return;
+ }
+ stack[depth - 1].parentRecord._collapsed = false;
+ recordsInWindow.push(stack[depth].parentRecord);
+ stack[depth].windowLengthBeforeChildrenTraversal = recordsInWindow.length;
+ stack[depth].parentIsRevealed = true;
+ revealedDepth = depth;
+ }
+ }
+
+ while (stack.length) {
+ var entry = stack[stack.length - 1];
+ var records = entry.children;
+ if (records && entry.index < records.length) {
+ var record = records[entry.index];
+ ++entry.index;
+ if (record.startTime() < this._windowEndTime && record.endTime() > this._windowStartTime) {
+ if (this._model.isVisible(record.record())) {
+ record._presentationParent._expandable = true;
+ if (this._textFilter)
+ revealRecordsInStack();
+ if (!entry.parentIsCollapsed) {
+ recordsInWindow.push(record);
+ revealedDepth = stack.length;
+ entry.parentRecord._collapsed = false;
+ }
+ }
+ }
+
+ record._expandable = false;
+
+ stack.push({children: record._presentationChildren,
+ index: 0,
+ parentIsCollapsed: entry.parentIsCollapsed || (record._collapsed && (!this._textFilter || record._expandedOrCollapsedWhileFiltered)),
+ parentRecord: record,
+ windowLengthBeforeChildrenTraversal: recordsInWindow.length});
+ } else {
+ stack.pop();
+ revealedDepth = Math.min(revealedDepth, stack.length - 1);
+ entry.parentRecord._visibleChildrenCount = recordsInWindow.length - entry.windowLengthBeforeChildrenTraversal;
+ }
+ }
+
+ this._filteredRecords = recordsInWindow;
+ return recordsInWindow;
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord
+ */
+WebInspector.TimelinePresentationModel.Record = function(parentRecord)
+{
+ /**
+ * @type {!Array.<!WebInspector.TimelinePresentationModel.Record>}
+ */
+ this._presentationChildren = [];
+
+ if (parentRecord) {
+ this._presentationParent = parentRecord;
+ parentRecord._presentationChildren.push(this);
+ }
+}
+
+WebInspector.TimelinePresentationModel.Record.prototype = {
+ /**
+ * @return {number}
+ */
+ startTime: function()
+ {
+ throw new Error("Not implemented.");
+ },
+
+ /**
+ * @return {number}
+ */
+ endTime: function()
+ {
+ throw new Error("Not implemented.");
+ },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function()
+ {
+ throw new Error("Not implemented.");
+ },
+
+ /**
+ * @return {!WebInspector.TimelineModel.Record}
+ */
+ record: function()
+ {
+ throw new Error("Not implemented.");
+ },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ presentationAggregatedStats: function()
+ {
+ throw new Error("Not implemented.");
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelinePresentationModel.Record>}
+ */
+ presentationChildren: function()
+ {
+ return this._presentationChildren;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ coalesced: function()
+ {
+ return false;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ collapsed: function()
+ {
+ return this._collapsed;
+ },
+
+ /**
+ * @param {boolean} collapsed
+ */
+ setCollapsed: function(collapsed)
+ {
+ this._collapsed = collapsed;
+ this._expandedOrCollapsedWhileFiltered = true;
+ },
+
+ /**
+ * @return {?WebInspector.TimelinePresentationModel.Record}
+ */
+ presentationParent: function()
+ {
+ return this._presentationParent || null;
+ },
+
+ /**
+ * @return {number}
+ */
+ visibleChildrenCount: function()
+ {
+ return this._visibleChildrenCount || 0;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ expandable: function()
+ {
+ return !!this._expandable;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasWarnings: function()
+ {
+ return false;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ childHasWarnings: function()
+ {
+ return this._childHasWarnings;
+ },
+
+ /**
+ * @return {?WebInspector.TimelineRecordListRow}
+ */
+ listRow: function()
+ {
+ return this._listRow;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineRecordListRow} listRow
+ */
+ setListRow: function(listRow)
+ {
+ this._listRow = listRow;
+ },
+
+ /**
+ * @return {?WebInspector.TimelineRecordGraphRow}
+ */
+ graphRow: function()
+ {
+ return this._graphRow;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineRecordGraphRow} graphRow
+ */
+ setGraphRow: function(graphRow)
+ {
+ this._graphRow = graphRow;
+ }
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelinePresentationModel.Record}
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {?WebInspector.TimelinePresentationModel.Record} parentRecord
+ */
+WebInspector.TimelinePresentationModel.ActualRecord = function(record, parentRecord)
+{
+ WebInspector.TimelinePresentationModel.Record.call(this, parentRecord);
+ this._record = record;
+
+ if (this.hasWarnings()) {
+ for (var parent = this._presentationParent; parent && !parent._childHasWarnings; parent = parent._presentationParent)
+ parent._childHasWarnings = true;
+ }
+}
+
+WebInspector.TimelinePresentationModel.ActualRecord.prototype = {
+ /**
+ * @return {number}
+ */
+ startTime: function()
+ {
+ return this._record.startTime();
+ },
+
+ /**
+ * @return {number}
+ */
+ endTime: function()
+ {
+ return this._record.endTime();
+ },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function()
+ {
+ return this._record.selfTime();
+ },
+
+ /**
+ * @return {!WebInspector.TimelineModel.Record}
+ */
+ record: function()
+ {
+ return this._record;
+ },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ presentationAggregatedStats: function()
+ {
+ return this._record.aggregatedStats();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasWarnings: function()
+ {
+ return !!this._record.warnings();
+ },
+
+ __proto__: WebInspector.TimelinePresentationModel.Record.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelinePresentationModel.Record}
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+WebInspector.TimelinePresentationModel.CoalescedRecord = function(record)
+{
+ WebInspector.TimelinePresentationModel.Record.call(this, null);
+ this._startTime = record.startTime();
+ this._endTime = record.endTime();
+ this._aggregatedStats = {};
+}
+
+WebInspector.TimelinePresentationModel.CoalescedRecord.prototype = {
+ /**
+ * @return {number}
+ */
+ startTime: function()
+ {
+ return this._startTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ endTime: function()
+ {
+ return this._endTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @return {!WebInspector.TimelineModel.Record}
+ */
+ record: function()
+ {
+ return this._presentationChildren[0].record();
+ },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ presentationAggregatedStats: function()
+ {
+ return this._aggregatedStats;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ coalesced: function()
+ {
+ return true;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasWarnings: function()
+ {
+ return false;
+ },
+
+ __proto__: WebInspector.TimelinePresentationModel.Record.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelinePresentationModel.Record}
+ */
+WebInspector.TimelinePresentationModel.RootRecord = function()
+{
+ WebInspector.TimelinePresentationModel.Record.call(this, null);
+ this._aggregatedStats = {};
+}
+
+WebInspector.TimelinePresentationModel.RootRecord.prototype = {
+ /**
+ * @return {!Object.<string, number>}
+ */
+ presentationAggregatedStats: function()
+ {
+ return this._aggregatedStats;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasWarnings: function()
+ {
+ return false;
+ },
+
+ __proto__: WebInspector.TimelinePresentationModel.Record.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTracingView.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTracingView.js
new file mode 100644
index 00000000000..24e6fd763d7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineTracingView.js
@@ -0,0 +1,556 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineModeView}
+ * @implements {WebInspector.FlameChartDelegate}
+ * @extends {WebInspector.VBox}
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TracingModel} tracingModel
+ * @param {!WebInspector.TimelineModel} modelForMinimumBoundary
+ */
+WebInspector.TimelineTracingView = function(delegate, tracingModel, modelForMinimumBoundary)
+{
+ WebInspector.VBox.call(this);
+ this._delegate = delegate;
+ this._tracingModel = tracingModel;
+ this.element.classList.add("timeline-flamechart");
+ this.registerRequiredCSS("flameChart.css");
+ this._dataProvider = new WebInspector.TraceViewFlameChartDataProvider(this._tracingModel, modelForMinimumBoundary);
+ this._mainView = new WebInspector.FlameChart(this._dataProvider, this, true);
+ this._mainView.show(this.element);
+ this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
+}
+
+WebInspector.TimelineTracingView.prototype = {
+ /**
+ * @param {number} windowStartTime
+ * @param {number} windowEndTime
+ */
+ requestWindowTimes: function(windowStartTime, windowEndTime)
+ {
+ this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
+ },
+
+ wasShown: function()
+ {
+ this._mainView._scheduleUpdate();
+ },
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function()
+ {
+ return this;
+ },
+
+ dispose: function()
+ {
+ },
+
+ reset: function()
+ {
+ this._dataProvider.reset();
+ this._mainView.setWindowTimes(0, Infinity);
+ },
+
+ /**
+ * @param {?RegExp} textFilter
+ */
+ refreshRecords: function(textFilter)
+ {
+ this._dataProvider.reset();
+ this._mainView._scheduleUpdate();
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record) {},
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord) {},
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._mainView.setWindowTimes(startTime, endTime);
+ },
+
+ /**
+ * @param {number} width
+ */
+ setSidebarSize: function(width) {},
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ setSelection: function(selection) {},
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onEntrySelected: function(event)
+ {
+ var index = /** @type {number} */ (event.data);
+ var record = this._dataProvider._recordAt(index);
+ if (!record || this._dataProvider._isHeaderRecord(record)) {
+ this._delegate.showInDetails("", document.createTextNode(""));
+ return;
+ }
+ var contentHelper = new WebInspector.TimelineDetailsContentHelper(null, null, false);
+ contentHelper.appendTextRow(WebInspector.UIString("Name"), record.name);
+ contentHelper.appendTextRow(WebInspector.UIString("Category"), record.category);
+ contentHelper.appendTextRow(WebInspector.UIString("Start"), Number.millisToString(record.startTime - this._tracingModel.minimumRecordTime(), true));
+ contentHelper.appendTextRow(WebInspector.UIString("Duration"), Number.millisToString(record.duration, true));
+ if (!Object.isEmpty(record.args))
+ contentHelper.appendElementRow(WebInspector.UIString("Arguments"), this._formatArguments(record.args));
+ /**
+ * @this {WebInspector.TimelineTracingView}
+ */
+ function reveal()
+ {
+ WebInspector.Revealer.reveal(new WebInspector.DeferredTracingLayerTree(this._tracingModel.target(), record.args["snapshot"]["active_tree"]["root_layer"], record.args["snapshot"]["device_viewport_size"]));
+ }
+ /**
+ * @param {!Node=} node
+ * @this {WebInspector.TimelineTracingView}
+ */
+ function appendPreviewAndshowDetails(node)
+ {
+ if (node)
+ contentHelper.appendElementRow("Preview", node);
+ this._delegate.showInDetails(WebInspector.UIString("Selected Event"), contentHelper.element);
+ }
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+ switch (record.name) {
+ case recordTypes.PictureSnapshot:
+ WebInspector.TracingTimelineUIUtils._buildPicturePreviewContent(record.args["snapshot"]["skp64"], appendPreviewAndshowDetails.bind(this));
+ break;
+ case recordTypes.LayerTreeHostImplSnapshot:
+ var link = document.createElement("span");
+ link.classList.add("revealable-link");
+ link.textContent = "show";
+ link.addEventListener("click", reveal.bind(this), false);
+ contentHelper.appendElementRow(WebInspector.UIString("Layer tree"), link);
+ // Fall-through intended.
+ default:
+ this._delegate.showInDetails(WebInspector.UIString("Selected Event"), contentHelper.element);
+ }
+ },
+
+ /**
+ * @param {!Object} args
+ * @return {!Element}
+ */
+ _formatArguments: function(args)
+ {
+ var table = document.createElement("table");
+ for (var name in args) {
+ var row = table.createChild("tr");
+ row.createChild("td", "timeline-details-row-title").textContent = name + ":";
+ var valueContainer = row.createChild("td", "timeline-details-row-data");
+ var value = args[name];
+ if (typeof value === "object" && value) {
+ var localObject = new WebInspector.LocalJSONObject(value);
+ var propertiesSection = new WebInspector.ObjectPropertiesSection(localObject, localObject.description);
+ valueContainer.appendChild(propertiesSection.element);
+ } else {
+ valueContainer.textContent = String(value);
+ }
+ }
+ return table;
+ },
+
+ __proto__: WebInspector.VBox.prototype
+};
+
+/**
+ * @constructor
+ * @implements {WebInspector.FlameChartDataProvider}
+ * @param {!WebInspector.TracingModel} model
+ * @param {!WebInspector.TimelineModel} timelineModelForMinimumBoundary
+ */
+WebInspector.TraceViewFlameChartDataProvider = function(model, timelineModelForMinimumBoundary)
+{
+ WebInspector.FlameChartDataProvider.call(this);
+ this._model = model;
+ this._timelineModelForMinimumBoundary = timelineModelForMinimumBoundary;
+ this._font = "12px " + WebInspector.fontFamily();
+ this._palette = new WebInspector.TraceViewPalette();
+ var dummyEventPayload = {
+ cat: "dummy",
+ pid: 0,
+ tid: 0,
+ ts: 0,
+ ph: "dummy",
+ name: "dummy",
+ args: {},
+ dur: 0,
+ id: 0,
+ s: ""
+ }
+ this._processHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0, null);
+ this._threadHeaderRecord = new WebInspector.TracingModel.Event(dummyEventPayload, 0, null);
+}
+
+WebInspector.TraceViewFlameChartDataProvider.prototype = {
+ /**
+ * @return {number}
+ */
+ barHeight: function()
+ {
+ return 20;
+ },
+
+ /**
+ * @return {number}
+ */
+ textBaseline: function()
+ {
+ return 6;
+ },
+
+ /**
+ * @return {number}
+ */
+ textPadding: function()
+ {
+ return 5;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryFont: function(entryIndex)
+ {
+ return this._font;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?string}
+ */
+ entryTitle: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (this._isHeaderRecord(record))
+ return this._headerTitles[entryIndex]
+ return record.name;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ * @return {?Array.<number>}
+ */
+ dividerOffsets: function(startTime, endTime)
+ {
+ return null;
+ },
+
+ reset: function()
+ {
+ this._timelineData = null;
+ /** @type {!Array.<!WebInspector.TracingModel.Event>} */
+ this._records = [];
+ },
+
+ /**
+ * @return {!WebInspector.FlameChart.TimelineData}
+ */
+ timelineData: function()
+ {
+ if (this._timelineData)
+ return this._timelineData;
+
+ /**
+ * @type {?WebInspector.FlameChart.TimelineData}
+ */
+ this._timelineData = {
+ entryLevels: [],
+ entryTotalTimes: [],
+ entryStartTimes: []
+ };
+
+ this._currentLevel = 0;
+ this._headerTitles = {};
+ this._minimumBoundary = this._timelineModelForMinimumBoundary.minimumRecordTime();
+ this._timeSpan = Math.max(this._model.maximumRecordTime() - this._minimumBoundary, 1000);
+ var processes = this._model.sortedProcesses();
+ for (var processIndex = 0; processIndex < processes.length; ++processIndex) {
+ var process = processes[processIndex];
+ this._appendHeaderRecord(process.name(), this._processHeaderRecord);
+ var objectNames = process.sortedObjectNames();
+ for (var objectNameIndex = 0; objectNameIndex < objectNames.length; ++objectNameIndex) {
+ this._appendHeaderRecord(WebInspector.UIString("Object %s", objectNames[objectNameIndex]), this._threadHeaderRecord);
+ var objects = process.objectsByName(objectNames[objectNameIndex]);
+ for (var objectIndex = 0; objectIndex < objects.length; ++objectIndex)
+ this._appendRecord(objects[objectIndex], 0);
+ ++this._currentLevel;
+ }
+ var threads = process.sortedThreads();
+ for (var threadIndex = 0; threadIndex < threads.length; ++threadIndex) {
+ this._appendHeaderRecord(threads[threadIndex].name(), this._threadHeaderRecord);
+ var events = threads[threadIndex].events();
+ for (var eventIndex = 0; eventIndex < events.length; ++eventIndex) {
+ var event = events[eventIndex];
+ if (event.duration)
+ this._appendRecord(event, event.level);
+ }
+ this._currentLevel += threads[threadIndex].maxStackDepth();
+ }
+ ++this._currentLevel;
+ }
+ return this._timelineData;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundary;
+ },
+
+ /**
+ * @return {number}
+ */
+ totalTime: function()
+ {
+ return this._timeSpan;
+ },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function()
+ {
+ return this._currentLevel;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?Array.<!{title: string, text: string}>}
+ */
+ prepareHighlightedEntryInfo: function(entryIndex)
+ {
+ return null;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ canJumpToEntry: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ return record.phase === WebInspector.TracingModel.Phase.SnapshotObject;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ entryColor: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (record.phase === WebInspector.TracingModel.Phase.SnapshotObject)
+ return "rgb(20, 150, 20)";
+ if (record === this._processHeaderRecord)
+ return "#555";
+ if (record === this._threadHeaderRecord)
+ return "#777";
+ return this._palette.colorForString(record.name);
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @param {!CanvasRenderingContext2D} context
+ * @param {?string} text
+ * @param {number} barX
+ * @param {number} barY
+ * @param {number} barWidth
+ * @param {number} barHeight
+ * @param {function(number):number} timeToPosition
+ * @return {boolean}
+ */
+ decorateEntry: function(entryIndex, context, text, barX, barY, barWidth, barHeight, timeToPosition)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {boolean}
+ */
+ forceDecoration: function(entryIndex)
+ {
+ return false;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {?{startTime: number, endTime: number}}
+ */
+ highlightTimeRange: function(entryIndex)
+ {
+ var record = this._records[entryIndex];
+ if (!record || this._isHeaderRecord(record))
+ return null;
+ return {
+ startTime: record.startTime,
+ endTime: record.endTime
+ }
+ },
+
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return 0;
+ },
+
+ /**
+ * @param {number} entryIndex
+ * @return {string}
+ */
+ textColor: function(entryIndex)
+ {
+ return "white";
+ },
+
+ /**
+ * @param {string} title
+ * @param {!WebInspector.TracingModel.Event} record
+ */
+ _appendHeaderRecord: function(title, record)
+ {
+ var index = this._records.length;
+ this._records.push(record);
+ this._timelineData.entryLevels[index] = this._currentLevel++;
+ this._timelineData.entryTotalTimes[index] = this.totalTime();
+ this._timelineData.entryStartTimes[index] = this._minimumBoundary;
+ this._headerTitles[index] = title;
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} record
+ * @param {number} level
+ */
+ _appendRecord: function(record, level)
+ {
+ var index = this._records.length;
+ this._records.push(record);
+ this._timelineData.entryLevels[index] = this._currentLevel + level;
+ this._timelineData.entryTotalTimes[index] = record.phase === WebInspector.TracingModel.Phase.SnapshotObject ? NaN : record.duration || 0;
+ this._timelineData.entryStartTimes[index] = record.startTime;
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} record
+ */
+ _isHeaderRecord: function(record)
+ {
+ return record === this._threadHeaderRecord || record === this._processHeaderRecord;
+ },
+
+ /**
+ * @param {number} index
+ * @return {!WebInspector.TracingModel.Event|undefined}
+ */
+ _recordAt: function(index)
+ {
+ return this._records[index];
+ }
+}
+
+// The below logic is shamelessly stolen from https://code.google.com/p/trace-viewer/source/browse/trunk/trace_viewer/tracing/color_scheme.js
+
+/**
+ * @constructor
+ */
+WebInspector.TraceViewPalette = function()
+{
+ this._palette = WebInspector.TraceViewPalette._paletteBase.map(WebInspector.TraceViewPalette._rgbToString);
+}
+
+WebInspector.TraceViewPalette._paletteBase = [
+ [138, 113, 152],
+ [175, 112, 133],
+ [127, 135, 225],
+ [93, 81, 137],
+ [116, 143, 119],
+ [178, 214, 122],
+ [87, 109, 147],
+ [119, 155, 95],
+ [114, 180, 160],
+ [132, 85, 103],
+ [157, 210, 150],
+ [148, 94, 86],
+ [164, 108, 138],
+ [139, 191, 150],
+ [110, 99, 145],
+ [80, 129, 109],
+ [125, 140, 149],
+ [93, 124, 132],
+ [140, 85, 140],
+ [104, 163, 162],
+ [132, 141, 178],
+ [131, 105, 147],
+ [135, 183, 98],
+ [152, 134, 177],
+ [141, 188, 141],
+ [133, 160, 210],
+ [126, 186, 148],
+ [112, 198, 205],
+ [180, 122, 195],
+ [203, 144, 152]
+];
+
+/**
+ * @param {string} string
+ * @return {number}
+ */
+WebInspector.TraceViewPalette._stringHash = function(string)
+{
+ var hash = 0;
+ for (var i = 0; i < string.length; ++i)
+ hash = (hash + 37 * hash + 11 * string.charCodeAt(i)) % 0xFFFFFFFF;
+ return hash;
+}
+
+/**
+ * @param {!Array.<number>} rgb
+ * @return {string}
+ */
+WebInspector.TraceViewPalette._rgbToString = function(rgb)
+{
+ return "rgb(" + rgb.join(",") + ")";
+}
+
+WebInspector.TraceViewPalette.prototype = {
+ /**
+ * @param {string} string
+ * @return {string}
+ */
+ colorForString: function(string)
+ {
+ var hash = WebInspector.TraceViewPalette._stringHash(string);
+ return this._palette[hash % this._palette.length];
+ }
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
new file mode 100644
index 00000000000..2983f59d770
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtils.js
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Intel Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineUIUtils = function() { }
+
+WebInspector.TimelineUIUtils.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isBeginFrame: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isProgram: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {string} recordType
+ * @return {boolean}
+ */
+ isCoalescable: function(recordType)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isEventDivider: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ countersForRecord: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ highlightQuadForRecord: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {string}
+ */
+ titleForRecord: function(record)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {boolean} loadedFromFile
+ * @return {?Node}
+ */
+ buildDetailsNode: function(record, linkifier, loadedFromFile)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!DocumentFragment)} callback
+ * @param {boolean} loadedFromFile
+ */
+ generateDetailsContent: function(record, model, linkifier, callback, loadedFromFile)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @return {!Element}
+ */
+ createBeginFrameDivider: function()
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {string} recordType
+ * @param {string=} title
+ * @return {!Element}
+ */
+ createEventDivider: function(recordType, title)
+ {
+ throw new Error("Not implemented.");
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!RegExp} regExp
+ * @return {boolean}
+ */
+ testContentMatching: function(record, regExp)
+ {
+ throw new Error("Not implemented.");
+ }
+}
+
+/**
+ * @return {!Object.<string, !WebInspector.TimelineCategory>}
+ */
+WebInspector.TimelineUIUtils.categories = function()
+{
+ if (WebInspector.TimelineUIUtils._categories)
+ return WebInspector.TimelineUIUtils._categories;
+ WebInspector.TimelineUIUtils._categories = {
+ loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), 0, "hsl(214, 53%, 58%)", "hsl(214, 67%, 90%)", "hsl(214, 67%, 74%)", "hsl(214, 67%, 66%)"),
+ scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), 1, "hsl(43, 90%, 45%)", "hsl(43, 83%, 90%)", "hsl(43, 83%, 72%)", "hsl(43, 83%, 64%) "),
+ rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), 2, "hsl(256, 50%, 60%)", "hsl(256, 67%, 90%)", "hsl(256, 67%, 76%)", "hsl(256, 67%, 70%)"),
+ painting: new WebInspector.TimelineCategory("painting", WebInspector.UIString("Painting"), 2, "hsl(109, 33%, 47%)", "hsl(109, 33%, 90%)", "hsl(109, 33%, 64%)", "hsl(109, 33%, 55%)"),
+ other: new WebInspector.TimelineCategory("other", WebInspector.UIString("Other"), -1, "hsl(0, 0%, 73%)", "hsl(0, 0%, 90%)", "hsl(0, 0%, 87%)", "hsl(0, 0%, 79%)"),
+ idle: new WebInspector.TimelineCategory("idle", WebInspector.UIString("Idle"), -1, "hsl(0, 0%, 87%)", "hsl(0, 100%, 100%)", "hsl(0, 100%, 100%)", "hsl(0, 100%, 100%)")
+ };
+ return WebInspector.TimelineUIUtils._categories;
+};
+
+/**
+ * @return {!Object.<string, !{title: string, category: !WebInspector.TimelineCategory}>}
+ */
+WebInspector.TimelineUIUtils._initRecordStyles = function()
+{
+ if (WebInspector.TimelineUIUtils._recordStylesMap)
+ return WebInspector.TimelineUIUtils._recordStylesMap;
+
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ var categories = WebInspector.TimelineUIUtils.categories();
+
+ var recordStyles = {};
+ recordStyles[recordTypes.Root] = { title: "#root", category: categories["loading"] };
+ recordStyles[recordTypes.Program] = { title: WebInspector.UIString("Other"), category: categories["other"] };
+ recordStyles[recordTypes.EventDispatch] = { title: WebInspector.UIString("Event"), category: categories["scripting"] };
+ recordStyles[recordTypes.BeginFrame] = { title: WebInspector.UIString("Frame Start"), category: categories["rendering"] };
+ recordStyles[recordTypes.ScheduleStyleRecalculation] = { title: WebInspector.UIString("Schedule Style Recalculation"), category: categories["rendering"] };
+ recordStyles[recordTypes.RecalculateStyles] = { title: WebInspector.UIString("Recalculate Style"), category: categories["rendering"] };
+ recordStyles[recordTypes.InvalidateLayout] = { title: WebInspector.UIString("Invalidate Layout"), category: categories["rendering"] };
+ recordStyles[recordTypes.Layout] = { title: WebInspector.UIString("Layout"), category: categories["rendering"] };
+ recordStyles[recordTypes.UpdateLayerTree] = { title: WebInspector.UIString("Update layer tree"), category: categories["rendering"] };
+ recordStyles[recordTypes.PaintSetup] = { title: WebInspector.UIString("Paint Setup"), category: categories["painting"] };
+ recordStyles[recordTypes.Paint] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
+ recordStyles[recordTypes.Rasterize] = { title: WebInspector.UIString("Paint"), category: categories["painting"] };
+ recordStyles[recordTypes.ScrollLayer] = { title: WebInspector.UIString("Scroll"), category: categories["rendering"] };
+ recordStyles[recordTypes.DecodeImage] = { title: WebInspector.UIString("Image Decode"), category: categories["painting"] };
+ recordStyles[recordTypes.ResizeImage] = { title: WebInspector.UIString("Image Resize"), category: categories["painting"] };
+ recordStyles[recordTypes.CompositeLayers] = { title: WebInspector.UIString("Composite Layers"), category: categories["painting"] };
+ recordStyles[recordTypes.ParseHTML] = { title: WebInspector.UIString("Parse HTML"), category: categories["loading"] };
+ recordStyles[recordTypes.TimerInstall] = { title: WebInspector.UIString("Install Timer"), category: categories["scripting"] };
+ recordStyles[recordTypes.TimerRemove] = { title: WebInspector.UIString("Remove Timer"), category: categories["scripting"] };
+ recordStyles[recordTypes.TimerFire] = { title: WebInspector.UIString("Timer Fired"), category: categories["scripting"] };
+ recordStyles[recordTypes.XHRReadyStateChange] = { title: WebInspector.UIString("XHR Ready State Change"), category: categories["scripting"] };
+ recordStyles[recordTypes.XHRLoad] = { title: WebInspector.UIString("XHR Load"), category: categories["scripting"] };
+ recordStyles[recordTypes.EvaluateScript] = { title: WebInspector.UIString("Evaluate Script"), category: categories["scripting"] };
+ recordStyles[recordTypes.ResourceSendRequest] = { title: WebInspector.UIString("Send Request"), category: categories["loading"] };
+ recordStyles[recordTypes.ResourceReceiveResponse] = { title: WebInspector.UIString("Receive Response"), category: categories["loading"] };
+ recordStyles[recordTypes.ResourceFinish] = { title: WebInspector.UIString("Finish Loading"), category: categories["loading"] };
+ recordStyles[recordTypes.FunctionCall] = { title: WebInspector.UIString("Function Call"), category: categories["scripting"] };
+ recordStyles[recordTypes.ResourceReceivedData] = { title: WebInspector.UIString("Receive Data"), category: categories["loading"] };
+ recordStyles[recordTypes.GCEvent] = { title: WebInspector.UIString("GC Event"), category: categories["scripting"] };
+ recordStyles[recordTypes.JSFrame] = { title: WebInspector.UIString("JS Frame"), category: categories["scripting"] };
+ recordStyles[recordTypes.MarkDOMContent] = { title: WebInspector.UIString("DOMContentLoaded event"), category: categories["scripting"] };
+ recordStyles[recordTypes.MarkLoad] = { title: WebInspector.UIString("Load event"), category: categories["scripting"] };
+ recordStyles[recordTypes.MarkFirstPaint] = { title: WebInspector.UIString("First paint"), category: categories["painting"] };
+ recordStyles[recordTypes.TimeStamp] = { title: WebInspector.UIString("Stamp"), category: categories["scripting"] };
+ recordStyles[recordTypes.ConsoleTime] = { title: WebInspector.UIString("Console Time"), category: categories["scripting"] };
+ recordStyles[recordTypes.RequestAnimationFrame] = { title: WebInspector.UIString("Request Animation Frame"), category: categories["scripting"] };
+ recordStyles[recordTypes.CancelAnimationFrame] = { title: WebInspector.UIString("Cancel Animation Frame"), category: categories["scripting"] };
+ recordStyles[recordTypes.FireAnimationFrame] = { title: WebInspector.UIString("Animation Frame Fired"), category: categories["scripting"] };
+ recordStyles[recordTypes.WebSocketCreate] = { title: WebInspector.UIString("Create WebSocket"), category: categories["scripting"] };
+ recordStyles[recordTypes.WebSocketSendHandshakeRequest] = { title: WebInspector.UIString("Send WebSocket Handshake"), category: categories["scripting"] };
+ recordStyles[recordTypes.WebSocketReceiveHandshakeResponse] = { title: WebInspector.UIString("Receive WebSocket Handshake"), category: categories["scripting"] };
+ recordStyles[recordTypes.WebSocketDestroy] = { title: WebInspector.UIString("Destroy WebSocket"), category: categories["scripting"] };
+ recordStyles[recordTypes.EmbedderCallback] = { title: WebInspector.UIString("Embedder Callback"), category: categories["scripting"] };
+
+ WebInspector.TimelineUIUtils._recordStylesMap = recordStyles;
+ return recordStyles;
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {!{title: string, category: !WebInspector.TimelineCategory}}
+ */
+WebInspector.TimelineUIUtils.recordStyle = function(record)
+{
+ var type = record.type();
+ var recordStyles = WebInspector.TimelineUIUtils._initRecordStyles();
+ var result = recordStyles[type];
+ if (!result) {
+ result = {
+ title: WebInspector.UIString("Unknown: %s", type),
+ category: WebInspector.TimelineUIUtils.categories()["other"]
+ };
+ recordStyles[type] = result;
+ }
+ return result;
+}
+
+/**
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!{name: string, tasks: !Array.<!{startTime: number, endTime: number}>, firstTaskIndex: number, lastTaskIndex: number}} info
+ * @return {!Element}
+ */
+WebInspector.TimelineUIUtils.generateMainThreadBarPopupContent = function(model, info)
+{
+ var firstTaskIndex = info.firstTaskIndex;
+ var lastTaskIndex = info.lastTaskIndex;
+ var tasks = info.tasks;
+ var messageCount = lastTaskIndex - firstTaskIndex + 1;
+ var cpuTime = 0;
+
+ for (var i = firstTaskIndex; i <= lastTaskIndex; ++i) {
+ var task = tasks[i];
+ cpuTime += task.endTime - task.startTime;
+ }
+ var startTime = tasks[firstTaskIndex].startTime;
+ var endTime = tasks[lastTaskIndex].endTime;
+ var duration = endTime - startTime;
+
+ var contentHelper = new WebInspector.TimelinePopupContentHelper(info.name);
+ var durationText = WebInspector.UIString("%s (at %s)", Number.millisToString(duration, true),
+ Number.millisToString(startTime - model.minimumRecordTime(), true));
+ contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
+ contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.millisToString(cpuTime, true));
+ contentHelper.appendTextRow(WebInspector.UIString("Message Count"), messageCount);
+ return contentHelper.contentTable();
+}
+
+/**
+ * @param {!Object} total
+ * @param {!Object} addend
+ */
+WebInspector.TimelineUIUtils.aggregateTimeByCategory = function(total, addend)
+{
+ for (var category in addend)
+ total[category] = (total[category] || 0) + addend[category];
+}
+
+/**
+ * @param {!Object} total
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+WebInspector.TimelineUIUtils.aggregateTimeForRecord = function(total, record)
+{
+ var childrenTime = 0;
+ var children = record.children();
+ for (var i = 0; i < children.length; ++i) {
+ WebInspector.TimelineUIUtils.aggregateTimeForRecord(total, children[i]);
+ childrenTime += children[i].endTime() - children[i].startTime();
+ }
+ var categoryName = WebInspector.TimelineUIUtils.recordStyle(record).category.name;
+ var ownTime = record.endTime() - record.startTime() - childrenTime;
+ total[categoryName] = (total[categoryName] || 0) + ownTime;
+}
+
+/**
+ * @param {!Object} aggregatedStats
+ */
+WebInspector.TimelineUIUtils._generateAggregatedInfo = function(aggregatedStats)
+{
+ var cell = document.createElement("span");
+ cell.className = "timeline-aggregated-info";
+ for (var index in aggregatedStats) {
+ var label = document.createElement("div");
+ label.className = "timeline-aggregated-category timeline-" + index;
+ cell.appendChild(label);
+ var text = document.createElement("span");
+ text.textContent = Number.millisToString(aggregatedStats[index], true);
+ cell.appendChild(text);
+ }
+ return cell;
+}
+
+/**
+ * @param {!Object} aggregatedStats
+ * @param {!WebInspector.TimelineCategory=} selfCategory
+ * @param {number=} selfTime
+ * @return {!Element}
+ */
+WebInspector.TimelineUIUtils.generatePieChart = function(aggregatedStats, selfCategory, selfTime)
+{
+ var element = document.createElement("div");
+ element.className = "timeline-aggregated-info";
+
+ var total = 0;
+ for (var categoryName in aggregatedStats)
+ total += aggregatedStats[categoryName];
+
+ function formatter(value)
+ {
+ return Number.millisToString(value, true);
+ }
+ var pieChart = new WebInspector.PieChart(total, formatter);
+ element.appendChild(pieChart.element);
+ var footerElement = element.createChild("div", "timeline-aggregated-info-legend");
+
+ // In case of self time, first add self, then children of the same category.
+ if (selfCategory && selfTime) {
+ // Self.
+ pieChart.addSlice(selfTime, selfCategory.fillColorStop1);
+ var rowElement = footerElement.createChild("div");
+ rowElement.createChild("div", "timeline-aggregated-category timeline-" + selfCategory.name);
+ rowElement.createTextChild(WebInspector.UIString("%s %s (Self)", formatter(selfTime), selfCategory.title));
+
+ // Children of the same category.
+ var categoryTime = aggregatedStats[selfCategory.name];
+ var value = categoryTime - selfTime;
+ if (value > 0) {
+ pieChart.addSlice(value, selfCategory.fillColorStop0);
+ rowElement = footerElement.createChild("div");
+ rowElement.createChild("div", "timeline-aggregated-category timeline-" + selfCategory.name);
+ rowElement.createTextChild(WebInspector.UIString("%s %s (Children)", formatter(value), selfCategory.title));
+ }
+ }
+
+ // Add other categories.
+ for (var categoryName in WebInspector.TimelineUIUtils.categories()) {
+ var category = WebInspector.TimelineUIUtils.categories()[categoryName];
+ if (category === selfCategory)
+ continue;
+ var value = aggregatedStats[category.name];
+ if (!value)
+ continue;
+ pieChart.addSlice(value, category.fillColorStop0);
+ var rowElement = footerElement.createChild("div");
+ rowElement.createChild("div", "timeline-aggregated-category timeline-" + category.name);
+ rowElement.createTextChild(WebInspector.UIString("%s %s", formatter(value), category.title));
+ }
+ return element;
+}
+
+/**
+ * @param {!WebInspector.TimelineFrameModel} frameModel
+ * @param {!WebInspector.TimelineFrame} frame
+ * @return {!Element}
+ */
+WebInspector.TimelineUIUtils.generateDetailsContentForFrame = function(frameModel, frame)
+{
+ var contentHelper = new WebInspector.TimelineDetailsContentHelper(null, null, true);
+ var durationInMillis = frame.endTime - frame.startTime;
+ var durationText = WebInspector.UIString("%s (at %s)", Number.millisToString(frame.endTime - frame.startTime, true),
+ Number.millisToString(frame.startTimeOffset, true));
+ contentHelper.appendTextRow(WebInspector.UIString("Duration"), durationText);
+ contentHelper.appendTextRow(WebInspector.UIString("FPS"), Math.floor(1000 / durationInMillis));
+ contentHelper.appendTextRow(WebInspector.UIString("CPU time"), Number.millisToString(frame.cpuTime, true));
+ contentHelper.appendElementRow(WebInspector.UIString("Aggregated Time"),
+ WebInspector.TimelineUIUtils._generateAggregatedInfo(frame.timeByCategory));
+ if (WebInspector.experimentsSettings.layersPanel.isEnabled() && frame.layerTree) {
+ contentHelper.appendElementRow(WebInspector.UIString("Layer tree"),
+ WebInspector.Linkifier.linkifyUsingRevealer(frame.layerTree, WebInspector.UIString("show")));
+ }
+ return contentHelper.element;
+}
+
+/**
+ * @param {!CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {string} color0
+ * @param {string} color1
+ * @param {string} color2
+ * @return {!CanvasGradient}
+ */
+WebInspector.TimelineUIUtils.createFillStyle = function(context, width, height, color0, color1, color2)
+{
+ var gradient = context.createLinearGradient(0, 0, width, height);
+ gradient.addColorStop(0, color0);
+ gradient.addColorStop(0.25, color1);
+ gradient.addColorStop(0.75, color1);
+ gradient.addColorStop(1, color2);
+ return gradient;
+}
+
+/**
+ * @param {!CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {!WebInspector.TimelineCategory} category
+ * @return {!CanvasGradient}
+ */
+WebInspector.TimelineUIUtils.createFillStyleForCategory = function(context, width, height, category)
+{
+ return WebInspector.TimelineUIUtils.createFillStyle(context, width, height, category.fillColorStop0, category.fillColorStop1, category.borderColor);
+}
+
+/**
+ * @param {!WebInspector.TimelineCategory} category
+ * @return {string}
+ */
+WebInspector.TimelineUIUtils.createStyleRuleForCategory = function(category)
+{
+ var selector = ".timeline-category-" + category.name + " .timeline-graph-bar, " +
+ ".panel.timeline .timeline-filters-header .filter-checkbox-filter.filter-checkbox-filter-" + category.name + " .checkbox-filter-checkbox, " +
+ ".popover .timeline-" + category.name + ", " +
+ ".timeline-details-view .timeline-" + category.name + ", " +
+ ".timeline-category-" + category.name + " .timeline-tree-icon"
+
+ return selector + " { background-image: linear-gradient(" +
+ category.fillColorStop0 + ", " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + " 25%, " + category.fillColorStop1 + ");" +
+ " border-color: " + category.borderColor +
+ "}";
+}
+
+/**
+ * @param {!Array.<number>} quad
+ * @return {number}
+ */
+WebInspector.TimelineUIUtils._quadWidth = function(quad)
+{
+ return Math.round(Math.sqrt(Math.pow(quad[0] - quad[2], 2) + Math.pow(quad[1] - quad[3], 2)));
+}
+
+/**
+ * @param {!Array.<number>} quad
+ * @return {number}
+ */
+WebInspector.TimelineUIUtils._quadHeight = function(quad)
+{
+ return Math.round(Math.sqrt(Math.pow(quad[0] - quad[6], 2) + Math.pow(quad[1] - quad[7], 2)));
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {string} name
+ * @param {string} title
+ * @param {number} overviewStripGroupIndex
+ * @param {string} borderColor
+ * @param {string} backgroundColor
+ * @param {string} fillColorStop0
+ * @param {string} fillColorStop1
+ */
+WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, borderColor, backgroundColor, fillColorStop0, fillColorStop1)
+{
+ this.name = name;
+ this.title = title;
+ this.overviewStripGroupIndex = overviewStripGroupIndex;
+ this.borderColor = borderColor;
+ this.backgroundColor = backgroundColor;
+ this.fillColorStop0 = fillColorStop0;
+ this.fillColorStop1 = fillColorStop1;
+ this.hidden = false;
+}
+
+WebInspector.TimelineCategory.Events = {
+ VisibilityChanged: "VisibilityChanged"
+};
+
+WebInspector.TimelineCategory.prototype = {
+ /**
+ * @return {boolean}
+ */
+ get hidden()
+ {
+ return this._hidden;
+ },
+
+ set hidden(hidden)
+ {
+ this._hidden = hidden;
+ this.dispatchEventToListeners(WebInspector.TimelineCategory.Events.VisibilityChanged, this);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
+
+/**
+ * @constructor
+ * @param {string} title
+ */
+WebInspector.TimelinePopupContentHelper = function(title)
+{
+ this._contentTable = document.createElement("table");
+ var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title");
+ titleCell.colSpan = 2;
+ var titleRow = document.createElement("tr");
+ titleRow.appendChild(titleCell);
+ this._contentTable.appendChild(titleRow);
+}
+
+WebInspector.TimelinePopupContentHelper.prototype = {
+ /**
+ * @return {!Element}
+ */
+ contentTable: function()
+ {
+ return this._contentTable;
+ },
+
+ /**
+ * @param {string|number} content
+ * @param {string=} styleName
+ */
+ _createCell: function(content, styleName)
+ {
+ var text = document.createElement("label");
+ text.appendChild(document.createTextNode(content));
+ var cell = document.createElement("td");
+ cell.className = "timeline-details";
+ if (styleName)
+ cell.className += " " + styleName;
+ cell.textContent = content;
+ return cell;
+ },
+
+ /**
+ * @param {string} title
+ * @param {string|number} content
+ */
+ appendTextRow: function(title, content)
+ {
+ var row = document.createElement("tr");
+ row.appendChild(this._createCell(title, "timeline-details-row-title"));
+ row.appendChild(this._createCell(content, "timeline-details-row-data"));
+ this._contentTable.appendChild(row);
+ },
+
+ /**
+ * @param {string} title
+ * @param {!Node|string} content
+ */
+ appendElementRow: function(title, content)
+ {
+ var row = document.createElement("tr");
+ var titleCell = this._createCell(title, "timeline-details-row-title");
+ row.appendChild(titleCell);
+ var cell = document.createElement("td");
+ cell.className = "details";
+ if (content instanceof Node)
+ cell.appendChild(content);
+ else
+ cell.createTextChild(content || "");
+ row.appendChild(cell);
+ this._contentTable.appendChild(row);
+ }
+}
+
+/**
+ * @constructor
+ * @param {?WebInspector.Target} target
+ * @param {?WebInspector.Linkifier} linkifier
+ * @param {boolean} monospaceValues
+ */
+WebInspector.TimelineDetailsContentHelper = function(target, linkifier, monospaceValues)
+{
+ this._linkifier = linkifier;
+ this._target = target;
+ this.element = document.createElement("div");
+ this.element.className = "timeline-details-view-block";
+ this._monospaceValues = monospaceValues;
+}
+
+WebInspector.TimelineDetailsContentHelper.prototype = {
+ /**
+ * @param {string} title
+ * @param {string|number|boolean} value
+ */
+ appendTextRow: function(title, value)
+ {
+ var rowElement = this.element.createChild("div", "timeline-details-view-row");
+ rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
+ rowElement.createChild("span", "timeline-details-view-row-value" + (this._monospaceValues ? " monospace" : "")).textContent = value;
+ },
+
+ /**
+ * @param {string} title
+ * @param {!Node|string} content
+ */
+ appendElementRow: function(title, content)
+ {
+ var rowElement = this.element.createChild("div", "timeline-details-view-row");
+ rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
+ var valueElement = rowElement.createChild("span", "timeline-details-view-row-details" + (this._monospaceValues ? " monospace" : ""));
+ if (content instanceof Node)
+ valueElement.appendChild(content);
+ else
+ valueElement.createTextChild(content || "");
+ },
+
+ /**
+ * @param {string} title
+ * @param {string} url
+ * @param {number} line
+ */
+ appendLocationRow: function(title, url, line)
+ {
+ if (!this._linkifier || !this._target)
+ return;
+ this.appendElementRow(title, this._linkifier.linkifyLocation(this._target, url, line - 1) || "");
+ },
+
+ /**
+ * @param {string} title
+ * @param {!Array.<!ConsoleAgent.CallFrame>} stackTrace
+ */
+ appendStackTrace: function(title, stackTrace)
+ {
+ if (!this._linkifier || !this._target)
+ return;
+
+ var rowElement = this.element.createChild("div", "timeline-details-view-row");
+ rowElement.createChild("span", "timeline-details-view-row-title").textContent = WebInspector.UIString("%s: ", title);
+ var stackTraceElement = rowElement.createChild("div", "timeline-details-view-row-stack-trace monospace");
+
+ for (var i = 0; i < stackTrace.length; ++i) {
+ var stackFrame = stackTrace[i];
+ var row = stackTraceElement.createChild("div");
+ row.createTextChild(stackFrame.functionName || WebInspector.UIString("(anonymous function)"));
+ row.createTextChild(" @ ");
+ var urlElement = this._linkifier.linkifyLocation(this._target, stackFrame.url, stackFrame.lineNumber - 1);
+ row.appendChild(urlElement);
+ }
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtilsImpl.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtilsImpl.js
new file mode 100644
index 00000000000..79cca164d1b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineUIUtilsImpl.js
@@ -0,0 +1,571 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineUIUtils}
+ */
+WebInspector.TimelineUIUtilsImpl = function()
+{
+ WebInspector.TimelineUIUtils.call(this);
+}
+
+WebInspector.TimelineUIUtilsImpl.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isBeginFrame: function(record)
+ {
+ return record.type() === WebInspector.TimelineModel.RecordType.BeginFrame;
+ },
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isProgram: function(record)
+ {
+ return record.type() === WebInspector.TimelineModel.RecordType.Program;
+ },
+ /**
+ * @param {string} recordType
+ * @return {boolean}
+ */
+ isCoalescable: function(recordType)
+ {
+ return !!WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[recordType];
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isEventDivider: function(record)
+ {
+ return WebInspector.TimelineUIUtilsImpl.isEventDivider(record);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ countersForRecord: function(record)
+ {
+ return record.type() === WebInspector.TimelineModel.RecordType.UpdateCounters ? record.data() : null;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ highlightQuadForRecord: function(record)
+ {
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ switch(record.type()) {
+ case recordTypes.Layout:
+ return record.data().root;
+ case recordTypes.Paint:
+ return record.data().clip;
+ default:
+ return null;
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {string}
+ */
+ titleForRecord: function(record)
+ {
+ return WebInspector.TimelineUIUtilsImpl.recordTitle(record);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {boolean} loadedFromFile
+ * @return {?Node}
+ */
+ buildDetailsNode: function(record, linkifier, loadedFromFile)
+ {
+ return WebInspector.TimelineUIUtilsImpl.buildDetailsNode(record, linkifier, loadedFromFile);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!DocumentFragment)} callback
+ * @param {boolean} loadedFromFile
+ */
+ generateDetailsContent: function(record, model, linkifier, callback, loadedFromFile)
+ {
+ WebInspector.TimelineUIUtilsImpl.generateDetailsContent(record, model, linkifier, callback, loadedFromFile);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ createBeginFrameDivider: function()
+ {
+ return this.createEventDivider(WebInspector.TimelineModel.RecordType.BeginFrame);
+ },
+
+ /**
+ * @param {string} recordType
+ * @param {string=} title
+ * @return {!Element}
+ */
+ createEventDivider: function(recordType, title)
+ {
+ return WebInspector.TimelineUIUtilsImpl._createEventDivider(recordType, title);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!RegExp} regExp
+ * @return {boolean}
+ */
+ testContentMatching: function(record, regExp)
+ {
+ var tokens = [WebInspector.TimelineUIUtilsImpl.recordTitle(record)];
+ var data = record.data();
+ for (var key in data)
+ tokens.push(data[key])
+ return regExp.test(tokens.join("|"));
+ },
+
+ __proto__: WebInspector.TimelineUIUtils.prototype
+}
+
+
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes = {};
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineModel.RecordType.Layout] = 1;
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineModel.RecordType.Paint] = 1;
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineModel.RecordType.Rasterize] = 1;
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineModel.RecordType.DecodeImage] = 1;
+WebInspector.TimelineUIUtilsImpl._coalescableRecordTypes[WebInspector.TimelineModel.RecordType.ResizeImage] = 1;
+
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {string}
+ */
+WebInspector.TimelineUIUtilsImpl.recordTitle = function(record)
+{
+ var recordData = record.data();
+ if (record.type() === WebInspector.TimelineModel.RecordType.TimeStamp)
+ return recordData["message"];
+ if (record.type() === WebInspector.TimelineModel.RecordType.JSFrame)
+ return recordData["functionName"];
+ if (WebInspector.TimelineUIUtilsImpl.isEventDivider(record)) {
+ var startTime = Number.millisToString(record.startTime() - record._model.minimumRecordTime());
+ return WebInspector.UIString("%s at %s", WebInspector.TimelineUIUtils.recordStyle(record).title, startTime, true);
+ }
+ return WebInspector.TimelineUIUtils.recordStyle(record).title;
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+WebInspector.TimelineUIUtilsImpl.isEventDivider = function(record)
+{
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+ if (record.type() === recordTypes.TimeStamp)
+ return true;
+ if (record.type() === recordTypes.MarkFirstPaint)
+ return true;
+ if (record.type() === recordTypes.MarkDOMContent || record.type() === recordTypes.MarkLoad)
+ return record.data()["isMainFrame"];
+ return false;
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {boolean} loadedFromFile
+ * @return {?Node}
+ */
+WebInspector.TimelineUIUtilsImpl.buildDetailsNode = function(record, linkifier, loadedFromFile)
+{
+ var details;
+ var detailsText;
+ var recordData = record.data();
+ switch (record.type()) {
+ case WebInspector.TimelineModel.RecordType.GCEvent:
+ detailsText = WebInspector.UIString("%s collected", Number.bytesToString(recordData["usedHeapSizeDelta"]));
+ break;
+ case WebInspector.TimelineModel.RecordType.TimerFire:
+ detailsText = recordData["timerId"];
+ break;
+ case WebInspector.TimelineModel.RecordType.FunctionCall:
+ details = linkifyLocation(recordData["scriptId"], recordData["scriptName"], recordData["scriptLine"], 0);
+ break;
+ case WebInspector.TimelineModel.RecordType.FireAnimationFrame:
+ detailsText = recordData["id"];
+ break;
+ case WebInspector.TimelineModel.RecordType.EventDispatch:
+ detailsText = recordData ? recordData["type"] : null;
+ break;
+ case WebInspector.TimelineModel.RecordType.Paint:
+ var width = WebInspector.TimelineUIUtils._quadWidth(recordData.clip);
+ var height = WebInspector.TimelineUIUtils._quadHeight(recordData.clip);
+ if (width && height)
+ detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
+ break;
+ case WebInspector.TimelineModel.RecordType.TimerInstall:
+ case WebInspector.TimelineModel.RecordType.TimerRemove:
+ details = linkifyTopCallFrame();
+ detailsText = recordData["timerId"];
+ break;
+ case WebInspector.TimelineModel.RecordType.RequestAnimationFrame:
+ case WebInspector.TimelineModel.RecordType.CancelAnimationFrame:
+ details = linkifyTopCallFrame();
+ detailsText = recordData["id"];
+ break;
+ case WebInspector.TimelineModel.RecordType.ParseHTML:
+ case WebInspector.TimelineModel.RecordType.RecalculateStyles:
+ details = linkifyTopCallFrame();
+ break;
+ case WebInspector.TimelineModel.RecordType.EvaluateScript:
+ var url = recordData["url"];
+ if (url)
+ details = linkifyLocation("", url, recordData["lineNumber"], 0);
+ break;
+ case WebInspector.TimelineModel.RecordType.XHRReadyStateChange:
+ case WebInspector.TimelineModel.RecordType.XHRLoad:
+ case WebInspector.TimelineModel.RecordType.ResourceSendRequest:
+ case WebInspector.TimelineModel.RecordType.DecodeImage:
+ case WebInspector.TimelineModel.RecordType.ResizeImage:
+ var url = recordData["url"];
+ if (url)
+ detailsText = WebInspector.displayNameForURL(url);
+ break;
+ case WebInspector.TimelineModel.RecordType.ResourceReceivedData:
+ case WebInspector.TimelineModel.RecordType.ResourceReceiveResponse:
+ case WebInspector.TimelineModel.RecordType.ResourceFinish:
+ var initiator = record.initiator();
+ if (initiator) {
+ var url = initiator.data()["url"];
+ if (url)
+ detailsText = WebInspector.displayNameForURL(url);
+ }
+ break;
+ case WebInspector.TimelineModel.RecordType.ConsoleTime:
+ detailsText = recordData["message"];
+ break;
+ case WebInspector.TimelineModel.RecordType.EmbedderCallback:
+ detailsText = recordData["callbackName"];
+ break;
+ default:
+ details = linkifyTopCallFrame();
+ break;
+ }
+
+ if (!details && detailsText)
+ details = document.createTextNode(detailsText);
+ return details;
+
+ /**
+ * @param {string} scriptId
+ * @param {string} url
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ */
+ function linkifyLocation(scriptId, url, lineNumber, columnNumber)
+ {
+ if (!loadedFromFile && scriptId !== "0") {
+ var location = new WebInspector.DebuggerModel.Location(
+ record.target(),
+ scriptId,
+ lineNumber - 1,
+ (columnNumber || 1) - 1);
+ return linkifier.linkifyRawLocation(location, "timeline-details");
+ }
+
+ if (!url)
+ return null;
+
+ // FIXME(62725): stack trace line/column numbers are one-based.
+ columnNumber = columnNumber ? columnNumber - 1 : 0;
+ return linkifier.linkifyLocation(record.target(), url, lineNumber - 1, columnNumber, "timeline-details");
+ }
+
+ /**
+ * @param {!ConsoleAgent.CallFrame} callFrame
+ */
+ function linkifyCallFrame(callFrame)
+ {
+ return linkifyLocation(callFrame.scriptId, callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
+ }
+
+ /**
+ * @return {?Element}
+ */
+ function linkifyTopCallFrame()
+ {
+ if (record.stackTrace())
+ return linkifyCallFrame(record.stackTrace()[0]);
+ if (record.callSiteStackTrace())
+ return linkifyCallFrame(record.callSiteStackTrace()[0]);
+ return null;
+ }
+}
+
+/**
+ * @param {string=} recordType
+ * @return {boolean}
+ */
+WebInspector.TimelineUIUtilsImpl._needsPreviewElement = function(recordType)
+{
+ if (!recordType)
+ return false;
+ const recordTypes = WebInspector.TimelineModel.RecordType;
+ switch (recordType) {
+ case recordTypes.ResourceSendRequest:
+ case recordTypes.ResourceReceiveResponse:
+ case recordTypes.ResourceReceivedData:
+ case recordTypes.ResourceFinish:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!DocumentFragment)} callback
+ * @param {boolean} loadedFromFile
+ */
+WebInspector.TimelineUIUtilsImpl.generateDetailsContent = function(record, model, linkifier, callback, loadedFromFile)
+{
+ var imageElement = /** @type {?Element} */ (record.getUserObject("TimelineUIUtils::preview-element") || null);
+ var relatedNode = null;
+ var recordData = record.data();
+ var barrier = new CallbackBarrier();
+ if (!imageElement && WebInspector.TimelineUIUtilsImpl._needsPreviewElement(record.type()))
+ WebInspector.DOMPresentationUtils.buildImagePreviewContents(record.target(), recordData["url"], false, barrier.createCallback(saveImage));
+ if (recordData["backendNodeId"])
+ record.target().domModel.pushNodesByBackendIdsToFrontend([recordData["backendNodeId"]], barrier.createCallback(setRelatedNode));
+ barrier.callWhenDone(callbackWrapper);
+
+ /**
+ * @param {!Element=} element
+ */
+ function saveImage(element)
+ {
+ imageElement = element || null;
+ record.setUserObject("TimelineUIUtils::preview-element", element);
+ }
+
+ /**
+ * @param {?Array.<!DOMAgent.NodeId>} nodeIds
+ */
+ function setRelatedNode(nodeIds)
+ {
+ if (nodeIds)
+ relatedNode = record.target().domModel.nodeForId(nodeIds[0]);
+ }
+
+ function callbackWrapper()
+ {
+ callback(WebInspector.TimelineUIUtilsImpl._generateDetailsContentSynchronously(record, model, linkifier, imageElement, relatedNode, loadedFromFile));
+ }
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {?Element} imagePreviewElement
+ * @param {?WebInspector.DOMNode} relatedNode
+ * @param {boolean} loadedFromFile
+ * @return {!DocumentFragment}
+ */
+WebInspector.TimelineUIUtilsImpl._generateDetailsContentSynchronously = function(record, model, linkifier, imagePreviewElement, relatedNode, loadedFromFile)
+{
+ var fragment = document.createDocumentFragment();
+ if (record.children().length)
+ fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(record.aggregatedStats(), record.category(), record.selfTime()));
+ else
+ fragment.appendChild(WebInspector.TimelineUIUtils.generatePieChart(record.aggregatedStats()));
+
+ const recordTypes = WebInspector.TimelineModel.RecordType;
+
+ // The messages may vary per record.type();
+ var callSiteStackTraceLabel;
+ var callStackLabel;
+ var relatedNodeLabel;
+
+ var contentHelper = new WebInspector.TimelineDetailsContentHelper(record.target(), linkifier, true);
+ contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.millisToString(record.selfTime(), true));
+ contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.millisToString(record.startTime() - model.minimumRecordTime()));
+ var recordData = record.data();
+
+ switch (record.type()) {
+ case recordTypes.GCEvent:
+ contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(recordData["usedHeapSizeDelta"]));
+ break;
+ case recordTypes.TimerFire:
+ callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
+ // Fall-through intended.
+
+ case recordTypes.TimerInstall:
+ case recordTypes.TimerRemove:
+ contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), recordData["timerId"]);
+ if (record.type() === recordTypes.TimerInstall) {
+ contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.millisToString(recordData["timeout"]));
+ contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !recordData["singleShot"]);
+ }
+ break;
+ case recordTypes.FireAnimationFrame:
+ callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested");
+ contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), recordData["id"]);
+ break;
+ case recordTypes.FunctionCall:
+ if (recordData["scriptName"])
+ contentHelper.appendLocationRow(WebInspector.UIString("Location"), recordData["scriptName"], recordData["scriptLine"]);
+ break;
+ case recordTypes.ResourceSendRequest:
+ case recordTypes.ResourceReceiveResponse:
+ case recordTypes.ResourceReceivedData:
+ case recordTypes.ResourceFinish:
+ var url;
+ if (record.type() === recordTypes.ResourceSendRequest)
+ url = recordData["url"];
+ else if (record.initiator())
+ url = record.initiator().data()["url"];
+ if (url)
+ contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(url));
+ if (imagePreviewElement)
+ contentHelper.appendElementRow(WebInspector.UIString("Preview"), imagePreviewElement);
+ if (recordData["requestMethod"])
+ contentHelper.appendTextRow(WebInspector.UIString("Request Method"), recordData["requestMethod"]);
+ if (typeof recordData["statusCode"] === "number")
+ contentHelper.appendTextRow(WebInspector.UIString("Status Code"), recordData["statusCode"]);
+ if (recordData["mimeType"])
+ contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), recordData["mimeType"]);
+ if (recordData["encodedDataLength"])
+ contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", recordData["encodedDataLength"]));
+ break;
+ case recordTypes.EvaluateScript:
+ var url = recordData["url"];
+ if (url)
+ contentHelper.appendLocationRow(WebInspector.UIString("Script"), url, recordData["lineNumber"]);
+ break;
+ case recordTypes.Paint:
+ var clip = recordData["clip"];
+ contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1]));
+ var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip);
+ var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip);
+ contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight));
+ // Fall-through intended.
+
+ case recordTypes.PaintSetup:
+ case recordTypes.Rasterize:
+ case recordTypes.ScrollLayer:
+ relatedNodeLabel = WebInspector.UIString("Layer root");
+ break;
+ case recordTypes.DecodeImage:
+ case recordTypes.ResizeImage:
+ relatedNodeLabel = WebInspector.UIString("Image element");
+ var url = recordData["url"];
+ if (url)
+ contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(url));
+ break;
+ case recordTypes.RecalculateStyles: // We don't want to see default details.
+ if (recordData["elementCount"])
+ contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), recordData["elementCount"]);
+ callStackLabel = WebInspector.UIString("Styles recalculation forced");
+ break;
+ case recordTypes.Layout:
+ if (recordData["dirtyObjects"])
+ contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), recordData["dirtyObjects"]);
+ if (recordData["totalObjects"])
+ contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), recordData["totalObjects"]);
+ if (typeof recordData["partialLayout"] === "boolean") {
+ contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
+ recordData["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document"));
+ }
+ callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
+ callStackLabel = WebInspector.UIString("Layout forced");
+ relatedNodeLabel = WebInspector.UIString("Layout root");
+ break;
+ case recordTypes.ConsoleTime:
+ contentHelper.appendTextRow(WebInspector.UIString("Message"), recordData["message"]);
+ break;
+ case recordTypes.WebSocketCreate:
+ case recordTypes.WebSocketSendHandshakeRequest:
+ case recordTypes.WebSocketReceiveHandshakeResponse:
+ case recordTypes.WebSocketDestroy:
+ var initiatorData = record.initiator() ? record.initiator().data() : recordData;
+ if (typeof initiatorData["webSocketURL"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorData["webSocketURL"]);
+ if (typeof initiatorData["webSocketProtocol"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), initiatorData["webSocketProtocol"]);
+ if (typeof recordData["message"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("Message"), recordData["message"]);
+ break;
+ case recordTypes.EmbedderCallback:
+ contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), recordData["callbackName"]);
+ break;
+ default:
+ var detailsNode = WebInspector.TimelineUIUtilsImpl.buildDetailsNode(record, linkifier, loadedFromFile);
+ if (detailsNode)
+ contentHelper.appendElementRow(WebInspector.UIString("Details"), detailsNode);
+ break;
+ }
+
+ if (relatedNode)
+ contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(relatedNode));
+
+ if (recordData["scriptName"] && record.type() !== recordTypes.FunctionCall)
+ contentHelper.appendLocationRow(WebInspector.UIString("Function Call"), recordData["scriptName"], recordData["scriptLine"]);
+ var callSiteStackTrace = record.callSiteStackTrace();
+ if (callSiteStackTrace)
+ contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.UIString("Call Site stack"), callSiteStackTrace);
+ var recordStackTrace = record.stackTrace();
+ if (recordStackTrace)
+ contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("Call Stack"), recordStackTrace);
+
+ if (record.warnings()) {
+ var ul = document.createElement("ul");
+ for (var i = 0; i < record.warnings().length; ++i)
+ ul.createChild("li").textContent = record.warnings()[i];
+ contentHelper.appendElementRow(WebInspector.UIString("Warning"), ul);
+ }
+ fragment.appendChild(contentHelper.element);
+ return fragment;
+}
+
+/**
+ * @param {string} recordType
+ * @param {string=} title
+ * @return {!Element}
+ */
+WebInspector.TimelineUIUtilsImpl._createEventDivider = function(recordType, title)
+{
+ var eventDivider = document.createElement("div");
+ eventDivider.className = "resources-event-divider";
+ var recordTypes = WebInspector.TimelineModel.RecordType;
+
+ if (recordType === recordTypes.MarkDOMContent)
+ eventDivider.className += " resources-blue-divider";
+ else if (recordType === recordTypes.MarkLoad)
+ eventDivider.className += " resources-red-divider";
+ else if (recordType === recordTypes.MarkFirstPaint)
+ eventDivider.className += " resources-green-divider";
+ else if (recordType === recordTypes.TimeStamp)
+ eventDivider.className += " resources-orange-divider";
+ else if (recordType === recordTypes.BeginFrame)
+ eventDivider.className += " timeline-frame-divider";
+
+ if (title)
+ eventDivider.title = title;
+
+ return eventDivider;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineView.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineView.js
new file mode 100644
index 00000000000..5b5fc6333eb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TimelineView.js
@@ -0,0 +1,1304 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Intel Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.HBox}
+ * @implements {WebInspector.TimelineModeView}
+ * @param {!WebInspector.TimelineModeViewDelegate} delegate
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
+ */
+WebInspector.TimelineView = function(delegate, model, uiUtils)
+{
+ WebInspector.HBox.call(this);
+ this.element.classList.add("timeline-view");
+
+ this._delegate = delegate;
+ this._model = model;
+ this._uiUtils = uiUtils;
+ this._presentationModel = new WebInspector.TimelinePresentationModel(model, uiUtils);
+ this._calculator = new WebInspector.TimelineCalculator(model);
+ this._linkifier = new WebInspector.Linkifier();
+ this._frameStripByFrame = new Map();
+
+ this._boundariesAreValid = true;
+ this._scrollTop = 0;
+
+ this._recordsView = this._createRecordsView();
+ this._recordsView.addEventListener(WebInspector.SplitView.Events.SidebarSizeChanged, this._sidebarResized, this);
+ this._recordsView.show(this.element);
+ this._headerElement = this.element.createChild("div", "fill");
+ this._headerElement.id = "timeline-graph-records-header";
+
+ // Create gpu tasks containers.
+ this._cpuBarsElement = this._headerElement.createChild("div", "timeline-utilization-strip");
+ if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
+ this._gpuBarsElement = this._headerElement.createChild("div", "timeline-utilization-strip gpu");
+
+ this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
+
+ this.element.addEventListener("mousemove", this._mouseMove.bind(this), false);
+ this.element.addEventListener("mouseout", this._mouseOut.bind(this), false);
+ this.element.addEventListener("keydown", this._keyDown.bind(this), false);
+
+ this._expandOffset = 15;
+}
+
+WebInspector.TimelineView.prototype = {
+ /**
+ * @param {?WebInspector.TimelineFrameModelBase} frameModel
+ */
+ setFrameModel: function(frameModel)
+ {
+ this._frameModel = frameModel;
+ },
+
+ /**
+ * @return {!WebInspector.SplitView}
+ */
+ _createRecordsView: function()
+ {
+ var recordsView = new WebInspector.SplitView(true, false, "timelinePanelRecorsSplitViewState");
+ this._containerElement = recordsView.element;
+ this._containerElement.tabIndex = 0;
+ this._containerElement.id = "timeline-container";
+ this._containerElement.addEventListener("scroll", this._onScroll.bind(this), false);
+
+ // Create records list in the records sidebar.
+ recordsView.sidebarElement().createChild("div", "timeline-records-title").textContent = WebInspector.UIString("RECORDS");
+ this._sidebarListElement = recordsView.sidebarElement().createChild("div", "timeline-records-list");
+
+ // Create grid in the records main area.
+ this._gridContainer = new WebInspector.VBoxWithResizeCallback(this._onViewportResize.bind(this));
+ this._gridContainer.element.id = "resources-container-content";
+ this._gridContainer.show(recordsView.mainElement());
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._gridContainer.element.appendChild(this._timelineGrid.element);
+
+ this._itemsGraphsElement = this._gridContainer.element.createChild("div");
+ this._itemsGraphsElement.id = "timeline-graphs";
+
+ // Create gap elements
+ this._topGapElement = this._itemsGraphsElement.createChild("div", "timeline-gap");
+ this._graphRowsElement = this._itemsGraphsElement.createChild("div");
+ this._bottomGapElement = this._itemsGraphsElement.createChild("div", "timeline-gap");
+ this._expandElements = this._itemsGraphsElement.createChild("div");
+ this._expandElements.id = "orphan-expand-elements";
+
+ return recordsView;
+ },
+
+ _rootRecord: function()
+ {
+ return this._presentationModel.rootRecord();
+ },
+
+ _updateEventDividers: function()
+ {
+ this._timelineGrid.removeEventDividers();
+ var clientWidth = this._graphRowsElementWidth;
+ var dividers = [];
+ var eventDividerRecords = this._model.eventDividerRecords();
+
+ for (var i = 0; i < eventDividerRecords.length; ++i) {
+ var record = eventDividerRecords[i];
+ var position = this._calculator.computePosition(record.startTime());
+ var dividerPosition = Math.round(position);
+ if (dividerPosition < 0 || dividerPosition >= clientWidth || dividers[dividerPosition])
+ continue;
+ var title = this._uiUtils.titleForRecord(record);
+ var divider = this._uiUtils.createEventDivider(record.type(), title);
+ divider.style.left = dividerPosition + "px";
+ dividers[dividerPosition] = divider;
+ }
+ this._timelineGrid.addEventDividers(dividers);
+ },
+
+ _updateFrameBars: function(frames)
+ {
+ var clientWidth = this._graphRowsElementWidth;
+ if (this._frameContainer) {
+ this._frameContainer.removeChildren();
+ } else {
+ const frameContainerBorderWidth = 1;
+ this._frameContainer = document.createElement("div");
+ this._frameContainer.classList.add("fill");
+ this._frameContainer.classList.add("timeline-frame-container");
+ this._frameContainer.style.height = WebInspector.TimelinePanel.rowHeight + frameContainerBorderWidth + "px";
+ this._frameContainer.addEventListener("dblclick", this._onFrameDoubleClicked.bind(this), false);
+ this._frameContainer.addEventListener("click", this._onFrameClicked.bind(this), false);
+ }
+ this._frameStripByFrame.clear();
+
+ var dividers = [];
+
+ for (var i = 0; i < frames.length; ++i) {
+ var frame = frames[i];
+ var frameStart = this._calculator.computePosition(frame.startTime);
+ var frameEnd = this._calculator.computePosition(frame.endTime);
+
+ var frameStrip = document.createElement("div");
+ frameStrip.className = "timeline-frame-strip";
+ var actualStart = Math.max(frameStart, 0);
+ var width = frameEnd - actualStart;
+ frameStrip.style.left = actualStart + "px";
+ frameStrip.style.width = width + "px";
+ frameStrip._frame = frame;
+ this._frameStripByFrame.put(frame, frameStrip);
+
+ const minWidthForFrameInfo = 60;
+ if (width > minWidthForFrameInfo)
+ frameStrip.textContent = Number.millisToString(frame.endTime - frame.startTime, true);
+
+ this._frameContainer.appendChild(frameStrip);
+
+ if (actualStart > 0) {
+ var frameMarker = this._uiUtils.createBeginFrameDivider();
+ frameMarker.style.left = frameStart + "px";
+ dividers.push(frameMarker);
+ }
+ }
+ this._timelineGrid.addEventDividers(dividers);
+ this._headerElement.appendChild(this._frameContainer);
+ },
+
+ _onFrameDoubleClicked: function(event)
+ {
+ var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip");
+ if (!frameBar)
+ return;
+ this._delegate.requestWindowTimes(frameBar._frame.startTime, frameBar._frame.endTime);
+ },
+
+ _onFrameClicked: function(event)
+ {
+ var frameBar = event.target.enclosingNodeOrSelfWithClass("timeline-frame-strip");
+ if (!frameBar)
+ return;
+ this._delegate.select(WebInspector.TimelineSelection.fromFrame(frameBar._frame));
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ */
+ addRecord: function(record)
+ {
+ this._presentationModel.addRecord(record);
+ this._invalidateAndScheduleRefresh(false, false);
+ },
+
+ /**
+ * @param {number} width
+ */
+ setSidebarSize: function(width)
+ {
+ this._recordsView.setSidebarSize(width);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _sidebarResized: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.SplitView.Events.SidebarSizeChanged, event.data);
+ },
+
+ _onViewportResize: function()
+ {
+ this._resize(this._recordsView.sidebarSize());
+ },
+
+ /**
+ * @param {number} sidebarWidth
+ */
+ _resize: function(sidebarWidth)
+ {
+ this._closeRecordDetails();
+ this._graphRowsElementWidth = this._graphRowsElement.offsetWidth;
+ this._headerElement.style.left = sidebarWidth + "px";
+ this._headerElement.style.width = this._itemsGraphsElement.offsetWidth + "px";
+ this._scheduleRefresh(false, true);
+ },
+
+ _resetView: function()
+ {
+ this._windowStartTime = 0;
+ this._windowEndTime = 0;
+ this._boundariesAreValid = false;
+ this._adjustScrollPosition(0);
+ this._linkifier.reset();
+ this._closeRecordDetails();
+ this._automaticallySizeWindow = true;
+ this._presentationModel.reset();
+ },
+
+
+ /**
+ * @return {!WebInspector.View}
+ */
+ view: function()
+ {
+ return this;
+ },
+
+ dispose: function()
+ {
+ },
+
+ reset: function()
+ {
+ this._resetView();
+ this._invalidateAndScheduleRefresh(true, true);
+ },
+
+ /**
+ * @return {!Array.<!Element>}
+ */
+ elementsToRestoreScrollPositionsFor: function()
+ {
+ return [this._containerElement];
+ },
+
+ /**
+ * @param {?RegExp} textFilter
+ */
+ refreshRecords: function(textFilter)
+ {
+ this._presentationModel.reset();
+ var records = this._model.records();
+ for (var i = 0; i < records.length; ++i)
+ this.addRecord(records[i]);
+ this._automaticallySizeWindow = false;
+ this._presentationModel.setTextFilter(textFilter);
+ this._invalidateAndScheduleRefresh(false, true);
+ },
+
+ willHide: function()
+ {
+ this._closeRecordDetails();
+ WebInspector.View.prototype.willHide.call(this);
+ },
+
+ _onScroll: function(event)
+ {
+ this._closeRecordDetails();
+ this._scrollTop = this._containerElement.scrollTop;
+ var dividersTop = Math.max(0, this._scrollTop);
+ this._timelineGrid.setScrollAndDividerTop(this._scrollTop, dividersTop);
+ this._scheduleRefresh(true, true);
+ },
+
+ /**
+ * @param {boolean} preserveBoundaries
+ * @param {boolean} userGesture
+ */
+ _invalidateAndScheduleRefresh: function(preserveBoundaries, userGesture)
+ {
+ this._presentationModel.invalidateFilteredRecords();
+ this._scheduleRefresh(preserveBoundaries, userGesture);
+ },
+
+ _clearSelection: function()
+ {
+ this._delegate.select(null);
+ },
+
+ /**
+ * @param {?WebInspector.TimelinePresentationModel.Record} presentationRecord
+ */
+ _selectRecord: function(presentationRecord)
+ {
+ if (presentationRecord.coalesced()) {
+ // Presentation record does not have model record to highlight.
+ this._innerSetSelectedRecord(presentationRecord);
+ var aggregatedStats = {};
+ var presentationChildren = presentationRecord.presentationChildren();
+ for (var i = 0; i < presentationChildren.length; ++i)
+ WebInspector.TimelineUIUtils.aggregateTimeByCategory(aggregatedStats, presentationChildren[i].record().aggregatedStats());
+ var idle = presentationRecord.record().endTime() - presentationRecord.record().startTime();
+ for (var category in aggregatedStats)
+ idle -= aggregatedStats[category];
+ aggregatedStats["idle"] = idle;
+ var pieChart = WebInspector.TimelineUIUtils.generatePieChart(aggregatedStats);
+ this._delegate.showInDetails(WebInspector.TimelineUIUtils.recordStyle(presentationRecord.record()).title, pieChart);
+ return;
+ }
+ this._delegate.select(WebInspector.TimelineSelection.fromRecord(presentationRecord.record()));
+ },
+
+ /**
+ * @param {?WebInspector.TimelineSelection} selection
+ */
+ setSelection: function(selection)
+ {
+ if (!selection) {
+ this._innerSetSelectedRecord(null);
+ this._setSelectedFrame(null);
+ return;
+ }
+ if (selection.type() === WebInspector.TimelineSelection.Type.Record) {
+ var record = /** @type {!WebInspector.TimelineModel.Record} */ (selection.object());
+ this._innerSetSelectedRecord(this._presentationModel.toPresentationRecord(record));
+ this._setSelectedFrame(null);
+ } else if (selection.type() === WebInspector.TimelineSelection.Type.Frame) {
+ var frame = /** @type {!WebInspector.TimelineFrame} */ (selection.object());
+ this._innerSetSelectedRecord(null);
+ this._setSelectedFrame(frame);
+ }
+ },
+
+ /**
+ * @param {?WebInspector.TimelinePresentationModel.Record} presentationRecord
+ */
+ _innerSetSelectedRecord: function(presentationRecord)
+ {
+ if (presentationRecord === this._lastSelectedRecord)
+ return;
+
+ // Remove selection rendering.p
+ if (this._lastSelectedRecord) {
+ if (this._lastSelectedRecord.listRow())
+ this._lastSelectedRecord.listRow().renderAsSelected(false);
+ if (this._lastSelectedRecord.graphRow())
+ this._lastSelectedRecord.graphRow().renderAsSelected(false);
+ }
+
+ this._lastSelectedRecord = presentationRecord;
+ if (!presentationRecord)
+ return;
+
+ this._innerRevealRecord(presentationRecord);
+ if (presentationRecord.listRow())
+ presentationRecord.listRow().renderAsSelected(true);
+ if (presentationRecord.graphRow())
+ presentationRecord.graphRow().renderAsSelected(true);
+ },
+
+ /**
+ * @param {?WebInspector.TimelineFrame} frame
+ */
+ _setSelectedFrame: function(frame)
+ {
+ if (this._lastSelectedFrame === frame)
+ return;
+ var oldStripElement = this._lastSelectedFrame && this._frameStripByFrame.get(this._lastSelectedFrame);
+ if (oldStripElement)
+ oldStripElement.classList.remove("selected");
+ var newStripElement = frame && this._frameStripByFrame.get(frame);
+ if (newStripElement)
+ newStripElement.classList.add("selected");
+ this._lastSelectedFrame = frame;
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
+ {
+ this._windowStartTime = startTime;
+ this._windowEndTime = endTime;
+ this._presentationModel.setWindowTimes(startTime, endTime);
+ this._automaticallySizeWindow = false;
+ this._invalidateAndScheduleRefresh(false, true);
+ this._clearSelection();
+ },
+
+ /**
+ * @param {boolean} preserveBoundaries
+ * @param {boolean} userGesture
+ */
+ _scheduleRefresh: function(preserveBoundaries, userGesture)
+ {
+ this._closeRecordDetails();
+ this._boundariesAreValid &= preserveBoundaries;
+
+ if (!this.isShowing())
+ return;
+
+ if (preserveBoundaries || userGesture)
+ this._refresh();
+ else {
+ if (!this._refreshTimeout)
+ this._refreshTimeout = setTimeout(this._refresh.bind(this), 300);
+ }
+ },
+
+ _refresh: function()
+ {
+ if (this._refreshTimeout) {
+ clearTimeout(this._refreshTimeout);
+ delete this._refreshTimeout;
+ }
+ var windowStartTime = this._windowStartTime || this._model.minimumRecordTime();
+ var windowEndTime = this._windowEndTime || this._model.maximumRecordTime();
+ this._timelinePaddingLeft = this._expandOffset;
+ this._calculator.setWindow(windowStartTime, windowEndTime);
+ this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth);
+
+ this._refreshRecords();
+ if (!this._boundariesAreValid) {
+ this._updateEventDividers();
+ if (this._frameContainer)
+ this._frameContainer.remove();
+ if (this._frameModel) {
+ var frames = this._frameModel.filteredFrames(windowStartTime, windowEndTime);
+ const maxFramesForFrameBars = 30;
+ if (frames.length && frames.length < maxFramesForFrameBars) {
+ this._timelineGrid.removeDividers();
+ this._updateFrameBars(frames);
+ } else {
+ this._timelineGrid.updateDividers(this._calculator);
+ }
+ } else
+ this._timelineGrid.updateDividers(this._calculator);
+ this._refreshAllUtilizationBars();
+ }
+ this._boundariesAreValid = true;
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} recordToReveal
+ */
+ _innerRevealRecord: function(recordToReveal)
+ {
+ var needRefresh = false;
+ // Expand all ancestors.
+ for (var parent = recordToReveal.presentationParent(); parent !== this._rootRecord(); parent = parent.presentationParent()) {
+ if (!parent.collapsed())
+ continue;
+ this._presentationModel.invalidateFilteredRecords();
+ parent.setCollapsed(false);
+ needRefresh = true;
+ }
+ var recordsInWindow = this._presentationModel.filteredRecords();
+ var index = recordsInWindow.indexOf(recordToReveal);
+
+ var itemOffset = index * WebInspector.TimelinePanel.rowHeight;
+ var visibleTop = this._scrollTop - WebInspector.TimelinePanel.headerHeight;
+ var visibleBottom = visibleTop + this._containerElementHeight - WebInspector.TimelinePanel.rowHeight;
+ if (itemOffset < visibleTop)
+ this._containerElement.scrollTop = itemOffset;
+ else if (itemOffset > visibleBottom)
+ this._containerElement.scrollTop = itemOffset - this._containerElementHeight + WebInspector.TimelinePanel.headerHeight + WebInspector.TimelinePanel.rowHeight;
+ else if (needRefresh)
+ this._refreshRecords();
+ },
+
+ _refreshRecords: function()
+ {
+ this._containerElementHeight = this._containerElement.clientHeight;
+ var recordsInWindow = this._presentationModel.filteredRecords();
+
+ // Calculate the visible area.
+ var visibleTop = this._scrollTop;
+ var visibleBottom = visibleTop + this._containerElementHeight;
+
+ var rowHeight = WebInspector.TimelinePanel.rowHeight;
+ var headerHeight = WebInspector.TimelinePanel.headerHeight;
+
+ // Convert visible area to visible indexes. Always include top-level record for a visible nested record.
+ var startIndex = Math.max(0, Math.min(Math.floor((visibleTop - headerHeight) / rowHeight), recordsInWindow.length - 1));
+ var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight));
+ var lastVisibleLine = Math.max(0, Math.floor((visibleBottom - headerHeight) / rowHeight));
+ if (this._automaticallySizeWindow && recordsInWindow.length > lastVisibleLine) {
+ this._automaticallySizeWindow = false;
+ this._clearSelection();
+ // If we're at the top, always use real timeline start as a left window bound so that expansion arrow padding logic works.
+ var windowStartTime = startIndex ? recordsInWindow[startIndex].startTime() : this._model.minimumRecordTime();
+ var windowEndTime = recordsInWindow[Math.max(0, lastVisibleLine - 1)].endTime();
+ this._delegate.requestWindowTimes(windowStartTime, windowEndTime);
+ recordsInWindow = this._presentationModel.filteredRecords();
+ endIndex = Math.min(recordsInWindow.length, lastVisibleLine);
+ }
+
+ // Resize gaps first.
+ this._topGapElement.style.height = (startIndex * rowHeight) + "px";
+ this._recordsView.sidebarElement().firstElementChild.style.flexBasis = (startIndex * rowHeight + headerHeight) + "px";
+ this._bottomGapElement.style.height = (recordsInWindow.length - endIndex) * rowHeight + "px";
+ var rowsHeight = headerHeight + recordsInWindow.length * rowHeight;
+ var totalHeight = Math.max(this._containerElementHeight, rowsHeight);
+
+ this._recordsView.mainElement().style.height = totalHeight + "px";
+ this._recordsView.sidebarElement().style.height = totalHeight + "px";
+ this._recordsView.resizerElement().style.height = totalHeight + "px";
+
+ // Update visible rows.
+ var listRowElement = this._sidebarListElement.firstChild;
+ var width = this._graphRowsElementWidth;
+ this._itemsGraphsElement.removeChild(this._graphRowsElement);
+ var graphRowElement = this._graphRowsElement.firstChild;
+ var scheduleRefreshCallback = this._invalidateAndScheduleRefresh.bind(this, true, true);
+ var selectRecordCallback = this._selectRecord.bind(this);
+ this._itemsGraphsElement.removeChild(this._expandElements);
+ this._expandElements.removeChildren();
+
+ for (var i = 0; i < endIndex; ++i) {
+ var record = recordsInWindow[i];
+
+ if (i < startIndex) {
+ var lastChildIndex = i + record.visibleChildrenCount();
+ if (lastChildIndex >= startIndex && lastChildIndex < endIndex) {
+ var expandElement = new WebInspector.TimelineExpandableElement(this._expandElements);
+ var positions = this._calculator.computeBarGraphWindowPosition(record);
+ expandElement._update(record, i, positions.left - this._expandOffset, positions.width);
+ }
+ } else {
+ if (!listRowElement) {
+ listRowElement = new WebInspector.TimelineRecordListRow(this._linkifier, selectRecordCallback, scheduleRefreshCallback).element;
+ this._sidebarListElement.appendChild(listRowElement);
+ }
+ if (!graphRowElement) {
+ graphRowElement = new WebInspector.TimelineRecordGraphRow(this._itemsGraphsElement, selectRecordCallback, scheduleRefreshCallback).element;
+ this._graphRowsElement.appendChild(graphRowElement);
+ }
+
+ listRowElement.row.update(record, visibleTop, this._model.loadedFromFile(), this._uiUtils);
+ graphRowElement.row.update(record, this._calculator, this._expandOffset, i);
+ if (this._lastSelectedRecord === record) {
+ listRowElement.row.renderAsSelected(true);
+ graphRowElement.row.renderAsSelected(true);
+ }
+
+ listRowElement = listRowElement.nextSibling;
+ graphRowElement = graphRowElement.nextSibling;
+ }
+ }
+
+ // Remove extra rows.
+ while (listRowElement) {
+ var nextElement = listRowElement.nextSibling;
+ listRowElement.row.dispose();
+ listRowElement = nextElement;
+ }
+ while (graphRowElement) {
+ var nextElement = graphRowElement.nextSibling;
+ graphRowElement.row.dispose();
+ graphRowElement = nextElement;
+ }
+
+ this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement);
+ this._itemsGraphsElement.appendChild(this._expandElements);
+ this._adjustScrollPosition(recordsInWindow.length * rowHeight + headerHeight);
+
+ return recordsInWindow.length;
+ },
+
+ _refreshAllUtilizationBars: function()
+ {
+ this._refreshUtilizationBars(WebInspector.UIString("CPU"), this._model.mainThreadTasks(), this._cpuBarsElement);
+ if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
+ this._refreshUtilizationBars(WebInspector.UIString("GPU"), this._model.gpuThreadTasks(), this._gpuBarsElement);
+ },
+
+ /**
+ * @param {string} name
+ * @param {!Array.<!WebInspector.TimelineModel.Record>} tasks
+ * @param {?Element} container
+ */
+ _refreshUtilizationBars: function(name, tasks, container)
+ {
+ if (!container)
+ return;
+
+ const barOffset = 3;
+ const minGap = 3;
+
+ var minWidth = WebInspector.TimelineCalculator._minWidth;
+ var widthAdjustment = minWidth / 2;
+
+ var width = this._graphRowsElementWidth;
+ var boundarySpan = this._windowEndTime - this._windowStartTime;
+ var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft);
+ var startTime = (this._windowStartTime - this._timelinePaddingLeft * scale);
+ var endTime = startTime + width * scale;
+
+ /**
+ * @param {number} value
+ * @param {!WebInspector.TimelineModel.Record} task
+ * @return {number}
+ */
+ function compareEndTime(value, task)
+ {
+ return value < task.endTime() ? -1 : 1;
+ }
+
+ var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
+
+ var foreignStyle = "gpu-task-foreign";
+ var element = /** @type {?Element} */ (container.firstChild);
+ var lastElement;
+ var lastLeft;
+ var lastRight;
+
+ for (; taskIndex < tasks.length; ++taskIndex) {
+ var task = tasks[taskIndex];
+ if (task.startTime() > endTime)
+ break;
+
+ var left = Math.max(0, this._calculator.computePosition(task.startTime()) + barOffset - widthAdjustment);
+ var right = Math.min(width, this._calculator.computePosition(task.endTime() || 0) + barOffset + widthAdjustment);
+
+ if (lastElement) {
+ var gap = Math.floor(left) - Math.ceil(lastRight);
+ if (gap < minGap) {
+ if (!task.data["foreign"])
+ lastElement.classList.remove(foreignStyle);
+ lastRight = right;
+ lastElement._tasksInfo.lastTaskIndex = taskIndex;
+ continue;
+ }
+ lastElement.style.width = (lastRight - lastLeft) + "px";
+ }
+
+ if (!element)
+ element = container.createChild("div", "timeline-graph-bar");
+ element.style.left = left + "px";
+ element._tasksInfo = {name: name, tasks: tasks, firstTaskIndex: taskIndex, lastTaskIndex: taskIndex};
+ if (task.data["foreign"])
+ element.classList.add(foreignStyle);
+ lastLeft = left;
+ lastRight = right;
+ lastElement = element;
+ element = element.nextSibling;
+ }
+
+ if (lastElement)
+ lastElement.style.width = (lastRight - lastLeft) + "px";
+
+ while (element) {
+ var nextElement = element.nextSibling;
+ element._tasksInfo = null;
+ container.removeChild(element);
+ element = nextElement;
+ }
+ },
+
+ _adjustScrollPosition: function(totalHeight)
+ {
+ // Prevent the container from being scrolled off the end.
+ if ((this._scrollTop + this._containerElementHeight) > totalHeight + 1)
+ this._containerElement.scrollTop = (totalHeight - this._containerElement.offsetHeight);
+ },
+
+ _getPopoverAnchor: function(element)
+ {
+ var anchor = element.enclosingNodeOrSelfWithClass("timeline-graph-bar");
+ if (anchor && anchor._tasksInfo)
+ return anchor;
+ return null;
+ },
+
+ _mouseOut: function()
+ {
+ this._hideQuadHighlight();
+ },
+
+ /**
+ * @param {?Event} e
+ */
+ _mouseMove: function(e)
+ {
+ var rowElement = e.target.enclosingNodeOrSelfWithClass("timeline-tree-item");
+ if (!this._highlightQuad(rowElement))
+ this._hideQuadHighlight();
+
+ var taskBarElement = e.target.enclosingNodeOrSelfWithClass("timeline-graph-bar");
+ if (taskBarElement && taskBarElement._tasksInfo) {
+ var offset = taskBarElement.offsetLeft;
+ this._timelineGrid.showCurtains(offset >= 0 ? offset : 0, taskBarElement.offsetWidth);
+ } else
+ this._timelineGrid.hideCurtains();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _keyDown: function(event)
+ {
+ if (!this._lastSelectedRecord || event.shiftKey || event.metaKey || event.ctrlKey)
+ return;
+
+ var record = this._lastSelectedRecord;
+ var recordsInWindow = this._presentationModel.filteredRecords();
+ var index = recordsInWindow.indexOf(record);
+ var recordsInPage = Math.floor(this._containerElementHeight / WebInspector.TimelinePanel.rowHeight);
+ var rowHeight = WebInspector.TimelinePanel.rowHeight;
+
+ if (index === -1)
+ index = 0;
+
+ switch (event.keyIdentifier) {
+ case "Left":
+ if (record.presentationParent()) {
+ if ((!record.expandable() || record.collapsed()) && record.presentationParent() !== this._presentationModel.rootRecord()) {
+ this._selectRecord(record.presentationParent());
+ } else {
+ record.setCollapsed(true);
+ this._invalidateAndScheduleRefresh(true, true);
+ }
+ }
+ event.consume(true);
+ break;
+ case "Up":
+ if (--index < 0)
+ break;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ case "Right":
+ if (record.expandable() && record.collapsed()) {
+ record.setCollapsed(false);
+ this._invalidateAndScheduleRefresh(true, true);
+ } else {
+ if (++index >= recordsInWindow.length)
+ break;
+ this._selectRecord(recordsInWindow[index]);
+ }
+ event.consume(true);
+ break;
+ case "Down":
+ if (++index >= recordsInWindow.length)
+ break;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ case "PageUp":
+ index = Math.max(0, index - recordsInPage);
+ this._scrollTop = Math.max(0, this._scrollTop - recordsInPage * rowHeight);
+ this._containerElement.scrollTop = this._scrollTop;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ case "PageDown":
+ index = Math.min(recordsInWindow.length - 1, index + recordsInPage);
+ this._scrollTop = Math.min(this._containerElement.scrollHeight - this._containerElementHeight, this._scrollTop + recordsInPage * rowHeight);
+ this._containerElement.scrollTop = this._scrollTop;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ case "Home":
+ index = 0;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ case "End":
+ index = recordsInWindow.length - 1;
+ this._selectRecord(recordsInWindow[index]);
+ event.consume(true);
+ break;
+ }
+ },
+
+ /**
+ * @param {?Element} rowElement
+ * @return {boolean}
+ */
+ _highlightQuad: function(rowElement)
+ {
+ if (!rowElement || !rowElement.row)
+ return false;
+ var presentationRecord = rowElement.row._record;
+ if (presentationRecord.coalesced())
+ return false;
+ var record = presentationRecord.record();
+ if (this._highlightedQuadRecord === record)
+ return true;
+ this._highlightedQuadRecord = record;
+
+ var quad = this._uiUtils.highlightQuadForRecord(record);
+ if (!quad)
+ return false;
+ record.target().domAgent().highlightQuad(quad, WebInspector.Color.PageHighlight.Content.toProtocolRGBA(), WebInspector.Color.PageHighlight.ContentOutline.toProtocolRGBA());
+ return true;
+ },
+
+ _hideQuadHighlight: function()
+ {
+ if (this._highlightedQuadRecord) {
+ this._highlightedQuadRecord.target().domAgent().hideHighlight();
+ delete this._highlightedQuadRecord;
+ }
+ },
+
+ /**
+ * @param {!Element} anchor
+ * @param {!WebInspector.Popover} popover
+ */
+ _showPopover: function(anchor, popover)
+ {
+ if (!anchor._tasksInfo)
+ return;
+ popover.show(WebInspector.TimelineUIUtils.generateMainThreadBarPopupContent(this._model, anchor._tasksInfo), anchor, null, null, WebInspector.Popover.Orientation.Bottom);
+ },
+
+ _closeRecordDetails: function()
+ {
+ this._popoverHelper.hidePopover();
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord)
+ {
+ if (this._highlightDomChanges)
+ WebInspector.revertDomChanges(this._highlightDomChanges);
+ this._highlightDomChanges = [];
+
+ var presentationRecord = this._presentationModel.toPresentationRecord(record);
+ if (!presentationRecord)
+ return;
+
+ if (selectRecord)
+ this._selectRecord(presentationRecord);
+
+ for (var element = this._sidebarListElement.firstChild; element; element = element.nextSibling) {
+ if (element.row._record === presentationRecord) {
+ element.row.highlight(regex, this._highlightDomChanges);
+ break;
+ }
+ }
+ },
+
+ __proto__: WebInspector.HBox.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TimelineModel} model
+ * @implements {WebInspector.TimelineGrid.Calculator}
+ */
+WebInspector.TimelineCalculator = function(model)
+{
+ this._model = model;
+}
+
+WebInspector.TimelineCalculator._minWidth = 5;
+
+WebInspector.TimelineCalculator.prototype = {
+ /**
+ * @return {number}
+ */
+ paddingLeft: function()
+ {
+ return this._paddingLeft;
+ },
+
+ /**
+ * @param {number} time
+ * @return {number}
+ */
+ computePosition: function(time)
+ {
+ return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea + this._paddingLeft;
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {!{start: number, end: number, cpuWidth: number}}
+ */
+ computeBarGraphPercentages: function(record)
+ {
+ var start = (record.startTime() - this._minimumBoundary) / this.boundarySpan() * 100;
+ var end = (record.startTime() + record.selfTime() - this._minimumBoundary) / this.boundarySpan() * 100;
+ var cpuWidth = (record.endTime() - record.startTime()) / this.boundarySpan() * 100;
+ return {start: start, end: end, cpuWidth: cpuWidth};
+ },
+
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @return {!{left: number, width: number, cpuWidth: number}}
+ */
+ computeBarGraphWindowPosition: function(record)
+ {
+ var percentages = this.computeBarGraphPercentages(record);
+ var widthAdjustment = 0;
+
+ var left = this.computePosition(record.startTime());
+ var width = (percentages.end - percentages.start) / 100 * this._workingArea;
+ if (width < WebInspector.TimelineCalculator._minWidth) {
+ widthAdjustment = WebInspector.TimelineCalculator._minWidth - width;
+ width = WebInspector.TimelineCalculator._minWidth;
+ }
+ var cpuWidth = percentages.cpuWidth / 100 * this._workingArea + widthAdjustment;
+ return {left: left, width: width, cpuWidth: cpuWidth};
+ },
+
+ setWindow: function(minimumBoundary, maximumBoundary)
+ {
+ this._minimumBoundary = minimumBoundary;
+ this._maximumBoundary = maximumBoundary;
+ },
+
+ /**
+ * @param {number} paddingLeft
+ * @param {number} clientWidth
+ */
+ setDisplayWindow: function(paddingLeft, clientWidth)
+ {
+ this._workingArea = clientWidth - WebInspector.TimelineCalculator._minWidth - paddingLeft;
+ this._paddingLeft = paddingLeft;
+ },
+
+ /**
+ * @param {number} value
+ * @param {number=} precision
+ * @return {string}
+ */
+ formatTime: function(value, precision)
+ {
+ return Number.preciseMillisToString(value - this.zeroTime(), precision);
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumBoundary: function()
+ {
+ return this._maximumBoundary;
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumBoundary: function()
+ {
+ return this._minimumBoundary;
+ },
+
+ /**
+ * @return {number}
+ */
+ zeroTime: function()
+ {
+ return this._model.minimumRecordTime();
+ },
+
+ /**
+ * @return {number}
+ */
+ boundarySpan: function()
+ {
+ return this._maximumBoundary - this._minimumBoundary;
+ }
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!WebInspector.TimelinePresentationModel.Record)} selectRecord
+ * @param {function()} scheduleRefresh
+ */
+WebInspector.TimelineRecordListRow = function(linkifier, selectRecord, scheduleRefresh)
+{
+ this.element = document.createElement("div");
+ this.element.row = this;
+ this.element.style.cursor = "pointer";
+ this.element.addEventListener("click", this._onClick.bind(this), false);
+ this.element.addEventListener("mouseover", this._onMouseOver.bind(this), false);
+ this.element.addEventListener("mouseout", this._onMouseOut.bind(this), false);
+ this._linkifier = linkifier;
+
+ // Warning is float right block, it goes first.
+ this._warningElement = this.element.createChild("div", "timeline-tree-item-warning hidden");
+
+ this._expandArrowElement = this.element.createChild("div", "timeline-tree-item-expand-arrow");
+ this._expandArrowElement.addEventListener("click", this._onExpandClick.bind(this), false);
+ var iconElement = this.element.createChild("span", "timeline-tree-icon");
+ this._typeElement = this.element.createChild("span", "type");
+
+ this._dataElement = this.element.createChild("span", "data dimmed");
+ this._scheduleRefresh = scheduleRefresh;
+ this._selectRecord = selectRecord;
+}
+
+WebInspector.TimelineRecordListRow.prototype = {
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} presentationRecord
+ * @param {number} offset
+ * @param {boolean} loadedFromFile
+ * @param {!WebInspector.TimelineUIUtils} uiUtils
+ */
+ update: function(presentationRecord, offset, loadedFromFile, uiUtils)
+ {
+ this._record = presentationRecord;
+ var record = presentationRecord.record();
+ this._offset = offset;
+
+ this.element.className = "timeline-tree-item timeline-category-" + record.category().name;
+ var paddingLeft = 5;
+ var step = -3;
+ for (var currentRecord = presentationRecord.presentationParent() ? presentationRecord.presentationParent().presentationParent() : null; currentRecord; currentRecord = currentRecord.presentationParent())
+ paddingLeft += 12 / (Math.max(1, step++));
+ this.element.style.paddingLeft = paddingLeft + "px";
+ if (record.thread())
+ this.element.classList.add("background");
+
+ this._typeElement.textContent = uiUtils.titleForRecord(record);
+
+ if (this._dataElement.firstChild)
+ this._dataElement.removeChildren();
+
+ this._warningElement.classList.toggle("hidden", !presentationRecord.hasWarnings() && !presentationRecord.childHasWarnings());
+ this._warningElement.classList.toggle("timeline-tree-item-child-warning", presentationRecord.childHasWarnings() && !presentationRecord.hasWarnings());
+
+ if (presentationRecord.coalesced()) {
+ this._dataElement.createTextChild(WebInspector.UIString("× %d", presentationRecord.presentationChildren().length));
+ } else {
+ var detailsNode = uiUtils.buildDetailsNode(record, this._linkifier, loadedFromFile);
+ if (detailsNode) {
+ this._dataElement.appendChild(document.createTextNode("("));
+ this._dataElement.appendChild(detailsNode);
+ this._dataElement.appendChild(document.createTextNode(")"));
+ }
+ }
+
+ this._expandArrowElement.classList.toggle("parent", presentationRecord.expandable());
+ this._expandArrowElement.classList.toggle("expanded", !!presentationRecord.visibleChildrenCount());
+ this._record.setListRow(this);
+ },
+
+ highlight: function(regExp, domChanges)
+ {
+ var matchInfo = this.element.textContent.match(regExp);
+ if (matchInfo)
+ WebInspector.highlightSearchResult(this.element, matchInfo.index, matchInfo[0].length, domChanges);
+ },
+
+ dispose: function()
+ {
+ this.element.remove();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onExpandClick: function(event)
+ {
+ this._record.setCollapsed(!this._record.collapsed());
+ this._scheduleRefresh();
+ event.consume(true);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onClick: function(event)
+ {
+ this._selectRecord(this._record);
+ },
+
+ /**
+ * @param {boolean} selected
+ */
+ renderAsSelected: function(selected)
+ {
+ this.element.classList.toggle("selected", selected);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOver: function(event)
+ {
+ this.element.classList.add("hovered");
+ if (this._record.graphRow())
+ this._record.graphRow().element.classList.add("hovered");
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOut: function(event)
+ {
+ this.element.classList.remove("hovered");
+ if (this._record.graphRow())
+ this._record.graphRow().element.classList.remove("hovered");
+ }
+}
+
+/**
+ * @constructor
+ * @param {!Element} graphContainer
+ * @param {function(!WebInspector.TimelinePresentationModel.Record)} selectRecord
+ * @param {function()} scheduleRefresh
+ */
+WebInspector.TimelineRecordGraphRow = function(graphContainer, selectRecord, scheduleRefresh)
+{
+ this.element = document.createElement("div");
+ this.element.row = this;
+ this.element.addEventListener("mouseover", this._onMouseOver.bind(this), false);
+ this.element.addEventListener("mouseout", this._onMouseOut.bind(this), false);
+ this.element.addEventListener("click", this._onClick.bind(this), false);
+
+ this._barAreaElement = document.createElement("div");
+ this._barAreaElement.className = "timeline-graph-bar-area";
+ this.element.appendChild(this._barAreaElement);
+
+ this._barCpuElement = document.createElement("div");
+ this._barCpuElement.className = "timeline-graph-bar cpu"
+ this._barCpuElement.row = this;
+ this._barAreaElement.appendChild(this._barCpuElement);
+
+ this._barElement = document.createElement("div");
+ this._barElement.className = "timeline-graph-bar";
+ this._barElement.row = this;
+ this._barAreaElement.appendChild(this._barElement);
+
+ this._expandElement = new WebInspector.TimelineExpandableElement(graphContainer);
+
+ this._selectRecord = selectRecord;
+ this._scheduleRefresh = scheduleRefresh;
+}
+
+WebInspector.TimelineRecordGraphRow.prototype = {
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} presentationRecord
+ * @param {!WebInspector.TimelineCalculator} calculator
+ * @param {number} expandOffset
+ * @param {number} index
+ */
+ update: function(presentationRecord, calculator, expandOffset, index)
+ {
+ this._record = presentationRecord;
+ var record = presentationRecord.record();
+ this.element.className = "timeline-graph-side timeline-category-" + record.category().name;
+ if (record.thread())
+ this.element.classList.add("background");
+
+ var barPosition = calculator.computeBarGraphWindowPosition(presentationRecord);
+ this._barElement.style.left = barPosition.left + "px";
+ this._barElement.style.width = barPosition.width + "px";
+ this._barCpuElement.style.left = barPosition.left + "px";
+ this._barCpuElement.style.width = barPosition.cpuWidth + "px";
+ this._expandElement._update(presentationRecord, index, barPosition.left - expandOffset, barPosition.width);
+ this._record.setGraphRow(this);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onClick: function(event)
+ {
+ // check if we click arrow and expand if yes.
+ if (this._expandElement._arrow.containsEventPoint(event))
+ this._expand();
+ this._selectRecord(this._record);
+ },
+
+ /**
+ * @param {boolean} selected
+ */
+ renderAsSelected: function(selected)
+ {
+ this.element.classList.toggle("selected", selected);
+ },
+
+ _expand: function()
+ {
+ this._record.setCollapsed(!this._record.collapsed());
+ this._scheduleRefresh();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOver: function(event)
+ {
+ this.element.classList.add("hovered");
+ if (this._record.listRow())
+ this._record.listRow().element.classList.add("hovered");
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOut: function(event)
+ {
+ this.element.classList.remove("hovered");
+ if (this._record.listRow())
+ this._record.listRow().element.classList.remove("hovered");
+ },
+
+ dispose: function()
+ {
+ this.element.remove();
+ this._expandElement._dispose();
+ }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TimelineExpandableElement = function(container)
+{
+ this._element = container.createChild("div", "timeline-expandable");
+ this._element.createChild("div", "timeline-expandable-left");
+ this._arrow = this._element.createChild("div", "timeline-expandable-arrow");
+}
+
+WebInspector.TimelineExpandableElement.prototype = {
+ /**
+ * @param {!WebInspector.TimelinePresentationModel.Record} record
+ * @param {number} index
+ * @param {number} left
+ * @param {number} width
+ */
+ _update: function(record, index, left, width)
+ {
+ const rowHeight = WebInspector.TimelinePanel.rowHeight;
+ if (record.visibleChildrenCount() || record.expandable()) {
+ this._element.style.top = index * rowHeight + "px";
+ this._element.style.left = left + "px";
+ this._element.style.width = Math.max(12, width + 25) + "px";
+ if (!record.collapsed()) {
+ this._element.style.height = (record.visibleChildrenCount() + 1) * rowHeight + "px";
+ this._element.classList.add("timeline-expandable-expanded");
+ this._element.classList.remove("timeline-expandable-collapsed");
+ } else {
+ this._element.style.height = rowHeight + "px";
+ this._element.classList.add("timeline-expandable-collapsed");
+ this._element.classList.remove("timeline-expandable-expanded");
+ }
+ this._element.classList.remove("hidden");
+ } else
+ this._element.classList.add("hidden");
+ },
+
+ _dispose: function()
+ {
+ this._element.remove();
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingModel.js
new file mode 100644
index 00000000000..c327bf84606
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingModel.js
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.TargetAwareObject}
+ */
+WebInspector.TracingModel = function(target)
+{
+ WebInspector.TargetAwareObject.call(this, target);
+ this.reset();
+ this._active = false;
+ InspectorBackend.registerTracingDispatcher(new WebInspector.TracingDispatcher(this));
+}
+
+WebInspector.TracingModel.Events = {
+ "BufferUsage": "BufferUsage"
+}
+
+/** @typedef {!{
+ cat: string,
+ pid: number,
+ tid: number,
+ ts: number,
+ ph: string,
+ name: string,
+ args: !Object,
+ dur: number,
+ id: number,
+ s: string
+ }}
+ */
+WebInspector.TracingModel.EventPayload;
+
+/**
+ * @enum {string}
+ */
+WebInspector.TracingModel.Phase = {
+ Begin: "B",
+ End: "E",
+ Complete: "X",
+ Instant: "i",
+ AsyncBegin: "S",
+ AsyncStepInto: "T",
+ AsyncStepPast: "p",
+ AsyncEnd: "F",
+ FlowBegin: "s",
+ FlowStep: "t",
+ FlowEnd: "f",
+ Metadata: "M",
+ Counter: "C",
+ Sample: "P",
+ CreateObject: "N",
+ SnapshotObject: "O",
+ DeleteObject: "D"
+};
+
+WebInspector.TracingModel.MetadataEvent = {
+ ProcessSortIndex: "process_sort_index",
+ ProcessName: "process_name",
+ ThreadSortIndex: "thread_sort_index",
+ ThreadName: "thread_name"
+}
+
+WebInspector.TracingModel.DevToolsMetadataEventCategory = "disabled-by-default-devtools.timeline";
+
+WebInspector.TracingModel.FrameLifecycleEventCategory = "cc,devtools";
+
+WebInspector.TracingModel.DevToolsMetadataEvent = {
+ TracingStartedInPage: "TracingStartedInPage",
+};
+
+WebInspector.TracingModel.prototype = {
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Event>}
+ */
+ devtoolsMetadataEvents: function()
+ {
+ return this._devtoolsMetadataEvents;
+ },
+
+ /**
+ * @param {string} categoryFilter
+ * @param {string} options
+ * @param {function(?string)=} callback
+ */
+ start: function(categoryFilter, options, callback)
+ {
+ this.reset();
+ var bufferUsageReportingIntervalMs = 500;
+ /**
+ * @param {?string} error
+ * @param {string} sessionId
+ * @this {WebInspector.TracingModel}
+ */
+ function callbackWrapper(error, sessionId)
+ {
+ this._sessionId = sessionId;
+ if (callback)
+ callback(error);
+ }
+ TracingAgent.start(categoryFilter, options, bufferUsageReportingIntervalMs, callbackWrapper.bind(this));
+ this._active = true;
+ },
+
+ /**
+ * @param {function()} callback
+ */
+ stop: function(callback)
+ {
+ if (!this._active) {
+ callback();
+ return;
+ }
+ this._pendingStopCallback = callback;
+ TracingAgent.end();
+ },
+
+ /**
+ * @return {?string}
+ */
+ sessionId: function()
+ {
+ return this._sessionId;
+ },
+
+ /**
+ * @param {string} sessionId
+ * @param {!Array.<!WebInspector.TracingModel.EventPayload>} events
+ */
+ setEventsForTest: function(sessionId, events)
+ {
+ this.reset();
+ this._sessionId = sessionId;
+ this._eventsCollected(events);
+ this._tracingComplete();
+ },
+
+ /**
+ * @param {number} usage
+ */
+ _bufferUsage: function(usage)
+ {
+ this.dispatchEventToListeners(WebInspector.TracingModel.Events.BufferUsage, usage);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.TracingModel.EventPayload>} events
+ */
+ _eventsCollected: function(events)
+ {
+ for (var i = 0; i < events.length; ++i)
+ this._addEvent(events[i]);
+ },
+
+ _tracingComplete: function()
+ {
+ this._active = false;
+ if (!this._pendingStopCallback)
+ return;
+ this._pendingStopCallback();
+ this._pendingStopCallback = null;
+ },
+
+ reset: function()
+ {
+ this._processById = {};
+ this._minimumRecordTime = 0;
+ this._maximumRecordTime = 0;
+ this._sessionId = null;
+ this._devtoolsMetadataEvents = [];
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.EventPayload} payload
+ */
+ _addEvent: function(payload)
+ {
+ var process = this._processById[payload.pid];
+ if (!process) {
+ process = new WebInspector.TracingModel.Process(payload.pid);
+ this._processById[payload.pid] = process;
+ }
+ var thread = process.threadById(payload.tid);
+ if (payload.ph !== WebInspector.TracingModel.Phase.Metadata) {
+ var timestamp = payload.ts / 1000;
+ // We do allow records for unrelated threads to arrive out-of-order,
+ // so there's a chance we're getting records from the past.
+ if (timestamp && (!this._minimumRecordTime || timestamp < this._minimumRecordTime))
+ this._minimumRecordTime = timestamp;
+ if (!this._maximumRecordTime || timestamp > this._maximumRecordTime)
+ this._maximumRecordTime = timestamp;
+ var event = thread.addEvent(payload);
+ if (payload.ph === WebInspector.TracingModel.Phase.SnapshotObject)
+ process.addObject(event);
+ if (event && event.name === WebInspector.TracingModel.DevToolsMetadataEvent.TracingStartedInPage &&
+ event.category === WebInspector.TracingModel.DevToolsMetadataEventCategory &&
+ event.args["sessionId"] === this._sessionId)
+ this._devtoolsMetadataEvents.push(event);
+ return;
+ }
+ switch (payload.name) {
+ case WebInspector.TracingModel.MetadataEvent.ProcessSortIndex:
+ process._setSortIndex(payload.args["sort_index"]);
+ break;
+ case WebInspector.TracingModel.MetadataEvent.ProcessName:
+ process._setName(payload.args["name"]);
+ break;
+ case WebInspector.TracingModel.MetadataEvent.ThreadSortIndex:
+ thread._setSortIndex(payload.args["sort_index"]);
+ break;
+ case WebInspector.TracingModel.MetadataEvent.ThreadName:
+ thread._setName(payload.args["name"]);
+ break;
+ }
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRecordTime: function()
+ {
+ return this._minimumRecordTime;
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumRecordTime: function()
+ {
+ return this._maximumRecordTime;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Process>}
+ */
+ sortedProcesses: function()
+ {
+ return WebInspector.TracingModel.NamedObject._sort(Object.values(this._processById));
+ },
+
+ __proto__: WebInspector.TargetAwareObject.prototype
+}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TracingModel.EventPayload} payload
+ * @param {number} level
+ * @param {?WebInspector.TracingModel.Thread} thread
+ */
+WebInspector.TracingModel.Event = function(payload, level, thread)
+{
+ this.name = payload.name;
+ this.category = payload.cat;
+ this.startTime = payload.ts / 1000;
+ this.args = payload.args;
+ this.phase = payload.ph;
+ this.level = level;
+
+ if (payload.dur)
+ this._setEndTime((payload.ts + payload.dur) / 1000);
+
+ if (payload.id)
+ this.id = payload.id;
+
+ this.thread = thread;
+
+ /** @type {?string} */
+ this.warning = null;
+ /** @type {?WebInspector.TracingModel.Event} */
+ this.initiator = null;
+ /** @type {?Array.<!ConsoleAgent.CallFrame>} */
+ this.stackTrace = null;
+ /** @type {?Element} */
+ this.previewElement = null;
+ /** @type {?string} */
+ this.imageURL = null;
+ /** @type {number} */
+ this.backendNodeId = 0;
+
+ /** @type {number} */
+ this.selfTime = 0;
+}
+
+WebInspector.TracingModel.Event.prototype = {
+ /**
+ * @param {number} endTime
+ */
+ _setEndTime: function(endTime)
+ {
+ if (endTime < this.startTime) {
+ console.assert(false, "Event out of order: " + this.name);
+ return;
+ }
+ this.endTime = endTime;
+ this.duration = endTime - this.startTime;
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.EventPayload} payload
+ */
+ _complete: function(payload)
+ {
+ if (this.name !== payload.name) {
+ console.assert(false, "Open/close event mismatch: " + this.name + " vs. " + payload.name);
+ return;
+ }
+ if (payload.args) {
+ for (var name in payload.args) {
+ if (name in this.args)
+ console.error("Same argument name (" + name + ") is used for begin and end phases of " + this.name);
+ this.args[name] = payload.args[name];
+ }
+ }
+ this._setEndTime(payload.ts / 1000);
+ }
+}
+
+/**
+ * @param {!WebInspector.TracingModel.Event} a
+ * @param {!WebInspector.TracingModel.Event} b
+ * @return {number}
+ */
+WebInspector.TracingModel.Event.compareStartTime = function (a, b)
+{
+ return a.startTime - b.startTime;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.TracingModel.NamedObject = function()
+{
+}
+
+WebInspector.TracingModel.NamedObject.prototype =
+{
+ /**
+ * @param {string} name
+ */
+ _setName: function(name)
+ {
+ this._name = name;
+ },
+
+ /**
+ * @return {string}
+ */
+ name: function()
+ {
+ return this._name;
+ },
+
+ /**
+ * @param {number} sortIndex
+ */
+ _setSortIndex: function(sortIndex)
+ {
+ this._sortIndex = sortIndex;
+ },
+}
+
+/**
+ * @param {!Array.<!WebInspector.TracingModel.NamedObject>} array
+ */
+WebInspector.TracingModel.NamedObject._sort = function(array)
+{
+ /**
+ * @param {!WebInspector.TracingModel.NamedObject} a
+ * @param {!WebInspector.TracingModel.NamedObject} b
+ */
+ function comparator(a, b)
+ {
+ return a._sortIndex !== b._sortIndex ? a._sortIndex - b._sortIndex : a.name().localeCompare(b.name());
+ }
+ return array.sort(comparator);
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TracingModel.NamedObject}
+ * @param {number} id
+ */
+WebInspector.TracingModel.Process = function(id)
+{
+ WebInspector.TracingModel.NamedObject.call(this);
+ this._setName("Process " + id);
+ this._threads = {};
+ this._objects = {};
+}
+
+WebInspector.TracingModel.Process.prototype = {
+ /**
+ * @param {number} id
+ * @return {!WebInspector.TracingModel.Thread}
+ */
+ threadById: function(id)
+ {
+ var thread = this._threads[id];
+ if (!thread) {
+ thread = new WebInspector.TracingModel.Thread(this, id);
+ this._threads[id] = thread;
+ }
+ return thread;
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ addObject: function(event)
+ {
+ this.objectsByName(event.name).push(event);
+ },
+
+ /**
+ * @param {string} name
+ * @return {!Array.<!WebInspector.TracingModel.Event>}
+ */
+ objectsByName: function(name)
+ {
+ var objects = this._objects[name];
+ if (!objects) {
+ objects = [];
+ this._objects[name] = objects;
+ }
+ return objects;
+ },
+
+ /**
+ * @return {!Array.<string>}
+ */
+ sortedObjectNames: function()
+ {
+ return Object.keys(this._objects).sort();
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Thread>}
+ */
+ sortedThreads: function()
+ {
+ return WebInspector.TracingModel.NamedObject._sort(Object.values(this._threads));
+ },
+
+ __proto__: WebInspector.TracingModel.NamedObject.prototype
+}
+
+/**
+ * @constructor
+ * @extends {WebInspector.TracingModel.NamedObject}
+ * @param {!WebInspector.TracingModel.Process} process
+ * @param {number} id
+ */
+WebInspector.TracingModel.Thread = function(process, id)
+{
+ WebInspector.TracingModel.NamedObject.call(this);
+ this._process = process;
+ this._setName("Thread " + id);
+ this._events = [];
+ this._stack = [];
+ this._maxStackDepth = 0;
+}
+
+WebInspector.TracingModel.Thread.prototype = {
+ /**
+ * @param {!WebInspector.TracingModel.EventPayload} payload
+ * @return {?WebInspector.TracingModel.Event} event
+ */
+ addEvent: function(payload)
+ {
+ for (var top = this._stack.peekLast(); top && top.endTime && top.endTime <= payload.ts / 1000;) {
+ this._stack.pop();
+ top = this._stack.peekLast();
+ }
+ if (payload.ph === WebInspector.TracingModel.Phase.End) {
+ var openEvent = this._stack.pop();
+ // Quietly ignore unbalanced close events, they're legit (we could have missed start one).
+ if (openEvent)
+ openEvent._complete(payload);
+ return null;
+ }
+
+ var event = new WebInspector.TracingModel.Event(payload, this._stack.length, this);
+ if (payload.ph === WebInspector.TracingModel.Phase.Begin || payload.ph === WebInspector.TracingModel.Phase.Complete) {
+ this._stack.push(event);
+ if (this._maxStackDepth < this._stack.length)
+ this._maxStackDepth = this._stack.length;
+ }
+ if (this._events.length && this._events.peekLast().startTime > event.startTime)
+ console.assert(false, "Event is our of order: " + event.name);
+ this._events.push(event);
+ return event;
+ },
+
+ /**
+ * @return {!WebInspector.TracingModel.Process}
+ */
+ process: function()
+ {
+ return this._process;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Event>}
+ */
+ events: function()
+ {
+ return this._events;
+ },
+
+ /**
+ * @return {number}
+ */
+ maxStackDepth: function()
+ {
+ // Reserve one for non-container events.
+ return this._maxStackDepth + 1;
+ },
+
+ __proto__: WebInspector.TracingModel.NamedObject.prototype
+}
+
+
+/**
+ * @constructor
+ * @implements {TracingAgent.Dispatcher}
+ * @param {!WebInspector.TracingModel} tracingModel
+ */
+WebInspector.TracingDispatcher = function(tracingModel)
+{
+ this._tracingModel = tracingModel;
+}
+
+WebInspector.TracingDispatcher.prototype = {
+ /**
+ * @param {number} usage
+ */
+ bufferUsage: function(usage)
+ {
+ this._tracingModel._bufferUsage(usage);
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.TracingModel.EventPayload>} data
+ */
+ dataCollected: function(data)
+ {
+ this._tracingModel._eventsCollected(data);
+ },
+
+ tracingComplete: function()
+ {
+ this._tracingModel._tracingComplete();
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineModel.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineModel.js
new file mode 100644
index 00000000000..482fa1364e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineModel.js
@@ -0,0 +1,661 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @param {!WebInspector.TracingModel} tracingModel
+ * @constructor
+ * @extends {WebInspector.TimelineModel}
+ */
+WebInspector.TracingTimelineModel = function(tracingModel)
+{
+ WebInspector.TimelineModel.call(this, tracingModel.target());
+ this._tracingModel = tracingModel;
+ this._mainThreadEvents = [];
+ this._inspectedTargetEvents = [];
+
+ this.reset();
+}
+
+WebInspector.TracingTimelineModel.RecordType = {
+ Program: "Program",
+ EventDispatch: "EventDispatch",
+
+ GPUTask: "GPUTask",
+
+ RequestMainThreadFrame: "RequestMainThreadFrame",
+ BeginFrame: "BeginFrame",
+ BeginMainThreadFrame: "BeginMainThreadFrame",
+ ActivateLayerTree: "ActivateLayerTree",
+ DrawFrame: "DrawFrame",
+ ScheduleStyleRecalculation: "ScheduleStyleRecalculation",
+ RecalculateStyles: "RecalculateStyles",
+ InvalidateLayout: "InvalidateLayout",
+ Layout: "Layout",
+ UpdateLayer: "UpdateLayer",
+ PaintSetup: "PaintSetup",
+ Paint: "Paint",
+ PaintImage: "PaintImage",
+ Rasterize: "Rasterize",
+ RasterTask: "RasterTask",
+ ScrollLayer: "ScrollLayer",
+ CompositeLayers: "CompositeLayers",
+
+ ParseHTML: "ParseHTML",
+
+ TimerInstall: "TimerInstall",
+ TimerRemove: "TimerRemove",
+ TimerFire: "TimerFire",
+
+ XHRReadyStateChange: "XHRReadyStateChange",
+ XHRLoad: "XHRLoad",
+ EvaluateScript: "EvaluateScript",
+
+ MarkLoad: "MarkLoad",
+ MarkDOMContent: "MarkDOMContent",
+ MarkFirstPaint: "MarkFirstPaint",
+
+ TimeStamp: "TimeStamp",
+ ConsoleTime: "ConsoleTime",
+
+ ResourceSendRequest: "ResourceSendRequest",
+ ResourceReceiveResponse: "ResourceReceiveResponse",
+ ResourceReceivedData: "ResourceReceivedData",
+ ResourceFinish: "ResourceFinish",
+
+ FunctionCall: "FunctionCall",
+ GCEvent: "GCEvent",
+ JSFrame: "JSFrame",
+
+ UpdateCounters: "UpdateCounters",
+
+ RequestAnimationFrame: "RequestAnimationFrame",
+ CancelAnimationFrame: "CancelAnimationFrame",
+ FireAnimationFrame: "FireAnimationFrame",
+
+ WebSocketCreate : "WebSocketCreate",
+ WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest",
+ WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse",
+ WebSocketDestroy : "WebSocketDestroy",
+
+ EmbedderCallback : "EmbedderCallback",
+
+ CallStack: "CallStack",
+ SetLayerTreeId: "SetLayerTreeId",
+ TracingStartedInPage: "TracingStartedInPage",
+
+ DecodeImage: "Decode Image",
+ ResizeImage: "Resize Image",
+ DrawLazyPixelRef: "Draw LazyPixelRef",
+ DecodeLazyPixelRef: "Decode LazyPixelRef",
+
+ LazyPixelRef: "LazyPixelRef",
+ LayerTreeHostImplSnapshot: "cc::LayerTreeHostImpl",
+ PictureSnapshot: "cc::Picture"
+};
+
+WebInspector.TracingTimelineModel.defaultTracingCategoryFilter = "*,disabled-by-default-cc.debug,disabled-by-default-devtools.timeline,disabled-by-default-devtools.timeline.frame";
+
+WebInspector.TracingTimelineModel.prototype = {
+ /**
+ * @param {boolean} captureStacks
+ * @param {boolean} captureMemory
+ * @param {boolean} capturePictures
+ */
+ startRecording: function(captureStacks, captureMemory, capturePictures)
+ {
+ var categories;
+ if (WebInspector.experimentsSettings.timelineTracingMode.isEnabled()) {
+ categories = WebInspector.TracingTimelineModel.defaultTracingCategoryFilter;
+ } else {
+ var categoriesArray = ["disabled-by-default-devtools.timeline", "disabled-by-default-devtools.timeline.frame", "devtools"];
+ if (captureStacks)
+ categoriesArray.push("disabled-by-default-devtools.timeline.stack");
+ if (capturePictures)
+ categoriesArray.push("disabled-by-default-devtools.timeline.layers", "disabled-by-default-devtools.timeline.picture");
+ categories = categoriesArray.join(",");
+ }
+ this._startRecordingWithCategories(categories);
+ },
+
+ stopRecording: function()
+ {
+ this._tracingModel.stop(this._didStopRecordingTraceEvents.bind(this));
+ },
+
+ /**
+ * @param {string} sessionId
+ * @param {!Array.<!WebInspector.TracingModel.EventPayload>} events
+ */
+ setEventsForTest: function(sessionId, events)
+ {
+ this.reset();
+ this._didStartRecordingTraceEvents();
+ this._tracingModel.setEventsForTest(sessionId, events);
+ this._didStopRecordingTraceEvents();
+ },
+
+ /**
+ * @param {string} categories
+ */
+ _startRecordingWithCategories: function(categories)
+ {
+ this.reset();
+ this._tracingModel.start(categories, "", this._didStartRecordingTraceEvents.bind(this));
+ },
+
+ _didStartRecordingTraceEvents: function()
+ {
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStarted);
+ },
+
+ _didStopRecordingTraceEvents: function()
+ {
+ var events = this._tracingModel.devtoolsMetadataEvents();
+ events.sort(WebInspector.TracingModel.Event.compareStartTime);
+
+ this._resetProcessingState();
+ for (var i = 0, length = events.length; i < length; i++) {
+ var event = events[i];
+ var process = event.thread.process();
+ var startTime = event.startTime;
+
+ var endTime = Infinity;
+ if (i + 1 < length)
+ endTime = events[i + 1].startTime;
+
+ process.sortedThreads().forEach(this._processThreadEvents.bind(this, startTime, endTime, event.thread));
+ }
+ this._resetProcessingState();
+
+ this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
+
+ this._buildTimelineRecords();
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
+ },
+
+ /**
+ * @return {number}
+ */
+ minimumRecordTime: function()
+ {
+ return this._tracingModel.minimumRecordTime();
+ },
+
+ /**
+ * @return {number}
+ */
+ maximumRecordTime: function()
+ {
+ return this._tracingModel.maximumRecordTime();
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Event>}
+ */
+ inspectedTargetEvents: function()
+ {
+ return this._inspectedTargetEvents;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TracingModel.Event>}
+ */
+ mainThreadEvents: function()
+ {
+ return this._mainThreadEvents;
+ },
+
+ reset: function()
+ {
+ this._mainThreadEvents = [];
+ this._inspectedTargetEvents = [];
+ WebInspector.TimelineModel.prototype.reset.call(this);
+ },
+
+ _buildTimelineRecords: function()
+ {
+ var recordStack = [];
+ var mainThreadEvents = this._mainThreadEvents;
+ for (var i = 0, size = mainThreadEvents.length; i < size; ++i) {
+ var event = mainThreadEvents[i];
+ while (recordStack.length) {
+ var top = recordStack.peekLast();
+ if (top._event.endTime >= event.startTime)
+ break;
+ recordStack.pop();
+ }
+ var parentRecord = recordStack.peekLast() || null;
+ var record = new WebInspector.TracingTimelineModel.TraceEventRecord(this, event, parentRecord);
+ if (WebInspector.TracingTimelineUIUtils.isEventDivider(record))
+ this._eventDividerRecords.push(record);
+ if (!recordStack.length)
+ this._addTopLevelRecord(record);
+ if (event.endTime)
+ recordStack.push(record);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TracingTimelineModel.TraceEventRecord} record
+ */
+ _addTopLevelRecord: function(record)
+ {
+ this._updateBoundaries(record);
+ this._records.push(record);
+ if (record.type() === WebInspector.TimelineModel.RecordType.Program)
+ this._mainThreadTasks.push(record);
+ if (record.type() === WebInspector.TimelineModel.RecordType.GPUTask)
+ this._gpuThreadTasks.push(record);
+ this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAdded, record);
+ },
+
+ _resetProcessingState: function()
+ {
+ this._sendRequestEvents = {};
+ this._timerEvents = {};
+ this._requestAnimationFrameEvents = {};
+ this._layoutInvalidate = {};
+ this._lastScheduleStyleRecalculation = {};
+ this._webSocketCreateEvents = {};
+ this._paintImageEventByPixelRefId = {};
+ this._lastPaintForLayer = {};
+ this._lastRecalculateStylesEvent = null;
+ this._currentScriptEvent = null;
+ this._eventStack = [];
+ },
+
+ /**
+ * @param {number} startTime
+ * @param {?number} endTime
+ * @param {!WebInspector.TracingModel.Thread} mainThread
+ * @param {!WebInspector.TracingModel.Thread} thread
+ */
+ _processThreadEvents: function(startTime, endTime, mainThread, thread)
+ {
+ var events = thread.events();
+ var length = events.length;
+ var i = events.lowerBound(startTime, function (time, event) { return time - event.startTime });
+
+ this._eventStack = [];
+ for (; i < length; i++) {
+ var event = events[i];
+ if (endTime && event.startTime >= endTime)
+ break;
+ this._processEvent(event);
+ if (thread === mainThread)
+ this._mainThreadEvents.push(event);
+ this._inspectedTargetEvents.push(event);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.TracingModel.Event} event
+ */
+ _processEvent: function(event)
+ {
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+
+ var eventStack = this._eventStack;
+ while (eventStack.length && eventStack.peekLast().endTime < event.startTime)
+ eventStack.pop();
+ var duration = event.duration;
+ if (duration) {
+ if (eventStack.length) {
+ var parent = eventStack.peekLast();
+ parent.selfTime -= duration;
+ }
+ event.selfTime = duration;
+ eventStack.push(event);
+ }
+
+ if (this._currentScriptEvent && event.startTime > this._currentScriptEvent.endTime)
+ this._currentScriptEvent = null;
+
+ switch (event.name) {
+ case recordTypes.CallStack:
+ var lastMainThreadEvent = this._mainThreadEvents.peekLast();
+ if (lastMainThreadEvent && event.args.stack && event.args.stack.length)
+ lastMainThreadEvent.stackTrace = event.args.stack;
+ break;
+
+ case recordTypes.ResourceSendRequest:
+ this._sendRequestEvents[event.args.data["requestId"]] = event;
+ event.imageURL = event.args.data["url"];
+ break;
+
+ case recordTypes.ResourceReceiveResponse:
+ case recordTypes.ResourceReceivedData:
+ case recordTypes.ResourceFinish:
+ event.initiator = this._sendRequestEvents[event.args.data["requestId"]];
+ if (event.initiator)
+ event.imageURL = event.initiator.imageURL;
+ break;
+
+ case recordTypes.TimerInstall:
+ this._timerEvents[event.args.data["timerId"]] = event;
+ break;
+
+ case recordTypes.TimerFire:
+ event.initiator = this._timerEvents[event.args.data["timerId"]];
+ break;
+
+ case recordTypes.RequestAnimationFrame:
+ this._requestAnimationFrameEvents[event.args.data["id"]] = event;
+ break;
+
+ case recordTypes.FireAnimationFrame:
+ event.initiator = this._requestAnimationFrameEvents[event.args.data["id"]];
+ break;
+
+ case recordTypes.ScheduleStyleRecalculation:
+ this._lastScheduleStyleRecalculation[event.args.frame] = event;
+ break;
+
+ case recordTypes.RecalculateStyles:
+ event.initiator = this._lastScheduleStyleRecalculation[event.args.frame];
+ this._lastRecalculateStylesEvent = event;
+ break;
+
+ case recordTypes.InvalidateLayout:
+ // Consider style recalculation as a reason for layout invalidation,
+ // but only if we had no earlier layout invalidation records.
+ var layoutInitator = event;
+ var frameId = event.args.frame;
+ if (!this._layoutInvalidate[frameId] && this._lastRecalculateStylesEvent && this._lastRecalculateStylesEvent.endTime > event.startTime)
+ layoutInitator = this._lastRecalculateStylesEvent.initiator;
+ this._layoutInvalidate[frameId] = layoutInitator;
+ break;
+
+ case recordTypes.Layout:
+ var frameId = event.args["beginData"]["frame"];
+ event.initiator = this._layoutInvalidate[frameId];
+ event.backendNodeId = event.args["endData"]["rootNode"];
+ event.highlightQuad = event.args["endData"]["root"];
+ this._layoutInvalidate[frameId] = null;
+ if (this._currentScriptEvent)
+ event.warning = WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck.");
+ break;
+
+ case recordTypes.WebSocketCreate:
+ this._webSocketCreateEvents[event.args.data["identifier"]] = event;
+ break;
+
+ case recordTypes.WebSocketSendHandshakeRequest:
+ case recordTypes.WebSocketReceiveHandshakeResponse:
+ case recordTypes.WebSocketDestroy:
+ event.initiator = this._webSocketCreateEvents[event.args.data["identifier"]];
+ break;
+
+ case recordTypes.EvaluateScript:
+ case recordTypes.FunctionCall:
+ if (!this._currentScriptEvent)
+ this._currentScriptEvent = event;
+ break;
+
+ case recordTypes.SetLayerTreeId:
+ this._inspectedTargetLayerTreeId = event.args["layerTreeId"];
+ break;
+
+ case recordTypes.Paint:
+ event.highlightQuad = event.args["data"]["clip"];
+ event.backendNodeId = event.args["data"]["nodeId"];
+ var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
+ if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== this._inspectedTargetLayerTreeId)
+ break;
+ this._lastPaintForLayer[layerUpdateEvent.args["layerId"]] = event;
+ break;
+
+ case recordTypes.PictureSnapshot:
+ var layerUpdateEvent = this._findAncestorEvent(recordTypes.UpdateLayer);
+ if (!layerUpdateEvent || layerUpdateEvent.args["layerTreeId"] !== this._inspectedTargetLayerTreeId)
+ break;
+ var paintEvent = this._lastPaintForLayer[layerUpdateEvent.args["layerId"]];
+ if (!paintEvent)
+ break;
+ paintEvent.picture = event.args["snapshot"]["skp64"];
+ break;
+
+ case recordTypes.ScrollLayer:
+ event.backendNodeId = event.args["data"]["nodeId"];
+ break;
+
+ case recordTypes.PaintImage:
+ event.backendNodeId = event.args["data"]["nodeId"];
+ event.imageURL = event.args["data"]["url"];
+ break;
+
+ case recordTypes.DecodeImage:
+ case recordTypes.ResizeImage:
+ var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
+ if (!paintImageEvent) {
+ var decodeLazyPixelRefEvent = this._findAncestorEvent(recordTypes.DecodeLazyPixelRef);
+ paintImageEvent = decodeLazyPixelRefEvent && this._paintImageEventByPixelRefId[decodeLazyPixelRefEvent.args["LazyPixelRef"]];
+ }
+ if (!paintImageEvent)
+ break;
+ event.backendNodeId = paintImageEvent.backendNodeId;
+ event.imageURL = paintImageEvent.imageURL;
+ break;
+
+ case recordTypes.DrawLazyPixelRef:
+ var paintImageEvent = this._findAncestorEvent(recordTypes.PaintImage);
+ if (!paintImageEvent)
+ break;
+ this._paintImageEventByPixelRefId[event.args["LazyPixelRef"]] = paintImageEvent;
+ event.backendNodeId = paintImageEvent.backendNodeId;
+ event.imageURL = paintImageEvent.imageURL;
+ break;
+ }
+ },
+
+ /**
+ * @param {string} name
+ * @return {?WebInspector.TracingModel.Event}
+ */
+ _findAncestorEvent: function(name)
+ {
+ for (var i = this._eventStack.length - 1; i >= 0; --i) {
+ var event = this._eventStack[i];
+ if (event.name === name)
+ return event;
+ }
+ return null;
+ },
+
+ __proto__: WebInspector.TimelineModel.prototype
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.TimelineModel.Record}
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.TracingModel.Event} traceEvent
+ * @param {?WebInspector.TracingTimelineModel.TraceEventRecord} parentRecord
+ */
+WebInspector.TracingTimelineModel.TraceEventRecord = function(model, traceEvent, parentRecord)
+{
+ this._model = model;
+ this._event = traceEvent;
+ traceEvent._timelineRecord = this;
+ if (parentRecord) {
+ this.parent = parentRecord;
+ parentRecord._children.push(this);
+ }
+ this._children = [];
+}
+
+WebInspector.TracingTimelineModel.TraceEventRecord.prototype = {
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ callSiteStackTrace: function()
+ {
+ var initiator = this._event.initiator;
+ return initiator ? initiator.stackTrace : null;
+ },
+
+ /**
+ * @return {?WebInspector.TimelineModel.Record}
+ */
+ initiator: function()
+ {
+ var initiator = this._event.initiator;
+ return initiator ? initiator._timelineRecord : null;
+ },
+
+ /**
+ * @return {!WebInspector.Target}
+ */
+ target: function()
+ {
+ return this._model.target();
+ },
+
+ /**
+ * @return {number}
+ */
+ selfTime: function()
+ {
+ return this._event.selfTime;
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.TimelineModel.Record>}
+ */
+ children: function()
+ {
+ return this._children;
+ },
+
+ /**
+ * @return {!WebInspector.TimelineCategory}
+ */
+ category: function()
+ {
+ var style = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(this._event.name);
+ return style.category;
+ },
+
+ /**
+ * @return {number}
+ */
+ startTime: function()
+ {
+ return this._event.startTime;
+ },
+
+ /**
+ * @return {string|undefined}
+ */
+ thread: function()
+ {
+ return "CPU";
+ },
+
+ /**
+ * @return {number}
+ */
+ endTime: function()
+ {
+ return this._event.endTime || this._event.startTime;
+ },
+
+ /**
+ * @param {number} endTime
+ */
+ setEndTime: function(endTime)
+ {
+ throw new Error("Unsupported operation setEndTime");
+ },
+
+ /**
+ * @return {!Object}
+ */
+ data: function()
+ {
+ return this._event.args.data;
+ },
+
+ /**
+ * @return {string}
+ */
+ type: function()
+ {
+ return this._event.name;
+ },
+
+ /**
+ * @return {string}
+ */
+ frameId: function()
+ {
+ switch (this._event.name) {
+ case WebInspector.TracingTimelineModel.RecordType.ScheduleStyleRecalculation:
+ case WebInspector.TracingTimelineModel.RecordType.RecalculateStyles:
+ case WebInspector.TracingTimelineModel.RecordType.InvalidateLayout:
+ return this._event.args["frameId"];
+ case WebInspector.TracingTimelineModel.RecordType.Layout:
+ return this._event.args["beginData"]["frameId"];
+ default:
+ var data = this._event.args.data;
+ return (data && data["frame"]) || "";
+ }
+ },
+
+ /**
+ * @return {?Array.<!ConsoleAgent.CallFrame>}
+ */
+ stackTrace: function()
+ {
+ return this._event.stackTrace;
+ },
+
+ /**
+ * @param {string} key
+ * @return {?Object}
+ */
+ getUserObject: function(key)
+ {
+ if (key === "TimelineUIUtils::preview-element")
+ return this._event.previewElement;
+ throw new Error("Unexpected key: " + key);
+ },
+
+ /**
+ * @param {string} key
+ * @param {?Object|undefined} value
+ */
+ setUserObject: function(key, value)
+ {
+ if (key !== "TimelineUIUtils::preview-element")
+ throw new Error("Unexpected key: " + key);
+ this._event.previewElement = /** @type {?Element} */ (value);
+ },
+
+ /**
+ * @return {!Object.<string, number>}
+ */
+ aggregatedStats: function()
+ {
+ return {};
+ },
+
+ /**
+ * @return {?Array.<string>}
+ */
+ warnings: function()
+ {
+ if (this._event.warning)
+ return [this._event.warning];
+ return null;
+ },
+
+ /**
+ * @return {!WebInspector.TracingModel.Event}
+ */
+ traceEvent: function()
+ {
+ return this._event;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineUIUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineUIUtils.js
new file mode 100644
index 00000000000..725f9b1c27f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TracingTimelineUIUtils.js
@@ -0,0 +1,729 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.TimelineUIUtils}
+ */
+WebInspector.TracingTimelineUIUtils = function()
+{
+ WebInspector.TimelineUIUtils.call(this);
+}
+
+WebInspector.TracingTimelineUIUtils.prototype = {
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isBeginFrame: function(record)
+ {
+ return record.type() === WebInspector.TracingTimelineModel.RecordType.BeginFrame;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isProgram: function(record)
+ {
+ return record.type() === WebInspector.TracingTimelineModel.RecordType.Program;
+ },
+
+ /**
+ * @param {string} recordType
+ * @return {boolean}
+ */
+ isCoalescable: function(recordType)
+ {
+ return !!WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[recordType];
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+ isEventDivider: function(record)
+ {
+ return WebInspector.TracingTimelineUIUtils.isEventDivider(record);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ countersForRecord: function(record)
+ {
+ return record.type() === WebInspector.TracingTimelineModel.RecordType.UpdateCounters ? record.data() : null;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {?Object}
+ */
+ highlightQuadForRecord: function(record)
+ {
+ return record.traceEvent().highlightQuad || null;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {string}
+ */
+ titleForRecord: function(record)
+ {
+ return WebInspector.TracingTimelineUIUtils.styleForTraceEvent(record.traceEvent().name).title;
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {boolean} loadedFromFile
+ * @return {?Node}
+ */
+ buildDetailsNode: function(record, linkifier, loadedFromFile)
+ {
+ return WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent(record.traceEvent(), linkifier, loadedFromFile, record.target());
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!WebInspector.TimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!DocumentFragment)} callback
+ * @param {boolean} loadedFromFile
+ */
+ generateDetailsContent: function(record, model, linkifier, callback, loadedFromFile)
+ {
+ if (!(model instanceof WebInspector.TracingTimelineModel))
+ throw new Error("Illegal argument.");
+ var tracingTimelineModel = /** @type {!WebInspector.TracingTimelineModel} */ (model);
+ WebInspector.TracingTimelineUIUtils.buildTraceEventDetails(record.traceEvent(), tracingTimelineModel, linkifier, callback, loadedFromFile, record.target());
+ },
+
+ /**
+ * @return {!Element}
+ */
+ createBeginFrameDivider: function()
+ {
+ return this.createEventDivider(WebInspector.TracingTimelineModel.RecordType.BeginFrame);
+ },
+
+ /**
+ * @param {string} recordType
+ * @param {string=} title
+ * @return {!Element}
+ */
+ createEventDivider: function(recordType, title)
+ {
+ return WebInspector.TracingTimelineUIUtils._createEventDivider(recordType, title);
+ },
+
+ /**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @param {!RegExp} regExp
+ * @return {boolean}
+ */
+ testContentMatching: function(record, regExp)
+ {
+ var traceEvent = record.traceEvent();
+ var title = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(traceEvent.name).title;
+ var tokens = [title];
+ for (var argName in traceEvent.args) {
+ var argValue = traceEvent.args[argName];
+ for (var key in argValue)
+ tokens.push(argValue[key]);
+ }
+ return regExp.test(tokens.join("|"));
+ },
+
+ __proto__: WebInspector.TimelineUIUtils.prototype
+}
+
+/**
+ * @constructor
+ * @param {string} title
+ * @param {!WebInspector.TimelineCategory} category
+ */
+WebInspector.TimelineRecordStyle = function(title, category)
+{
+ this.title = title;
+ this.category = category;
+}
+
+/**
+ * @return {!Object.<string, !WebInspector.TimelineRecordStyle>}
+ */
+WebInspector.TracingTimelineUIUtils._initEventStyles = function()
+{
+ if (WebInspector.TracingTimelineUIUtils._eventStylesMap)
+ return WebInspector.TracingTimelineUIUtils._eventStylesMap;
+
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+ var categories = WebInspector.TimelineUIUtils.categories();
+
+ var eventStyles = {};
+ eventStyles[recordTypes.Program] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Other"), categories["other"]);
+ eventStyles[recordTypes.EventDispatch] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Event"), categories["scripting"]);
+ eventStyles[recordTypes.RequestMainThreadFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Main Thread Frame"), categories["rendering"]);
+ eventStyles[recordTypes.BeginFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start"), categories["rendering"]);
+ eventStyles[recordTypes.BeginMainThreadFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Frame Start (main thread)"), categories["rendering"]);
+ eventStyles[recordTypes.DrawFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Draw Frame"), categories["rendering"]);
+ eventStyles[recordTypes.ScheduleStyleRecalculation] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Schedule Style Recalculation"), categories["rendering"]);
+ eventStyles[recordTypes.RecalculateStyles] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Recalculate Style"), categories["rendering"]);
+ eventStyles[recordTypes.InvalidateLayout] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Invalidate Layout"), categories["rendering"]);
+ eventStyles[recordTypes.Layout] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Layout"), categories["rendering"]);
+ eventStyles[recordTypes.PaintSetup] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint Setup"), categories["painting"]);
+ eventStyles[recordTypes.UpdateLayer] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Update Layer"), categories["painting"]);
+ eventStyles[recordTypes.Paint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"), categories["painting"]);
+ eventStyles[recordTypes.Rasterize] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"), categories["painting"]);
+ eventStyles[recordTypes.RasterTask] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Paint"), categories["painting"]);
+ eventStyles[recordTypes.ScrollLayer] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Scroll"), categories["rendering"]);
+ eventStyles[recordTypes.CompositeLayers] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Composite Layers"), categories["painting"]);
+ eventStyles[recordTypes.ParseHTML] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Parse HTML"), categories["loading"]);
+ eventStyles[recordTypes.TimerInstall] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Install Timer"), categories["scripting"]);
+ eventStyles[recordTypes.TimerRemove] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Remove Timer"), categories["scripting"]);
+ eventStyles[recordTypes.TimerFire] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Timer Fired"), categories["scripting"]);
+ eventStyles[recordTypes.XHRReadyStateChange] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Ready State Change"), categories["scripting"]);
+ eventStyles[recordTypes.XHRLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("XHR Load"), categories["scripting"]);
+ eventStyles[recordTypes.EvaluateScript] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Evaluate Script"), categories["scripting"]);
+ eventStyles[recordTypes.MarkLoad] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Load event"), categories["scripting"]);
+ eventStyles[recordTypes.MarkDOMContent] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("DOMContentLoaded event"), categories["scripting"]);
+ eventStyles[recordTypes.MarkFirstPaint] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("First paint"), categories["painting"]);
+ eventStyles[recordTypes.TimeStamp] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Stamp"), categories["scripting"]);
+ eventStyles[recordTypes.ConsoleTime] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Console Time"), categories["scripting"]);
+ eventStyles[recordTypes.ResourceSendRequest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send Request"), categories["loading"]);
+ eventStyles[recordTypes.ResourceReceiveResponse] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Response"), categories["loading"]);
+ eventStyles[recordTypes.ResourceFinish] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Finish Loading"), categories["loading"]);
+ eventStyles[recordTypes.ResourceReceivedData] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive Data"), categories["loading"]);
+ eventStyles[recordTypes.FunctionCall] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Function Call"), categories["scripting"]);
+ eventStyles[recordTypes.GCEvent] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("GC Event"), categories["scripting"]);
+ eventStyles[recordTypes.JSFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("JS Frame"), categories["scripting"]);
+ eventStyles[recordTypes.RequestAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Request Animation Frame"), categories["scripting"]);
+ eventStyles[recordTypes.CancelAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Cancel Animation Frame"), categories["scripting"]);
+ eventStyles[recordTypes.FireAnimationFrame] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Animation Frame Fired"), categories["scripting"]);
+ eventStyles[recordTypes.WebSocketCreate] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Create WebSocket"), categories["scripting"]);
+ eventStyles[recordTypes.WebSocketSendHandshakeRequest] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Send WebSocket Handshake"), categories["scripting"]);
+ eventStyles[recordTypes.WebSocketReceiveHandshakeResponse] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Receive WebSocket Handshake"), categories["scripting"]);
+ eventStyles[recordTypes.WebSocketDestroy] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Destroy WebSocket"), categories["scripting"]);
+ eventStyles[recordTypes.EmbedderCallback] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Embedder Callback"), categories["scripting"]);
+ eventStyles[recordTypes.DecodeImage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Decode"), categories["painting"]);
+ eventStyles[recordTypes.ResizeImage] = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Image Resize"), categories["painting"]);
+
+ WebInspector.TracingTimelineUIUtils._eventStylesMap = eventStyles;
+ return eventStyles;
+}
+
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes = {};
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.TracingTimelineModel.RecordType.Layout] = 1;
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.TracingTimelineModel.RecordType.Paint] = 1;
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.TracingTimelineModel.RecordType.Rasterize] = 1;
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.TracingTimelineModel.RecordType.DecodeImage] = 1;
+WebInspector.TracingTimelineUIUtils._coalescableRecordTypes[WebInspector.TracingTimelineModel.RecordType.ResizeImage] = 1;
+
+/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {!{title: string, category: !WebInspector.TimelineCategory}}
+ */
+WebInspector.TracingTimelineUIUtils.eventStyle = function(event)
+{
+ return WebInspector.TracingTimelineUIUtils.styleForTraceEvent(event.name);
+}
+
+/**
+ * @param {string} name
+ * @return {!{title: string, category: !WebInspector.TimelineCategory}}
+ */
+WebInspector.TracingTimelineUIUtils.styleForTraceEvent = function(name)
+{
+ var eventStyles = WebInspector.TracingTimelineUIUtils._initEventStyles();
+ var result = eventStyles[name];
+ if (!result) {
+ result = new WebInspector.TimelineRecordStyle(WebInspector.UIString("Unknown: %s", name), WebInspector.TimelineUIUtils.categories()["other"]);
+ eventStyles[name] = result;
+ }
+ return result;
+}
+
+/**
+ * @param {!WebInspector.TimelineModel.Record} record
+ * @return {boolean}
+ */
+WebInspector.TracingTimelineUIUtils.isEventDivider = function(record)
+{
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+ if (record.type() === recordTypes.TimeStamp)
+ return true;
+ if (record.type() === recordTypes.MarkFirstPaint)
+ return true;
+ if (record.type() === recordTypes.MarkDOMContent || record.type() === recordTypes.MarkLoad)
+ return record.data()["isMainFrame"];
+ return false;
+}
+
+/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {boolean} loadedFromFile
+ * @param {!WebInspector.Target} target
+ * @return {?Node}
+ */
+WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent = function(event, linkifier, loadedFromFile, target)
+{
+ var recordType = WebInspector.TracingTimelineModel.RecordType;
+
+ var details;
+ var detailsText;
+ var eventData = event.args.data;
+ switch (event.name) {
+ case recordType.GCEvent:
+ var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"];
+ detailsText = WebInspector.UIString("%s collected", Number.bytesToString(delta));
+ break;
+ case recordType.TimerFire:
+ detailsText = eventData["timerId"];
+ break;
+ case recordType.FunctionCall:
+ details = linkifyLocation(eventData["scriptId"], eventData["scriptName"], eventData["scriptLine"], 0);
+ break;
+ case recordType.FireAnimationFrame:
+ detailsText = eventData["id"];
+ break;
+ case recordType.EventDispatch:
+ detailsText = eventData ? eventData["type"] : null;
+ break;
+ case recordType.Paint:
+ var width = WebInspector.TimelineUIUtils._quadWidth(eventData.clip);
+ var height = WebInspector.TimelineUIUtils._quadHeight(eventData.clip);
+ if (width && height)
+ detailsText = WebInspector.UIString("%d\u2009\u00d7\u2009%d", width, height);
+ break;
+ case recordType.TimerInstall:
+ case recordType.TimerRemove:
+ details = linkifyTopCallFrame();
+ detailsText = eventData["timerId"];
+ break;
+ case recordType.RequestAnimationFrame:
+ case recordType.CancelAnimationFrame:
+ details = linkifyTopCallFrame();
+ detailsText = eventData["id"];
+ break;
+ case recordType.ParseHTML:
+ case recordType.RecalculateStyles:
+ details = linkifyTopCallFrame();
+ break;
+ case recordType.EvaluateScript:
+ var url = eventData["url"];
+ if (url)
+ details = linkifyLocation("", url, eventData["lineNumber"], 0);
+ break;
+ case recordType.XHRReadyStateChange:
+ case recordType.XHRLoad:
+ case recordType.ResourceSendRequest:
+ var url = eventData["url"];
+ if (url)
+ detailsText = WebInspector.displayNameForURL(url);
+ break;
+ case recordType.ResourceReceivedData:
+ case recordType.ResourceReceiveResponse:
+ case recordType.ResourceFinish:
+ var initiator = event.initiator;
+ if (initiator) {
+ var url = initiator.args.data["url"];
+ if (url)
+ detailsText = WebInspector.displayNameForURL(url);
+ }
+ break;
+ case recordType.ConsoleTime:
+ detailsText = eventData["message"];
+ break;
+ case recordType.EmbedderCallback:
+ detailsText = eventData["callbackName"];
+ break;
+
+ case recordType.PaintImage:
+ case recordType.DecodeImage:
+ case recordType.ResizeImage:
+ case recordType.DecodeLazyPixelRef:
+ var url = event.imageURL;
+ if (url)
+ detailsText = WebInspector.displayNameForURL(url);
+ break;
+
+ default:
+ details = linkifyTopCallFrame();
+ break;
+ }
+
+ if (!details && detailsText)
+ details = document.createTextNode(detailsText);
+ return details;
+
+ /**
+ * @param {string} scriptId
+ * @param {string} url
+ * @param {number} lineNumber
+ * @param {number=} columnNumber
+ */
+ function linkifyLocation(scriptId, url, lineNumber, columnNumber)
+ {
+ if (!loadedFromFile && scriptId !== "0") {
+ var location = new WebInspector.DebuggerModel.Location(
+ target,
+ scriptId,
+ lineNumber - 1,
+ (columnNumber || 1) - 1);
+ return linkifier.linkifyRawLocation(location, "timeline-details");
+ }
+
+ if (!url)
+ return null;
+
+ // FIXME(62725): stack trace line/column numbers are one-based.
+ columnNumber = columnNumber ? columnNumber - 1 : 0;
+ return linkifier.linkifyLocation(target, url, lineNumber - 1, columnNumber, "timeline-details");
+ }
+
+ /**
+ * @param {!ConsoleAgent.CallFrame} callFrame
+ */
+ function linkifyCallFrame(callFrame)
+ {
+ return linkifyLocation(callFrame.scriptId, callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
+ }
+
+ /**
+ * @return {?Element}
+ */
+ function linkifyTopCallFrame()
+ {
+ var stackTrace = event.stackTrace;
+ if (!stackTrace) {
+ var initiator = event.initiator;
+ if (initiator)
+ stackTrace = initiator.stackTrace;
+ }
+ if (!stackTrace || !stackTrace.length)
+ return null;
+ return linkifyCallFrame(stackTrace[0]);
+ }
+}
+
+/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @param {!WebInspector.TracingTimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {function(!DocumentFragment)} callback
+ * @param {boolean} loadedFromFile
+ * @param {!WebInspector.Target} target
+ */
+WebInspector.TracingTimelineUIUtils.buildTraceEventDetails = function(event, model, linkifier, callback, loadedFromFile, target)
+{
+ var relatedNode = null;
+ var barrier = new CallbackBarrier();
+ if (!event.previewElement) {
+ if (event.imageURL)
+ WebInspector.DOMPresentationUtils.buildImagePreviewContents(target, event.imageURL, false, barrier.createCallback(saveImage));
+ else if (event.picture)
+ WebInspector.TracingTimelineUIUtils._buildPicturePreviewContent(event.picture, barrier.createCallback(saveImage));
+ }
+ if (event.backendNodeId)
+ target.domModel.pushNodesByBackendIdsToFrontend([event.backendNodeId], barrier.createCallback(setRelatedNode));
+ barrier.callWhenDone(callbackWrapper);
+
+ /**
+ * @param {!Element=} element
+ */
+ function saveImage(element)
+ {
+ event.previewElement = element || null;
+ }
+
+ /**
+ * @param {?Array.<!DOMAgent.NodeId>} nodeIds
+ */
+ function setRelatedNode(nodeIds)
+ {
+ if (nodeIds)
+ relatedNode = target.domModel.nodeForId(nodeIds[0]);
+ }
+
+ function callbackWrapper()
+ {
+ callback(WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSynchronously(event, model, linkifier, relatedNode, loadedFromFile, target));
+ }
+}
+
+/**
+ * @param {!WebInspector.TracingModel.Event} event
+ * @param {!WebInspector.TracingTimelineModel} model
+ * @param {!WebInspector.Linkifier} linkifier
+ * @param {?WebInspector.DOMNode} relatedNode
+ * @param {boolean} loadedFromFile
+ * @param {!WebInspector.Target} target
+ * @return {!DocumentFragment}
+ */
+WebInspector.TracingTimelineUIUtils._buildTraceEventDetailsSynchronously = function(event, model, linkifier, relatedNode, loadedFromFile, target)
+{
+ var fragment = document.createDocumentFragment();
+ var stats = WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEvent(model, event);
+ var pieChart = stats.hasChildren ?
+ WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats, WebInspector.TracingTimelineUIUtils.styleForTraceEvent(event.name).category, event.selfTime) :
+ WebInspector.TimelineUIUtils.generatePieChart(stats.aggregatedStats);
+ fragment.appendChild(pieChart);
+
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+
+ // The messages may vary per event.name;
+ var callSiteStackTraceLabel;
+ var callStackLabel;
+ var relatedNodeLabel;
+
+ var contentHelper = new WebInspector.TimelineDetailsContentHelper(target, linkifier, true);
+ contentHelper.appendTextRow(WebInspector.UIString("Self Time"), Number.millisToString(event.selfTime, true));
+ contentHelper.appendTextRow(WebInspector.UIString("Start Time"), Number.millisToString((event.startTime - model.minimumRecordTime())));
+ var eventData = event.args.data;
+ var initiator = event.initiator;
+
+ switch (event.name) {
+ case recordTypes.GCEvent:
+ var delta = event.args["usedHeapSizeBefore"] - event.args["usedHeapSizeAfter"];
+ contentHelper.appendTextRow(WebInspector.UIString("Collected"), Number.bytesToString(delta));
+ break;
+ case recordTypes.TimerFire:
+ callSiteStackTraceLabel = WebInspector.UIString("Timer installed");
+ // Fall-through intended.
+
+ case recordTypes.TimerInstall:
+ case recordTypes.TimerRemove:
+ contentHelper.appendTextRow(WebInspector.UIString("Timer ID"), eventData["timerId"]);
+ if (event.name === recordTypes.TimerInstall) {
+ contentHelper.appendTextRow(WebInspector.UIString("Timeout"), Number.millisToString(eventData["timeout"]));
+ contentHelper.appendTextRow(WebInspector.UIString("Repeats"), !eventData["singleShot"]);
+ }
+ break;
+ case recordTypes.FireAnimationFrame:
+ callSiteStackTraceLabel = WebInspector.UIString("Animation frame requested");
+ contentHelper.appendTextRow(WebInspector.UIString("Callback ID"), eventData["id"]);
+ break;
+ case recordTypes.FunctionCall:
+ if (eventData["scriptName"])
+ contentHelper.appendLocationRow(WebInspector.UIString("Location"), eventData["scriptName"], eventData["scriptLine"]);
+ break;
+ case recordTypes.ResourceSendRequest:
+ case recordTypes.ResourceReceiveResponse:
+ case recordTypes.ResourceReceivedData:
+ case recordTypes.ResourceFinish:
+ var url = (event.name === recordTypes.ResourceSendRequest) ? eventData["url"] : initiator.args.data["url"];
+ if (url)
+ contentHelper.appendElementRow(WebInspector.UIString("Resource"), WebInspector.linkifyResourceAsNode(url));
+ if (eventData["requestMethod"])
+ contentHelper.appendTextRow(WebInspector.UIString("Request Method"), eventData["requestMethod"]);
+ if (typeof eventData["statusCode"] === "number")
+ contentHelper.appendTextRow(WebInspector.UIString("Status Code"), eventData["statusCode"]);
+ if (eventData["mimeType"])
+ contentHelper.appendTextRow(WebInspector.UIString("MIME Type"), eventData["mimeType"]);
+ if (eventData["encodedDataLength"])
+ contentHelper.appendTextRow(WebInspector.UIString("Encoded Data Length"), WebInspector.UIString("%d Bytes", eventData["encodedDataLength"]));
+ break;
+ case recordTypes.EvaluateScript:
+ var url = eventData["url"];
+ if (url)
+ contentHelper.appendLocationRow(WebInspector.UIString("Script"), url, eventData["lineNumber"]);
+ break;
+ case recordTypes.Paint:
+ var clip = eventData["clip"];
+ contentHelper.appendTextRow(WebInspector.UIString("Location"), WebInspector.UIString("(%d, %d)", clip[0], clip[1]));
+ var clipWidth = WebInspector.TimelineUIUtils._quadWidth(clip);
+ var clipHeight = WebInspector.TimelineUIUtils._quadHeight(clip);
+ contentHelper.appendTextRow(WebInspector.UIString("Dimensions"), WebInspector.UIString("%d × %d", clipWidth, clipHeight));
+ // Fall-through intended.
+
+ case recordTypes.PaintSetup:
+ case recordTypes.Rasterize:
+ case recordTypes.ScrollLayer:
+ relatedNodeLabel = WebInspector.UIString("Layer root");
+ break;
+ case recordTypes.PaintImage:
+ case recordTypes.DecodeLazyPixelRef:
+ case recordTypes.DecodeImage:
+ case recordTypes.ResizeImage:
+ case recordTypes.DrawLazyPixelRef:
+ relatedNodeLabel = WebInspector.UIString("Image element");
+ if (event.imageURL)
+ contentHelper.appendElementRow(WebInspector.UIString("Image URL"), WebInspector.linkifyResourceAsNode(event.imageURL));
+ break;
+ case recordTypes.RecalculateStyles: // We don't want to see default details.
+ contentHelper.appendTextRow(WebInspector.UIString("Elements affected"), event.args["elementCount"]);
+ callStackLabel = WebInspector.UIString("Styles recalculation forced");
+ break;
+ case recordTypes.Layout:
+ var beginData = event.args["beginData"];
+ contentHelper.appendTextRow(WebInspector.UIString("Nodes that need layout"), beginData["dirtyObjects"]);
+ contentHelper.appendTextRow(WebInspector.UIString("Layout tree size"), beginData["totalObjects"]);
+ contentHelper.appendTextRow(WebInspector.UIString("Layout scope"),
+ beginData["partialLayout"] ? WebInspector.UIString("Partial") : WebInspector.UIString("Whole document"));
+ callSiteStackTraceLabel = WebInspector.UIString("Layout invalidated");
+ callStackLabel = WebInspector.UIString("Layout forced");
+ relatedNodeLabel = WebInspector.UIString("Layout root");
+ break;
+ case recordTypes.ConsoleTime:
+ contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]);
+ break;
+ case recordTypes.WebSocketCreate:
+ case recordTypes.WebSocketSendHandshakeRequest:
+ case recordTypes.WebSocketReceiveHandshakeResponse:
+ case recordTypes.WebSocketDestroy:
+ var initiatorData = initiator ? initiator.args.data : eventData;
+ if (typeof initiatorData["webSocketURL"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("URL"), initiatorData["webSocketURL"]);
+ if (typeof initiatorData["webSocketProtocol"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("WebSocket Protocol"), initiatorData["webSocketProtocol"]);
+ if (typeof eventData["message"] !== "undefined")
+ contentHelper.appendTextRow(WebInspector.UIString("Message"), eventData["message"]);
+ break;
+ case recordTypes.EmbedderCallback:
+ contentHelper.appendTextRow(WebInspector.UIString("Callback Function"), eventData["callbackName"]);
+ break;
+ default:
+ var detailsNode = WebInspector.TracingTimelineUIUtils.buildDetailsNodeForTraceEvent(event, linkifier, loadedFromFile, target);
+ if (detailsNode)
+ contentHelper.appendElementRow(WebInspector.UIString("Details"), detailsNode);
+ break;
+ }
+
+ if (relatedNode)
+ contentHelper.appendElementRow(relatedNodeLabel || WebInspector.UIString("Related node"), WebInspector.DOMPresentationUtils.linkifyNodeReference(relatedNode));
+
+ if (eventData && eventData["scriptName"] && event.name !== recordTypes.FunctionCall)
+ contentHelper.appendLocationRow(WebInspector.UIString("Function Call"), eventData["scriptName"], eventData["scriptLine"]);
+
+ if (initiator) {
+ var callSiteStackTrace = initiator.stackTrace;
+ if (callSiteStackTrace)
+ contentHelper.appendStackTrace(callSiteStackTraceLabel || WebInspector.UIString("Call Site stack"), callSiteStackTrace);
+ }
+ var eventStackTrace = event.stackTrace;
+ if (eventStackTrace)
+ contentHelper.appendStackTrace(callStackLabel || WebInspector.UIString("Call Stack"), eventStackTrace);
+
+ var warning = event.warning;
+ if (warning) {
+ var div = document.createElement("div");
+ div.textContent = warning;
+ contentHelper.appendElementRow(WebInspector.UIString("Warning"), div);
+ }
+ if (event.previewElement)
+ contentHelper.appendElementRow(WebInspector.UIString("Preview"), event.previewElement);
+ fragment.appendChild(contentHelper.element);
+ return fragment;
+}
+
+/**
+ * @param {!WebInspector.TracingTimelineModel} model
+ * @param {!WebInspector.TracingModel.Event} event
+ * @return {!{ aggregatedStats: !Object, hasChildren: boolean }}
+ */
+WebInspector.TracingTimelineUIUtils._aggregatedStatsForTraceEvent = function(model, event)
+{
+ var events = model.inspectedTargetEvents();
+ /**
+ * @param {number} startTime
+ * @param {!WebInspector.TracingModel.Event} e
+ * @return {number}
+ */
+ function eventComparator(startTime, e)
+ {
+ return startTime - e.startTime;
+ }
+ var index = events.binaryIndexOf(event.startTime, eventComparator);
+ var hasChildren = false;
+ var aggregatedStats = {};
+ var endTime = event.endTime;
+ if (endTime) {
+ for (var i = index; i < events.length; i++) {
+ var nextEvent = events[i];
+ if (nextEvent.startTime >= endTime)
+ break;
+ if (!nextEvent.selfTime)
+ continue;
+ if (i > index)
+ hasChildren = true;
+ var category = WebInspector.TracingTimelineUIUtils.styleForTraceEvent(nextEvent.name).category.name;
+ aggregatedStats[category] = (aggregatedStats[category] || 0) + nextEvent.selfTime;
+ }
+ }
+ return { aggregatedStats: aggregatedStats, hasChildren: hasChildren };
+}
+
+/**
+ * @param {string} encodedPicture
+ * @param {function(!Element=)} callback
+ */
+WebInspector.TracingTimelineUIUtils._buildPicturePreviewContent = function(encodedPicture, callback)
+{
+ var snapshotId;
+
+ LayerTreeAgent.loadSnapshot(encodedPicture, onSnapshotLoaded);
+ /**
+ * @param {string} error
+ * @param {string} id
+ */
+ function onSnapshotLoaded(error, id)
+ {
+ if (error) {
+ console.error("LayerTreeAgent.loadSnapshot(): " + error);
+ callback();
+ return;
+ }
+ snapshotId = id;
+ LayerTreeAgent.replaySnapshot(snapshotId, onSnapshotReplayed);
+ }
+
+ /**
+ * @param {string} error
+ * @param {string} encodedBitmap
+ */
+ function onSnapshotReplayed(error, encodedBitmap)
+ {
+ LayerTreeAgent.releaseSnapshot(snapshotId);
+ if (error) {
+ console.error("LayerTreeAgent.replaySnapshot(): " + error);
+ callback();
+ return;
+ }
+ var container = document.createElement("div");
+ container.className = "image-preview-container";
+ var img = container.createChild("img");
+ img.src = encodedBitmap;
+ callback(container);
+ }
+}
+
+/**
+ * @param {string} recordType
+ * @param {string=} title
+ * @return {!Element}
+ */
+WebInspector.TracingTimelineUIUtils._createEventDivider = function(recordType, title)
+{
+ var eventDivider = document.createElement("div");
+ eventDivider.className = "resources-event-divider";
+ var recordTypes = WebInspector.TracingTimelineModel.RecordType;
+
+ if (recordType === recordTypes.MarkDOMContent)
+ eventDivider.className += " resources-blue-divider";
+ else if (recordType === recordTypes.MarkLoad)
+ eventDivider.className += " resources-red-divider";
+ else if (recordType === recordTypes.MarkFirstPaint)
+ eventDivider.className += " resources-green-divider";
+ else if (recordType === recordTypes.TimeStamp)
+ eventDivider.className += " resources-orange-divider";
+ else if (recordType === recordTypes.BeginFrame)
+ eventDivider.className += " timeline-frame-divider";
+
+ if (title)
+ eventDivider.title = title;
+
+ return eventDivider;
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TransformController.js b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TransformController.js
new file mode 100644
index 00000000000..00d5bd98c28
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/TransformController.js
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ * @param {!Element} element
+ */
+WebInspector.TransformController = function(element)
+{
+ this.element = element;
+ element.addEventListener("mousemove", this._onMouseMove.bind(this), false);
+ element.addEventListener("mousedown", this._onMouseDown.bind(this), false);
+ element.addEventListener("mouseup", this._onMouseUp.bind(this), false);
+ element.addEventListener("mousewheel", this._onMouseWheel.bind(this), false);
+ this._reset();
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.TransformController.Events = {
+ TransformChanged: "TransformChanged"
+}
+
+WebInspector.TransformController.prototype = {
+ /**
+ * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(?Event=))} registerShortcutDelegate
+ */
+ registerShortcuts: function(registerShortcutDelegate)
+ {
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView, this._resetAndNotify.bind(this));
+ var zoomFactor = 1.1;
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, this._onKeyboardZoom.bind(this, zoomFactor));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, this._onKeyboardZoom.bind(this, 1 / zoomFactor));
+ var panDistanceInPixels = 6;
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanUp, this._onPan.bind(this, 0, -panDistanceInPixels));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanDown, this._onPan.bind(this, 0, panDistanceInPixels));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanLeft, this._onPan.bind(this, -panDistanceInPixels, 0));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanRight, this._onPan.bind(this, panDistanceInPixels, 0));
+ var rotateDegrees = 5;
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWX, this._onKeyboardRotate.bind(this, rotateDegrees, 0));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWX, this._onKeyboardRotate.bind(this, -rotateDegrees, 0));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWY, this._onKeyboardRotate.bind(this, 0, -rotateDegrees));
+ registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWY, this._onKeyboardRotate.bind(this, 0, rotateDegrees));
+ },
+
+ _postChangeEvent: function()
+ {
+ this.dispatchEventToListeners(WebInspector.TransformController.Events.TransformChanged);
+ },
+
+ _reset: function()
+ {
+ this._scale = 1;
+ this._offsetX = 0;
+ this._offsetY = 0;
+ this._rotateX = 0;
+ this._rotateY = 0;
+ },
+
+ /**
+ * @param {?Event=} event
+ */
+ _resetAndNotify: function(event)
+ {
+ this._reset();
+ this._postChangeEvent();
+ if (event)
+ event.preventDefault();
+ },
+
+ /**
+ * @return {number}
+ */
+ scale: function()
+ {
+ return this._scale;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetX: function()
+ {
+ return this._offsetX;
+ },
+
+ /**
+ * @return {number}
+ */
+ offsetY: function()
+ {
+ return this._offsetY;
+ },
+
+ /**
+ * @return {number}
+ */
+ rotateX: function()
+ {
+ return this._rotateX;
+ },
+
+ /**
+ * @return {number}
+ */
+ rotateY: function()
+ {
+ return this._rotateY;
+ },
+
+ /**
+ * @param {number} scaleFactor
+ * @param {number} x
+ * @param {number} y
+ */
+ _onScale: function(scaleFactor, x, y)
+ {
+ this._scale *= scaleFactor;
+ this._offsetX -= (x - this._offsetX) * (scaleFactor - 1);
+ this._offsetY -= (y - this._offsetY) * (scaleFactor - 1);
+ this._postChangeEvent();
+ },
+
+ /**
+ * @param {number} offsetX
+ * @param {number} offsetY
+ */
+ _onPan: function(offsetX, offsetY)
+ {
+ this._offsetX += offsetX;
+ this._offsetY += offsetY;
+ this._postChangeEvent();
+ },
+
+ /**
+ * @param {number} rotateX
+ * @param {number} rotateY
+ */
+ _onRotate: function(rotateX, rotateY)
+ {
+ this._rotateX = rotateX;
+ this._rotateY = rotateY;
+ this._postChangeEvent();
+ },
+
+ /**
+ * @param {number} zoomFactor
+ */
+ _onKeyboardZoom: function(zoomFactor)
+ {
+ this._onScale(zoomFactor, this.element.clientWidth / 2, this.element.clientHeight / 2);
+ },
+
+ /**
+ * @param {number} rotateX
+ * @param {number} rotateY
+ */
+ _onKeyboardRotate: function(rotateX, rotateY)
+ {
+ this._onRotate(this._rotateX + rotateX, this._rotateY + rotateY);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseWheel: function(event)
+ {
+ if (!event.altKey) {
+ /** @const */
+ var zoomFactor = 1.1;
+ /** @const */
+ var mouseWheelZoomSpeed = 1 / 120;
+ var scaleFactor = Math.pow(zoomFactor, event.wheelDeltaY * mouseWheelZoomSpeed);
+ this._onScale(scaleFactor, event.clientX - this.element.totalOffsetLeft(), event.clientY - this.element.totalOffsetTop());
+ } else {
+ /** @const */
+ var moveFactor = 1 / 20;
+ this._onPan(event.wheelDeltaX * moveFactor, event.wheelDeltaY * moveFactor);
+ }
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseMove: function(event)
+ {
+ if (event.which !== 1 || typeof this._originX !== "number")
+ return;
+ this._onRotate(this._oldRotateX + (this._originY - event.clientY) / this.element.clientHeight * 180, this._oldRotateY - (this._originX - event.clientX) / this.element.clientWidth * 180);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _setReferencePoint: function(event)
+ {
+ this._originX = event.clientX;
+ this._originY = event.clientY;
+ this._oldRotateX = this._rotateX;
+ this._oldRotateY = this._rotateY;
+ },
+
+ _resetReferencePoint: function()
+ {
+ delete this._originX;
+ delete this._originY;
+ delete this._oldRotateX;
+ delete this._oldRotateY;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseDown: function(event)
+ {
+ if (event.which !== 1)
+ return;
+ this._setReferencePoint(event);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseUp: function(event)
+ {
+ if (event.which !== 1)
+ return;
+ this._resetReferencePoint();
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/module.json b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/module.json
new file mode 100644
index 00000000000..b9f20de80fa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/module.json
@@ -0,0 +1,12 @@
+{
+ "extensions": [
+ {
+ "type": "@WebInspector.Panel",
+ "name": "timeline",
+ "title": "Timeline",
+ "order": 3,
+ "className": "WebInspector.TimelinePanel"
+ }
+ ],
+ "scripts": [ "TimelinePanel.js" ]
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timelinePanel.css b/chromium/third_party/WebKit/Source/devtools/front_end/timelinePanel.css
index 942c3e4c1c8..d4270be27f3 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/timelinePanel.css
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/timelinePanel.css
@@ -28,7 +28,7 @@
*/
#timeline-overview-panel {
- flex: 0 0 81px;
+ flex: none;
position: relative;
border-bottom: 1px solid rgb(140, 140, 140);
}
@@ -37,6 +37,16 @@
pointer-events: none;
}
+#timeline-overview-panel .split-view-sidebar > label {
+ margin: 6px 0 3px 5px;
+ height: auto;
+ display: flex;
+}
+
+#timeline-overview-panel .split-view-sidebar > label > input {
+ margin-right: 6px;
+}
+
.timeline-records-title, .timeline-records-list {
background-color: rgb(236, 236, 236);
}
@@ -51,21 +61,11 @@
flex: auto;
}
-#timeline-overview-sidebar {
- flex: none;
- padding-right: 10px;
- border-right: 1px solid rgb(64%, 64%, 64%);
-}
-
#timeline-overview-grid {
background-color: rgb(255, 255, 255);
}
-.timeline-frames-view .timeline-records-counter {
- display: none;
-}
-
-.timeline-frames-view #timeline-overview-grid {
+.timeline-overview-frames-mode #timeline-overview-grid {
display: none;
}
@@ -73,10 +73,9 @@
pointer-events: auto;
}
-.timeline-frames-view .overview-grid-window,
-.timeline-frames-view .overview-grid-dividers-background,
-.timeline-frames-view .overview-grid-window-resizer {
- height: 15px;
+.timeline-overview-frames-mode .overview-grid-window,
+.timeline-overview-frames-mode .overview-grid-dividers-background {
+ height: 100%;
}
#timeline-overview-grid #resources-graphs {
@@ -93,10 +92,24 @@
overflow-x: hidden;
}
+.timeline-records-view {
+ overflow: hidden !important;
+}
+
.timeline-details-split {
flex: auto;
}
+.timeline-view {
+ flex: auto;
+ overflow: hidden;
+}
+
+.timeline-view-stack {
+ flex: auto;
+ display: flex;
+}
+
#timeline-container .webkit-html-external-link,
#timeline-container .webkit-html-resource-link {
color: inherit;
@@ -143,7 +156,7 @@
display: inline-block;
-webkit-user-select: none;
-webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
+ -webkit-mask-size: 320px 144px;
width: 10px;
height: 10px;
content: "";
@@ -155,7 +168,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.timeline-tree-item-expand-arrow {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
+ -webkit-mask-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -169,7 +182,7 @@
.timeline-expandable-arrow {
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
opacity: 0.5;
width: 10px;
height: 10px;
@@ -180,7 +193,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.timeline-expandable-arrow {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -218,7 +231,7 @@
.timeline-tree-item-warning {
display: block;
background-image: url(Images/statusbarButtonGlyphs.png);
- background-size: 320px 120px;
+ background-size: 320px 144px;
width: 10px;
height: 10px;
float: right;
@@ -233,7 +246,7 @@
@media (-webkit-min-device-pixel-ratio: 1.5) {
.timeline-tree-item-warning {
- background-image: url(Images/statusbarButtonGlyphs2x.png);
+ background-image: url(Images/statusbarButtonGlyphs_2x.png);
}
} /* media */
@@ -253,28 +266,33 @@
}
#timeline-overview-events,
-#timeline-overview-memory {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- top: 20px;
+#timeline-overview-memory,
+#timeline-overview-power {
+ flex: 0 0 60px;
z-index: 160;
+ width: 100%;
}
-#timeline-overview-memory {
- top: 25px;
+#timeline-overview-memory {
+ flex-basis: 20px;
+}
+
+#timeline-overview-frames {
+ flex-basis: 79px;
}
#timeline-overview-pane {
- flex: auto;
+ flex: none;
position: relative;
+ overflow: hidden;
}
#timeline-overview-container {
- flex: auto;
+ display: flex;
+ flex-direction: column;
+ flex: none;
position: relative;
- height: 80px;
+ overflow: hidden;
}
#timeline-overview-container canvas {
@@ -366,16 +384,16 @@
list-style-type: none;
}
-.garbage-collect-status-bar-item .glyph {
+.timeline-garbage-collect-status-bar-item .glyph {
-webkit-mask-position: -128px -24px;
}
-.glue-async-status-bar-item .glyph {
- -webkit-mask-position: -128px -48px;
+.timeline-frames-status-bar-item .glyph {
+ -webkit-mask-position: -160px -48px;
}
-.glue-async-status-bar-item.toggled-on:disabled .glyph {
- background-color: rgba(0, 0, 0, 0.75);
+.timeline-flame-chart-status-bar-item .glyph {
+ -webkit-mask-position: -192px -48px;
}
#resources-container-content {
@@ -409,64 +427,6 @@
left: 9px;
}
-#timeline-overview-sidebar .sidebar-tree {
- height: 100%;
-}
-
-#timeline-overview-sidebar .sidebar-tree-item {
- height: auto;
- flex: auto;
- margin: 1px 0 1px 0;
- border-top: none;
- display: flex;
- align-items: center;
- border-left: 6px solid transparent;
- padding-left: 0;
- color: #666;
-}
-
-#timeline-overview-sidebar .sidebar-tree-item:hover {
- color: inherit;
-}
-
-#timeline-overview-sidebar .sidebar-tree-item.selected {
- font-weight: bold;
- color: inherit;
- text-shadow: none;
- background: none;
- border-left: 6px solid #555;
-}
-
-#timeline-overview-sidebar .sidebar-tree-item .titles.no-subtitle {
- top: initial;
-}
-
-#timeline-overview-sidebar .icon {
- height: 24px;
- margin: 0;
- -webkit-mask-image: url(Images/statusbarButtonGlyphs.png);
- -webkit-mask-size: 320px 120px;
- background-color: black;
-}
-
-@media (-webkit-min-device-pixel-ratio: 1.5) {
-#timeline-overview-sidebar .icon {
- -webkit-mask-image: url(Images/statusbarButtonGlyphs2x.png);
-}
-} /* media */
-
-.timeline-overview-sidebar-events .icon {
- -webkit-mask-position: -192px -48px;
-}
-
-.timeline-overview-sidebar-frames .icon {
- -webkit-mask-position: -160px -48px;
-}
-
-.timeline-overview-sidebar-memory .icon {
- -webkit-mask-position: -224px -48px;
-}
-
.memory-graph-label {
position: absolute;
left: 5px;
@@ -475,41 +435,42 @@
white-space: nowrap;
}
-.max.memory-graph-label {
- top: 5px;
-}
-
-.min.memory-graph-label {
- bottom: 5px;
-}
-
-#memory-counters-graph {
- border-right: 1px solid rgb(196, 196, 196);
-}
-
#memory-graphs-canvas-container {
overflow: hidden;
+ flex: auto;
+ position: relative;
}
-#memory-graphs-canvas-container.dom-counters .resources-dividers,
#memory-counters-graph {
- top: 17px;
+ flex: auto;
+}
+
+#memory-graphs-canvas-container .memory-counter-marker {
+ position: absolute;
+ border-radius: 3px;
+ width: 5px;
+ height: 5px;
+ margin-left: -3px;
+ margin-top: -2px;
}
#memory-graphs-container .split-view-contents-first {
background-color: rgb(236, 236, 236);
+ overflow-y: hidden;
}
#memory-graphs-container .sidebar-tree-section {
- padding-left: 5px;
+ flex: 0 0 24px;
+ padding: 5px 0 0 5px;
}
.memory-counter-sidebar-info {
- margin: 5px;
+ flex: 0 0 18px;
+ margin-left: 5px;
white-space: nowrap;
}
-.memory-counter-sidebar-info .swatch{
+.memory-counter-sidebar-info .swatch {
background-image: none;
border: 1px solid rgba(0,0,0,0.3);
opacity: 0.5;
@@ -528,10 +489,11 @@
}
#counter-values-bar {
+ flex: 0 0 18px;
border-bottom: solid 1px lightgray;
width: 100%;
- height: 17px;
overflow: hidden;
+ line-height: 18px;
}
.timeline .resources-event-divider {
@@ -578,30 +540,39 @@
opacity: 0.8;
color: black;
text-align: center;
- padding-top: 3px;
- z-index: 350;
+ z-index: 220;
pointer-events: auto;
}
.timeline-frame-strip {
position: absolute;
height: 19px;
+ padding-top: 3px;
+}
+
+.timeline-frame-strip.selected {
+ background-color: rgb(56, 121, 217);
+ color: white;
}
#timeline-grid-header {
pointer-events: none;
+ height: 19px;
}
-.timeline-utilization-strips {
+#timeline-graph-records-header {
+ pointer-events: none;
height: 19px;
padding: 1px 0;
+ justify-content: center;
}
.timeline-utilization-strip {
- z-index: 350;
+ z-index: 250;
overflow: hidden;
- flex: auto;
+ flex: 0 1 12px;
position: relative;
+ height: 9px;
}
.timeline-utilization-strip .timeline-graph-bar {
@@ -660,15 +631,6 @@
float: right;
}
-.highlighted-timeline-record {
- -webkit-animation: "timeline_record_highlight" 2s 0s;
-}
-
-@-webkit-keyframes timeline_record_highlight {
- from {background-color: rgba(255, 255, 120, 1); }
- to { background-color: rgba(255, 255, 120, 0); }
-}
-
.timeline-filters-header {
flex: 0 0 23px;
overflow: hidden;
@@ -699,6 +661,7 @@
.timeline-details-view {
color: #333;
+ overflow: hidden;
}
.timeline-details-view-title {
@@ -710,6 +673,8 @@
display: flex;
color: rgb(92, 110, 129);
text-shadow: rgba(255, 255, 255, 0.75) 0 1px 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.timeline-details-view-body {
@@ -745,6 +710,23 @@
padding: 10px;
}
+.timeline-details-view-row-details table {
+ padding-left: 10px;
+}
+
+.timeline-details-view-row-details table td {
+ text-align: left;
+ vertical-align: top;
+}
+
+.timeline-details-view-row-details table td .section {
+ margin-top: -1px;
+}
+
+.timeline-details-view-row-details table td .section > .header .title {
+ white-space: nowrap;
+}
+
.timeline-details-view-row-stack-trace {
padding: 4px 0 4px 20px;
}
@@ -767,50 +749,19 @@
overflow: hidden;
}
-.pie-chart {
- width: 100px;
- height: 110px;
-}
-
-.pie-chart-background {
- position: absolute;
- width: 100px;
- height: 100px;
- border-radius: 50px;
- background-color: rgb(248, 248, 248);
- box-shadow: 0 1px 2px;
-}
-
-.pie-chart-foreground {
- position: absolute;
- width: 100px;
- height: 100px;
- text-align: center;
- line-height: 100px;
- z-index: 10;
-}
-
-.pie-chart-slice {
- position: absolute;
- width: 100px;
- height: 100px;
- border-radius: 50px;
- clip: rect(0px, 100px, 100px, 50px);
+.timeline-aggregated-info {
+ flex: none;
+ position: relative;
+ margin: 8px;
}
-.pie-chart-slice-inner {
- position: absolute;
- width: 100px;
- height: 100px;
- border-radius: 50px;
- clip: rect(0px, 50px, 100px, 0px);
+.timeline-range-summary {
+ align-items: center;
+ margin: 6px;
}
-.timeline-aggregated-info {
- flex: none;
- position: relative;
- margin: 8px 2px;
- width: 160px;
+.timeline-range-summary > div {
+ flex-shrink: 0;
}
.timeline-aggregated-info-legend > div {
@@ -821,4 +772,29 @@
.timeline-aggregated-info .pie-chart {
margin-left: 20px;
+ margin-bottom: 10px;
+}
+
+.timeline-flamechart {
+ overflow: hidden;
+}
+
+.timeline-progress-pane {
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ left: 0px;
+ color: #777;
+ background-color: rgba(255, 255, 255, 0.8);
+ font-size: 30px;
+ z-index: 500;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.revealable-link {
+ text-decoration: underline;
+ cursor: pointer;
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/ActionRegistry.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ActionRegistry.js
new file mode 100644
index 00000000000..0cf9faf7538
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ActionRegistry.js
@@ -0,0 +1,79 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ */
+WebInspector.ActionRegistry = function()
+{
+ /** @type {!StringMap.<!WebInspector.ModuleManager.Extension>} */
+ this._actionsById = new StringMap();
+ this._registerActions();
+}
+
+WebInspector.ActionRegistry.prototype = {
+ _registerActions: function()
+ {
+ WebInspector.moduleManager.extensions(WebInspector.ActionDelegate).forEach(registerExtension, this);
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @this {WebInspector.ActionRegistry}
+ */
+ function registerExtension(extension)
+ {
+ var actionId = extension.descriptor()["actionId"];
+ console.assert(actionId);
+ console.assert(!this._actionsById.get(actionId));
+ this._actionsById.put(actionId, extension);
+ }
+ },
+
+ /**
+ * @param {!Array.<string>} actionIds
+ * @param {!WebInspector.Context} context
+ * @return {!Array.<string>}
+ */
+ applicableActions: function(actionIds, context)
+ {
+ var extensions = [];
+ actionIds.forEach(function(actionId) {
+ var extension = this._actionsById.get(actionId);
+ if (extension)
+ extensions.push(extension);
+ }, this);
+ return context.applicableExtensions(extensions).values().map(function(extension) {
+ return extension.descriptor()["actionId"];
+ });
+ },
+
+ /**
+ * @param {string} actionId
+ * @return {boolean}
+ */
+ execute: function(actionId)
+ {
+ var extension = this._actionsById.get(actionId);
+ console.assert(extension, "No action found for actionId '" + actionId + "'");
+ return extension.instance().handleAction(WebInspector.context);
+ }
+}
+
+/**
+ * @interface
+ */
+WebInspector.ActionDelegate = function()
+{
+}
+
+WebInspector.ActionDelegate.prototype = {
+ /**
+ * @param {!WebInspector.Context} context
+ * @return {boolean}
+ */
+ handleAction: function(context) {}
+}
+
+/** @type {!WebInspector.ActionRegistry} */
+WebInspector.actionRegistry;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Checkbox.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Checkbox.js
index f71590f985b..7802c095490 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Checkbox.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Checkbox.js
@@ -25,6 +25,8 @@
/**
* @constructor
+ * @param {string} label
+ * @param {string} className
* @param {string=} tooltip
*/
WebInspector.Checkbox = function(label, className, tooltip)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/Context.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Context.js
new file mode 100644
index 00000000000..0dd80bc98d3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Context.js
@@ -0,0 +1,119 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ */
+WebInspector.Context = function()
+{
+ this._flavors = new Map();
+ this._eventDispatchers = new Map();
+}
+
+/**
+ * @enum {string}
+ */
+WebInspector.Context.Events = {
+ FlavorChanged: "FlavorChanged"
+}
+
+WebInspector.Context.prototype = {
+ /**
+ * @param {function(new:T, ...)} flavorType
+ * @param {?T} flavorValue
+ * @template T
+ */
+ setFlavor: function(flavorType, flavorValue)
+ {
+ var value = this._flavors.get(flavorType) || null;
+ if (value === flavorValue)
+ return;
+ if (flavorValue)
+ this._flavors.put(flavorType, flavorValue);
+ else
+ this._flavors.remove(flavorType);
+
+ this._dispatchFlavorChange(flavorType, flavorValue);
+ },
+
+ /**
+ * @param {function(new:T, ...)} flavorType
+ * @param {?T} flavorValue
+ * @template T
+ */
+ _dispatchFlavorChange: function(flavorType, flavorValue)
+ {
+ var dispatcher = this._eventDispatchers.get(flavorType);
+ if (!dispatcher)
+ return;
+ dispatcher.dispatchEventToListeners(WebInspector.Context.Events.FlavorChanged, flavorValue);
+ },
+
+ /**
+ * @param {function(new:Object, ...)} flavorType
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ addFlavorChangeListener: function(flavorType, listener, thisObject)
+ {
+ var dispatcher = this._eventDispatchers.get(flavorType);
+ if (!dispatcher) {
+ dispatcher = new WebInspector.Object();
+ this._eventDispatchers.put(flavorType, dispatcher);
+ }
+ dispatcher.addEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject);
+ },
+
+ /**
+ * @param {function(new:Object, ...)} flavorType
+ * @param {function(!WebInspector.Event)} listener
+ * @param {!Object=} thisObject
+ */
+ removeFlavorChangeListener: function(flavorType, listener, thisObject)
+ {
+ var dispatcher = this._eventDispatchers.get(flavorType);
+ if (!dispatcher)
+ return;
+ dispatcher.removeEventListener(WebInspector.Context.Events.FlavorChanged, listener, thisObject);
+ if (!dispatcher.hasEventListeners(WebInspector.Context.Events.FlavorChanged))
+ this._eventDispatchers.remove(flavorType);
+ },
+
+ /**
+ * @param {function(new:T, ...)} flavorType
+ * @return {?T}
+ * @template T
+ */
+ flavor: function(flavorType)
+ {
+ return this._flavors.get(flavorType) || null;
+ },
+
+ /**
+ * @return {!Array.<function(new:Object, ...)>}
+ */
+ flavors: function()
+ {
+ return this._flavors.keys();
+ },
+
+ /**
+ * @param {!Array.<!WebInspector.ModuleManager.Extension>} extensions
+ * @return {!Set.<!WebInspector.ModuleManager.Extension>}
+ */
+ applicableExtensions: function(extensions)
+ {
+ var targetExtensionSet = new Set();
+
+ var availableFlavors = Set.fromArray(this.flavors());
+ extensions.forEach(function(extension) {
+ if (WebInspector.moduleManager.isExtensionApplicableToContextTypes(extension, availableFlavors))
+ targetExtensionSet.add(extension);
+ });
+
+ return targetExtensionSet;
+ }
+}
+
+WebInspector.context = new WebInspector.Context(); \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ContextMenu.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ContextMenu.js
index e069b1f3c23..0eb53028f5e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ContextMenu.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ContextMenu.js
@@ -30,7 +30,7 @@
/**
* @constructor
- * @param {!WebInspector.ContextSubMenuItem} topLevelMenu
+ * @param {!WebInspector.ContextMenu} topLevelMenu
* @param {string} type
* @param {string=} label
* @param {boolean=} disabled
@@ -48,11 +48,17 @@ WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, che
}
WebInspector.ContextMenuItem.prototype = {
+ /**
+ * @return {number}
+ */
id: function()
{
return this._id;
},
+ /**
+ * @return {string}
+ */
type: function()
{
return this._type;
@@ -90,7 +96,7 @@ WebInspector.ContextMenuItem.prototype = {
/**
* @constructor
* @extends {WebInspector.ContextMenuItem}
- * @param topLevelMenu
+ * @param {!WebInspector.ContextMenu} topLevelMenu
* @param {string=} label
* @param {boolean=} disabled
*/
@@ -119,7 +125,7 @@ WebInspector.ContextSubMenuItem.prototype = {
/**
* @param {string} label
* @param {boolean=} disabled
- * @return {!WebInspector.ContextMenuItem}
+ * @return {!WebInspector.ContextSubMenuItem}
*/
appendSubMenuItem: function(label, disabled)
{
@@ -129,7 +135,11 @@ WebInspector.ContextSubMenuItem.prototype = {
},
/**
+ * @param {string} label
+ * @param {function()} handler
+ * @param {boolean=} checked
* @param {boolean=} disabled
+ * @return {!WebInspector.ContextMenuItem}
*/
appendCheckboxItem: function(label, handler, checked, disabled)
{
@@ -179,10 +189,12 @@ WebInspector.ContextSubMenuItem.prototype = {
/**
* @constructor
* @extends {WebInspector.ContextSubMenuItem}
+ * @param {?Event} event
*/
-WebInspector.ContextMenu = function(event) {
+WebInspector.ContextMenu = function(event)
+{
WebInspector.ContextSubMenuItem.call(this, this, "");
- this._event = event;
+ this._event = /** @type {!Event} */ (event);
this._handlers = {};
this._id = 0;
}
@@ -196,6 +208,9 @@ WebInspector.ContextMenu.setUseSoftMenu = function(useSoftMenu)
}
WebInspector.ContextMenu.prototype = {
+ /**
+ * @return {number}
+ */
nextId: function()
{
return this._id++;
@@ -213,10 +228,14 @@ WebInspector.ContextMenu.prototype = {
} else {
InspectorFrontendHost.showContextMenu(this._event, menuObject);
}
- this._event.consume();
+ this._event.consume(true);
}
},
+ /**
+ * @param {number} id
+ * @param {function(?)} handler
+ */
_setHandler: function(id, handler)
{
if (handler)
@@ -242,8 +261,15 @@ WebInspector.ContextMenu.prototype = {
*/
appendApplicableItems: function(target)
{
- for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) {
- var provider = WebInspector.ContextMenu._providers[i];
+ WebInspector.moduleManager.extensions(WebInspector.ContextMenu.Provider, target).forEach(processProviders.bind(this));
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @this {WebInspector.ContextMenu}
+ */
+ function processProviders(extension)
+ {
+ var provider = /** @type {!WebInspector.ContextMenu.Provider} */ (extension.instance());
this.appendSeparator();
provider.appendApplicableItems(this._event, this, target);
this.appendSeparator();
@@ -256,27 +282,18 @@ WebInspector.ContextMenu.prototype = {
/**
* @interface
*/
-WebInspector.ContextMenu.Provider = function() {
+WebInspector.ContextMenu.Provider = function() {
}
WebInspector.ContextMenu.Provider.prototype = {
- /**
+ /**
+ * @param {!Event} event
* @param {!WebInspector.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems: function(event, contextMenu, target) { }
}
-/**
- * @param {!WebInspector.ContextMenu.Provider} provider
- */
-WebInspector.ContextMenu.registerProvider = function(provider)
-{
- WebInspector.ContextMenu._providers.push(provider);
-}
-
-WebInspector.ContextMenu._providers = [];
-
WebInspector.contextMenuItemSelected = function(id)
{
if (WebInspector._contextMenu)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/DataGrid.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/DataGrid.js
index 2bcc879c1db..7edaf5c62d6 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/DataGrid.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/DataGrid.js
@@ -37,12 +37,15 @@ WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, ref
WebInspector.View.call(this);
this.registerRequiredCSS("dataGrid.css");
- this.element.className = "data-grid";
+ this.element.className = "data-grid"; // Override
this.element.tabIndex = 0;
this.element.addEventListener("keydown", this._keyDown.bind(this), false);
this._headerTable = document.createElement("table");
this._headerTable.className = "header";
+ /**
+ * @type {!Object.<string, !Element>}
+ */
this._headerTableHeaders = {};
this._dataTable = document.createElement("table");
@@ -69,30 +72,24 @@ WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, ref
this.element.appendChild(this._headerTable);
this.element.appendChild(this._scrollContainer);
- var headerRow = document.createElement("tr");
- var columnGroup = document.createElement("colgroup");
- columnGroup.span = columnsArray.length;
+ this._headerRow = document.createElement("tr");
+ this._headerTableColumnGroup = document.createElement("colgroup");
+ this._dataTableColumnGroup = document.createElement("colgroup");
- var fillerRow = document.createElement("tr");
- fillerRow.className = "filler";
+ this._fillerRow = document.createElement("tr");
+ this._fillerRow.className = "filler";
this._columnsArray = columnsArray;
- this.columns = {};
+ this._visibleColumnsArray = columnsArray;
+ this._columns = {};
for (var i = 0; i < columnsArray.length; ++i) {
var column = columnsArray[i];
- column.ordinal = i;
var columnIdentifier = column.identifier = column.id || i;
- this.columns[columnIdentifier] = column;
+ this._columns[columnIdentifier] = column;
if (column.disclosure)
this.disclosureColumnIdentifier = columnIdentifier;
- var col = document.createElement("col");
- if (column.width)
- col.style.width = column.width;
- column.element = col;
- columnGroup.appendChild(col);
-
var cell = document.createElement("th");
cell.className = columnIdentifier + "-column";
cell.columnIdentifier = columnIdentifier;
@@ -114,31 +111,28 @@ WebInspector.DataGrid = function(columnsArray, editCallback, deleteCallback, ref
cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
cell.classList.add("sortable");
}
-
- headerRow.appendChild(cell);
- fillerRow.createChild("td", columnIdentifier + "-column");
}
- headerRow.createChild("th", "corner");
- fillerRow.createChild("td", "corner");
- columnGroup.createChild("col", "corner");
-
- this._headerTableColumnGroup = columnGroup;
this._headerTable.appendChild(this._headerTableColumnGroup);
- this.headerTableBody.appendChild(headerRow);
+ this.headerTableBody.appendChild(this._headerRow);
- this._dataTableColumnGroup = columnGroup.cloneNode(true);
this._dataTable.appendChild(this._dataTableColumnGroup);
- this.dataTableBody.appendChild(fillerRow);
+ this.dataTableBody.appendChild(this._fillerRow);
+
+ this._refreshHeader();
this.selectedNode = null;
this.expandNodesWhenArrowing = false;
this.setRootNode(new WebInspector.DataGridNode());
this.indentWidth = 15;
- this.resizers = [];
+ this._resizers = [];
this._columnWidthsInitialized = false;
+ this._cornerWidth = WebInspector.DataGrid.CornerWidth;
}
+// Keep in sync with .data-grid col.corner style rule.
+WebInspector.DataGrid.CornerWidth = 14;
+
/** @typedef {!{id: ?string, editable: boolean, longText: ?boolean, sort: !WebInspector.DataGrid.Order, sortable: boolean, align: !WebInspector.DataGrid.Align}} */
WebInspector.DataGrid.ColumnDescriptor;
@@ -238,6 +232,32 @@ WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values)
}
WebInspector.DataGrid.prototype = {
+ _refreshHeader: function()
+ {
+ this._headerTableColumnGroup.removeChildren();
+ this._dataTableColumnGroup.removeChildren();
+ this._headerRow.removeChildren();
+ this._fillerRow.removeChildren();
+
+ for (var i = 0; i < this._visibleColumnsArray.length; ++i) {
+ var column = this._visibleColumnsArray[i];
+ var columnIdentifier = column.identifier;
+ var headerColumn = this._headerTableColumnGroup.createChild("col");
+ var dataColumn = this._dataTableColumnGroup.createChild("col");
+ if (column.width) {
+ headerColumn.style.width = column.width;
+ dataColumn.style.width = column.width;
+ }
+ this._headerRow.appendChild(this._headerTableHeaders[columnIdentifier]);
+ this._fillerRow.createChild("td", columnIdentifier + "-column");
+ }
+
+ this._headerRow.createChild("th", "corner");
+ this._fillerRow.createChild("td", "corner");
+ this._headerTableColumnGroup.createChild("col", "corner");
+ this._dataTableColumnGroup.createChild("col", "corner");
+ },
+
/**
* @param {!WebInspector.DataGridNode} rootNode
*/
@@ -271,24 +291,24 @@ WebInspector.DataGrid.prototype = {
return;
var columnIdentifier = this.columnIdentifierFromNode(event.target);
- if (!columnIdentifier || !this.columns[columnIdentifier].editable)
+ if (!columnIdentifier || !this._columns[columnIdentifier].editable)
return;
this._startEditing(event.target);
},
/**
* @param {!WebInspector.DataGridNode} node
- * @param {number} columnOrdinal
+ * @param {number} cellIndex
*/
- _startEditingColumnOfDataGridNode: function(node, columnOrdinal)
+ _startEditingColumnOfDataGridNode: function(node, cellIndex)
{
this._editing = true;
/** @type {!WebInspector.DataGridNode} */
this._editingNode = node;
this._editingNode.select();
- var element = this._editingNode._element.children[columnOrdinal];
- WebInspector.startEditing(element, this._startEditingConfig(element));
+ var element = this._editingNode._element.children[cellIndex];
+ WebInspector.InplaceEditor.startEditing(element, this._startEditingConfig(element));
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
@@ -310,7 +330,7 @@ WebInspector.DataGrid.prototype = {
return this._startEditingColumnOfDataGridNode(this._editingNode, this._nextEditableColumn(-1));
this._editing = true;
- WebInspector.startEditing(element, this._startEditingConfig(element));
+ WebInspector.InplaceEditor.startEditing(element, this._startEditingConfig(element));
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
@@ -318,11 +338,13 @@ WebInspector.DataGrid.prototype = {
renderInline: function()
{
this.element.classList.add("inline");
+ this._cornerWidth = 0;
+ this.updateWidths();
},
_startEditingConfig: function(element)
{
- return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ return new WebInspector.InplaceEditor.Config(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
},
_editingCommitted: function(element, newText, oldText, context, moveDirection)
@@ -332,7 +354,8 @@ WebInspector.DataGrid.prototype = {
this._editingCancelled(element);
return;
}
- var columnOrdinal = this.columns[columnIdentifier].ordinal;
+ var column = this._columns[columnIdentifier];
+ var cellIndex = this._visibleColumnsArray.indexOf(column);
var textBeforeEditing = this._editingNode.data[columnIdentifier];
var currentEditingNode = this._editingNode;
@@ -345,11 +368,11 @@ WebInspector.DataGrid.prototype = {
return;
if (moveDirection === "forward") {
- var firstEditableColumn = this._nextEditableColumn(-1);
- if (currentEditingNode.isCreationNode && columnOrdinal === firstEditableColumn && !wasChange)
+ var firstEditableColumn = this._nextEditableColumn(-1);
+ if (currentEditingNode.isCreationNode && cellIndex === firstEditableColumn && !wasChange)
return;
- var nextEditableColumn = this._nextEditableColumn(columnOrdinal);
+ var nextEditableColumn = this._nextEditableColumn(cellIndex);
if (nextEditableColumn !== -1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, nextEditableColumn);
@@ -364,11 +387,11 @@ WebInspector.DataGrid.prototype = {
}
if (moveDirection === "backward") {
- var prevEditableColumn = this._nextEditableColumn(columnOrdinal, true);
+ var prevEditableColumn = this._nextEditableColumn(cellIndex, true);
if (prevEditableColumn !== -1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, prevEditableColumn);
- var lastEditableColumn = this._nextEditableColumn(this._columnsArray.length, true);
+ var lastEditableColumn = this._nextEditableColumn(this._visibleColumnsArray.length, true);
var nextDataGridNode = currentEditingNode.traversePreviousNode(true, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, lastEditableColumn);
@@ -403,15 +426,15 @@ WebInspector.DataGrid.prototype = {
},
/**
- * @param {number} columnOrdinal
+ * @param {number} cellIndex
* @param {boolean=} moveBackward
* @return {number}
*/
- _nextEditableColumn: function(columnOrdinal, moveBackward)
+ _nextEditableColumn: function(cellIndex, moveBackward)
{
var increment = moveBackward ? -1 : 1;
- var columns = this._columnsArray;
- for (var i = columnOrdinal + increment; (i >= 0) && (i < columns.length); i += increment) {
+ var columns = this._visibleColumnsArray;
+ for (var i = cellIndex + increment; (i >= 0) && (i < columns.length); i += increment) {
if (columns[i].editable)
return i;
}
@@ -551,7 +574,7 @@ WebInspector.DataGrid.prototype = {
widths = this._autoSizeWidths(widths, minPercent, maxPercent);
for (var i = 0; i < this._columnsArray.length; ++i)
- this._columnsArray[i].element.style.width = widths[i] + "%";
+ this._columnsArray[i].weight = widths[i];
this._columnWidthsInitialized = false;
this.updateWidths();
},
@@ -586,7 +609,8 @@ WebInspector.DataGrid.prototype = {
{
var headerTableColumns = this._headerTableColumnGroup.children;
- var tableWidth = this._dataTable.offsetWidth;
+ // Use container size to avoid changes of table width caused by change of column widths.
+ var tableWidth = this.element.offsetWidth - this._cornerWidth;
var numColumns = headerTableColumns.length - 1; // Do not process corner column.
// Do not attempt to use offsetes if we're not attached to the document tree yet.
@@ -597,14 +621,13 @@ WebInspector.DataGrid.prototype = {
// for their widths.
for (var i = 0; i < numColumns; i++) {
var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
- var percentWidth = (100 * columnWidth / tableWidth) + "%";
- this._headerTableColumnGroup.children[i].style.width = percentWidth;
- this._dataTableColumnGroup.children[i].style.width = percentWidth;
+ var column = this._visibleColumnsArray[i];
+ if (!column.weight)
+ column.weight = 100 * columnWidth / tableWidth;
}
this._columnWidthsInitialized = true;
}
- this._positionResizers();
- this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
+ this._applyColumnWeights();
},
/**
@@ -627,7 +650,7 @@ WebInspector.DataGrid.prototype = {
if (weight)
column.weight = weight;
}
- this.applyColumnWeights();
+ this._applyColumnWeights();
},
_saveColumnWeights: function()
@@ -647,20 +670,26 @@ WebInspector.DataGrid.prototype = {
this._loadColumnWeights();
},
- applyColumnWeights: function()
+ _applyColumnWeights: function()
{
+ var tableWidth = this.element.offsetWidth - this._cornerWidth;
+ if (tableWidth <= 0)
+ return;
+
var sumOfWeights = 0.0;
- for (var i = 0; i < this._columnsArray.length; ++i) {
- var column = this._columnsArray[i];
- if (this.isColumnVisible(column))
- sumOfWeights += column.weight;
- }
+ for (var i = 0; i < this._visibleColumnsArray.length; ++i)
+ sumOfWeights += this._visibleColumnsArray[i].weight;
- for (var i = 0; i < this._columnsArray.length; ++i) {
- var column = this._columnsArray[i];
- var width = this.isColumnVisible(column) ? (100 * column.weight / sumOfWeights) + "%" : "0%";
+ var sum = 0;
+ var lastOffset = 0;
+
+ for (var i = 0; i < this._visibleColumnsArray.length; ++i) {
+ sum += this._visibleColumnsArray[i].weight;
+ var offset = (sum * tableWidth / sumOfWeights) | 0;
+ var width = (offset - lastOffset) + "px";
this._headerTableColumnGroup.children[i].style.width = width;
this._dataTableColumnGroup.children[i].style.width = width;
+ lastOffset = offset;
}
this._positionResizers();
@@ -668,25 +697,21 @@ WebInspector.DataGrid.prototype = {
},
/**
- * @param {!WebInspector.DataGrid.ColumnDescriptor} column
- * @return {boolean}
+ * @param {!Object.<string, boolean>} columnsVisibility
*/
- isColumnVisible: function(column)
+ setColumnsVisiblity: function(columnsVisibility)
{
- return !column.hidden;
- },
-
- /**
- * @param {string} columnIdentifier
- * @param {boolean} visible
- */
- setColumnVisible: function(columnIdentifier, visible)
- {
- if (visible === !this.columns[columnIdentifier].hidden)
- return;
-
- this.columns[columnIdentifier].hidden = !visible;
- this.element.enableStyleClass("hide-" + columnIdentifier + "-column", !visible);
+ this._visibleColumnsArray = [];
+ for (var i = 0; i < this._columnsArray.length; ++i) {
+ var column = this._columnsArray[i];
+ if (columnsVisibility[column.identifier])
+ this._visibleColumnsArray.push(column);
+ }
+ this._refreshHeader();
+ this._applyColumnWeights();
+ var nodes = this._enumerateChildren(this.rootNode(), [], -1);
+ for (var i = 0; i < nodes.length; ++i)
+ nodes[i].refresh();
},
get scrollContainer()
@@ -694,6 +719,9 @@ WebInspector.DataGrid.prototype = {
return this._scrollContainer;
},
+ /**
+ * @return {boolean}
+ */
isScrolledToLastRow: function()
{
return this._scrollContainer.isScrolledToBottom();
@@ -708,51 +736,38 @@ WebInspector.DataGrid.prototype = {
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length - 1; // Do not process corner column.
- var left = 0;
- var previousResizer = null;
+ var left = [];
+ var resizers = this._resizers;
+
+ while (resizers.length > numColumns - 1)
+ resizers.pop().remove();
- // Make n - 1 resizers for n columns.
for (var i = 0; i < numColumns - 1; i++) {
- var resizer = this.resizers[i];
+ // Get the width of the cell in the first (and only) row of the
+ // header table in order to determine the width of the column, since
+ // it is not possible to query a column for its width.
+ left[i] = (left[i-1] || 0) + this.headerTableBody.rows[0].cells[i].offsetWidth;
+ }
+ // Make n - 1 resizers for n columns.
+ for (var i = 0; i < numColumns - 1; i++) {
+ var resizer = this._resizers[i];
if (!resizer) {
// This is the first call to updateWidth, so the resizers need
// to be created.
resizer = document.createElement("div");
+ resizer.__index = i;
resizer.classList.add("data-grid-resizer");
// This resizer is associated with the column to its right.
WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
this.element.appendChild(resizer);
- this.resizers[i] = resizer;
+ resizers.push(resizer);
}
-
- // Get the width of the cell in the first (and only) row of the
- // header table in order to determine the width of the column, since
- // it is not possible to query a column for its width.
- left += this.headerTableBody.rows[0].cells[i].offsetWidth;
-
- if (!this._columnsArray[i].hidden) {
- resizer.style.removeProperty("display");
- if (resizer._position !== left) {
- resizer._position = left;
- resizer.style.left = left + "px";
- }
- resizer.leftNeighboringColumnIndex = i;
- if (previousResizer)
- previousResizer.rightNeighboringColumnIndex = i;
- previousResizer = resizer;
- } else {
- if (previousResizer && previousResizer._position !== left) {
- previousResizer._position = left;
- previousResizer.style.left = left + "px";
- }
- resizer.style.setProperty("display", "none");
- resizer.leftNeighboringColumnIndex = 0;
- resizer.rightNeighboringColumnIndex = 0;
+ if (resizer.__position !== left[i]) {
+ resizer.__position = left[i];
+ resizer.style.left = left[i] + "px";
}
}
- if (previousResizer)
- previousResizer.rightNeighboringColumnIndex = numColumns - 1;
},
addCreationNode: function(hasChildren)
@@ -761,7 +776,7 @@ WebInspector.DataGrid.prototype = {
this.creationNode.makeNormal();
var emptyData = {};
- for (var column in this.columns)
+ for (var column in this._columns)
emptyData[column] = null;
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.rootNode().appendChild(this.creationNode);
@@ -949,6 +964,10 @@ WebInspector.DataGrid.prototype = {
this._sortColumnCell.classList.add("sort-" + sortOrder);
},
+ /**
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
headerTableHeader: function(columnIdentifier)
{
return this._headerTableHeaders[columnIdentifier];
@@ -981,14 +1000,13 @@ WebInspector.DataGrid.prototype = {
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));
if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {
- // FIXME: Use the column names for Editing, instead of just "Edit".
if (this._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add new" : "Add New"), this._startEditing.bind(this, event.target));
else {
var columnIdentifier = this.columnIdentifierFromNode(event.target);
- if (columnIdentifier && this.columns[columnIdentifier].editable)
- contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
+ if (columnIdentifier && this._columns[columnIdentifier].editable)
+ contextMenu.appendItem(WebInspector.UIString("Edit \"%s\"", this._columns[columnIdentifier].title), this._startEditing.bind(this, event.target));
}
}
if (this._deleteCallback && gridNode !== this.creationNode)
@@ -1040,7 +1058,7 @@ WebInspector.DataGrid.prototype = {
_startResizerDragging: function(event)
{
this._currentResizer = event.target;
- return !!this._currentResizer.rightNeighboringColumnIndex;
+ return true;
},
_resizerDragging: function(event)
@@ -1049,23 +1067,23 @@ WebInspector.DataGrid.prototype = {
if (!resizer)
return;
- var tableWidth = this._dataTable.offsetWidth; // Cache it early, before we invalidate layout.
+ var tableWidth = this.element.offsetWidth; // Cache it early, before we invalidate layout.
// Constrain the dragpoint to be within the containing div of the
// datagrid.
var dragPoint = event.clientX - this.element.totalOffsetLeft();
- // Constrain the dragpoint to be within the space made up by the
- // column directly to the left and the column directly to the right.
- var leftCellIndex = resizer.leftNeighboringColumnIndex;
- var rightCellIndex = resizer.rightNeighboringColumnIndex;
var firstRowCells = this.headerTableBody.rows[0].cells;
var leftEdgeOfPreviousColumn = 0;
+ // Constrain the dragpoint to be within the space made up by the
+ // column directly to the left and the column directly to the right.
+ var leftCellIndex = resizer.__index;
+ var rightCellIndex = leftCellIndex + 1;
for (var i = 0; i < leftCellIndex; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
// Differences for other resize methods
if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) {
- rightCellIndex = this.resizers.length;
+ rightCellIndex = this._resizers.length;
} else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) {
leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
leftCellIndex = 0;
@@ -1081,18 +1099,20 @@ WebInspector.DataGrid.prototype = {
dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
- resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";
+ var position = (dragPoint - this.CenterResizerOverBorderAdjustment);
+ resizer.__position = position;
+ resizer.style.left = position + "px";
- var percentLeftColumn = (100 * (dragPoint - leftEdgeOfPreviousColumn) / tableWidth) + "%";
- this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
- this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
+ var pxLeftColumn = (dragPoint - leftEdgeOfPreviousColumn) + "px";
+ this._headerTableColumnGroup.children[leftCellIndex].style.width = pxLeftColumn;
+ this._dataTableColumnGroup.children[leftCellIndex].style.width = pxLeftColumn;
- var percentRightColumn = (100 * (rightEdgeOfNextColumn - dragPoint) / tableWidth) + "%";
- this._headerTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;
- this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;
+ var pxRightColumn = (rightEdgeOfNextColumn - dragPoint) + "px";
+ this._headerTableColumnGroup.children[rightCellIndex].style.width = pxRightColumn;
+ this._dataTableColumnGroup.children[rightCellIndex].style.width = pxRightColumn;
- var leftColumn = this._columnsArray[leftCellIndex];
- var rightColumn = this._columnsArray[rightCellIndex];
+ var leftColumn = this._visibleColumnsArray[leftCellIndex];
+ var rightColumn = this._visibleColumnsArray[rightCellIndex];
if (leftColumn.weight || rightColumn.weight) {
var sumOfWeights = leftColumn.weight + rightColumn.weight;
var delta = rightEdgeOfNextColumn - leftEdgeOfPreviousColumn;
@@ -1105,6 +1125,21 @@ WebInspector.DataGrid.prototype = {
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},
+ /**
+ * @param {string} columnId
+ * @return {number}
+ */
+ columnOffset: function(columnId)
+ {
+ if (!this.element.offsetWidth)
+ return 0;
+ for (var i = 1; i < this._visibleColumnsArray.length; ++i) {
+ if (columnId === this._visibleColumnsArray[i].identifier)
+ return this._resizers[i - 1].__position;
+ }
+ return 0;
+ },
+
_endResizerDragging: function(event)
{
this._currentResizer = null;
@@ -1112,6 +1147,14 @@ WebInspector.DataGrid.prototype = {
this.dispatchEventToListeners(WebInspector.DataGrid.Events.ColumnsResized);
},
+ /**
+ * @return {?Element}
+ */
+ defaultAttachLocation: function()
+ {
+ return this.dataTableBody.firstChild;
+ },
+
ColumnResizePadding: 24,
CenterResizerOverBorderAdjustment: 3,
@@ -1186,7 +1229,7 @@ WebInspector.DataGridNode.prototype = {
createCells: function()
{
- var columnsArray = this.dataGrid._columnsArray;
+ var columnsArray = this.dataGrid._visibleColumnsArray;
for (var i = 0; i < columnsArray.length; ++i) {
var cell = this.createCell(columnsArray[i].identifier);
this._element.appendChild(cell);
@@ -1233,8 +1276,8 @@ WebInspector.DataGridNode.prototype = {
if (!this._element)
return;
- this._element.enableStyleClass("parent", this._hasChildren);
- this._element.enableStyleClass("expanded", this._hasChildren && this.expanded);
+ this._element.classList.toggle("parent", this._hasChildren);
+ this._element.classList.toggle("expanded", this._hasChildren && this.expanded);
},
get hasChildren()
@@ -1250,7 +1293,7 @@ WebInspector.DataGridNode.prototype = {
this._revealed = x;
if (this._element)
- this._element.enableStyleClass("revealed", this._revealed);
+ this._element.classList.toggle("revealed", this._revealed);
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = x && this.expanded;
@@ -1337,7 +1380,7 @@ WebInspector.DataGridNode.prototype = {
cell.className = columnIdentifier + "-column";
cell.columnIdentifier_ = columnIdentifier;
- var alignment = this.dataGrid.columns[columnIdentifier].align;
+ var alignment = this.dataGrid._columns[columnIdentifier].align;
if (alignment)
cell.classList.add(alignment);
@@ -1353,15 +1396,13 @@ WebInspector.DataGridNode.prototype = {
var cell = this.createTD(columnIdentifier);
var data = this.data[columnIdentifier];
- var div = document.createElement("div");
- if (data instanceof Node)
- div.appendChild(data);
- else {
- div.textContent = data;
- if (this.dataGrid.columns[columnIdentifier].longText)
- div.title = data;
+ if (data instanceof Node) {
+ cell.appendChild(data);
+ } else {
+ cell.textContent = data;
+ if (this.dataGrid._columns[columnIdentifier].longText)
+ cell.title = data;
}
- cell.appendChild(div);
if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.classList.add("disclosure");
@@ -1375,17 +1416,9 @@ WebInspector.DataGridNode.prototype = {
/**
* @return {number}
*/
- nodeHeight: function()
+ nodeSelfHeight: function()
{
- var rowHeight = 16;
- if (!this.revealed)
- return 0;
- if (!this.expanded)
- return rowHeight;
- var result = rowHeight;
- for (var i = 0; i < this.children.length; i++)
- result += this.children[i].nodeHeight();
- return result;
+ return 16;
},
/**
@@ -1492,21 +1525,15 @@ WebInspector.DataGridNode.prototype = {
if (!this.parent)
return;
- var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);
-
- if (previousChild) {
+ var previousChild = this.parent.children[myIndex - 1] || null;
+ if (previousChild)
previousChild.nextSibling = this;
- this.previousSibling = previousChild;
- } else
- this.previousSibling = null;
+ this.previousSibling = previousChild;
- var nextChild = this.parent.children[myIndex + 1];
-
- if (nextChild) {
+ var nextChild = this.parent.children[myIndex + 1] || null;
+ if (nextChild)
nextChild.previousSibling = this;
- this.nextSibling = nextChild;
- } else
- this.nextSibling = null;
+ this.nextSibling = nextChild;
},
collapse: function()
@@ -1734,7 +1761,7 @@ WebInspector.DataGridNode.prototype = {
if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling)
nextNode = previousNode.element.nextSibling;
if (!nextNode)
- nextNode = this.dataGrid.dataTableBody.firstChild;
+ nextNode = this.dataGrid.defaultAttachLocation();
this.dataGrid.dataTableBody.insertBefore(this.element, nextNode);
if (this.expanded)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Dialog.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
index 171f4a16229..feab83ac024 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Dialog.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
@@ -42,6 +42,7 @@ WebInspector.Dialog = function(relativeToElement, delegate)
// Install glass pane capturing events.
this._glassPane.element.tabIndex = 0;
this._glassPane.element.addEventListener("focus", this._onGlassPaneFocus.bind(this), false);
+ this._glassPane.element.addEventListener("keydown", this._onGlassPaneKeyDown.bind(this), false);
this._element = this._glassPane.element.createChild("div");
this._element.tabIndex = 0;
@@ -55,13 +56,11 @@ WebInspector.Dialog = function(relativeToElement, delegate)
delegate.show(this._element);
this._position();
- this._windowResizeHandler = this._position.bind(this);
- window.addEventListener("resize", this._windowResizeHandler, true);
this._delegate.focus();
}
/**
- * @return {!WebInspector.Dialog}
+ * @return {?WebInspector.Dialog}
*/
WebInspector.Dialog.currentInstance = function()
{
@@ -97,7 +96,6 @@ WebInspector.Dialog.prototype = {
delete WebInspector.Dialog._instance;
this._glassPane.dispose();
- window.removeEventListener("resize", this._windowResizeHandler, true);
},
_onGlassPaneFocus: function(event)
@@ -105,6 +103,16 @@ WebInspector.Dialog.prototype = {
this._hide();
},
+ /**
+ * @param {?Event} event
+ */
+ _onGlassPaneKeyDown: function(event)
+ {
+ var actions = WebInspector.shortcutRegistry.applicableActions(WebInspector.KeyboardShortcut.makeKeyFromEvent(/** @type {?KeyboardEvent} */ (event)));
+ if (actions.length)
+ event.consume(true);
+ },
+
_onFocus: function(event)
{
this._delegate.focus();
@@ -138,6 +146,8 @@ WebInspector.Dialog.prototype = {
*/
WebInspector.DialogDelegate = function()
{
+ /** @type {!Element} */
+ this.element;
}
WebInspector.DialogDelegate.prototype = {
@@ -157,16 +167,17 @@ WebInspector.DialogDelegate.prototype = {
*/
position: function(element, relativeToElement)
{
- var offset = relativeToElement.offsetRelativeToWindow(window);
+ var container = WebInspector.Dialog._modalHostView.element;
+ var box = relativeToElement.boxInWindow(window).relativeToElement(container);
- var positionX = offset.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2;
- positionX = Number.constrain(positionX, 0, window.innerWidth - element.offsetWidth);
+ var positionX = box.x + (relativeToElement.offsetWidth - element.offsetWidth) / 2;
+ positionX = Number.constrain(positionX, 0, container.offsetWidth - element.offsetWidth);
- var positionY = offset.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2;
- positionY = Number.constrain(positionY, 0, window.innerHeight - element.offsetHeight);
+ var positionY = box.y + (relativeToElement.offsetHeight - element.offsetHeight) / 2;
+ positionY = Number.constrain(positionY, 0, container.offsetHeight - element.offsetHeight);
- element.style.left = positionX + "px";
- element.style.top = positionY + "px";
+ element.style.position = "absolute";
+ element.positionAt(positionX, positionY, container);
},
focus: function() { },
@@ -178,3 +189,30 @@ WebInspector.DialogDelegate.prototype = {
__proto__: WebInspector.Object.prototype
}
+/** @type {?WebInspector.View} */
+WebInspector.Dialog._modalHostView = null;
+
+/**
+ * @param {!WebInspector.View} view
+ */
+WebInspector.Dialog.setModalHostView = function(view)
+{
+ WebInspector.Dialog._modalHostView = view;
+};
+
+/**
+ * FIXME: make utility method in Dialog, so clients use it instead of this getter.
+ * Method should be like Dialog.showModalElement(position params, reposition callback).
+ * @return {?WebInspector.View}
+ */
+WebInspector.Dialog.modalHostView = function()
+{
+ return WebInspector.Dialog._modalHostView;
+};
+
+WebInspector.Dialog.modalHostRepositioned = function()
+{
+ if (WebInspector.Dialog._instance)
+ WebInspector.Dialog._instance._position();
+};
+
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/DropDownMenu.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/DropDownMenu.js
new file mode 100644
index 00000000000..129cb75ba85
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/DropDownMenu.js
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.DropDownMenu = function()
+{
+ this.element = document.createElementWithClass("select", "drop-down-menu");
+ this.element.addEventListener("mousedown", this._onBeforeMouseDown.bind(this), true);
+ this.element.addEventListener("mousedown", consumeEvent, false);
+ this.element.addEventListener("change", this._onChange.bind(this), false);
+}
+
+WebInspector.DropDownMenu.Events = {
+ BeforeShow: "BeforeShow",
+ ItemSelected: "ItemSelected"
+}
+
+WebInspector.DropDownMenu.prototype = {
+ _onBeforeMouseDown: function()
+ {
+ this.dispatchEventToListeners(WebInspector.DropDownMenu.Events.BeforeShow, null);
+ },
+
+ _onChange: function()
+ {
+ var options = this.element.options;
+ var selectedOption = options[this.element.selectedIndex];
+ this.dispatchEventToListeners(WebInspector.DropDownMenu.Events.ItemSelected, selectedOption.id);
+ },
+
+ /**
+ * @param {string} id
+ * @param {string} title
+ */
+ addItem: function(id, title)
+ {
+ var option = new Option(title);
+ option.id = id;
+ this.element.appendChild(option);
+ },
+
+ /**
+ * @param {?string} id
+ */
+ selectItem: function(id)
+ {
+ var children = this.element.children;
+ for (var i = 0; i < children.length; ++i) {
+ var child = children[i];
+ if (child.id === id) {
+ this.element.selectedIndex = i;
+ return;
+ }
+ }
+ this.element.selectedIndex = -1;
+ },
+
+ clear: function()
+ {
+ this.element.removeChildren();
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/EmptyView.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/EmptyView.js
index a8b51c17df9..0394ecbe78f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/EmptyView.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/EmptyView.js
@@ -30,18 +30,18 @@
/**
* @constructor
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
*/
WebInspector.EmptyView = function(text)
{
- WebInspector.View.call(this);
+ WebInspector.VBox.call(this);
this._text = text;
}
WebInspector.EmptyView.prototype = {
wasShown: function()
{
- this.element.className = "empty-view";
+ this.element.classList.add("empty-view");
this.element.textContent = this._text;
},
@@ -52,6 +52,6 @@ WebInspector.EmptyView.prototype = {
this.element.textContent = this._text;
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/InplaceEditor.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/InplaceEditor.js
new file mode 100644
index 00000000000..d0e1c363e1c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/InplaceEditor.js
@@ -0,0 +1,260 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ */
+WebInspector.InplaceEditor = function()
+{
+};
+
+/**
+ * @param {!Element} element
+ * @param {!WebInspector.InplaceEditor.Config=} config
+ * @return {?{cancel: function(), commit: function(), setWidth: function(number)}}
+ */
+WebInspector.InplaceEditor.startEditing = function(element, config)
+{
+ if (config.multiline)
+ return WebInspector.moduleManager.instance(WebInspector.InplaceEditor).startEditing(element, config);
+
+ if (!WebInspector.InplaceEditor._defaultInstance)
+ WebInspector.InplaceEditor._defaultInstance = new WebInspector.InplaceEditor();
+ return WebInspector.InplaceEditor._defaultInstance.startEditing(element, config);
+}
+
+WebInspector.InplaceEditor.prototype = {
+ /**
+ * @return {string}
+ */
+ editorContent: function(editingContext) {
+ var element = editingContext.element;
+ if (element.tagName === "INPUT" && element.type === "text")
+ return element.value;
+
+ return element.textContent;
+ },
+
+ setUpEditor: function(editingContext)
+ {
+ var element = editingContext.element;
+ element.classList.add("editing");
+
+ var oldTabIndex = element.getAttribute("tabIndex");
+ if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
+ element.tabIndex = 0;
+ WebInspector.setCurrentFocusElement(element);
+ editingContext.oldTabIndex = oldTabIndex;
+ },
+
+ closeEditor: function(editingContext)
+ {
+ var element = editingContext.element;
+ element.classList.remove("editing");
+
+ if (typeof editingContext.oldTabIndex !== "number")
+ element.removeAttribute("tabIndex");
+ else
+ element.tabIndex = editingContext.oldTabIndex;
+ element.scrollTop = 0;
+ element.scrollLeft = 0;
+ },
+
+ cancelEditing: function(editingContext)
+ {
+ var element = editingContext.element;
+ if (element.tagName === "INPUT" && element.type === "text")
+ element.value = editingContext.oldText;
+ else
+ element.textContent = editingContext.oldText;
+ },
+
+ augmentEditingHandle: function(editingContext, handle)
+ {
+ },
+
+ /**
+ * @param {!Element} element
+ * @param {!WebInspector.InplaceEditor.Config=} config
+ * @return {?{cancel: function(), commit: function()}}
+ */
+ startEditing: function(element, config)
+ {
+ if (!WebInspector.markBeingEdited(element, true))
+ return null;
+
+ config = config || new WebInspector.InplaceEditor.Config(function() {}, function() {});
+ var editingContext = { element: element, config: config };
+ var committedCallback = config.commitHandler;
+ var cancelledCallback = config.cancelHandler;
+ var pasteCallback = config.pasteHandler;
+ var context = config.context;
+ var isMultiline = config.multiline || false;
+ var moveDirection = "";
+ var self = this;
+
+ /**
+ * @param {?Event} e
+ */
+ function consumeCopy(e)
+ {
+ e.consume();
+ }
+
+ this.setUpEditor(editingContext);
+
+ editingContext.oldText = isMultiline ? config.initialValue : this.editorContent(editingContext);
+
+ /**
+ * @param {?Event=} e
+ */
+ function blurEventListener(e) {
+ if (!isMultiline || !e || !e.relatedTarget || !e.relatedTarget.isSelfOrDescendant(element))
+ editingCommitted.call(element);
+ }
+
+ function cleanUpAfterEditing()
+ {
+ WebInspector.markBeingEdited(element, false);
+
+ element.removeEventListener("blur", blurEventListener, isMultiline);
+ element.removeEventListener("keydown", keyDownEventListener, true);
+ if (pasteCallback)
+ element.removeEventListener("paste", pasteEventListener, true);
+
+ WebInspector.restoreFocusFromElement(element);
+ self.closeEditor(editingContext);
+ }
+
+ /** @this {Element} */
+ function editingCancelled()
+ {
+ self.cancelEditing(editingContext);
+ cleanUpAfterEditing();
+ cancelledCallback(this, context);
+ }
+
+ /** @this {Element} */
+ function editingCommitted()
+ {
+ cleanUpAfterEditing();
+
+ committedCallback(this, self.editorContent(editingContext), editingContext.oldText, context, moveDirection);
+ }
+
+ function defaultFinishHandler(event)
+ {
+ var isMetaOrCtrl = WebInspector.isMac() ?
+ event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
+ event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
+ if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !isMultiline || isMetaOrCtrl))
+ return "commit";
+ else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
+ return "cancel";
+ else if (!isMultiline && event.keyIdentifier === "U+0009") // Tab key
+ return "move-" + (event.shiftKey ? "backward" : "forward");
+ }
+
+ function handleEditingResult(result, event)
+ {
+ if (result === "commit") {
+ editingCommitted.call(element);
+ event.consume(true);
+ } else if (result === "cancel") {
+ editingCancelled.call(element);
+ event.consume(true);
+ } else if (result && result.startsWith("move-")) {
+ moveDirection = result.substring(5);
+ if (event.keyIdentifier !== "U+0009")
+ blurEventListener();
+ }
+ }
+
+ function pasteEventListener(event)
+ {
+ var result = pasteCallback(event);
+ handleEditingResult(result, event);
+ }
+
+ function keyDownEventListener(event)
+ {
+ var handler = config.customFinishHandler || defaultFinishHandler;
+ var result = handler(event);
+ handleEditingResult(result, event);
+ }
+
+ element.addEventListener("blur", blurEventListener, isMultiline);
+ element.addEventListener("keydown", keyDownEventListener, true);
+ if (pasteCallback)
+ element.addEventListener("paste", pasteEventListener, true);
+
+ var handle = {
+ cancel: editingCancelled.bind(element),
+ commit: editingCommitted.bind(element)
+ };
+ this.augmentEditingHandle(editingContext, handle);
+ return handle;
+ }
+}
+
+/**
+ * @constructor
+ * @param {function(!Element,string,string,T,string)} commitHandler
+ * @param {function(!Element,T)} cancelHandler
+ * @param {T=} context
+ * @template T
+ */
+WebInspector.InplaceEditor.Config = function(commitHandler, cancelHandler, context)
+{
+ this.commitHandler = commitHandler;
+ this.cancelHandler = cancelHandler
+ this.context = context;
+
+ /**
+ * Handles the "paste" event, return values are the same as those for customFinishHandler
+ * @type {function(!Element)|undefined}
+ */
+ this.pasteHandler;
+
+ /**
+ * Whether the edited element is multiline
+ * @type {boolean|undefined}
+ */
+ this.multiline;
+
+ /**
+ * Custom finish handler for the editing session (invoked on keydown)
+ * @type {function(!Element,*)|undefined}
+ */
+ this.customFinishHandler;
+}
+
+WebInspector.InplaceEditor.Config.prototype = {
+ setPasteHandler: function(pasteHandler)
+ {
+ this.pasteHandler = pasteHandler;
+ },
+
+ /**
+ * @param {string} initialValue
+ * @param {!Object} mode
+ * @param {string} theme
+ * @param {boolean=} lineWrapping
+ * @param {boolean=} smartIndent
+ */
+ setMultilineOptions: function(initialValue, mode, theme, lineWrapping, smartIndent)
+ {
+ this.multiline = true;
+ this.initialValue = initialValue;
+ this.mode = mode;
+ this.theme = theme;
+ this.lineWrapping = lineWrapping;
+ this.smartIndent = smartIndent;
+ },
+
+ setCustomFinishHandler: function(customFinishHandler)
+ {
+ this.customFinishHandler = customFinishHandler;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/KeyboardShortcut.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/KeyboardShortcut.js
index dae45b15b13..0d12ed03c7c 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/KeyboardShortcut.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/KeyboardShortcut.js
@@ -48,6 +48,11 @@ WebInspector.KeyboardShortcut.Modifiers = {
{
// "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
return WebInspector.isMac() ? this.Meta : this.Ctrl;
+ },
+ get ShiftOrOption()
+ {
+ // Shift on Mac, Alt on other platforms
+ return WebInspector.isMac() ? this.Shift : this.Alt;
}
};
@@ -59,6 +64,7 @@ WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
Tab: { code: 9, name: { mac: "\u21e5", other: "Tab" } },
Enter: { code: 13, name: { mac: "\u21a9", other: "Enter" } },
+ Ctrl: { code: 17, name: "Ctrl" },
Esc: { code: 27, name: { mac: "\u238b", other: "Esc" } },
Space: { code: 32, name: "Space" },
PageUp: { code: 33, name: { mac: "\u21de", other: "PageUp" } }, // also NUM_NORTH_EAST
@@ -71,6 +77,8 @@ WebInspector.KeyboardShortcut.Keys = {
Down: { code: 40, name: "\u2193" }, // also NUM_SOUTH
Delete: { code: 46, name: "Del" },
Zero: { code: 48, name: "0" },
+ H: { code: 72, name: "H" },
+ Meta: { code: 91, name: "Meta" },
F1: { code: 112, name: "F1" },
F2: { code: 113, name: "F2" },
F3: { code: 114, name: "F3" },
@@ -84,18 +92,19 @@ WebInspector.KeyboardShortcut.Keys = {
F11: { code: 122, name: "F11" },
F12: { code: 123, name: "F12" },
Semicolon: { code: 186, name: ";" },
+ NumpadPlus: { code: 107, name: "Numpad +" },
+ NumpadMinus: { code: 109, name: "Numpad -" },
+ Numpad0: { code: 96, name: "Numpad 0" },
Plus: { code: 187, name: "+" },
Comma: { code: 188, name: "," },
Minus: { code: 189, name: "-" },
Period: { code: 190, name: "." },
Slash: { code: 191, name: "/" },
+ QuestionMark: { code: 191, name: "?" },
Apostrophe: { code: 192, name: "`" },
+ Tilde: { code: 192, name: "Tilde" },
Backslash: { code: 220, name: "\\" },
SingleQuote: { code: 222, name: "\'" },
- H: { code: 72, name: "H" },
- Ctrl: { code: 17, name: "Ctrl" },
- Meta: { code: 91, name: "Meta" },
- Tilde: { code: 192, name: "Tilde" },
get CtrlOrMeta()
{
// "default" command/ctrl key for platform, Command on Mac, Ctrl on other platforms
@@ -103,18 +112,30 @@ WebInspector.KeyboardShortcut.Keys = {
},
};
+WebInspector.KeyboardShortcut.KeyBindings = {};
+
+(function() {
+ for (var key in WebInspector.KeyboardShortcut.Keys) {
+ var descriptor = WebInspector.KeyboardShortcut.Keys[key];
+ if (typeof descriptor === "object" && descriptor["code"]) {
+ var name = typeof descriptor["name"] === "string" ? descriptor["name"] : key;
+ WebInspector.KeyboardShortcut.KeyBindings[name] = { code: descriptor["code"] };
+ }
+ }
+})();
+
/**
* Creates a number encoding keyCode in the lower 8 bits and modifiers mask in the higher 8 bits.
* It is useful for matching pressed keys.
*
* @param {number|string} keyCode The code of the key, or a character "a-z" which is converted to a keyCode value.
- * @param {number=} modifiers Optional list of modifiers passed as additional paramerters.
+ * @param {number=} modifiers Optional list of modifiers passed as additional parameters.
* @return {number}
*/
WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
{
if (typeof keyCode === "string")
- keyCode = keyCode.charCodeAt(0) - 32;
+ keyCode = keyCode.charCodeAt(0) - (/^[a-z]/.test(keyCode) ? 32 : 0);
modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
}
@@ -134,7 +155,13 @@ WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
if (keyboardEvent.metaKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
- return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
+
+ function keyCodeForEvent(keyboardEvent)
+ {
+ // Use either a real or a synthetic keyCode (for events originating from extensions).
+ return keyboardEvent.keyCode || keyboardEvent["__keyCode"];
+ }
+ return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCodeForEvent(keyboardEvent), modifiers);
}
/**
@@ -172,6 +199,29 @@ WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
}
/**
+ * @param {string} shortcut
+ * @return {number}
+ */
+WebInspector.KeyboardShortcut.makeKeyFromBindingShortcut = function(shortcut)
+{
+ var parts = shortcut.split(/\+(?!$)/);
+ var modifiers = 0;
+ for (var i = 0; i < parts.length; ++i) {
+ if (typeof WebInspector.KeyboardShortcut.Modifiers[parts[i]] !== "undefined") {
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers[parts[i]];
+ continue;
+ }
+ console.assert(i === parts.length - 1, "Modifiers-only shortcuts are not allowed (encountered <" + shortcut + ">)");
+ var key = WebInspector.KeyboardShortcut.Keys[parts[i]] || WebInspector.KeyboardShortcut.KeyBindings[parts[i]];
+ if (key && key.shiftKey)
+ modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
+ return WebInspector.KeyboardShortcut.makeKey(key ? key.code : parts[i].toLowerCase(), modifiers)
+ }
+ console.assert(false);
+ return 0;
+}
+
+/**
* @param {string|!WebInspector.KeyboardShortcut.Key} key
* @param {number=} modifiers
* @return {string}
@@ -205,6 +255,15 @@ WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, m
};
/**
+ * @param {number} key
+ * @return {!{keyCode: number, modifiers: number}}
+ */
+WebInspector.KeyboardShortcut.keyCodeAndModifiersFromKey = function(key)
+{
+ return { keyCode: key & 255, modifiers: key >> 8 };
+}
+
+/**
* @param {number|undefined} modifiers
* @return {string}
*/
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/PieChart.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/PieChart.js
new file mode 100644
index 00000000000..8cacabdd920
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/PieChart.js
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {number=} totalValue
+ * @param {function(number):string=} formatter
+ */
+WebInspector.PieChart = function(totalValue, formatter)
+{
+ const shadowOffset = 0.04;
+ this.element = document.createElementWithClass("div", "pie-chart");
+ var svg = this._createSVGChild(this.element, "svg");
+ svg.setAttribute("width", "100%");
+ svg.setAttribute("height", (100 * (1 + shadowOffset)) + "%");
+ this._group = this._createSVGChild(svg, "g");
+ var shadow = this._createSVGChild(this._group, "circle");
+ shadow.setAttribute("r", 1);
+ shadow.setAttribute("cy", shadowOffset);
+ shadow.setAttribute("fill", "hsl(0,0%,70%)");
+ var background = this._createSVGChild(this._group, "circle");
+ background.setAttribute("r", 1);
+ background.setAttribute("fill", "hsl(0,0%,92%)");
+ if (totalValue) {
+ var totalString = formatter ? formatter(totalValue) : totalValue;
+ this._totalElement = this.element.createChild("div", "pie-chart-foreground");
+ this._totalElement.textContent = totalString;
+ this._totalValue = totalValue;
+ }
+ this._lastAngle = -Math.PI/2;
+ this.setSize(100);
+}
+
+WebInspector.PieChart.prototype = {
+ /**
+ * @param {number} value
+ */
+ setTotal: function(value)
+ {
+ this._totalValue = value;
+ },
+
+ /**
+ * @param {number} value
+ */
+ setSize: function(value)
+ {
+ this._group.setAttribute("transform", "scale(" + (value / 2) + ") translate(1,1)");
+ var size = value + "px";
+ this.element.style.width = size;
+ this.element.style.height = size;
+ if (this._totalElement)
+ this._totalElement.style.lineHeight = size;
+ },
+
+ /**
+ * @param {number} value
+ * @param {string} color
+ */
+ addSlice: function(value, color)
+ {
+ var sliceAngle = value / this._totalValue * 2 * Math.PI;
+ if (!isFinite(sliceAngle))
+ return;
+ sliceAngle = Math.min(sliceAngle, 2 * Math.PI * 0.9999);
+ var path = this._createSVGChild(this._group, "path");
+ var x1 = Math.cos(this._lastAngle);
+ var y1 = Math.sin(this._lastAngle);
+ this._lastAngle += sliceAngle;
+ var x2 = Math.cos(this._lastAngle);
+ var y2 = Math.sin(this._lastAngle);
+ var largeArc = sliceAngle > Math.PI ? 1 : 0;
+ path.setAttribute("d", "M0,0 L" + x1 + "," + y1 + " A1,1,0," + largeArc + ",1," + x2 + "," + y2 + " Z");
+ path.setAttribute("fill", color);
+ },
+
+ /**
+ * @param {!Element} parent
+ * @param {string} childType
+ * @return {!Element}
+ */
+ _createSVGChild: function(parent, childType)
+ {
+ var child = document.createElementNS("http://www.w3.org/2000/svg", childType);
+ parent.appendChild(child);
+ return child;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/Popover.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Popover.js
index e5b3db923c2..d183d2a1c4e 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/Popover.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/Popover.js
@@ -37,7 +37,7 @@ WebInspector.Popover = function(popoverHelper)
{
WebInspector.View.call(this);
this.markAsRoot();
- this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";
+ this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll"; // Override
this._popupArrowElement = document.createElement("div");
this._popupArrowElement.className = "arrow";
@@ -153,10 +153,13 @@ WebInspector.Popover.prototype = {
// Skinny tooltips are not pretty, their arrow location is not nice.
preferredWidth = Math.max(preferredWidth, 50);
- const totalWidth = window.innerWidth;
- const totalHeight = window.innerHeight;
+ // Position relative to main DevTools element.
+ const container = WebInspector.Dialog.modalHostView().element;
+ const totalWidth = container.offsetWidth;
+ const totalHeight = container.offsetHeight;
var anchorBox = anchorElement instanceof AnchorBox ? anchorElement : anchorElement.boxInWindow(window);
+ anchorBox = anchorBox.relativeToElement(container);
var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
var verticalAlignment;
@@ -179,8 +182,8 @@ WebInspector.Popover.prototype = {
} else {
// Positioning below the anchor.
newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
- if ((newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) && (arrowDirection !== WebInspector.Popover.Orientation.Top)) {
- newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
+ if ((newElementPosition.y + newElementPosition.height + borderRadius >= totalHeight) && (arrowDirection !== WebInspector.Popover.Orientation.Top)) {
+ newElementPosition.height = totalHeight - borderRadius - newElementPosition.y;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = totalHeight - preferredHeight - borderRadius;
newElementPosition.height = preferredHeight;
@@ -215,7 +218,7 @@ WebInspector.Popover.prototype = {
}
this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
- this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
+ this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth, container);
this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
},
@@ -336,6 +339,9 @@ WebInspector.PopoverHelper.prototype = {
}
},
+ /**
+ * @return {boolean}
+ */
isPopoverVisible: function()
{
return !!this._popover;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ProgressIndicator.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ProgressIndicator.js
index 58d4616a05f..8831be5b9dc 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ProgressIndicator.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ProgressIndicator.js
@@ -46,10 +46,6 @@ WebInspector.ProgressIndicator = function()
this._worked = 0;
}
-WebInspector.ProgressIndicator.Events = {
- Done: "Done"
-}
-
WebInspector.ProgressIndicator.prototype = {
/**
* @param {!Element} parent
@@ -72,7 +68,7 @@ WebInspector.ProgressIndicator.prototype = {
return;
this._isDone = true;
this.hide();
- this.dispatchEventToListeners(WebInspector.ProgressIndicator.Events.Done);
+ this.dispatchEventToListeners(WebInspector.Progress.Events.Done);
},
cancel: function()
@@ -81,6 +77,9 @@ WebInspector.ProgressIndicator.prototype = {
this.dispatchEventToListeners(WebInspector.Progress.Events.Canceled);
},
+ /**
+ * @return {boolean}
+ */
isCanceled: function()
{
return this._isCanceled;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/ResizerWidget.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ResizerWidget.js
new file mode 100644
index 00000000000..6e61114093c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ResizerWidget.js
@@ -0,0 +1,156 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.ResizerWidget = function()
+{
+ WebInspector.Object.call(this);
+
+ this._isEnabled = true;
+ this._isVertical = true;
+ this._elements = [];
+ this._installDragOnMouseDownBound = this._installDragOnMouseDown.bind(this);
+};
+
+WebInspector.ResizerWidget.Events = {
+ ResizeStart: "ResizeStart",
+ ResizeUpdate: "ResizeUpdate",
+ ResizeEnd: "ResizeEnd"
+};
+
+WebInspector.ResizerWidget.prototype = {
+ /**
+ * @return {boolean}
+ */
+ isEnabled: function()
+ {
+ return this._isEnabled;
+ },
+
+ /**
+ * @param {boolean} enabled
+ */
+ setEnabled: function(enabled)
+ {
+ this._isEnabled = enabled;
+ this._updateElementsClass();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isVertical: function()
+ {
+ return this._isVertical;
+ },
+
+ /**
+ * Vertical widget resizes height (along y-axis).
+ * @param {boolean} vertical
+ */
+ setVertical: function(vertical)
+ {
+ this._isVertical = vertical;
+ this._updateElementsClass();
+ },
+
+ /**
+ * @return {!Array.<!Element>}
+ */
+ elements: function()
+ {
+ return this._elements.slice();
+ },
+
+ /**
+ * @param {!Element} element
+ */
+ addElement: function(element)
+ {
+ if (this._elements.indexOf(element) !== -1)
+ return;
+
+ this._elements.push(element);
+ element.addEventListener("mousedown", this._installDragOnMouseDownBound, false);
+ element.classList.toggle("ns-resizer-widget", this._isVertical && this._isEnabled);
+ element.classList.toggle("ew-resizer-widget", !this._isVertical && this._isEnabled);
+ },
+
+ /**
+ * @param {!Element} element
+ */
+ removeElement: function(element)
+ {
+ if (this._elements.indexOf(element) === -1)
+ return;
+
+ this._elements.remove(element);
+ element.removeEventListener("mousedown", this._installDragOnMouseDownBound, false);
+ element.classList.remove("ns-resizer-widget");
+ element.classList.remove("ew-resizer-widget");
+ },
+
+ _updateElementsClass: function()
+ {
+ for (var i = 0; i < this._elements.length; ++i) {
+ this._elements[i].classList.toggle("ns-resizer-widget", this._isVertical && this._isEnabled);
+ this._elements[i].classList.toggle("ew-resizer-widget", !this._isVertical && this._isEnabled);
+ }
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _installDragOnMouseDown: function(event)
+ {
+ // Only handle drags of the nodes specified.
+ if (this._elements.indexOf(event.target) === -1)
+ return false;
+ WebInspector.elementDragStart(this._dragStart.bind(this), this._drag.bind(this), this._dragEnd.bind(this), this._isVertical ? "ns-resize" : "ew-resize", event);
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ * @return {boolean}
+ */
+ _dragStart: function(event)
+ {
+ if (!this._isEnabled)
+ return false;
+ this._startPosition = this._isVertical ? event.pageY : event.pageX;
+ this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeStart, { startPosition: this._startPosition, currentPosition: this._startPosition });
+ return true;
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ * @return {boolean}
+ */
+ _drag: function(event)
+ {
+ if (!this._isEnabled) {
+ this._dragEnd(event);
+ return true; // Cancel drag.
+ }
+
+ var position = this._isVertical ? event.pageY : event.pageX;
+ this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeUpdate, { startPosition: this._startPosition, currentPosition: position, shiftKey: event.shiftKey });
+ event.preventDefault();
+ return false; // Continue drag.
+ },
+
+ /**
+ * @param {!MouseEvent} event
+ */
+ _dragEnd: function(event)
+ {
+ this.dispatchEventToListeners(WebInspector.ResizerWidget.Events.ResizeEnd);
+ delete this._startPosition;
+ },
+
+ __proto__: WebInspector.Object.prototype
+};
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/SettingsUI.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SettingsUI.js
new file mode 100644
index 00000000000..5c5b3451acb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SettingsUI.js
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.SettingsUI = {}
+
+/**
+ * @param {string} name
+ * @param {!WebInspector.Setting} setting
+ * @param {boolean=} omitParagraphElement
+ * @param {!Element=} inputElement
+ * @param {string=} tooltip
+ * @return {!Element}
+ */
+WebInspector.SettingsUI.createSettingCheckbox = function(name, setting, omitParagraphElement, inputElement, tooltip)
+{
+ var input = inputElement || document.createElement("input");
+ input.type = "checkbox";
+ input.name = name;
+ WebInspector.SettingsUI.bindCheckbox(input, setting);
+
+ var label = document.createElement("label");
+ label.appendChild(input);
+ label.createTextChild(name);
+ if (tooltip)
+ label.title = tooltip;
+
+ if (omitParagraphElement)
+ return label;
+
+ var p = document.createElement("p");
+ p.appendChild(label);
+ return p;
+}
+
+/**
+ * @param {!Element} input
+ * @param {!WebInspector.Setting} setting
+ */
+WebInspector.SettingsUI.bindCheckbox = function(input, setting)
+{
+ function settingChanged()
+ {
+ if (input.checked !== setting.get())
+ input.checked = setting.get();
+ }
+ setting.addChangeListener(settingChanged);
+ settingChanged();
+
+ function inputChanged()
+ {
+ if (setting.get() !== input.checked)
+ setting.set(input.checked);
+ }
+ input.addEventListener("change", inputChanged, false);
+}
+
+/**
+ * @param {string} label
+ * @param {!WebInspector.Setting} setting
+ * @param {boolean} numeric
+ * @param {number=} maxLength
+ * @param {string=} width
+ * @param {function(string):?string=} validatorCallback
+ * @param {boolean=} instant
+ * @param {boolean=} clearForZero
+ * @param {string=} placeholder
+ * @return {!Element}
+ */
+WebInspector.SettingsUI.createSettingInputField = function(label, setting, numeric, maxLength, width, validatorCallback, instant, clearForZero, placeholder)
+{
+ var p = document.createElement("p");
+ var labelElement = p.createChild("label");
+ labelElement.textContent = label;
+ var inputElement = p.createChild("input");
+ inputElement.type = "text";
+ if (numeric)
+ inputElement.className = "numeric";
+ if (maxLength)
+ inputElement.maxLength = maxLength;
+ if (width)
+ inputElement.style.width = width;
+ inputElement.placeholder = placeholder || "";
+
+ if (validatorCallback || instant) {
+ inputElement.addEventListener("change", onInput, false);
+ inputElement.addEventListener("input", onInput, false);
+ }
+ inputElement.addEventListener("keydown", onKeyDown, false);
+
+ var errorMessageLabel;
+ if (validatorCallback) {
+ errorMessageLabel = p.createChild("div");
+ errorMessageLabel.classList.add("field-error-message");
+ validate();
+ }
+
+ function onInput()
+ {
+ if (validatorCallback)
+ validate();
+ if (instant)
+ apply();
+ }
+
+ function onKeyDown(event)
+ {
+ if (isEnterKey(event))
+ apply();
+ }
+
+ function validate()
+ {
+ var error = validatorCallback(inputElement.value);
+ if (!error)
+ error = "";
+ inputElement.classList.toggle("error-input", !!error);
+ errorMessageLabel.textContent = error;
+ }
+
+ if (!instant)
+ inputElement.addEventListener("blur", apply, false);
+
+ function apply()
+ {
+ if (validatorCallback && validatorCallback(inputElement.value))
+ return;
+ setting.removeChangeListener(onSettingChange);
+ setting.set(numeric ? Number(inputElement.value) : inputElement.value);
+ setting.addChangeListener(onSettingChange);
+ }
+
+ setting.addChangeListener(onSettingChange);
+
+ function onSettingChange()
+ {
+ var value = setting.get();
+ if (clearForZero && !value)
+ value = "";
+ inputElement.value = value;
+ }
+ onSettingChange();
+
+ return p;
+}
+
+/**
+ * @param {string} name
+ * @param {!Element} element
+ * @return {!Element}
+ */
+WebInspector.SettingsUI.createCustomSetting = function(name, element)
+{
+ var p = document.createElement("p");
+ var fieldsetElement = document.createElement("fieldset");
+ fieldsetElement.createChild("label").textContent = name;
+ fieldsetElement.appendChild(element);
+ p.appendChild(fieldsetElement);
+ return p;
+}
+
+/**
+ * @param {!WebInspector.Setting} setting
+ * @return {!Element}
+ */
+WebInspector.SettingsUI.createSettingFieldset = function(setting)
+{
+ var fieldset = document.createElement("fieldset");
+ fieldset.disabled = !setting.get();
+ setting.addChangeListener(settingChanged);
+ return fieldset;
+
+ function settingChanged()
+ {
+ fieldset.disabled = !setting.get();
+ }
+}
+
+/**
+ * @param {string} text
+ * @return {?string}
+ */
+WebInspector.SettingsUI.regexValidator = function(text)
+{
+ var regex;
+ try {
+ regex = new RegExp(text);
+ } catch (e) {
+ }
+ return regex ? null : WebInspector.UIString("Invalid pattern");
+}
+
+/**
+ * Creates an input element under the parentElement with the given id and defaultText.
+ * @param {!Element} parentElement
+ * @param {string} id
+ * @param {string} defaultText
+ * @param {function(*)} eventListener
+ * @param {boolean=} numeric
+ * @param {string=} size
+ * @return {!Element} element
+ */
+WebInspector.SettingsUI.createInput = function(parentElement, id, defaultText, eventListener, numeric, size)
+{
+ var element = parentElement.createChild("input");
+ element.id = id;
+ element.type = "text";
+ element.maxLength = 12;
+ element.style.width = size || "80px";
+ element.value = defaultText;
+ element.align = "right";
+ if (numeric)
+ element.className = "numeric";
+ element.addEventListener("input", eventListener, false);
+ element.addEventListener("keydown", keyDownListener, false);
+ function keyDownListener(event)
+ {
+ if (isEnterKey(event))
+ eventListener(event);
+ }
+ return element;
+}
+
+/**
+ * @constructor
+ */
+WebInspector.UISettingDelegate = function()
+{
+}
+
+WebInspector.UISettingDelegate.prototype = {
+ /**
+ * @return {?Element}
+ */
+ settingElement: function()
+ {
+ return null;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/ShortcutRegistry.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ShortcutRegistry.js
new file mode 100644
index 00000000000..abe497398dc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ShortcutRegistry.js
@@ -0,0 +1,214 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @param {!WebInspector.ActionRegistry} actionRegistry
+ */
+WebInspector.ShortcutRegistry = function(actionRegistry)
+{
+ this._actionRegistry = actionRegistry;
+ /** @type {!StringMultimap.<string>} */
+ this._defaultKeyToActions = new StringMultimap();
+ this._registerBindings();
+}
+
+WebInspector.ShortcutRegistry.prototype = {
+ /**
+ * @param {number} key
+ * @return {!Array.<string>}
+ */
+ applicableActions: function(key)
+ {
+ return this._actionRegistry.applicableActions(this._actionIdsForKey(key), WebInspector.context);
+ },
+
+ /**
+ * @param {number} key
+ * @return {!Array.<string>}
+ */
+ _actionIdsForKey: function(key)
+ {
+ var result = new StringSet();
+ var defaults = this._defaultActionsForKey(key);
+ defaults.values().forEach(function(actionId) {
+ result.add(actionId);
+ }, this);
+
+ return result.values();
+ },
+
+ /**
+ * @param {number} key
+ * @return {!Set.<string>}
+ */
+ _defaultActionsForKey: function(key)
+ {
+ return this._defaultKeyToActions.get(String(key));
+ },
+
+ /**
+ * @param {!Array.<string>} actionIds
+ * @return {!Array.<number>}
+ */
+ keysForActions: function(actionIds)
+ {
+ var actionIdSet = actionIds.keySet();
+ var result = [];
+ this._defaultKeyToActions.keys().forEach(function(key) {
+ var actionIdsForKey = this._defaultKeyToActions.get(key);
+ actionIdsForKey.values().some(function(actionId) {
+ if (actionIdSet.hasOwnProperty(actionId)) {
+ result.push(key);
+ return true;
+ }
+ });
+ }, this);
+ return result;
+ },
+
+ /**
+ * @param {!KeyboardEvent} event
+ */
+ handleShortcut: function(event)
+ {
+ this.handleKey(WebInspector.KeyboardShortcut.makeKeyFromEvent(event), event.keyIdentifier, event);
+ },
+
+ /**
+ * @param {number} key
+ * @param {string} keyIdentifier
+ * @param {!KeyboardEvent=} event
+ */
+ handleKey: function(key, keyIdentifier, event)
+ {
+ var actionIds = this.applicableActions(key);
+
+ for (var i = 0; i < actionIds.length; ++i) {
+ var keyModifiers = key >> 8;
+ if (!isPossiblyInputKey()) {
+ if (handler.call(this, actionIds[i]))
+ break;
+ } else {
+ this._pendingActionTimer = setTimeout(handler.bind(this, actionIds[i]), 0);
+ break;
+ }
+ }
+
+ /**
+ * @return {boolean}
+ */
+ function isPossiblyInputKey()
+ {
+ if (!event || !WebInspector.isBeingEdited(/** @type {!Node} */ (event.target)) || /^F\d+|Control|Shift|Alt|Meta|Win|U\+001B$/.test(keyIdentifier))
+ return false;
+
+ if (!keyModifiers)
+ return true;
+
+ var modifiers = WebInspector.KeyboardShortcut.Modifiers;
+ if ((keyModifiers & (modifiers.Ctrl | modifiers.Alt)) === (modifiers.Ctrl | modifiers.Alt))
+ return WebInspector.isWin();
+
+ return !hasModifier(modifiers.Ctrl) && !hasModifier(modifiers.Alt) && !hasModifier(modifiers.Meta);
+ }
+
+ /**
+ * @param {number} mod
+ * @return {boolean}
+ */
+ function hasModifier(mod)
+ {
+ return !!(keyModifiers & mod);
+ }
+
+ /**
+ * @param {string} actionId
+ * @return {boolean}
+ * @this {WebInspector.ShortcutRegistry}
+ */
+ function handler(actionId)
+ {
+ var result = this._actionRegistry.execute(actionId);
+ if (result && event)
+ event.consume(true);
+ delete this._pendingActionTimer;
+ return result;
+ }
+ },
+
+ /**
+ * @param {string} actionId
+ * @param {string} shortcut
+ */
+ registerShortcut: function(actionId, shortcut)
+ {
+ var key = WebInspector.KeyboardShortcut.makeKeyFromBindingShortcut(shortcut);
+ if (!key)
+ return;
+ this._defaultKeyToActions.put(String(key), actionId);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onInput: function(event)
+ {
+ if (this._pendingActionTimer) {
+ clearTimeout(this._pendingActionTimer);
+ delete this._pendingActionTimer;
+ }
+ },
+
+ _registerBindings: function()
+ {
+ document.addEventListener("input", this._onInput.bind(this), true);
+ var extensions = WebInspector.moduleManager.extensions(WebInspector.ActionDelegate);
+ extensions.forEach(registerExtension, this);
+
+ /**
+ * @param {!WebInspector.ModuleManager.Extension} extension
+ * @this {WebInspector.ShortcutRegistry}
+ */
+ function registerExtension(extension)
+ {
+ var descriptor = extension.descriptor();
+ var bindings = descriptor["bindings"];
+ for (var i = 0; bindings && i < bindings.length; ++i) {
+ if (!platformMatches(bindings[i].platform))
+ continue;
+ var shortcuts = bindings[i]["shortcut"].split(/\s+/);
+ shortcuts.forEach(this.registerShortcut.bind(this, descriptor["actionId"]));
+ }
+ }
+
+ /**
+ * @param {string=} platformsString
+ * @return {boolean}
+ */
+ function platformMatches(platformsString)
+ {
+ if (!platformsString)
+ return true;
+ var platforms = platformsString.split(",");
+ var isMatch = false;
+ var currentPlatform = WebInspector.platform();
+ for (var i = 0; !isMatch && i < platforms.length; ++i)
+ isMatch = platforms[i] === currentPlatform;
+ return isMatch;
+ }
+ }
+}
+
+/**
+ * @constructor
+ */
+WebInspector.ShortcutRegistry.ForwardedShortcut = function()
+{
+}
+
+WebInspector.ShortcutRegistry.ForwardedShortcut.instance = new WebInspector.ShortcutRegistry.ForwardedShortcut();
+
+/** @type {!WebInspector.ShortcutRegistry} */
+WebInspector.shortcutRegistry;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ShowMoreDataGridNode.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ShowMoreDataGridNode.js
index a222058e2b1..e8420fce60f 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/ShowMoreDataGridNode.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ShowMoreDataGridNode.js
@@ -91,24 +91,30 @@ WebInspector.ShowMoreDataGridNode.prototype = {
this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
},
+ /** override */
createCells: function()
{
- var cell = document.createElement("td");
- if (this.depth)
- cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
- cell.appendChild(this.showNext);
- cell.appendChild(this.showAll);
- cell.appendChild(this.showLast);
- this._element.appendChild(cell);
-
- var columns = this.dataGrid.columns;
- var count = 0;
- for (var c in columns)
- ++count;
- while (--count > 0) {
- cell = document.createElement("td");
- this._element.appendChild(cell);
+ this._hasCells = false;
+ WebInspector.DataGridNode.prototype.createCells.call(this);
+ },
+
+ /**
+ * @override
+ * @param {string} columnIdentifier
+ * @return {!Element}
+ */
+ createCell: function(columnIdentifier)
+ {
+ var cell = this.createTD(columnIdentifier);
+ if (!this._hasCells) {
+ this._hasCells = true;
+ if (this.depth)
+ cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
+ cell.appendChild(this.showNext);
+ cell.appendChild(this.showAll);
+ cell.appendChild(this.showLast);
}
+ return cell;
},
/**
@@ -133,7 +139,7 @@ WebInspector.ShowMoreDataGridNode.prototype = {
* @override
* @return {number}
*/
- nodeHeight: function()
+ nodeSelfHeight: function()
{
return 32;
},
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js
index 4a07e2ad381..85ac23037ad 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarPane.js
@@ -33,7 +33,8 @@
WebInspector.SidebarPane = function(title)
{
WebInspector.View.call(this);
- this.element.className = "sidebar-pane";
+ this.setMinimumSize(25, 0);
+ this.element.className = "sidebar-pane"; // Override
this.titleElement = document.createElement("div");
this.titleElement.className = "sidebar-pane-toolbar";
@@ -50,6 +51,9 @@ WebInspector.SidebarPane.EventTypes = {
}
WebInspector.SidebarPane.prototype = {
+ /**
+ * @return {string}
+ */
title: function()
{
return this._title;
@@ -122,7 +126,7 @@ WebInspector.SidebarPaneTitle.prototype = {
_expand: function()
{
this.element.classList.add("expanded");
- this._pane.show(this.element.parentNode, this.element.nextSibling);
+ this._pane.show(this.element.parentElement, /** @type {?Element} */ (this.element.nextSibling));
},
_collapse: function()
@@ -141,7 +145,7 @@ WebInspector.SidebarPaneTitle.prototype = {
},
/**
- * @param {!Event} event
+ * @param {?Event} event
*/
_onTitleKeyDown: function(event)
{
@@ -157,7 +161,8 @@ WebInspector.SidebarPaneTitle.prototype = {
WebInspector.SidebarPaneStack = function()
{
WebInspector.View.call(this);
- this.element.className = "sidebar-pane-stack fill";
+ this.setMinimumSize(25, 0);
+ this.element.className = "sidebar-pane-stack"; // Override
this.registerRequiredCSS("sidebarPane.css");
}
@@ -180,7 +185,7 @@ WebInspector.SidebarPaneStack.prototype = {
WebInspector.SidebarTabbedPane = function()
{
WebInspector.TabbedPane.call(this);
- this.setRetainTabsOrder(true);
+ this.setRetainTabOrder(true);
this.element.classList.add("sidebar-tabbed-pane");
this.registerRequiredCSS("sidebarPane.css");
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarTreeElement.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarTreeElement.js
index 10c5e366e74..77d97ae09a1 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SidebarTreeElement.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SidebarTreeElement.js
@@ -53,10 +53,7 @@ WebInspector.SidebarSectionTreeElement.prototype = {
this._smallChildren = x;
- if (this._smallChildren)
- this._childrenListNode.classList.add("small");
- else
- this._childrenListNode.classList.remove("small");
+ this._childrenListNode.classList.toggle("small", this._smallChildren);
},
onattach: function()
@@ -91,24 +88,14 @@ WebInspector.SidebarTreeElement = function(className, title, subtitle, represent
this.disclosureButton.className = "disclosure-button";
}
- if (!this.iconElement) {
- this.iconElement = document.createElement("img");
- this.iconElement.className = "icon";
- }
-
- this.statusElement = document.createElement("div");
- this.statusElement.className = "status";
-
- this.titlesElement = document.createElement("div");
- this.titlesElement.className = "titles";
+ this.iconElement = document.createElementWithClass("div", "icon");
+ this.statusElement = document.createElementWithClass("div", "status");
+ this.titlesElement = document.createElementWithClass("div", "titles");
- this.titleElement = document.createElement("span");
- this.titleElement.className = "title";
- this.titlesElement.appendChild(this.titleElement);
+ this.titleContainer = this.titlesElement.createChild("span", "title-container");
+ this.titleElement = this.titleContainer.createChild("span", "title");
- this.subtitleElement = document.createElement("span");
- this.subtitleElement.className = "subtitle";
- this.titlesElement.appendChild(this.subtitleElement);
+ this.subtitleElement = this.titlesElement.createChild("span", "subtitle");
this.className = className;
this.mainTitle = title;
@@ -124,13 +111,8 @@ WebInspector.SidebarTreeElement.prototype = {
set small(x)
{
this._small = x;
-
- if (this._listItemNode) {
- if (this._small)
- this._listItemNode.classList.add("small");
- else
- this._listItemNode.classList.remove("small");
- }
+ if (this._listItemNode)
+ this._listItemNode.classList.toggle("small", this._small);
},
get mainTitle()
@@ -157,10 +139,7 @@ WebInspector.SidebarTreeElement.prototype = {
set wait(x)
{
- if (x)
- this._listItemNode.classList.add("wait");
- else
- this._listItemNode.classList.remove("wait");
+ this._listItemNode.classList.toggle("wait", x);
},
refreshTitles: function()
@@ -180,6 +159,9 @@ WebInspector.SidebarTreeElement.prototype = {
}
},
+ /**
+ * @return {boolean}
+ */
isEventWithinDisclosureTriangle: function(event)
{
return event.target === this.disclosureButton;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SoftContextMenu.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
index 4a3ce84a047..a4626e36b1b 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SoftContextMenu.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SoftContextMenu.js
@@ -25,6 +25,7 @@
/**
* @constructor
+ * @param {!Array.<!WebInspector.ContextMenuItem>} items
* @param {!WebInspector.SoftContextMenu=} parentMenu
*/
WebInspector.SoftContextMenu = function(items, parentMenu)
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/SplitView.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SplitView.js
new file mode 100644
index 00000000000..29745153432
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SplitView.js
@@ -0,0 +1,888 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
+ * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ * @param {boolean} isVertical
+ * @param {boolean} secondIsSidebar
+ * @param {string=} settingName
+ * @param {number=} defaultSidebarWidth
+ * @param {number=} defaultSidebarHeight
+ * @param {boolean=} constraintsInDip
+ */
+WebInspector.SplitView = function(isVertical, secondIsSidebar, settingName, defaultSidebarWidth, defaultSidebarHeight, constraintsInDip)
+{
+ WebInspector.View.call(this);
+
+ this.registerRequiredCSS("splitView.css");
+ this.element.classList.add("split-view");
+
+ this._mainView = new WebInspector.VBox();
+ this._mainElement = this._mainView.element;
+ this._mainElement.className = "split-view-contents scroll-target split-view-main vbox"; // Override
+
+ this._sidebarView = new WebInspector.VBox();
+ this._sidebarElement = this._sidebarView.element;
+ this._sidebarElement.className = "split-view-contents scroll-target split-view-sidebar vbox"; // Override
+
+ this._resizerElement = this.element.createChild("div", "split-view-resizer");
+ this._resizerElement.createChild("div", "split-view-resizer-border");
+ if (secondIsSidebar) {
+ this._mainView.show(this.element);
+ this._sidebarView.show(this.element);
+ } else {
+ this._sidebarView.show(this.element);
+ this._mainView.show(this.element);
+ }
+
+ this._resizerWidget = new WebInspector.ResizerWidget();
+ this._resizerWidget.setEnabled(true);
+ this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
+ this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate, this);
+ this._resizerWidget.addEventListener(WebInspector.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
+
+ this._defaultSidebarWidth = defaultSidebarWidth || 200;
+ this._defaultSidebarHeight = defaultSidebarHeight || this._defaultSidebarWidth;
+ this._constraintsInDip = !!constraintsInDip;
+ this._settingName = settingName;
+
+ this.setSecondIsSidebar(secondIsSidebar);
+
+ this._innerSetVertical(isVertical);
+ this._showMode = WebInspector.SplitView.ShowMode.Both;
+
+ // Should be called after isVertical has the right value.
+ this.installResizer(this._resizerElement);
+}
+
+/** @typedef {{showMode: string, size: number}} */
+WebInspector.SplitView.SettingForOrientation;
+
+WebInspector.SplitView.ShowMode = {
+ Both: "Both",
+ OnlyMain: "OnlyMain",
+ OnlySidebar: "OnlySidebar"
+}
+
+WebInspector.SplitView.Events = {
+ SidebarSizeChanged: "SidebarSizeChanged",
+ ShowModeChanged: "ShowModeChanged"
+}
+
+WebInspector.SplitView.MinPadding = 20;
+
+WebInspector.SplitView.prototype = {
+ /**
+ * @return {boolean}
+ */
+ isVertical: function()
+ {
+ return this._isVertical;
+ },
+
+ /**
+ * @param {boolean} isVertical
+ */
+ setVertical: function(isVertical)
+ {
+ if (this._isVertical === isVertical)
+ return;
+
+ this._innerSetVertical(isVertical);
+
+ if (this.isShowing())
+ this._updateLayout();
+ },
+
+ /**
+ * @param {boolean} isVertical
+ */
+ _innerSetVertical: function(isVertical)
+ {
+ this.element.classList.remove(this._isVertical ? "hbox" : "vbox");
+ this._isVertical = isVertical;
+ this.element.classList.add(this._isVertical ? "hbox" : "vbox");
+ delete this._resizerElementSize;
+ this._sidebarSize = -1;
+ this._restoreSidebarSizeFromSettings();
+ if (this._shouldSaveShowMode)
+ this._restoreAndApplyShowModeFromSettings();
+ this._updateShowHideSidebarButton();
+ // FIXME: reverse SplitView.isVertical meaning.
+ this._resizerWidget.setVertical(!isVertical);
+ this.invalidateConstraints();
+ },
+
+ /**
+ * @param {boolean=} animate
+ */
+ _updateLayout: function(animate)
+ {
+ delete this._totalSize; // Lazy update.
+ delete this._totalSizeOtherDimension;
+
+ // Remove properties that might affect total size calculation.
+ this._mainElement.style.removeProperty("width");
+ this._mainElement.style.removeProperty("height");
+ this._sidebarElement.style.removeProperty("width");
+ this._sidebarElement.style.removeProperty("height");
+
+ this._innerSetSidebarSize(this._preferredSidebarSize(), !!animate);
+ },
+
+ /**
+ * @return {!Element}
+ */
+ mainElement: function()
+ {
+ return this._mainElement;
+ },
+
+ /**
+ * @return {!Element}
+ */
+ sidebarElement: function()
+ {
+ return this._sidebarElement;
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isSidebarSecond: function()
+ {
+ return this._secondIsSidebar;
+ },
+
+ enableShowModeSaving: function()
+ {
+ this._shouldSaveShowMode = true;
+ this._restoreAndApplyShowModeFromSettings();
+ },
+
+ /**
+ * @return {string}
+ */
+ showMode: function()
+ {
+ return this._showMode;
+ },
+
+ /**
+ * @param {boolean} secondIsSidebar
+ */
+ setSecondIsSidebar: function(secondIsSidebar)
+ {
+ this._mainElement.classList.toggle("split-view-contents-first", secondIsSidebar);
+ this._mainElement.classList.toggle("split-view-contents-second", !secondIsSidebar);
+ this._sidebarElement.classList.toggle("split-view-contents-first", !secondIsSidebar);
+ this._sidebarElement.classList.toggle("split-view-contents-second", secondIsSidebar);
+
+ // Make sure second is last in the children array.
+ if (secondIsSidebar) {
+ if (this._sidebarElement.parentElement && this._sidebarElement.nextSibling)
+ this.element.appendChild(this._sidebarElement);
+ } else {
+ if (this._mainElement.parentElement && this._mainElement.nextSibling)
+ this.element.appendChild(this._mainElement);
+ }
+
+ this._secondIsSidebar = secondIsSidebar;
+ },
+
+ /**
+ * @return {?string}
+ */
+ sidebarSide: function()
+ {
+ if (this._showMode !== WebInspector.SplitView.ShowMode.Both)
+ return null;
+ return this._isVertical ?
+ (this._secondIsSidebar ? "right" : "left") :
+ (this._secondIsSidebar ? "bottom" : "top");
+ },
+
+ /**
+ * @return {number}
+ */
+ preferredSidebarSize: function()
+ {
+ return this._preferredSidebarSize();
+ },
+
+ /**
+ * @return {!Element}
+ */
+ resizerElement: function()
+ {
+ return this._resizerElement;
+ },
+
+ /**
+ * @param {boolean=} animate
+ */
+ hideMain: function(animate)
+ {
+ this._showOnly(this._sidebarView, this._mainView, animate);
+ this._updateShowMode(WebInspector.SplitView.ShowMode.OnlySidebar);
+ },
+
+ /**
+ * @param {boolean=} animate
+ */
+ hideSidebar: function(animate)
+ {
+ this._showOnly(this._mainView, this._sidebarView, animate);
+ this._updateShowMode(WebInspector.SplitView.ShowMode.OnlyMain);
+ },
+
+ /**
+ * @override
+ */
+ detachChildViews: function()
+ {
+ this._mainView.detachChildViews();
+ this._sidebarView.detachChildViews();
+ },
+
+ /**
+ * @param {!WebInspector.View} sideToShow
+ * @param {!WebInspector.View} sideToHide
+ * @param {boolean=} animate
+ */
+ _showOnly: function(sideToShow, sideToHide, animate)
+ {
+ this._cancelAnimation();
+
+ /**
+ * @this {WebInspector.SplitView}
+ */
+ function callback()
+ {
+ sideToShow.show(this.element);
+ sideToHide.detach();
+ sideToShow.element.classList.add("maximized");
+ sideToHide.element.classList.remove("maximized");
+ this._resizerElement.classList.add("hidden");
+ this._removeAllLayoutProperties();
+ }
+
+ if (animate) {
+ this._animate(true, callback.bind(this));
+ } else {
+ callback.call(this);
+ this.doResize();
+ }
+
+ this._sidebarSize = -1;
+ this.setResizable(false);
+ },
+
+ _removeAllLayoutProperties: function()
+ {
+ this._sidebarElement.style.removeProperty("flexBasis");
+
+ this._mainElement.style.removeProperty("width");
+ this._mainElement.style.removeProperty("height");
+ this._sidebarElement.style.removeProperty("width");
+ this._sidebarElement.style.removeProperty("height");
+
+ this._resizerElement.style.removeProperty("left");
+ this._resizerElement.style.removeProperty("right");
+ this._resizerElement.style.removeProperty("top");
+ this._resizerElement.style.removeProperty("bottom");
+
+ this._resizerElement.style.removeProperty("margin-left");
+ this._resizerElement.style.removeProperty("margin-right");
+ this._resizerElement.style.removeProperty("margin-top");
+ this._resizerElement.style.removeProperty("margin-bottom");
+ },
+
+ /**
+ * @param {boolean=} animate
+ */
+ showBoth: function(animate)
+ {
+ if (this._showMode === WebInspector.SplitView.ShowMode.Both)
+ animate = false;
+
+ this._cancelAnimation();
+ this._mainElement.classList.remove("maximized");
+ this._sidebarElement.classList.remove("maximized");
+ this._resizerElement.classList.remove("hidden");
+
+ this._mainView.show(this.element);
+ this._sidebarView.show(this.element);
+ // Order views in DOM properly.
+ this.setSecondIsSidebar(this._secondIsSidebar);
+
+ this._sidebarSize = -1;
+ this.setResizable(true);
+ this._updateShowMode(WebInspector.SplitView.ShowMode.Both);
+ this._updateLayout(animate);
+ },
+
+ /**
+ * @param {boolean} resizable
+ */
+ setResizable: function(resizable)
+ {
+ this._resizerWidget.setEnabled(resizable);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ isResizable: function()
+ {
+ return this._resizerWidget.isEnabled();
+ },
+
+ /**
+ * @param {number} size
+ */
+ setSidebarSize: function(size)
+ {
+ size *= WebInspector.zoomManager.zoomFactor();
+ this._savedSidebarSize = size;
+ this._saveSetting();
+ this._innerSetSidebarSize(size, false, true);
+ },
+
+ /**
+ * @return {number}
+ */
+ sidebarSize: function()
+ {
+ var size = Math.max(0, this._sidebarSize);
+ return size / WebInspector.zoomManager.zoomFactor();
+ },
+
+ /**
+ * Returns total size in DIP.
+ * @return {number}
+ */
+ _totalSizeDIP: function()
+ {
+ if (!this._totalSize) {
+ this._totalSize = this._isVertical ? this.element.offsetWidth : this.element.offsetHeight;
+ this._totalSizeOtherDimension = this._isVertical ? this.element.offsetHeight : this.element.offsetWidth;
+ }
+ return this._totalSize * WebInspector.zoomManager.zoomFactor();
+ },
+
+ /**
+ * @param {string} showMode
+ */
+ _updateShowMode: function(showMode)
+ {
+ this._showMode = showMode;
+ this._saveShowModeToSettings();
+ this._updateShowHideSidebarButton();
+ this.dispatchEventToListeners(WebInspector.SplitView.Events.ShowModeChanged, showMode);
+ this.invalidateConstraints();
+ },
+
+ /**
+ * @param {number} size
+ * @param {boolean} animate
+ * @param {boolean=} userAction
+ */
+ _innerSetSidebarSize: function(size, animate, userAction)
+ {
+ if (this._showMode !== WebInspector.SplitView.ShowMode.Both || !this.isShowing())
+ return;
+
+ size = this._applyConstraints(size, userAction);
+ if (this._sidebarSize === size)
+ return;
+
+ if (!this._resizerElementSize)
+ this._resizerElementSize = this._isVertical ? this._resizerElement.offsetWidth : this._resizerElement.offsetHeight;
+
+ // Invalidate layout below.
+
+ this._removeAllLayoutProperties();
+
+ // this._totalSize is available below since we successfully applied constraints.
+ var sidebarSizeValue = (size / WebInspector.zoomManager.zoomFactor()) + "px";
+ var mainSizeValue = (this._totalSize - size / WebInspector.zoomManager.zoomFactor()) + "px";
+ this.sidebarElement().style.flexBasis = sidebarSizeValue;
+
+ // Make both sides relayout boundaries.
+ if (this._isVertical) {
+ this._sidebarElement.style.width = sidebarSizeValue;
+ this._mainElement.style.width = mainSizeValue;
+ this._sidebarElement.style.height = this._totalSizeOtherDimension + "px";
+ this._mainElement.style.height = this._totalSizeOtherDimension + "px";
+ } else {
+ this._sidebarElement.style.height = sidebarSizeValue;
+ this._mainElement.style.height = mainSizeValue;
+ this._sidebarElement.style.width = this._totalSizeOtherDimension + "px";
+ this._mainElement.style.width = this._totalSizeOtherDimension + "px";
+ }
+
+ // Position resizer.
+ if (this._isVertical) {
+ if (this._secondIsSidebar) {
+ this._resizerElement.style.right = sidebarSizeValue;
+ this._resizerElement.style.marginRight = -this._resizerElementSize / 2 + "px";
+ } else {
+ this._resizerElement.style.left = sidebarSizeValue;
+ this._resizerElement.style.marginLeft = -this._resizerElementSize / 2 + "px";
+ }
+ } else {
+ if (this._secondIsSidebar) {
+ this._resizerElement.style.bottom = sidebarSizeValue;
+ this._resizerElement.style.marginBottom = -this._resizerElementSize / 2 + "px";
+ } else {
+ this._resizerElement.style.top = sidebarSizeValue;
+ this._resizerElement.style.marginTop = -this._resizerElementSize / 2 + "px";
+ }
+ }
+
+ this._sidebarSize = size;
+
+ // Force layout.
+
+ if (animate) {
+ this._animate(false);
+ } else {
+ // No need to recalculate this._sidebarSize and this._totalSize again.
+ this.doResize();
+ this.dispatchEventToListeners(WebInspector.SplitView.Events.SidebarSizeChanged, this.sidebarSize());
+ }
+ },
+
+ /**
+ * @param {boolean} reverse
+ * @param {function()=} callback
+ */
+ _animate: function(reverse, callback)
+ {
+ var animationTime = 50;
+ this._animationCallback = callback;
+
+ var animatedMarginPropertyName;
+ if (this._isVertical)
+ animatedMarginPropertyName = this._secondIsSidebar ? "margin-right" : "margin-left";
+ else
+ animatedMarginPropertyName = this._secondIsSidebar ? "margin-bottom" : "margin-top";
+
+ var zoomFactor = WebInspector.zoomManager.zoomFactor();
+ var marginFrom = reverse ? "0" : "-" + (this._sidebarSize / zoomFactor) + "px";
+ var marginTo = reverse ? "-" + (this._sidebarSize / zoomFactor) + "px" : "0";
+
+ // This order of things is important.
+ // 1. Resize main element early and force layout.
+ this.element.style.setProperty(animatedMarginPropertyName, marginFrom);
+ if (!reverse) {
+ suppressUnused(this._mainElement.offsetWidth);
+ suppressUnused(this._sidebarElement.offsetWidth);
+ }
+
+ // 2. Issue onresize to the sidebar element, its size won't change.
+ if (!reverse)
+ this._sidebarView.doResize();
+
+ // 3. Configure and run animation
+ this.element.style.setProperty("transition", animatedMarginPropertyName + " " + animationTime + "ms linear");
+
+ var boundAnimationFrame;
+ var startTime;
+ /**
+ * @this {WebInspector.SplitView}
+ */
+ function animationFrame()
+ {
+ delete this._animationFrameHandle;
+
+ if (!startTime) {
+ // Kick animation on first frame.
+ this.element.style.setProperty(animatedMarginPropertyName, marginTo);
+ startTime = window.performance.now();
+ } else if (window.performance.now() < startTime + animationTime) {
+ // Process regular animation frame.
+ this._mainView.doResize();
+ } else {
+ // Complete animation.
+ this._cancelAnimation();
+ this._mainView.doResize();
+ this.dispatchEventToListeners(WebInspector.SplitView.Events.SidebarSizeChanged, this.sidebarSize());
+ return;
+ }
+ this._animationFrameHandle = window.requestAnimationFrame(boundAnimationFrame);
+ }
+ boundAnimationFrame = animationFrame.bind(this);
+ this._animationFrameHandle = window.requestAnimationFrame(boundAnimationFrame);
+ },
+
+ _cancelAnimation: function()
+ {
+ this.element.style.removeProperty("margin-top");
+ this.element.style.removeProperty("margin-right");
+ this.element.style.removeProperty("margin-bottom");
+ this.element.style.removeProperty("margin-left");
+ this.element.style.removeProperty("transition");
+
+ if (this._animationFrameHandle) {
+ window.cancelAnimationFrame(this._animationFrameHandle);
+ delete this._animationFrameHandle;
+ }
+ if (this._animationCallback) {
+ this._animationCallback();
+ delete this._animationCallback;
+ }
+ },
+
+ /**
+ * @param {number} sidebarSize
+ * @param {boolean=} userAction
+ * @return {number}
+ */
+ _applyConstraints: function(sidebarSize, userAction)
+ {
+ var totalSize = this._totalSizeDIP();
+ var zoomFactor = this._constraintsInDip ? 1 : WebInspector.zoomManager.zoomFactor();
+
+ var constraints = this._sidebarView.constraints();
+ var minSidebarSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
+ if (!minSidebarSize)
+ minSidebarSize = WebInspector.SplitView.MinPadding;
+ minSidebarSize *= zoomFactor;
+
+ var preferredSidebarSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
+ if (!preferredSidebarSize)
+ preferredSidebarSize = WebInspector.SplitView.MinPadding;
+ preferredSidebarSize *= zoomFactor;
+ // Allow sidebar to be less than preferred by explicit user action.
+ if (sidebarSize < preferredSidebarSize)
+ preferredSidebarSize = Math.max(sidebarSize, minSidebarSize);
+
+ constraints = this._mainView.constraints();
+ var minMainSize = this.isVertical() ? constraints.minimum.width : constraints.minimum.height;
+ if (!minMainSize)
+ minMainSize = WebInspector.SplitView.MinPadding;
+ minMainSize *= zoomFactor;
+
+ var preferredMainSize = this.isVertical() ? constraints.preferred.width : constraints.preferred.height;
+ if (!preferredMainSize)
+ preferredMainSize = WebInspector.SplitView.MinPadding;
+ preferredMainSize *= zoomFactor;
+ var savedMainSize = this.isVertical() ? this._savedVerticalMainSize : this._savedHorizontalMainSize;
+ if (typeof savedMainSize !== "undefined")
+ preferredMainSize = Math.min(preferredMainSize, savedMainSize * zoomFactor);
+ if (userAction)
+ preferredMainSize = minMainSize;
+
+ // Enough space for preferred.
+ var totalPreferred = preferredMainSize + preferredSidebarSize;
+ if (totalPreferred <= totalSize)
+ return Number.constrain(sidebarSize, preferredSidebarSize, totalSize - preferredMainSize);
+
+ // Enough space for minimum.
+ if (minMainSize + minSidebarSize <= totalSize) {
+ var delta = totalPreferred - totalSize;
+ var sidebarDelta = delta * preferredSidebarSize / totalPreferred;
+ sidebarSize = preferredSidebarSize - sidebarDelta;
+ return Number.constrain(sidebarSize, minSidebarSize, totalSize - minMainSize);
+ }
+
+ // Not enough space even for minimum sizes.
+ return Math.max(0, totalSize - minMainSize);
+ },
+
+ wasShown: function()
+ {
+ this._forceUpdateLayout();
+ WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
+ },
+
+ willHide: function()
+ {
+ WebInspector.zoomManager.removeEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._onZoomChanged, this);
+ },
+
+ onResize: function()
+ {
+ this._updateLayout();
+ },
+
+ onLayout: function()
+ {
+ this._updateLayout();
+ },
+
+ /**
+ * @return {!Constraints}
+ */
+ calculateConstraints: function()
+ {
+ if (this._showMode === WebInspector.SplitView.ShowMode.OnlyMain)
+ return this._mainView.constraints();
+ if (this._showMode === WebInspector.SplitView.ShowMode.OnlySidebar)
+ return this._sidebarView.constraints();
+
+ var mainConstraints = this._mainView.constraints();
+ var sidebarConstraints = this._sidebarView.constraints();
+ var min = WebInspector.SplitView.MinPadding;
+ if (this._isVertical) {
+ mainConstraints = mainConstraints.widthToMax(min);
+ sidebarConstraints = sidebarConstraints.widthToMax(min);
+ return mainConstraints.addWidth(sidebarConstraints).heightToMax(sidebarConstraints);
+ } else {
+ mainConstraints = mainConstraints.heightToMax(min);
+ sidebarConstraints = sidebarConstraints.heightToMax(min);
+ return mainConstraints.widthToMax(sidebarConstraints).addHeight(sidebarConstraints);
+ }
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeStart: function(event)
+ {
+ this._resizeStartSize = this._sidebarSize;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeUpdate: function(event)
+ {
+ var cssOffset = event.data.currentPosition - event.data.startPosition;
+ var dipOffset = cssOffset * WebInspector.zoomManager.zoomFactor();
+ var newSize = this._secondIsSidebar ? this._resizeStartSize - dipOffset : this._resizeStartSize + dipOffset;
+ var constrainedSize = this._applyConstraints(newSize, true);
+ this._savedSidebarSize = constrainedSize;
+ this._saveSetting();
+ this._innerSetSidebarSize(constrainedSize, false, true);
+ if (this.isVertical())
+ this._savedVerticalMainSize = this._totalSizeDIP() - this._sidebarSize;
+ else
+ this._savedHorizontalMainSize = this._totalSizeDIP() - this._sidebarSize;
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onResizeEnd: function(event)
+ {
+ delete this._resizeStartSize;
+ },
+
+ hideDefaultResizer: function()
+ {
+ this.uninstallResizer(this._resizerElement);
+ },
+
+ /**
+ * @param {!Element} resizerElement
+ */
+ installResizer: function(resizerElement)
+ {
+ this._resizerWidget.addElement(resizerElement);
+ },
+
+ /**
+ * @param {!Element} resizerElement
+ */
+ uninstallResizer: function(resizerElement)
+ {
+ this._resizerWidget.removeElement(resizerElement);
+ },
+
+ /**
+ * @return {boolean}
+ */
+ hasCustomResizer: function()
+ {
+ var elements = this._resizerWidget.elements();
+ return elements.length > 1 || (elements.length == 1 && elements[0] !== this._resizerElement);
+ },
+
+ /**
+ * @param {!Element} resizer
+ * @param {boolean} on
+ */
+ toggleResizer: function(resizer, on)
+ {
+ if (on)
+ this.installResizer(resizer);
+ else
+ this.uninstallResizer(resizer);
+ },
+
+ /**
+ * @return {?WebInspector.Setting}
+ */
+ _setting: function()
+ {
+ if (!this._settingName)
+ return null;
+
+ if (!WebInspector.settings[this._settingName])
+ WebInspector.settings[this._settingName] = WebInspector.settings.createSetting(this._settingName, {});
+
+ return WebInspector.settings[this._settingName];
+ },
+
+ /**
+ * @return {?WebInspector.SplitView.SettingForOrientation}
+ */
+ _settingForOrientation: function()
+ {
+ var state = this._setting() ? this._setting().get() : {};
+ return this._isVertical ? state.vertical : state.horizontal;
+ },
+
+ /**
+ * @return {number}
+ */
+ _preferredSidebarSize: function()
+ {
+ var size = this._savedSidebarSize;
+ if (!size) {
+ size = this._isVertical ? this._defaultSidebarWidth : this._defaultSidebarHeight;
+ // If we have default value in percents, calculate it on first use.
+ if (0 < size && size < 1)
+ size *= this._totalSizeDIP();
+ }
+ return size;
+ },
+
+ _restoreSidebarSizeFromSettings: function()
+ {
+ var settingForOrientation = this._settingForOrientation();
+ this._savedSidebarSize = settingForOrientation ? settingForOrientation.size : 0;
+ },
+
+ _restoreAndApplyShowModeFromSettings: function()
+ {
+ var orientationState = this._settingForOrientation();
+ this._savedShowMode = orientationState ? orientationState.showMode : WebInspector.SplitView.ShowMode.Both;
+ this._showMode = this._savedShowMode;
+
+ switch (this._savedShowMode) {
+ case WebInspector.SplitView.ShowMode.Both:
+ this.showBoth();
+ break;
+ case WebInspector.SplitView.ShowMode.OnlyMain:
+ this.hideSidebar();
+ break;
+ case WebInspector.SplitView.ShowMode.OnlySidebar:
+ this.hideMain();
+ break;
+ }
+ },
+
+ _saveShowModeToSettings: function()
+ {
+ this._savedShowMode = this._showMode;
+ this._saveSetting();
+ },
+
+ _saveSetting: function()
+ {
+ var setting = this._setting();
+ if (!setting)
+ return;
+ var state = setting.get();
+ var orientationState = (this._isVertical ? state.vertical : state.horizontal) || {};
+
+ orientationState.size = this._savedSidebarSize;
+ if (this._shouldSaveShowMode)
+ orientationState.showMode = this._savedShowMode;
+
+ if (this._isVertical)
+ state.vertical = orientationState;
+ else
+ state.horizontal = orientationState;
+ setting.set(state);
+ },
+
+ _forceUpdateLayout: function()
+ {
+ // Force layout even if sidebar size does not change.
+ this._sidebarSize = -1;
+ this._updateLayout();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onZoomChanged: function(event)
+ {
+ this._forceUpdateLayout();
+ },
+
+ /**
+ * @param {string} title
+ * @param {string} className
+ * @return {!WebInspector.StatusBarButton}
+ */
+ createShowHideSidebarButton: function(title, className)
+ {
+ console.assert(this.isVertical(), "Buttons for split view with horizontal split are not supported yet.");
+
+ this._showHideSidebarButtonTitle = WebInspector.UIString(title);
+ this._showHideSidebarButton = new WebInspector.StatusBarButton("", "sidebar-show-hide-button " + className, 3);
+ this._showHideSidebarButton.addEventListener("click", buttonClicked.bind(this));
+ this._updateShowHideSidebarButton();
+
+ /**
+ * @this {WebInspector.SplitView}
+ * @param {!WebInspector.Event} event
+ */
+ function buttonClicked(event)
+ {
+ if (this._showMode !== WebInspector.SplitView.ShowMode.Both)
+ this.showBoth(true);
+ else
+ this.hideSidebar(true);
+ }
+
+ return this._showHideSidebarButton;
+ },
+
+ _updateShowHideSidebarButton: function()
+ {
+ if (!this._showHideSidebarButton)
+ return;
+ var sidebarHidden = this._showMode === WebInspector.SplitView.ShowMode.OnlyMain;
+ this._showHideSidebarButton.state = sidebarHidden ? "show" : "hide";
+ this._showHideSidebarButton.element.classList.toggle("top-sidebar-show-hide-button", !this.isVertical() && !this.isSidebarSecond());
+ this._showHideSidebarButton.element.classList.toggle("right-sidebar-show-hide-button", this.isVertical() && this.isSidebarSecond());
+ this._showHideSidebarButton.element.classList.toggle("bottom-sidebar-show-hide-button", !this.isVertical() && this.isSidebarSecond());
+ this._showHideSidebarButton.element.classList.toggle("left-sidebar-show-hide-button", this.isVertical() && !this.isSidebarSecond());
+ this._showHideSidebarButton.title = sidebarHidden ? WebInspector.UIString("Show %s", this._showHideSidebarButtonTitle) : WebInspector.UIString("Hide %s", this._showHideSidebarButtonTitle);
+ },
+
+ __proto__: WebInspector.View.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanelDescriptor.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/StackView.js
index 58a7223e7df..1b9e4f20406 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/NetworkPanelDescriptor.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/StackView.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,29 +26,48 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/**
* @constructor
- * @extends {WebInspector.PanelDescriptor}
- * @implements {WebInspector.ContextMenu.Provider}
+ * @extends {WebInspector.VBox}
+ * @param {boolean} isVertical
*/
-WebInspector.NetworkPanelDescriptor = function()
+WebInspector.StackView = function(isVertical)
{
- WebInspector.PanelDescriptor.call(this, "network", WebInspector.UIString("Network"), "NetworkPanel", "NetworkPanel.js");
- WebInspector.ContextMenu.registerProvider(this);
+ WebInspector.VBox.call(this);
+ this._isVertical = isVertical;
+ this._currentSplitView = null;
}
-WebInspector.NetworkPanelDescriptor.prototype = {
- /**
- * @param {!WebInspector.ContextMenu} contextMenu
- * @param {!Object} target
+WebInspector.StackView.prototype = {
+ /**
+ * @param {!WebInspector.View} view
+ * @param {string=} sidebarSizeSettingName
+ * @param {number=} defaultSidebarWidth
+ * @param {number=} defaultSidebarHeight
+ * @return {!WebInspector.SplitView}
*/
- appendApplicableItems: function(event, contextMenu, target)
+ appendView: function(view, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight)
+ {
+ var splitView = new WebInspector.SplitView(this._isVertical, true, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight);
+ view.show(splitView.mainElement());
+ splitView.hideSidebar();
+
+ if (!this._currentSplitView) {
+ splitView.show(this.element);
+ } else {
+ splitView.show(this._currentSplitView.sidebarElement());
+ this._currentSplitView.showBoth();
+ }
+
+ this._currentSplitView = splitView;
+ return splitView;
+ },
+
+ detachChildViews: function()
{
- if (!(target instanceof WebInspector.NetworkRequest || target instanceof WebInspector.Resource || target instanceof WebInspector.UISourceCode))
- return;
- this.panel().appendApplicableItems(event, contextMenu, target);
+ WebInspector.View.prototype.detachChildViews.call(this);
+ this._currentSplitView = null;
},
- __proto__: WebInspector.PanelDescriptor.prototype
+ __proto__: WebInspector.VBox.prototype
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/StatusBarButton.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/StatusBarButton.js
index 1e6fd78c80e..cc0128d736d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/StatusBarButton.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/StatusBarButton.js
@@ -31,12 +31,13 @@
/**
* @constructor
* @extends {WebInspector.Object}
- * @param {!Element} element
+ * @param {string} elementType
*/
-WebInspector.StatusBarItem = function(element)
+WebInspector.StatusBarItem = function(elementType)
{
- this.element = element;
+ this.element = document.createElement(elementType);
this._enabled = true;
+ this._visible = true;
}
WebInspector.StatusBarItem.prototype = {
@@ -59,6 +60,19 @@ WebInspector.StatusBarItem.prototype = {
this.element.disabled = !this._enabled;
},
+ get visible()
+ {
+ return this._visible;
+ },
+
+ set visible(x)
+ {
+ if (this._visible === x)
+ return;
+ this.element.classList.toggle("hidden", !x);
+ this._visible = x;
+ },
+
__proto__: WebInspector.Object.prototype
}
@@ -70,7 +84,7 @@ WebInspector.StatusBarItem.prototype = {
*/
WebInspector.StatusBarText = function(text, className)
{
- WebInspector.StatusBarItem.call(this, document.createElement("span"));
+ WebInspector.StatusBarItem.call(this, "span");
this.element.className = "status-bar-item status-bar-text";
if (className)
this.element.classList.add(className);
@@ -89,6 +103,53 @@ WebInspector.StatusBarText.prototype = {
__proto__: WebInspector.StatusBarItem.prototype
}
+/**
+ * @constructor
+ * @extends {WebInspector.StatusBarItem}
+ * @param {string=} placeholder
+ * @param {number=} width
+ */
+WebInspector.StatusBarInput = function(placeholder, width)
+{
+ WebInspector.StatusBarItem.call(this, "input");
+ this.element.className = "status-bar-item";
+ this.element.addEventListener("input", this._onChangeCallback.bind(this), false);
+ if (width)
+ this.element.style.width = width + "px";
+ if (placeholder)
+ this.element.setAttribute("placeholder", placeholder);
+ this._value = "";
+}
+
+WebInspector.StatusBarInput.Event = {
+ TextChanged: "TextChanged"
+};
+
+WebInspector.StatusBarInput.prototype = {
+ /**
+ * @param {string} value
+ */
+ setValue: function(value)
+ {
+ this._value = value;
+ this.element.value = value;
+ },
+
+ /**
+ * @return {string}
+ */
+ value: function()
+ {
+ return this.element.value;
+ },
+
+ _onChangeCallback: function()
+ {
+ this.dispatchEventToListeners(WebInspector.StatusBarInput.Event.TextChanged, this.element.value);
+ },
+
+ __proto__: WebInspector.StatusBarItem.prototype
+}
/**
* @constructor
@@ -99,7 +160,7 @@ WebInspector.StatusBarText.prototype = {
*/
WebInspector.StatusBarButton = function(title, className, states)
{
- WebInspector.StatusBarItem.call(this, document.createElement("button"));
+ WebInspector.StatusBarItem.call(this, "button");
this.element.className = className + " status-bar-item";
this.element.addEventListener("click", this._clicked.bind(this), false);
@@ -122,7 +183,6 @@ WebInspector.StatusBarButton = function(title, className, states)
this.title = title;
this.className = className;
- this._visible = true;
}
WebInspector.StatusBarButton.prototype = {
@@ -179,7 +239,7 @@ WebInspector.StatusBarButton.prototype = {
return;
if (this.states === 2)
- this.element.enableStyleClass("toggled-on", x);
+ this.element.classList.toggle("toggled-on", x);
else {
this.element.classList.remove("toggled-" + this._state);
if (x !== 0)
@@ -202,20 +262,6 @@ WebInspector.StatusBarButton.prototype = {
this.state = x;
},
- get visible()
- {
- return this._visible;
- },
-
- set visible(x)
- {
- if (this._visible === x)
- return;
-
- this.element.enableStyleClass("hidden", !x);
- this._visible = x;
- },
-
makeLongClickEnabled: function()
{
var boundMouseDown = mouseDown.bind(this);
@@ -323,8 +369,7 @@ WebInspector.StatusBarButton.prototype = {
mainButtonClone.state = this.state;
buttons.push(mainButtonClone);
- var mouseUpListener = mouseUp.bind(this);
- document.documentElement.addEventListener("mouseup", mouseUpListener, false);
+ document.documentElement.addEventListener("mouseup", mouseUp, false);
var optionsGlassPane = new WebInspector.GlassPane();
var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar");
@@ -344,11 +389,9 @@ WebInspector.StatusBarButton.prototype = {
optionsBarElement.style.top = (hostButtonPosition.top - (buttonHeight * (buttons.length - 1))) + "px";
optionsBarElement.style.left = (hostButtonPosition.left + 1) + "px";
- var boundMouseOver = mouseOver.bind(this);
- var boundMouseOut = mouseOut.bind(this);
for (var i = 0; i < buttons.length; ++i) {
- buttons[i].element.addEventListener("mousemove", boundMouseOver, false);
- buttons[i].element.addEventListener("mouseout", boundMouseOut, false);
+ buttons[i].element.addEventListener("mousemove", mouseOver, false);
+ buttons[i].element.addEventListener("mouseout", mouseOut, false);
optionsBarElement.appendChild(buttons[i].element);
}
var hostButtonIndex = topNotBottom ? 0 : buttons.length - 1;
@@ -375,7 +418,7 @@ WebInspector.StatusBarButton.prototype = {
if (e.which !== 1)
return;
optionsGlassPane.dispose();
- document.documentElement.removeEventListener("mouseup", mouseUpListener, false);
+ document.documentElement.removeEventListener("mouseup", mouseUp, false);
for (var i = 0; i < buttons.length; ++i) {
if (buttons[i].element.classList.contains("emulate-active")) {
@@ -391,14 +434,28 @@ WebInspector.StatusBarButton.prototype = {
}
/**
+ * @interface
+ */
+WebInspector.StatusBarButton.Provider = function()
+{
+}
+
+WebInspector.StatusBarButton.Provider.prototype = {
+ /**
+ * @return {?WebInspector.StatusBarButton}
+ */
+ button: function() {}
+}
+
+/**
* @constructor
* @extends {WebInspector.StatusBarItem}
- * @param {?function(!Event)} changeHandler
+ * @param {?function(?Event)} changeHandler
* @param {string=} className
*/
WebInspector.StatusBarComboBox = function(changeHandler, className)
{
- WebInspector.StatusBarItem.call(this, document.createElement("span"));
+ WebInspector.StatusBarItem.call(this, "span");
this.element.className = "status-bar-select-container";
this._selectElement = this.element.createChild("select", "status-bar-item");
@@ -487,7 +544,7 @@ WebInspector.StatusBarComboBox.prototype = {
*/
select: function(option)
{
- this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option);
+ this._selectElement.selectedIndex = Array.prototype.indexOf.call(/** @type {?} */ (this._selectElement), option);
},
/**
@@ -516,10 +573,10 @@ WebInspector.StatusBarComboBox.prototype = {
*/
WebInspector.StatusBarCheckbox = function(title)
{
- WebInspector.StatusBarItem.call(this, document.createElement("label"));
+ WebInspector.StatusBarItem.call(this, "label");
this.element.classList.add("status-bar-item", "checkbox");
- this._checkbox = this.element.createChild("input");
- this._checkbox.type = "checkbox";
+ this.inputElement = this.element.createChild("input");
+ this.inputElement.type = "checkbox";
this.element.createTextChild(title);
}
@@ -529,8 +586,103 @@ WebInspector.StatusBarCheckbox.prototype = {
*/
checked: function()
{
- return this._checkbox.checked;
+ return this.inputElement.checked;
},
__proto__: WebInspector.StatusBarItem.prototype
}
+
+/**
+ * @constructor
+ * @extends {WebInspector.StatusBarButton}
+ * @param {string} className
+ * @param {!Array.<string>} states
+ * @param {!Array.<string>} titles
+ * @param {string} initialState
+ * @param {!WebInspector.Setting} currentStateSetting
+ * @param {!WebInspector.Setting} lastStateSetting
+ * @param {?function(string)} stateChangedCallback
+ */
+WebInspector.StatusBarStatesSettingButton = function(className, states, titles, initialState, currentStateSetting, lastStateSetting, stateChangedCallback)
+{
+ WebInspector.StatusBarButton.call(this, "", className, states.length);
+
+ var onClickBound = this._onClick.bind(this);
+ this.addEventListener("click", onClickBound, this);
+
+ this._states = states;
+ this._buttons = [];
+ for (var index = 0; index < states.length; index++) {
+ var button = new WebInspector.StatusBarButton(titles[index], className, states.length);
+ button.state = this._states[index];
+ button.addEventListener("click", onClickBound, this);
+ this._buttons.push(button);
+ }
+
+ this._currentStateSetting = currentStateSetting;
+ this._lastStateSetting = lastStateSetting;
+ this._stateChangedCallback = stateChangedCallback;
+ this.setLongClickOptionsEnabled(this._createOptions.bind(this));
+
+ this._currentState = null;
+ this.toggleState(initialState);
+}
+
+WebInspector.StatusBarStatesSettingButton.prototype = {
+ /**
+ * @param {!WebInspector.Event} e
+ */
+ _onClick: function(e)
+ {
+ this.toggleState(e.target.state);
+ },
+
+ /**
+ * @param {string} state
+ */
+ toggleState: function(state)
+ {
+ if (this._currentState === state)
+ return;
+
+ if (this._currentState)
+ this._lastStateSetting.set(this._currentState);
+ this._currentState = state;
+ this._currentStateSetting.set(this._currentState);
+
+ if (this._stateChangedCallback)
+ this._stateChangedCallback(state);
+
+ var defaultState = this._defaultState();
+ this.state = defaultState;
+ this.title = this._buttons[this._states.indexOf(defaultState)].title;
+ },
+
+ /**
+ * @return {string}
+ */
+ _defaultState: function()
+ {
+ var lastState = this._lastStateSetting.get();
+ if (lastState && this._states.indexOf(lastState) >= 0 && lastState != this._currentState)
+ return lastState;
+ if (this._states.length > 1 && this._currentState === this._states[0])
+ return this._states[1];
+ return this._states[0];
+ },
+
+ /**
+ * @return {!Array.<!WebInspector.StatusBarButton>}
+ */
+ _createOptions: function()
+ {
+ var options = [];
+ for (var index = 0; index < this._states.length; index++) {
+ if (this._states[index] !== this.state && this._states[index] !== this._currentState)
+ options.push(this._buttons[index]);
+ }
+ return options;
+ },
+
+ __proto__: WebInspector.StatusBarButton.prototype
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/SuggestBox.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
index a9f3c607580..2f805dfc080 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/SuggestBox.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js
@@ -51,29 +51,20 @@ WebInspector.SuggestBoxDelegate.prototype = {
/**
* @constructor
* @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate
- * @param {!Element} anchorElement
- * @param {string=} className
* @param {number=} maxItemsHeight
*/
-WebInspector.SuggestBox = function(suggestBoxDelegate, anchorElement, className, maxItemsHeight)
+WebInspector.SuggestBox = function(suggestBoxDelegate, maxItemsHeight)
{
this._suggestBoxDelegate = suggestBoxDelegate;
- this._anchorElement = anchorElement;
this._length = 0;
this._selectedIndex = -1;
this._selectedElement = null;
this._maxItemsHeight = maxItemsHeight;
- this._boundOnScroll = this._onScrollOrResize.bind(this, true);
- this._boundOnResize = this._onScrollOrResize.bind(this, false);
- window.addEventListener("scroll", this._boundOnScroll, true);
- window.addEventListener("resize", this._boundOnResize, true);
-
- this._bodyElement = anchorElement.ownerDocument.body;
- this._element = anchorElement.ownerDocument.createElement("div");
- this._element.className = "suggest-box " + (className || "");
+ this._bodyElement = document.body;
+ this._maybeHideBound = this._maybeHide.bind(this);
+ this._element = document.createElement("div");
+ this._element.className = "suggest-box";
this._element.addEventListener("mousedown", this._onBoxMouseDown.bind(this), true);
- this.containerElement = this._element.createChild("div", "container");
- this.contentElement = this.containerElement.createChild("div", "content");
}
WebInspector.SuggestBox.prototype = {
@@ -86,17 +77,6 @@ WebInspector.SuggestBox.prototype = {
},
/**
- * @param {boolean} isScroll
- * @param {?Event} event
- */
- _onScrollOrResize: function(isScroll, event)
- {
- if (isScroll && this._element.isAncestor(event.target) || !this.visible())
- return;
- this._updateBoxPosition(this._anchorBox);
- },
-
- /**
* @param {!AnchorBox} anchorBox
*/
setPosition: function(anchorBox)
@@ -105,58 +85,40 @@ WebInspector.SuggestBox.prototype = {
},
/**
- * @param {!AnchorBox=} anchorBox
+ * @param {!AnchorBox} anchorBox
*/
_updateBoxPosition: function(anchorBox)
{
- this._anchorBox = anchorBox;
- anchorBox = anchorBox || this._anchorElement.boxInWindow(window);
-
- // Measure the content element box.
- this.contentElement.style.display = "inline-block";
- document.body.appendChild(this.contentElement);
- this.contentElement.positionAt(0, 0);
- var contentWidth = this.contentElement.offsetWidth;
- var contentHeight = this.contentElement.offsetHeight;
- this.contentElement.style.display = "block";
- this.containerElement.appendChild(this.contentElement);
+ console.assert(this._overlay);
+ if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox))
+ return;
+ this._lastAnchorBox = anchorBox;
+
+ // Position relative to main DevTools element.
+ var container = WebInspector.Dialog.modalHostView().element;
+ anchorBox = anchorBox.relativeToElement(container);
+ var totalWidth = container.offsetWidth;
+ var totalHeight = container.offsetHeight;
+ var aboveHeight = anchorBox.y;
+ var underHeight = totalHeight - anchorBox.y - anchorBox.height;
+ var rowHeight = 17;
const spacer = 6;
- const suggestBoxPaddingX = 21;
- const suggestBoxPaddingY = 2;
-
- var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
- var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
- var paddedWidth = contentWidth + suggestBoxPaddingX;
- var boxX = anchorBox.x;
- if (width < paddedWidth) {
- // Shift the suggest box to the left to accommodate the content without trimming to the BODY edge.
- maxWidth = document.body.offsetWidth - spacer;
- width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
- boxX = document.body.offsetWidth - width;
- }
- var boxY;
- var aboveHeight = anchorBox.y;
- var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
-
- var maxHeight = this._maxItemsHeight ? contentHeight * this._maxItemsHeight / this._length : Math.max(underHeight, aboveHeight) - spacer;
- var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
- if (underHeight >= aboveHeight) {
- // Locate the suggest box under the anchorBox.
- boxY = anchorBox.y + anchorBox.height;
- this._element.classList.remove("above-anchor");
- this._element.classList.add("under-anchor");
+ var maxHeight = this._maxItemsHeight ? this._maxItemsHeight * rowHeight : Math.max(underHeight, aboveHeight) - spacer;
+ var under = underHeight >= aboveHeight;
+ this._leftSpacerElement.style.flexBasis = anchorBox.x + "px";
+
+ this._overlay.element.classList.toggle("under-anchor", under);
+
+ if (under) {
+ this._bottomSpacerElement.style.flexBasis = "auto";
+ this._topSpacerElement.style.flexBasis = (anchorBox.y + anchorBox.height) + "px";
} else {
- // Locate the suggest box above the anchorBox.
- boxY = anchorBox.y - height;
- this._element.classList.remove("under-anchor");
- this._element.classList.add("above-anchor");
+ this._bottomSpacerElement.style.flexBasis = (totalHeight - anchorBox.y) + "px";
+ this._topSpacerElement.style.flexBasis = "auto";
}
-
- this._element.positionAt(boxX, boxY);
- this._element.style.width = width + "px";
- this._element.style.height = height + "px";
+ this._element.style.maxHeight = maxHeight + "px";
},
/**
@@ -164,36 +126,61 @@ WebInspector.SuggestBox.prototype = {
*/
_onBoxMouseDown: function(event)
{
+ if (this._hideTimeoutId) {
+ window.clearTimeout(this._hideTimeoutId);
+ delete this._hideTimeoutId;
+ }
event.preventDefault();
},
+ _maybeHide: function()
+ {
+ if (!this._hideTimeoutId)
+ this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0);
+ },
+
+ _show: function()
+ {
+ if (this.visible())
+ return;
+ this._overlay = new WebInspector.SuggestBox.Overlay();
+ this._bodyElement.addEventListener("mousedown", this._maybeHideBound, true);
+
+ this._leftSpacerElement = this._overlay.element.createChild("div", "suggest-box-left-spacer");
+ this._horizontalElement = this._overlay.element.createChild("div", "suggest-box-horizontal");
+ this._topSpacerElement = this._horizontalElement.createChild("div", "suggest-box-top-spacer");
+ this._horizontalElement.appendChild(this._element);
+ this._bottomSpacerElement = this._horizontalElement.createChild("div", "suggest-box-bottom-spacer");
+ },
+
hide: function()
{
if (!this.visible())
return;
+ this._bodyElement.removeEventListener("mousedown", this._maybeHideBound, true);
this._element.remove();
+ this._overlay.dispose();
+ delete this._overlay;
delete this._selectedElement;
this._selectedIndex = -1;
+ delete this._lastAnchorBox;
},
removeFromElement: function()
{
- window.removeEventListener("scroll", this._boundOnScroll, true);
- window.removeEventListener("resize", this._boundOnResize, true);
this.hide();
},
/**
- * @param {string=} text
* @param {boolean=} isIntermediateSuggestion
*/
- _applySuggestion: function(text, isIntermediateSuggestion)
+ _applySuggestion: function(isIntermediateSuggestion)
{
- if (!this.visible() || !(text || this._selectedElement))
+ if (!this.visible() || !this._selectedElement)
return false;
- var suggestion = text || this._selectedElement.textContent;
+ var suggestion = this._selectedElement.textContent;
if (!suggestion)
return false;
@@ -202,12 +189,11 @@ WebInspector.SuggestBox.prototype = {
},
/**
- * @param {string=} text
* @return {boolean}
*/
- acceptSuggestion: function(text)
+ acceptSuggestion: function()
{
- var result = this._applySuggestion(text, false);
+ var result = this._applySuggestion();
this.hide();
if (!result)
return false;
@@ -237,18 +223,18 @@ WebInspector.SuggestBox.prototype = {
else
index = Number.constrain(index, 0, this._length - 1);
- this._selectItem(index);
- this._applySuggestion(undefined, true);
+ this._selectItem(index, true);
+ this._applySuggestion(true);
return true;
},
/**
- * @param {string} text
* @param {?Event} event
*/
- _onItemMouseDown: function(text, event)
+ _onItemMouseDown: function(event)
{
- this.acceptSuggestion(text);
+ this._selectedElement = event.currentTarget;
+ this.acceptSuggestion();
event.consume(true);
},
@@ -270,35 +256,33 @@ WebInspector.SuggestBox.prototype = {
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text;
}
- element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
+ element.createChild("span", "spacer");
+ element.addEventListener("mousedown", this._onItemMouseDown.bind(this), false);
return element;
},
/**
* @param {!Array.<string>} items
- * @param {number} selectedIndex
* @param {string} userEnteredText
*/
- _updateItems: function(items, selectedIndex, userEnteredText)
+ _updateItems: function(items, userEnteredText)
{
this._length = items.length;
- this.contentElement.removeChildren();
+ this._element.removeChildren();
+ delete this._selectedElement;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
var currentItemElement = this._createItemElement(userEnteredText, item);
- this.contentElement.appendChild(currentItemElement);
+ this._element.appendChild(currentItemElement);
}
-
- this._selectedElement = null;
- if (typeof selectedIndex === "number")
- this._selectItem(selectedIndex);
},
/**
* @param {number} index
+ * @param {boolean} scrollIntoView
*/
- _selectItem: function(index)
+ _selectItem: function(index, scrollIntoView)
{
if (this._selectedElement)
this._selectedElement.classList.remove("selected");
@@ -307,10 +291,11 @@ WebInspector.SuggestBox.prototype = {
if (index < 0)
return;
- this._selectedElement = this.contentElement.children[index];
+ this._selectedElement = this._element.children[index];
this._selectedElement.classList.add("selected");
- this._selectedElement.scrollIntoViewIfNeeded(false);
+ if (scrollIntoView)
+ this._selectedElement.scrollIntoViewIfNeeded(false);
},
/**
@@ -330,12 +315,14 @@ WebInspector.SuggestBox.prototype = {
return canShowForSingleItem && completions[0] !== userEnteredText;
},
- _rememberRowCountPerViewport: function()
+ _ensureRowCountPerViewport: function()
{
- if (!this.contentElement.firstChild)
+ if (this._rowCountPerViewport)
+ return;
+ if (!this._element.firstChild)
return;
- this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
+ this._rowCountPerViewport = Math.floor(this._element.offsetHeight / this._element.firstChild.offsetHeight);
},
/**
@@ -348,11 +335,11 @@ WebInspector.SuggestBox.prototype = {
updateSuggestions: function(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText)
{
if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
- this._updateItems(completions, selectedIndex, userEnteredText);
+ this._updateItems(completions, userEnteredText);
+ this._show();
this._updateBoxPosition(anchorBox);
- if (!this.visible())
- this._bodyElement.appendChild(this._element);
- this._rememberRowCountPerViewport();
+ this._selectItem(selectedIndex, selectedIndex > 0);
+ delete this._rowCountPerViewport;
} else
this.hide();
},
@@ -399,6 +386,7 @@ WebInspector.SuggestBox.prototype = {
*/
pageUpKeyPressed: function()
{
+ this._ensureRowCountPerViewport();
return this._selectClosest(-this._rowCountPerViewport, false);
},
@@ -407,6 +395,7 @@ WebInspector.SuggestBox.prototype = {
*/
pageDownKeyPressed: function()
{
+ this._ensureRowCountPerViewport();
return this._selectClosest(this._rowCountPerViewport, false);
},
@@ -423,3 +412,32 @@ WebInspector.SuggestBox.prototype = {
return hasSelectedItem;
}
}
+
+/**
+ * @constructor
+ */
+WebInspector.SuggestBox.Overlay = function()
+{
+ this.element = document.createElement("div");
+ this.element.classList.add("suggest-box-overlay");
+ this._resize();
+ document.body.appendChild(this.element);
+}
+
+WebInspector.SuggestBox.Overlay.prototype = {
+ _resize: function()
+ {
+ var container = WebInspector.Dialog.modalHostView().element;
+ var containerBox = container.boxInWindow(container.ownerDocument.defaultView);
+
+ this.element.style.left = containerBox.x + "px";
+ this.element.style.top = containerBox.y + "px";
+ this.element.style.height = containerBox.height + "px";
+ this.element.style.width = containerBox.width + "px";
+ },
+
+ dispose: function()
+ {
+ this.element.remove();
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TabbedPane.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
index ed059e8f0df..9d41fcb8094 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TabbedPane.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
@@ -29,22 +29,27 @@
*/
/**
- * @extends {WebInspector.View}
+ * @extends {WebInspector.VBox}
* @constructor
*/
WebInspector.TabbedPane = function()
{
- WebInspector.View.call(this);
- this.element.classList.add("tabbed-pane", "vbox");
+ WebInspector.VBox.call(this);
+ this.element.classList.add("tabbed-pane");
+ this.element.tabIndex = -1;
this._headerElement = this.element.createChild("div", "tabbed-pane-header");
this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
this._contentElement = this.element.createChild("div", "tabbed-pane-content scroll-target");
+ /** @type {!Array.<!WebInspector.TabbedPaneTab>} */
this._tabs = [];
+ /** @type {!Array.<!WebInspector.TabbedPaneTab>} */
this._tabsHistory = [];
+ /** @type {!Object.<string, !WebInspector.TabbedPaneTab>} */
this._tabsById = {};
this._dropDownButton = this._createDropDownButton();
+ WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
}
WebInspector.TabbedPane.EventTypes = {
@@ -54,7 +59,7 @@ WebInspector.TabbedPane.EventTypes = {
WebInspector.TabbedPane.prototype = {
/**
- * @return {!WebInspector.View}
+ * @return {?WebInspector.View}
*/
get visibleView()
{
@@ -62,7 +67,23 @@ WebInspector.TabbedPane.prototype = {
},
/**
- * @return {string}
+ * @return {!Array.<!WebInspector.View>}
+ */
+ tabViews: function()
+ {
+ /**
+ * @param {!WebInspector.TabbedPaneTab} tab
+ * @return {!WebInspector.View}
+ */
+ function tabToView(tab)
+ {
+ return tab.view;
+ }
+ return this._tabs.map(tabToView);
+ },
+
+ /**
+ * @return {?string}
*/
get selectedTabId()
{
@@ -83,6 +104,7 @@ WebInspector.TabbedPane.prototype = {
set verticalTabLayout(verticalTabLayout)
{
this._verticalTabLayout = verticalTabLayout;
+ this.invalidateConstraints();
},
/**
@@ -94,11 +116,13 @@ WebInspector.TabbedPane.prototype = {
},
/**
- * @param {boolean} retainTabsOrder
+ * @param {boolean} retainTabOrder
+ * @param {function(string, string):number=} tabOrderComparator
*/
- setRetainTabsOrder: function(retainTabsOrder)
+ setRetainTabOrder: function(retainTabOrder, tabOrderComparator)
{
- this._retainTabsOrder = retainTabsOrder;
+ this._retainTabOrder = retainTabOrder;
+ this._tabOrderComparator = tabOrderComparator;
},
/**
@@ -109,6 +133,14 @@ WebInspector.TabbedPane.prototype = {
return this.visibleView ? this.visibleView.defaultFocusedElement() : null;
},
+ focus: function()
+ {
+ if (this.visibleView)
+ this.visibleView.focus();
+ else
+ this.element.focus();
+ },
+
/**
* @return {!Element}
*/
@@ -153,10 +185,25 @@ WebInspector.TabbedPane.prototype = {
tab.setDelegate(this._delegate);
this._tabsById[id] = tab;
- this._tabs.push(tab);
+ /**
+ * @param {!WebInspector.TabbedPaneTab} tab1
+ * @param {!WebInspector.TabbedPaneTab} tab2
+ * @this {WebInspector.TabbedPane}
+ * @return {number}
+ */
+ function comparator(tab1, tab2)
+ {
+ return this._tabOrderComparator(tab1.id, tab2.id);
+ }
+
+ if (this._retainTabOrder && this._tabOrderComparator)
+ this._tabs.splice(insertionIndexForObjectInListSortedByFunction(tab, this._tabs, comparator.bind(this)), 0, tab);
+ else
+ this._tabs.push(tab);
+
this._tabsHistory.push(tab);
- if (this._tabsHistory[0] === tab)
+ if (this._tabsHistory[0] === tab && this.isShowing())
this.selectTab(tab.id, userGesture);
this._updateTabElements();
@@ -171,18 +218,21 @@ WebInspector.TabbedPane.prototype = {
this.closeTabs([id], userGesture);
},
- /**
- * @param {!Array.<string>} ids
- * @param {boolean=} userGesture
- */
- closeTabs: function(ids, userGesture)
- {
- for (var i = 0; i < ids.length; ++i)
- this._innerCloseTab(ids[i], userGesture);
- this._updateTabElements();
- if (this._tabsHistory.length)
- this.selectTab(this._tabsHistory[0].id, false);
- },
+ /**
+ * @param {!Array.<string>} ids
+ * @param {boolean=} userGesture
+ */
+ closeTabs: function(ids, userGesture)
+ {
+ var focused = this.hasFocus();
+ for (var i = 0; i < ids.length; ++i)
+ this._innerCloseTab(ids[i], userGesture);
+ this._updateTabElements();
+ if (this._tabsHistory.length)
+ this.selectTab(this._tabsHistory[0].id, false);
+ if (focused)
+ this.focus();
+ },
/**
* @param {string} id
@@ -249,23 +299,27 @@ WebInspector.TabbedPane.prototype = {
/**
* @param {string} id
* @param {boolean=} userGesture
+ * @return {boolean}
*/
selectTab: function(id, userGesture)
{
+ var focused = this.hasFocus();
var tab = this._tabsById[id];
if (!tab)
- return;
+ return false;
if (this._currentTab && this._currentTab.id === id)
- return;
+ return true;
this._hideCurrentTab();
this._showTab(tab);
this._currentTab = tab;
-
+
this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabsHistory.splice(0, 0, tab);
-
+
this._updateTabElements();
+ if (focused)
+ this.focus();
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
@@ -298,6 +352,17 @@ WebInspector.TabbedPane.prototype = {
},
/**
+ * @param {!WebInspector.Event} event
+ */
+ _zoomChanged: function(event)
+ {
+ for (var i = 0; i < this._tabs.length; ++i)
+ delete this._tabs[i]._measuredWidth;
+ if (this.isShowing())
+ this._updateTabElements();
+ },
+
+ /**
* @param {string} id
* @param {string} tabTitle
*/
@@ -346,6 +411,28 @@ WebInspector.TabbedPane.prototype = {
this._updateTabElements();
},
+ wasShown: function()
+ {
+ var effectiveTab = this._currentTab || this._tabsHistory[0];
+ if (effectiveTab)
+ this.selectTab(effectiveTab.id);
+ },
+
+ /**
+ * @return {!Constraints}
+ */
+ calculateConstraints: function()
+ {
+ var constraints = WebInspector.VBox.prototype.calculateConstraints.call(this);
+ var minContentConstraints = new Constraints(new Size(0, 0), new Size(50, 50));
+ constraints = constraints.widthToMax(minContentConstraints).heightToMax(minContentConstraints);
+ if (this._verticalTabLayout)
+ constraints = constraints.addWidth(new Constraints(new Size(this._headerElement.offsetWidth, 0)));
+ else
+ constraints = constraints.addHeight(new Constraints(new Size(0, this._headerElement.offsetHeight)));
+ return constraints;
+ },
+
_updateTabElements: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
@@ -377,7 +464,7 @@ WebInspector.TabbedPane.prototype = {
delete this._noTabsMessageElement;
}
}
-
+
if (!this._measuredDropDownButtonWidth)
this._measureDropDownButton();
@@ -413,11 +500,23 @@ WebInspector.TabbedPane.prototype = {
dropDownContainer.classList.add("tabbed-pane-header-tabs-drop-down-container");
var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down");
dropDownButton.appendChild(document.createTextNode("\u00bb"));
- this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select");
- this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false);
+
+ this._dropDownMenu = new WebInspector.DropDownMenu();
+ this._dropDownMenu.addEventListener(WebInspector.DropDownMenu.Events.ItemSelected, this._dropDownMenuItemSelected, this);
+ dropDownButton.appendChild(this._dropDownMenu.element);
+
return dropDownContainer;
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _dropDownMenuItemSelected: function(event)
+ {
+ var tabId = /** @type {string} */ (event.data);
+ this.selectTab(tabId, true);
+ },
+
_totalWidth: function()
{
return this._headerContentsElement.getBoundingClientRect().width;
@@ -436,7 +535,7 @@ WebInspector.TabbedPane.prototype = {
if (!tab._shown)
this._showTabElement(i, tab);
}
-
+
this._populateDropDownFromIndex();
},
@@ -445,7 +544,8 @@ WebInspector.TabbedPane.prototype = {
if (this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);
- this._tabsSelect.removeChildren();
+ this._dropDownMenu.clear();
+
var tabsToShow = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (!this._tabs[i]._shown)
@@ -457,30 +557,22 @@ WebInspector.TabbedPane.prototype = {
{
return tab1.title.localeCompare(tab2.title);
}
- if (!this._retainTabsOrder)
+ if (!this._retainTabOrder)
tabsToShow.sort(compareFunction);
- var selectedIndex = -1;
+ var selectedId = null;
for (var i = 0; i < tabsToShow.length; ++i) {
- var option = new Option(tabsToShow[i].title);
- option.tab = tabsToShow[i];
- this._tabsSelect.appendChild(option);
- if (this._tabsHistory[0] === tabsToShow[i])
- selectedIndex = i;
+ var tab = tabsToShow[i];
+ this._dropDownMenu.addItem(tab.id, tab.title);
+ if (this._tabsHistory[0] === tab)
+ selectedId = tab.id;
}
- if (this._tabsSelect.options.length) {
+ if (tabsToShow.length) {
this._headerContentsElement.appendChild(this._dropDownButton);
- this._tabsSelect.selectedIndex = selectedIndex;
+ this._dropDownMenu.selectItem(selectedId);
}
},
- _tabsSelectChanged: function()
- {
- var options = this._tabsSelect.options;
- var selectedOption = options[this._tabsSelect.selectedIndex];
- this.selectTab(selectedOption.tab.id, true);
- },
-
_measureDropDownButton: function()
{
this._dropDownButton.classList.add("measuring");
@@ -558,7 +650,7 @@ WebInspector.TabbedPane.prototype = {
totalExtraWidth += (measuredWidths.length - i) * extraWidth;
if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
- return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i);
+ return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i);
}
return totalWidth / measuredWidths.length;
@@ -578,7 +670,7 @@ WebInspector.TabbedPane.prototype = {
var totalTabsWidth = 0;
var tabCount = tabsOrdered.length;
for (var i = 0; i < tabCount; ++i) {
- var tab = this._retainTabsOrder ? tabsOrdered[i] : tabsHistory[i];
+ var tab = this._retainTabOrder ? tabsOrdered[i] : tabsHistory[i];
totalTabsWidth += tab.width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabCount - 1)
@@ -592,7 +684,7 @@ WebInspector.TabbedPane.prototype = {
return tabsToShowIndexes;
},
-
+
_hideCurrentTab: function()
{
if (!this._currentTab)
@@ -621,23 +713,6 @@ WebInspector.TabbedPane.prototype = {
},
/**
- * @override
- */
- canHighlightPosition: function()
- {
- return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightPosition();
- },
-
- /**
- * @override
- */
- highlightPosition: function(line, column)
- {
- if (this.canHighlightPosition())
- this._currentTab.view.highlightPosition(line, column);
- },
-
- /**
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor: function()
@@ -659,10 +734,9 @@ WebInspector.TabbedPane.prototype = {
this._tabs.splice(index, 0, tab);
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
-
/**
* @constructor
* @param {!WebInspector.TabbedPane} tabbedPane
@@ -916,7 +990,7 @@ WebInspector.TabbedPaneTab.prototype = {
{
this._closeTabs([this.id]);
}
-
+
/**
* @this {WebInspector.TabbedPaneTab}
*/
@@ -924,7 +998,7 @@ WebInspector.TabbedPaneTab.prototype = {
{
this._closeTabs(this._tabbedPane.otherTabs(this.id));
}
-
+
/**
* @this {WebInspector.TabbedPaneTab}
*/
@@ -932,7 +1006,7 @@ WebInspector.TabbedPaneTab.prototype = {
{
this._closeTabs(this._tabbedPane.allTabs());
}
-
+
var contextMenu = new WebInspector.ContextMenu(event);
contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Close others" : "Close Others"), closeOthers.bind(this));
@@ -1020,3 +1094,87 @@ WebInspector.TabbedPaneTabDelegate.prototype = {
*/
closeTabs: function(tabbedPane, ids) { }
}
+
+/**
+ * @constructor
+ * @param {!WebInspector.TabbedPane} tabbedPane
+ * @param {string} extensionPoint
+ * @param {function(string, !WebInspector.View)=} viewCallback
+ */
+WebInspector.ExtensibleTabbedPaneController = function(tabbedPane, extensionPoint, viewCallback)
+{
+ this._tabbedPane = tabbedPane;
+ this._extensionPoint = extensionPoint;
+ this._viewCallback = viewCallback;
+
+ this._tabbedPane.setRetainTabOrder(true, WebInspector.moduleManager.orderComparator(extensionPoint, "name", "order"));
+ this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
+ /** @type {!StringMap.<?WebInspector.View>} */
+ this._views = new StringMap();
+ this._initialize();
+}
+
+WebInspector.ExtensibleTabbedPaneController.prototype = {
+ _initialize: function()
+ {
+ this._extensions = {};
+ var extensions = WebInspector.moduleManager.extensions(this._extensionPoint);
+
+ for (var i = 0; i < extensions.length; ++i) {
+ var descriptor = extensions[i].descriptor();
+ var id = descriptor["name"];
+ var title = WebInspector.UIString(descriptor["title"]);
+ var settingName = descriptor["setting"];
+ var setting = settingName ? /** @type {!WebInspector.Setting|undefined} */ (WebInspector.settings[settingName]) : null;
+
+ this._extensions[id] = extensions[i];
+
+ if (setting) {
+ setting.addChangeListener(this._toggleSettingBasedView.bind(this, id, title, setting));
+ if (setting.get())
+ this._tabbedPane.appendTab(id, title, new WebInspector.View());
+ } else {
+ this._tabbedPane.appendTab(id, title, new WebInspector.View());
+ }
+ }
+ },
+
+ /**
+ * @param {string} id
+ * @param {string} title
+ * @param {!WebInspector.Setting} setting
+ */
+ _toggleSettingBasedView: function(id, title, setting)
+ {
+ this._tabbedPane.closeTab(id);
+ if (setting.get())
+ this._tabbedPane.appendTab(id, title, new WebInspector.View());
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _tabSelected: function(event)
+ {
+ var tabId = this._tabbedPane.selectedTabId;
+ if (!tabId)
+ return;
+ var view = this._viewForId(tabId);
+ if (view)
+ this._tabbedPane.changeTabView(tabId, view);
+ },
+
+ /**
+ * @return {?WebInspector.View}
+ */
+ _viewForId: function(id)
+ {
+ if (this._views.contains(id))
+ return /** @type {!WebInspector.View} */ (this._views.get(id));
+ var view = this._extensions[id] ? /** @type {!WebInspector.View} */ (this._extensions[id].instance()) : null;
+ this._views.put(id, view);
+ if (this._viewCallback && view)
+ this._viewCallback(id, view);
+ return view;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TextEditor.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextEditor.js
index 756e5c54a0c..ee36f9ec4f8 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TextEditor.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextEditor.js
@@ -114,11 +114,6 @@ WebInspector.TextEditor.prototype = {
/**
* @param {number} lineNumber
- */
- revealLine: function(lineNumber) { },
-
- /**
- * @param {number} lineNumber
* @param {boolean} disabled
* @param {boolean} conditional
*/
@@ -157,8 +152,9 @@ WebInspector.TextEditor.prototype = {
/**
* @param {number} lineNumber
* @param {number=} columnNumber
+ * @param {boolean=} shouldHighlight
*/
- highlightPosition: function(lineNumber, columnNumber) { },
+ revealPosition: function(lineNumber, columnNumber, shouldHighlight) { },
clearPositionHighlight: function() { },
@@ -206,6 +202,11 @@ WebInspector.TextEditor.prototype = {
selection: function() { },
/**
+ * @return {!Array.<!WebInspector.TextRange>}
+ */
+ selections: function() { },
+
+ /**
* @return {?WebInspector.TextRange}
*/
lastSelection: function() { },
@@ -222,7 +223,7 @@ WebInspector.TextEditor.prototype = {
copyRange: function(range) { },
/**
- * @param {string} text
+ * @param {string} text
*/
setText: function(text) { },
@@ -249,14 +250,14 @@ WebInspector.TextEditor.prototype = {
/**
* @param {number} line
- * @param {string} name
+ * @param {string} name
* @param {?Object} value
*/
setAttribute: function(line, name, value) { },
/**
* @param {number} line
- * @param {string} name
+ * @param {string} name
* @return {?Object} value
*/
getAttribute: function(line, name) { },
@@ -275,6 +276,35 @@ WebInspector.TextEditor.prototype = {
* @param {?WebInspector.CompletionDictionary} dictionary
*/
setCompletionDictionary: function(dictionary) { },
+
+ /**
+ * @param {number} lineNumber
+ * @param {number} columnNumber
+ * @return {?WebInspector.TextEditorPositionHandle}
+ */
+ textEditorPositionHandle: function(lineNumber, columnNumber) { },
+
+ dispose: function() { }
+}
+
+/**
+ * @interface
+ */
+WebInspector.TextEditorPositionHandle = function()
+{
+}
+
+WebInspector.TextEditorPositionHandle.prototype = {
+ /**
+ * @return {?{lineNumber: number, columnNumber: number}}
+ */
+ resolve: function() { },
+
+ /**
+ * @param {!WebInspector.TextEditorPositionHandle} positionHandle
+ * @return {boolean}
+ */
+ equal: function(positionHandle) { }
}
/**
@@ -320,5 +350,24 @@ WebInspector.TextEditorDelegate.prototype = {
* @param {boolean} isExternal
* @return {!Element}
*/
- createLink: function(hrefValue, isExternal) { }
+ createLink: function(hrefValue, isExternal) { },
+
+ /**
+ * @param {?WebInspector.TextRange} from
+ * @param {?WebInspector.TextRange} to
+ */
+ onJumpToPosition: function(from, to) { }
}
+
+/**
+ * @interface
+ */
+WebInspector.TokenizerFactory = function() { }
+
+WebInspector.TokenizerFactory.prototype = {
+ /**
+ * @param {string} mimeType
+ * @return {function(string, function(string, ?string, number, number))}
+ */
+ createTokenizer: function(mimeType) { }
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TextPrompt.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
index 575f2807dee..8efa6190b3d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TextPrompt.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextPrompt.js
@@ -29,7 +29,7 @@
/**
* @constructor
- * @extends WebInspector.Object
+ * @extends {WebInspector.Object}
* @implements {WebInspector.SuggestBoxDelegate}
* @param {function(!Element, !Range, boolean, function(!Array.<string>, number=))} completions
* @param {string=} stopCharacters
@@ -57,11 +57,11 @@ WebInspector.TextPrompt.prototype = {
},
/**
- * @param {string} className
+ * @param {boolean} suggestBoxEnabled
*/
- setSuggestBoxEnabled: function(className)
+ setSuggestBoxEnabled: function(suggestBoxEnabled)
{
- this._suggestBoxClassName = className;
+ this._suggestBoxEnabled = suggestBoxEnabled;
},
renderAsBlock: function()
@@ -74,6 +74,7 @@ WebInspector.TextPrompt.prototype = {
* they should use the result of this method to attach listeners for bubbling events.
*
* @param {!Element} element
+ * @return {!Element}
*/
attach: function(element)
{
@@ -88,6 +89,7 @@ WebInspector.TextPrompt.prototype = {
*
* @param {!Element} element
* @param {function(!Event)} blurListener
+ * @return {!Element}
*/
attachAndStartEditing: function(element, blurListener)
{
@@ -98,6 +100,7 @@ WebInspector.TextPrompt.prototype = {
/**
* @param {!Element} element
+ * @return {!Element}
*/
_attachInternal: function(element)
{
@@ -106,19 +109,23 @@ WebInspector.TextPrompt.prototype = {
this._element = element;
this._boundOnKeyDown = this.onKeyDown.bind(this);
+ this._boundOnInput = this.onInput.bind(this);
this._boundOnMouseWheel = this.onMouseWheel.bind(this);
this._boundSelectStart = this._selectStart.bind(this);
+ this._boundRemoveSuggestionAids = this._removeSuggestionAids.bind(this);
this._proxyElement = element.ownerDocument.createElement("span");
this._proxyElement.style.display = this._proxyElementDisplay;
element.parentElement.insertBefore(this.proxyElement, element);
this.proxyElement.appendChild(element);
this._element.classList.add("text-prompt");
this._element.addEventListener("keydown", this._boundOnKeyDown, false);
+ this._element.addEventListener("input", this._boundOnInput, false);
this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.addEventListener("selectstart", this._boundSelectStart, false);
+ this._element.addEventListener("blur", this._boundRemoveSuggestionAids, false);
- if (typeof this._suggestBoxClassName === "string")
- this._suggestBox = new WebInspector.SuggestBox(this, this._element, this._suggestBoxClassName);
+ if (this._suggestBoxEnabled)
+ this._suggestBox = new WebInspector.SuggestBox(this);
return this.proxyElement;
},
@@ -130,9 +137,6 @@ WebInspector.TextPrompt.prototype = {
this.proxyElement.remove();
delete this._proxyElement;
this._element.classList.remove("text-prompt");
- this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
- this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false);
- this._element.removeEventListener("selectstart", this._boundSelectStart, false);
WebInspector.restoreFocusFromElement(this._element);
},
@@ -165,7 +169,9 @@ WebInspector.TextPrompt.prototype = {
{
this.clearAutoComplete(true);
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
+ this._element.removeEventListener("input", this._boundOnInput, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
+ this._element.removeEventListener("blur", this._boundRemoveSuggestionAids, false);
if (this._isEditing)
this._stopEditing();
if (this._suggestBox)
@@ -230,16 +236,6 @@ WebInspector.TextPrompt.prototype = {
/**
* @param {boolean=} force
- * @return {boolean}
- */
- defaultKeyHandler: function(event, force)
- {
- this._updateAutoComplete(force);
- return false;
- },
-
- /**
- * @param {boolean=} force
*/
_updateAutoComplete: function(force)
{
@@ -252,7 +248,7 @@ WebInspector.TextPrompt.prototype = {
*/
onMouseWheel: function(event)
{
- // Subclasses can implement.
+ // Subclasses can implement.
},
/**
@@ -261,7 +257,7 @@ WebInspector.TextPrompt.prototype = {
onKeyDown: function(event)
{
var handled = false;
- var invokeDefault = true;
+ delete this._needUpdateAutocomplete;
switch (event.keyIdentifier) {
case "U+0009": // Tab
@@ -270,7 +266,6 @@ WebInspector.TextPrompt.prototype = {
case "Left":
case "Home":
this._removeSuggestionAids();
- invokeDefault = false;
break;
case "Right":
case "End":
@@ -278,7 +273,6 @@ WebInspector.TextPrompt.prototype = {
handled = this.acceptAutoComplete();
else
this._removeSuggestionAids();
- invokeDefault = false;
break;
case "U+001B": // Esc
if (this.isSuggestBoxVisible()) {
@@ -288,7 +282,7 @@ WebInspector.TextPrompt.prototype = {
break;
case "U+0020": // Space
if (event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
- this.defaultKeyHandler(event, true);
+ this._updateAutoComplete(true);
handled = true;
}
break;
@@ -296,20 +290,26 @@ WebInspector.TextPrompt.prototype = {
case "Meta":
case "Shift":
case "Control":
- invokeDefault = false;
break;
}
if (!handled && this.isSuggestBoxVisible())
handled = this._suggestBox.keyPressed(event);
- if (!handled && invokeDefault)
- handled = this.defaultKeyHandler(event);
+ if (!handled)
+ this._needUpdateAutocomplete = true;
if (handled)
event.consume(true);
+ },
- return handled;
+ /**
+ * @param {?Event} event
+ */
+ onInput: function(event)
+ {
+ if (this._needUpdateAutocomplete)
+ this._updateAutoComplete();
},
/**
@@ -342,24 +342,6 @@ WebInspector.TextPrompt.prototype = {
this.autoCompleteElement.remove();
delete this.autoCompleteElement;
-
- if (!this._userEnteredRange || !this._userEnteredText)
- return;
-
- this._userEnteredRange.deleteContents();
- this._element.normalize();
-
- var userTextNode = document.createTextNode(this._userEnteredText);
- this._userEnteredRange.insertNode(userTextNode);
-
- var selectionRange = document.createRange();
- selectionRange.setStart(userTextNode, this._userEnteredText.length);
- selectionRange.setEnd(userTextNode, this._userEnteredText.length);
-
- var selection = window.getSelection();
- selection.removeAllRanges();
- selection.addRange(selectionRange);
-
delete this._userEnteredRange;
delete this._userEnteredText;
},
@@ -375,6 +357,7 @@ WebInspector.TextPrompt.prototype = {
},
/**
+ * @param {boolean=} force
* @param {boolean=} reverse
*/
complete: function(force, reverse)
@@ -404,7 +387,7 @@ WebInspector.TextPrompt.prototype = {
var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
this._waitingForCompletions = true;
- this._loadCompletions(this.proxyElement, wordPrefixRange, force, this._completionsReady.bind(this, selection, wordPrefixRange, !!reverse));
+ this._loadCompletions(this.proxyElement, wordPrefixRange, force || false, this._completionsReady.bind(this, selection, wordPrefixRange, !!reverse));
},
disableDefaultSuggestionForEmptyInput: function()
@@ -508,6 +491,7 @@ WebInspector.TextPrompt.prototype = {
finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
+ this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied);
}
},
@@ -864,20 +848,20 @@ WebInspector.TextPromptWithHistory.prototype = {
/**
* @override
*/
- defaultKeyHandler: function(event, force)
+ onKeyDown: function(event)
{
var newText;
var isPrevious;
switch (event.keyIdentifier) {
case "Up":
- if (!this.isCaretOnFirstLine())
+ if (!this.isCaretOnFirstLine() || this.isSuggestBoxVisible())
break;
newText = this._previous();
isPrevious = true;
break;
case "Down":
- if (!this.isCaretOnLastLine())
+ if (!this.isCaretOnLastLine() || this.isSuggestBoxVisible())
break;
newText = this._next();
break;
@@ -913,10 +897,10 @@ WebInspector.TextPromptWithHistory.prototype = {
}
}
- return true;
+ return;
}
- return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
+ WebInspector.TextPrompt.prototype.onKeyDown.apply(this, arguments);
},
__proto__: WebInspector.TextPrompt.prototype
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/TextUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextUtils.js
index 917e91ab262..87273320313 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/TextUtils.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/TextUtils.js
@@ -100,12 +100,17 @@ WebInspector.TextUtils = {
return WebInspector.TextUtils.isOpeningBraceChar(char) || WebInspector.TextUtils.isClosingBraceChar(char);
},
- textToWords: function(text)
+ /**
+ * @param {string} text
+ * @param {function(string):boolean} isWordChar
+ * @return {!Array.<string>}
+ */
+ textToWords: function(text, isWordChar)
{
var words = [];
var startWord = -1;
for(var i = 0; i < text.length; ++i) {
- if (!WebInspector.TextUtils.isWordChar(text.charAt(i))) {
+ if (!isWordChar(text.charAt(i))) {
if (startWord !== -1)
words.push(text.substring(startWord, i));
startWord = -1;
@@ -116,6 +121,39 @@ WebInspector.TextUtils = {
words.push(text.substring(startWord));
return words;
},
+
+ /**
+ * @param {string} source
+ * @param {number=} startIndex
+ * @param {number=} lastIndex
+ * @return {number}
+ */
+ findBalancedCurlyBrackets: function(source, startIndex, lastIndex) {
+ lastIndex = lastIndex || source.length;
+ startIndex = startIndex || 0;
+ var counter = 0;
+ var inString = false;
+
+ for (var index = startIndex; index < lastIndex; ++index) {
+ var character = source[index];
+ if (inString) {
+ if (character === "\\")
+ ++index;
+ else if (character === "\"")
+ inString = false;
+ } else {
+ if (character === "\"")
+ inString = true;
+ else if (character === "{")
+ ++counter;
+ else if (character === "}") {
+ if (--counter === 0)
+ return index + 1;
+ }
+ }
+ }
+ return -1;
+ }
}
WebInspector.TextUtils._SpaceCharRegex = /\s/;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/UIUtils.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index 14bccb3d0c7..a2d7f8feadd 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/UIUtils.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -34,7 +34,7 @@
* @param {?function(!MouseEvent): boolean} elementDragStart
* @param {function(!MouseEvent)} elementDrag
* @param {?function(!MouseEvent)} elementDragEnd
- * @param {!string} cursor
+ * @param {string} cursor
* @param {?string=} hoverCursor
*/
WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor, hoverCursor)
@@ -156,105 +156,26 @@ WebInspector.GlassPane.prototype = {
dispose: function()
{
delete WebInspector._glassPane;
- if (WebInspector.HelpScreen.isVisible())
- WebInspector.HelpScreen.focus();
- else
- WebInspector.inspectorView.focus();
+ if (WebInspector.GlassPane.DefaultFocusedViewStack.length)
+ WebInspector.GlassPane.DefaultFocusedViewStack[0].focus();
this.element.remove();
}
}
-WebInspector.animateStyle = function(animations, duration, callback)
-{
- var startTime = new Date().getTime();
- var hasCompleted = false;
-
- const animationsLength = animations.length;
- const propertyUnit = {opacity: ""};
- const defaultUnit = "px";
-
- // Pre-process animations.
- for (var i = 0; i < animationsLength; ++i) {
- var animation = animations[i];
- var element = null, start = null, end = null, key = null;
- for (key in animation) {
- if (key === "element")
- element = animation[key];
- else if (key === "start")
- start = animation[key];
- else if (key === "end")
- end = animation[key];
- }
-
- if (!element || !end)
- continue;
-
- if (!start) {
- var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
- start = {};
- for (key in end)
- start[key] = parseInt(computedStyle.getPropertyValue(key), 10);
- animation.start = start;
- } else
- for (key in start)
- element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
- }
-
- function animateLoop()
- {
- if (hasCompleted)
- return;
-
- var complete = new Date().getTime() - startTime;
-
- // Make style changes.
- for (var i = 0; i < animationsLength; ++i) {
- var animation = animations[i];
- var element = animation.element;
- var start = animation.start;
- var end = animation.end;
- if (!element || !end)
- continue;
-
- var style = element.style;
- for (key in end) {
- var endValue = end[key];
- if (complete < duration) {
- var startValue = start[key];
- // Linear animation.
- var newValue = startValue + (endValue - startValue) * complete / duration;
- style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
- } else
- style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
- }
- }
-
- // End condition.
- if (complete >= duration)
- hasCompleted = true;
- if (callback)
- callback(hasCompleted);
- if (!hasCompleted)
- window.requestAnimationFrame(animateLoop);
- }
-
- function forceComplete()
- {
- if (hasCompleted)
- return;
-
- duration = 0;
- animateLoop();
- }
-
- window.requestAnimationFrame(animateLoop);
- return {
- forceComplete: forceComplete
- };
-}
+/**
+ * @type {!Array.<!WebInspector.View>}
+ */
+WebInspector.GlassPane.DefaultFocusedViewStack = [];
-WebInspector.isBeingEdited = function(element)
+/**
+ * @param {?Node=} node
+ * @return {boolean}
+ */
+WebInspector.isBeingEdited = function(node)
{
+ if (!node || node.nodeType !== Node.ELEMENT_NODE)
+ return false;
+ var element = /** {!Element} */ (node);
if (element.classList.contains("text-prompt") || element.nodeName === "INPUT" || element.nodeName === "TEXTAREA")
return true;
@@ -269,6 +190,11 @@ WebInspector.isBeingEdited = function(element)
return false;
}
+/**
+ * @param {!Element} element
+ * @param {boolean} value
+ * @return {boolean}
+ */
WebInspector.markBeingEdited = function(element, value)
{
if (value) {
@@ -287,67 +213,6 @@ WebInspector.markBeingEdited = function(element, value)
return true;
}
-/**
- * @constructor
- * @param {function(!Element,string,string,T,string)} commitHandler
- * @param {function(!Element,T)} cancelHandler
- * @param {T=} context
- * @template T
- */
-WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
-{
- this.commitHandler = commitHandler;
- this.cancelHandler = cancelHandler
- this.context = context;
-
- /**
- * Handles the "paste" event, return values are the same as those for customFinishHandler
- * @type {function(!Element)|undefined}
- */
- this.pasteHandler;
-
- /**
- * Whether the edited element is multiline
- * @type {boolean|undefined}
- */
- this.multiline;
-
- /**
- * Custom finish handler for the editing session (invoked on keydown)
- * @type {function(!Element,*)|undefined}
- */
- this.customFinishHandler;
-}
-
-WebInspector.EditingConfig.prototype = {
- setPasteHandler: function(pasteHandler)
- {
- this.pasteHandler = pasteHandler;
- },
-
- /**
- * @param {string} initialValue
- * @param {!Object} mode
- * @param {string} theme
- * @param {boolean=} lineWrapping
- * @param {boolean=} smartIndent
- */
- setMultilineOptions: function(initialValue, mode, theme, lineWrapping, smartIndent)
- {
- this.multiline = true;
- this.initialValue = initialValue;
- this.mode = mode;
- this.theme = theme;
- this.lineWrapping = lineWrapping;
- this.smartIndent = smartIndent;
- },
-
- setCustomFinishHandler: function(customFinishHandler)
- {
- this.customFinishHandler = customFinishHandler;
- }
-}
-
WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;
WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";
@@ -369,7 +234,7 @@ WebInspector._valueModificationDirection = function(event)
if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
direction = "Up";
else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
- direction = "Down";
+ direction = "Down";
}
return direction;
}
@@ -422,7 +287,7 @@ WebInspector._modifiedFloatNumber = function(number, event)
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return number;
-
+
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
// Jump by 10 when shift is down or jump by 0.1 when Alt/Option is down.
@@ -473,7 +338,7 @@ WebInspector.handleElementValueModifications = function(event, element, finishHa
var originalValue = element.textContent;
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
var wordString = wordRange.toString();
-
+
if (suggestionHandler && suggestionHandler(wordString))
return false;
@@ -486,7 +351,7 @@ WebInspector.handleElementValueModifications = function(event, element, finishHa
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedHexValue(matches[2], event);
-
+
if (customNumberHandler)
number = customNumberHandler(number);
@@ -497,11 +362,11 @@ WebInspector.handleElementValueModifications = function(event, element, finishHa
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);
-
+
// Need to check for null explicitly.
- if (number === null)
+ if (number === null)
return false;
-
+
if (customNumberHandler)
number = customNumberHandler(number);
@@ -524,7 +389,7 @@ WebInspector.handleElementValueModifications = function(event, element, finishHa
event.handled = true;
event.preventDefault();
-
+
if (finishHandler)
finishHandler(originalValue, replacementString);
@@ -533,217 +398,37 @@ WebInspector.handleElementValueModifications = function(event, element, finishHa
return false;
}
-/**
- * @param {!Element} element
- * @param {!WebInspector.EditingConfig=} config
- * @return {?{cancel: function(), commit: function(), codeMirror: !CodeMirror, setWidth: function(number)}}
+/**
+ * @param {number} ms
+ * @param {number=} precision
+ * @return {string}
*/
-WebInspector.startEditing = function(element, config)
+Number.preciseMillisToString = function(ms, precision)
{
- if (!WebInspector.markBeingEdited(element, true))
- return null;
-
- config = config || new WebInspector.EditingConfig(function() {}, function() {});
- var committedCallback = config.commitHandler;
- var cancelledCallback = config.cancelHandler;
- var pasteCallback = config.pasteHandler;
- var context = config.context;
- var isMultiline = config.multiline || false;
- var oldText = isMultiline ? config.initialValue : getContent(element);
- var moveDirection = "";
- var oldTabIndex;
- var codeMirror;
- var cssLoadView;
-
- /**
- * @param {?Event} e
- */
- function consumeCopy(e)
- {
- e.consume();
- }
-
- if (isMultiline) {
- loadScript("CodeMirrorTextEditor.js");
- cssLoadView = new WebInspector.CodeMirrorCSSLoadView();
- cssLoadView.show(element);
- WebInspector.setCurrentFocusElement(element);
- element.addEventListener("copy", consumeCopy, false);
- codeMirror = window.CodeMirror(element, {
- mode: config.mode,
- lineWrapping: config.lineWrapping,
- smartIndent: config.smartIndent,
- autofocus: true,
- theme: config.theme,
- value: oldText
- });
- codeMirror.getWrapperElement().classList.add("source-code");
- codeMirror.on("cursorActivity", function(cm) {
- cm.display.cursor.scrollIntoViewIfNeeded(false);
- });
- } else {
- element.classList.add("editing");
-
- oldTabIndex = element.getAttribute("tabIndex");
- if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
- element.tabIndex = 0;
- WebInspector.setCurrentFocusElement(element);
- }
-
- /**
- * @param {number} width
- */
- function setWidth(width)
- {
- const padding = 30;
- codeMirror.getWrapperElement().style.width = (width - codeMirror.getWrapperElement().offsetLeft - padding) + "px";
- codeMirror.refresh();
- }
-
- /**
- * @param {?Event=} e
- */
- function blurEventListener(e) {
- if (!isMultiline || !e || !e.relatedTarget || !e.relatedTarget.isSelfOrDescendant(element))
- editingCommitted.call(element);
- }
-
- function getContent(element) {
- if (isMultiline)
- return codeMirror.getValue();
-
- if (element.tagName === "INPUT" && element.type === "text")
- return element.value;
-
- return element.textContent;
- }
-
- /** @this {Element} */
- function cleanUpAfterEditing()
- {
- WebInspector.markBeingEdited(element, false);
-
- element.removeEventListener("blur", blurEventListener, isMultiline);
- element.removeEventListener("keydown", keyDownEventListener, true);
- if (pasteCallback)
- element.removeEventListener("paste", pasteEventListener, true);
-
- WebInspector.restoreFocusFromElement(element);
-
- if (isMultiline) {
- element.removeEventListener("copy", consumeCopy, false);
- cssLoadView.detach();
- return;
- }
-
- this.classList.remove("editing");
-
- if (typeof oldTabIndex !== "number")
- element.removeAttribute("tabIndex");
- else
- this.tabIndex = oldTabIndex;
- this.scrollTop = 0;
- this.scrollLeft = 0;
- }
-
- /** @this {Element} */
- function editingCancelled()
- {
- if (isMultiline)
- codeMirror.setValue(oldText);
- else {
- if (this.tagName === "INPUT" && this.type === "text")
- this.value = oldText;
- else
- this.textContent = oldText;
- }
-
- cleanUpAfterEditing.call(this);
-
- cancelledCallback(this, context);
- }
-
- /** @this {Element} */
- function editingCommitted()
- {
- cleanUpAfterEditing.call(this);
-
- committedCallback(this, getContent(this), oldText, context, moveDirection);
- }
-
- function defaultFinishHandler(event)
- {
- var isMetaOrCtrl = WebInspector.isMac() ?
- event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
- event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
- if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !isMultiline || isMetaOrCtrl))
- return "commit";
- else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
- return "cancel";
- else if (!isMultiline && event.keyIdentifier === "U+0009") // Tab key
- return "move-" + (event.shiftKey ? "backward" : "forward");
- }
-
- function handleEditingResult(result, event)
- {
- if (result === "commit") {
- editingCommitted.call(element);
- event.consume(true);
- } else if (result === "cancel") {
- editingCancelled.call(element);
- event.consume(true);
- } else if (result && result.startsWith("move-")) {
- moveDirection = result.substring(5);
- if (event.keyIdentifier !== "U+0009")
- blurEventListener();
- }
- }
-
- function pasteEventListener(event)
- {
- var result = pasteCallback(event);
- handleEditingResult(result, event);
- }
-
- function keyDownEventListener(event)
- {
- var handler = config.customFinishHandler || defaultFinishHandler;
- var result = handler(event);
- handleEditingResult(result, event);
- }
-
- element.addEventListener("blur", blurEventListener, isMultiline);
- element.addEventListener("keydown", keyDownEventListener, true);
- if (pasteCallback)
- element.addEventListener("paste", pasteEventListener, true);
-
- return {
- cancel: editingCancelled.bind(element),
- commit: editingCommitted.bind(element),
- codeMirror: codeMirror, // For testing.
- setWidth: setWidth
- };
+ precision = precision || 0;
+ var format = "%." + precision + "f\u2009ms";
+ return WebInspector.UIString(format, ms);
}
/**
- * @param {number} seconds
+ * @param {number} ms
* @param {boolean=} higherResolution
* @return {string}
*/
-Number.secondsToString = function(seconds, higherResolution)
+Number.millisToString = function(ms, higherResolution)
{
- if (!isFinite(seconds))
+ if (!isFinite(ms))
return "-";
- if (seconds === 0)
+ if (ms === 0)
return "0";
- var ms = seconds * 1000;
if (higherResolution && ms < 1000)
return WebInspector.UIString("%.3f\u2009ms", ms);
else if (ms < 1000)
return WebInspector.UIString("%.0f\u2009ms", ms);
+ var seconds = ms / 1000;
if (seconds < 60)
return WebInspector.UIString("%.2f\u2009s", seconds);
@@ -760,6 +445,18 @@ Number.secondsToString = function(seconds, higherResolution)
}
/**
+ * @param {number} seconds
+ * @param {boolean=} higherResolution
+ * @return {string}
+ */
+Number.secondsToString = function(seconds, higherResolution)
+{
+ if (!isFinite(seconds))
+ return "-";
+ return Number.millisToString(seconds * 1000, higherResolution);
+}
+
+/**
* @param {number} bytes
* @return {string}
*/
@@ -781,6 +478,10 @@ Number.bytesToString = function(bytes)
return WebInspector.UIString("%.0f\u2009MB", megabytes);
}
+/**
+ * @param {number} num
+ * @return {string}
+ */
Number.withThousandsSeparator = function(num)
{
var str = num + "";
@@ -790,104 +491,43 @@ Number.withThousandsSeparator = function(num)
return str;
}
+/**
+ * @return {boolean}
+ */
WebInspector.useLowerCaseMenuTitles = function()
{
return WebInspector.platform() === "windows";
}
+/**
+ * @param {string} format
+ * @param {?Array.<string>} substitutions
+ * @param {!Object.<string, function(string, ...):*>} formatters
+ * @param {string} initialValue
+ * @param {function(string, string): ?} append
+ * @return {!{formattedResult: string, unusedSubstitutions: ?Array.<string>}};
+ */
WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
{
return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
}
+/**
+ * @return {string}
+ */
WebInspector.openLinkExternallyLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
}
+/**
+ * @return {string}
+ */
WebInspector.copyLinkAddressLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
}
-WebInspector.platform = function()
-{
- if (!WebInspector._platform)
- WebInspector._platform = InspectorFrontendHost.platform();
- return WebInspector._platform;
-}
-
-WebInspector.isMac = function()
-{
- if (typeof WebInspector._isMac === "undefined")
- WebInspector._isMac = WebInspector.platform() === "mac";
-
- return WebInspector._isMac;
-}
-
-WebInspector.isWin = function()
-{
- if (typeof WebInspector._isWin === "undefined")
- WebInspector._isWin = WebInspector.platform() === "windows";
-
- return WebInspector._isWin;
-}
-
-WebInspector.PlatformFlavor = {
- WindowsVista: "windows-vista",
- MacTiger: "mac-tiger",
- MacLeopard: "mac-leopard",
- MacSnowLeopard: "mac-snowleopard",
- MacLion: "mac-lion",
- MacMountainLion: "mac-mountain-lion"
-}
-
-WebInspector.platformFlavor = function()
-{
- function detectFlavor()
- {
- const userAgent = navigator.userAgent;
-
- if (WebInspector.platform() === "windows") {
- var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
- if (match && match[1] >= 6)
- return WebInspector.PlatformFlavor.WindowsVista;
- return null;
- } else if (WebInspector.platform() === "mac") {
- var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
- if (!match || match[1] != 10)
- return WebInspector.PlatformFlavor.MacSnowLeopard;
- switch (Number(match[2])) {
- case 4:
- return WebInspector.PlatformFlavor.MacTiger;
- case 5:
- return WebInspector.PlatformFlavor.MacLeopard;
- case 6:
- return WebInspector.PlatformFlavor.MacSnowLeopard;
- case 7:
- return WebInspector.PlatformFlavor.MacLion;
- case 8:
- return WebInspector.PlatformFlavor.MacMountainLion;
- default:
- return "";
- }
- }
- }
-
- if (!WebInspector._platformFlavor)
- WebInspector._platformFlavor = detectFlavor();
-
- return WebInspector._platformFlavor;
-}
-
-WebInspector.port = function()
-{
- if (!WebInspector._port)
- WebInspector._port = InspectorFrontendHost.port();
-
- return WebInspector._port;
-}
-
WebInspector.installPortStyles = function()
{
var platform = WebInspector.platform();
@@ -911,11 +551,17 @@ WebInspector._windowBlurred = function(event)
document.body.classList.add("inactive");
}
+/**
+ * @return {!Element}
+ */
WebInspector.previousFocusElement = function()
{
return WebInspector._previousFocusElement;
}
+/**
+ * @return {!Element}
+ */
WebInspector.currentFocusElement = function()
{
return WebInspector._currentFocusElement;
@@ -926,7 +572,16 @@ WebInspector._focusChanged = function(event)
WebInspector.setCurrentFocusElement(event.target);
}
-WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet();
+WebInspector._documentBlurred = function(event)
+{
+ // We want to know when currentFocusElement loses focus to nowhere.
+ // This is the case when event.relatedTarget is null (no element is being focused)
+ // and document.activeElement is reset to default (this is not a window blur).
+ if (!event.relatedTarget && document.activeElement === document.body)
+ WebInspector.setCurrentFocusElement(null);
+}
+
+WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet();
WebInspector._isTextEditingElement = function(element)
{
if (element instanceof HTMLInputElement)
@@ -1008,6 +663,7 @@ WebInspector.resetToolbarColors = function()
* @param {number} offset
* @param {number} length
* @param {!Array.<!Object>=} domChanges
+ * @return {?Element}
*/
WebInspector.highlightSearchResult = function(element, offset, length, domChanges)
{
@@ -1019,6 +675,7 @@ WebInspector.highlightSearchResult = function(element, offset, length, domChange
* @param {!Element} element
* @param {!Array.<!WebInspector.SourceRange>} resultRanges
* @param {!Array.<!Object>=} changes
+ * @return {!Array.<!Element>}
*/
WebInspector.highlightSearchResults = function(element, resultRanges, changes)
{
@@ -1027,9 +684,29 @@ WebInspector.highlightSearchResults = function(element, resultRanges, changes)
/**
* @param {!Element} element
+ * @param {string} className
+ */
+WebInspector.runCSSAnimationOnce = function(element, className)
+{
+ function animationEndCallback()
+ {
+ element.classList.remove(className);
+ element.removeEventListener("animationend", animationEndCallback, false);
+ }
+
+ if (element.classList.contains(className))
+ element.classList.remove(className);
+
+ element.addEventListener("animationend", animationEndCallback, false);
+ element.classList.add(className);
+}
+
+/**
+ * @param {!Element} element
* @param {!Array.<!WebInspector.SourceRange>} resultRanges
* @param {string} styleClass
* @param {!Array.<!Object>=} changes
+ * @return {!Array.<!Element>}
*/
WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
@@ -1140,30 +817,71 @@ WebInspector.revertDomChanges = function(domChanges)
}
}
+/**
+ * @constructor
+ * @param {boolean} autoInvoke
+ */
+WebInspector.InvokeOnceHandlers = function(autoInvoke)
+{
+ this._handlers = null;
+ this._autoInvoke = autoInvoke;
+}
+
+WebInspector.InvokeOnceHandlers.prototype = {
+ /**
+ * @param {!Object} object
+ * @param {function()} method
+ */
+ add: function(object, method)
+ {
+ if (!this._handlers) {
+ this._handlers = new Map();
+ if (this._autoInvoke)
+ this.scheduleInvoke();
+ }
+ var methods = this._handlers.get(object);
+ if (!methods) {
+ methods = new Set();
+ this._handlers.put(object, methods);
+ }
+ methods.add(method);
+ },
+
+ scheduleInvoke: function()
+ {
+ if (this._handlers)
+ requestAnimationFrame(this._invoke.bind(this));
+ },
+
+ _invoke: function()
+ {
+ var handlers = this._handlers;
+ this._handlers = null;
+ var keys = handlers.keys();
+ for (var i = 0; i < keys.length; ++i) {
+ var object = keys[i];
+ var methods = handlers.get(object).values();
+ for (var j = 0; j < methods.length; ++j)
+ methods[j].call(object);
+ }
+ }
+}
+
WebInspector._coalescingLevel = 0;
+WebInspector._postUpdateHandlers = null;
WebInspector.startBatchUpdate = function()
{
- if (!WebInspector._coalescingLevel)
- WebInspector._postUpdateHandlers = new Map();
- WebInspector._coalescingLevel++;
+ if (!WebInspector._coalescingLevel++)
+ WebInspector._postUpdateHandlers = new WebInspector.InvokeOnceHandlers(false);
}
WebInspector.endBatchUpdate = function()
{
if (--WebInspector._coalescingLevel)
return;
-
- var handlers = WebInspector._postUpdateHandlers;
- delete WebInspector._postUpdateHandlers;
-
- var keys = handlers.keys();
- for (var i = 0; i < keys.length; ++i) {
- var object = keys[i];
- var methods = handlers.get(object).keys();
- for (var j = 0; j < methods.length; ++j)
- methods[j].call(object);
- }
+ WebInspector._postUpdateHandlers.scheduleInvoke();
+ WebInspector._postUpdateHandlers = null;
}
/**
@@ -1172,47 +890,19 @@ WebInspector.endBatchUpdate = function()
*/
WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
{
- if (!WebInspector._coalescingLevel) {
- method.call(object);
- return;
- }
-
- var methods = WebInspector._postUpdateHandlers.get(object);
- if (!methods) {
- methods = new Map();
- WebInspector._postUpdateHandlers.put(object, methods);
- }
- methods.put(method);
-}
-
-/**
- * This bogus view is needed to load/unload CodeMirror-related CSS on demand.
- *
- * @constructor
- * @extends {WebInspector.View}
- */
-WebInspector.CodeMirrorCSSLoadView = function()
-{
- WebInspector.View.call(this);
- this.element.classList.add("hidden");
- this.registerRequiredCSS("cm/codemirror.css");
- this.registerRequiredCSS("cm/cmdevtools.css");
-}
-
-WebInspector.CodeMirrorCSSLoadView.prototype = {
- __proto__: WebInspector.View.prototype
+ if (!WebInspector._postUpdateHandlers)
+ WebInspector._postUpdateHandlers = new WebInspector.InvokeOnceHandlers(true);
+ WebInspector._postUpdateHandlers.add(object, method);
}
;(function() {
-/**
- * @this {Window}
- */
function windowLoaded()
{
window.addEventListener("focus", WebInspector._windowFocused, false);
window.addEventListener("blur", WebInspector._windowBlurred, false);
- document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
+ document.addEventListener("focus", WebInspector._focusChanged, true);
+ document.addEventListener("blur", WebInspector._documentBlurred, true);
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/View.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/View.js
index bfd7547994d..3a841c088b5 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/View.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/View.js
@@ -31,6 +31,7 @@
WebInspector.View = function()
{
this.element = document.createElement("div");
+ this.element.className = "view";
this.element.__view = this;
this._visible = true;
this._isRoot = false;
@@ -45,6 +46,24 @@ WebInspector.View._cssFileToVisibleViewCount = {};
WebInspector.View._cssFileToStyleElement = {};
WebInspector.View._cssUnloadTimeout = 2000;
+WebInspector.View._buildSourceURL = function(cssFile)
+{
+ return "\n/*# sourceURL=" + WebInspector.ParsedURL.completeURL(window.location.href, cssFile) + " */";
+}
+
+/**
+ * @param {string} cssFile
+ * @return {!Element}
+ */
+WebInspector.View.createStyleElement = function(cssFile)
+{
+ var styleElement = document.createElement("style");
+ styleElement.type = "text/css";
+ styleElement.textContent = loadResource(cssFile) + WebInspector.View._buildSourceURL(cssFile);
+ document.head.insertBefore(styleElement, document.head.firstChild);
+ return styleElement;
+}
+
WebInspector.View.prototype = {
markAsRoot: function()
{
@@ -60,6 +79,17 @@ WebInspector.View.prototype = {
return this._parentView;
},
+ /**
+ * @return {!Array.<!WebInspector.View>}
+ */
+ children: function()
+ {
+ return this._children;
+ },
+
+ /**
+ * @return {boolean}
+ */
isShowing: function()
{
return this._isShowing;
@@ -71,7 +101,7 @@ WebInspector.View.prototype = {
},
/**
- * @return {boolean}
+ * @return {boolean}
*/
_inNotification: function()
{
@@ -110,7 +140,6 @@ WebInspector.View.prototype = {
return;
this.restoreScrollPositions();
this._notify(this.wasShown);
- this._notify(this.onResize);
this._callOnVisibleChildren(this._processWasShown);
},
@@ -166,9 +195,13 @@ WebInspector.View.prototype = {
{
},
+ onLayout: function()
+ {
+ },
+
/**
* @param {?Element} parentElement
- * @param {!Element=} insertBefore
+ * @param {?Element=} insertBefore
*/
show: function(parentElement, insertBefore)
{
@@ -211,6 +244,11 @@ WebInspector.View.prototype = {
if (this._parentIsShowing())
this._processWasShown();
+
+ if (this._parentView && this._hasNonZeroConstraints())
+ this._parentView.invalidateConstraints();
+ else
+ this._processOnResize();
},
/**
@@ -230,6 +268,8 @@ WebInspector.View.prototype = {
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
+ if (this._parentView && this._hasNonZeroConstraints())
+ this._parentView.invalidateConstraints();
return;
}
@@ -246,7 +286,10 @@ WebInspector.View.prototype = {
var childIndex = this._parentView._children.indexOf(this);
WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view");
this._parentView._children.splice(childIndex, 1);
+ var parent = this._parentView;
this._parentView = null;
+ if (this._hasNonZeroConstraints())
+ parent.invalidateConstraints();
} else
WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM");
},
@@ -258,6 +301,9 @@ WebInspector.View.prototype = {
children[i].detach();
},
+ /**
+ * @return {!Array.<!Element>}
+ */
elementsToRestoreScrollPositionsFor: function()
{
return [this.element];
@@ -285,28 +331,25 @@ WebInspector.View.prototype = {
}
},
- canHighlightPosition: function()
- {
- return false;
- },
-
- /**
- * @param {number} line
- * @param {number=} column
- */
- highlightPosition: function(line, column)
+ doResize: function()
{
+ if (!this.isShowing())
+ return;
+ // No matter what notification we are in, dispatching onResize is not needed.
+ if (!this._inNotification())
+ this._callOnVisibleChildren(this._processOnResize);
},
- doResize: function()
+ doLayout: function()
{
- this._processOnResize();
+ if (!this.isShowing())
+ return;
+ this._notify(this.onLayout);
+ this.doResize();
},
registerRequiredCSS: function(cssFile)
{
- if (window.flattenImports)
- cssFile = cssFile.split("/").reverse()[0];
this._cssFiles.push(cssFile);
},
@@ -329,31 +372,10 @@ WebInspector.View.prototype = {
styleElement.disabled = false;
return;
}
-
- if (window.debugCSS) { /* debugging support */
- styleElement = document.createElement("link");
- styleElement.rel = "stylesheet";
- styleElement.type = "text/css";
- styleElement.href = cssFile;
- } else {
- var xhr = new XMLHttpRequest();
- xhr.open("GET", cssFile, false);
- xhr.send(null);
-
- styleElement = document.createElement("style");
- styleElement.type = "text/css";
- styleElement.textContent = xhr.responseText + this._buildSourceURL(cssFile);
- }
- document.head.insertBefore(styleElement, document.head.firstChild);
-
+ styleElement = WebInspector.View.createStyleElement(cssFile);
WebInspector.View._cssFileToStyleElement[cssFile] = styleElement;
},
- _buildSourceURL: function(cssFile)
- {
- return "\n/*# sourceURL=" + WebInspector.ParsedURL.completeURL(window.location.href, cssFile) + " */";
- },
-
_disableCSSIfNeeded: function()
{
var scheduleUnload = !!WebInspector.View._cssUnloadTimer;
@@ -370,18 +392,13 @@ WebInspector.View.prototype = {
delete WebInspector.View._cssUnloadTimer;
for (cssFile in WebInspector.View._cssFileToVisibleViewCount) {
- if (WebInspector.View._cssFileToVisibleViewCount.hasOwnProperty(cssFile)
- && !WebInspector.View._cssFileToVisibleViewCount[cssFile])
+ if (WebInspector.View._cssFileToVisibleViewCount.hasOwnProperty(cssFile) && !WebInspector.View._cssFileToVisibleViewCount[cssFile])
WebInspector.View._cssFileToStyleElement[cssFile].disabled = true;
}
}
- if (scheduleUnload) {
- if (WebInspector.View._cssUnloadTimer)
- clearTimeout(WebInspector.View._cssUnloadTimer);
-
- WebInspector.View._cssUnloadTimer = setTimeout(doUnloadCSS, WebInspector.View._cssUnloadTimeout)
- }
+ if (scheduleUnload && !WebInspector.View._cssUnloadTimer)
+ WebInspector.View._cssUnloadTimer = setTimeout(doUnloadCSS, WebInspector.View._cssUnloadTimeout);
},
printViewHierarchy: function()
@@ -428,6 +445,15 @@ WebInspector.View.prototype = {
},
/**
+ * @return {boolean}
+ */
+ hasFocus: function()
+ {
+ var activeElement = document.activeElement;
+ return activeElement && activeElement.isSelfOrDescendant(this.element);
+ },
+
+ /**
* @return {!Size}
*/
measurePreferredSize: function()
@@ -442,6 +468,68 @@ WebInspector.View.prototype = {
return result;
},
+ /**
+ * @return {!Constraints}
+ */
+ calculateConstraints: function()
+ {
+ return new Constraints(new Size(0, 0));
+ },
+
+ /**
+ * @return {!Constraints}
+ */
+ constraints: function()
+ {
+ if (typeof this._constraints !== "undefined")
+ return this._constraints;
+ if (typeof this._cachedConstraints === "undefined")
+ this._cachedConstraints = this.calculateConstraints();
+ return this._cachedConstraints;
+ },
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @param {number} preferredWidth
+ * @param {number} preferredHeight
+ */
+ setMinimumAndPreferredSizes: function(width, height, preferredWidth, preferredHeight)
+ {
+ this._constraints = new Constraints(new Size(width, height), new Size(preferredWidth, preferredHeight));
+ this.invalidateConstraints();
+ },
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ */
+ setMinimumSize: function(width, height)
+ {
+ this._constraints = new Constraints(new Size(width, height));
+ this.invalidateConstraints();
+ },
+
+ /**
+ * @return {boolean}
+ */
+ _hasNonZeroConstraints: function()
+ {
+ var constraints = this.constraints();
+ return !!(constraints.minimum.width || constraints.minimum.height || constraints.preferred.width || constraints.preferred.height);
+ },
+
+ invalidateConstraints: function()
+ {
+ var cached = this._cachedConstraints;
+ delete this._cachedConstraints;
+ var actual = this.constraints();
+ if (!actual.isEqual(cached) && this._parentView)
+ this._parentView.invalidateConstraints();
+ else
+ this.doLayout();
+ },
+
__proto__: WebInspector.Object.prototype
}
@@ -483,54 +571,125 @@ WebInspector.View._assert = function(condition, message)
}
/**
- * @interface
+ * @constructor
+ * @extends {WebInspector.View}
*/
-WebInspector.ViewFactory = function()
+WebInspector.VBox = function()
{
-}
+ WebInspector.View.call(this);
+ this.element.classList.add("vbox");
+};
-WebInspector.ViewFactory.prototype = {
+WebInspector.VBox.prototype = {
/**
- * @param {string=} id
- * @return {?WebInspector.View}
+ * @return {!Constraints}
*/
- createView: function(id) {}
-}
+ calculateConstraints: function()
+ {
+ var constraints = new Constraints(new Size(0, 0));
+
+ /**
+ * @this {!WebInspector.View}
+ * @suppressReceiverCheck
+ */
+ function updateForChild()
+ {
+ var child = this.constraints();
+ constraints = constraints.widthToMax(child);
+ constraints = constraints.addHeight(child);
+ }
+
+ this._callOnVisibleChildren(updateForChild);
+ return constraints;
+ },
+
+ __proto__: WebInspector.View.prototype
+};
/**
* @constructor
* @extends {WebInspector.View}
- * @param {function()} resizeCallback
*/
-WebInspector.ViewWithResizeCallback = function(resizeCallback)
+WebInspector.HBox = function()
{
WebInspector.View.call(this);
+ this.element.classList.add("hbox");
+};
+
+WebInspector.HBox.prototype = {
+ /**
+ * @return {!Constraints}
+ */
+ calculateConstraints: function()
+ {
+ var constraints = new Constraints(new Size(0, 0));
+
+ /**
+ * @this {!WebInspector.View}
+ * @suppressReceiverCheck
+ */
+ function updateForChild()
+ {
+ var child = this.constraints();
+ constraints = constraints.addWidth(child);
+ constraints = constraints.heightToMax(child);
+ }
+
+ this._callOnVisibleChildren(updateForChild);
+ return constraints;
+ },
+
+ __proto__: WebInspector.View.prototype
+};
+
+/**
+ * @constructor
+ * @extends {WebInspector.VBox}
+ * @param {function()} resizeCallback
+ */
+WebInspector.VBoxWithResizeCallback = function(resizeCallback)
+{
+ WebInspector.VBox.call(this);
this._resizeCallback = resizeCallback;
}
-WebInspector.ViewWithResizeCallback.prototype = {
+WebInspector.VBoxWithResizeCallback.prototype = {
onResize: function()
{
this._resizeCallback();
},
- __proto__: WebInspector.View.prototype
+ __proto__: WebInspector.VBox.prototype
}
-
+/**
+ * @param {?Node} child
+ * @return {?Node}
+ * @suppress {duplicate}
+ */
Element.prototype.appendChild = function(child)
{
- WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
+ WebInspector.View._assert(!child.__view || child.parentElement === this, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalAppendChild.call(this, child);
}
+/**
+ * @param {?Node} child
+ * @param {?Node} anchor
+ * @return {?Node}
+ * @suppress {duplicate}
+ */
Element.prototype.insertBefore = function(child, anchor)
{
- WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
+ WebInspector.View._assert(!child.__view || child.parentElement === this, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalInsertBefore.call(this, child, anchor);
}
-
+/**
+ * @param {?Node} child
+ * @return {?Node}
+ * @suppress {duplicate}
+ */
Element.prototype.removeChild = function(child)
{
WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation");
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
new file mode 100644
index 00000000000..87d91652ad3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @constructor
+ * @param {!WebInspector.ViewportControl.Provider} provider
+ */
+WebInspector.ViewportControl = function(provider)
+{
+ this.element = document.createElement("div");
+ this.element.style.overflow = "auto";
+ this._topGapElement = this.element.createChild("div", "viewport-control-gap-element");
+ this._topGapElement.textContent = ".";
+ this._topGapElement.style.height = "0px";
+ this._contentElement = this.element.createChild("div");
+ this._bottomGapElement = this.element.createChild("div", "viewport-control-gap-element");
+ this._bottomGapElement.textContent = ".";
+ this._bottomGapElement.style.height = "0px";
+
+ this._provider = provider;
+ this.element.addEventListener("scroll", this._onScroll.bind(this), false);
+ this.element.addEventListener("copy", this._onCopy.bind(this), false);
+ this.element.addEventListener("dragstart", this._onDragStart.bind(this), false);
+
+ this._firstVisibleIndex = 0;
+ this._lastVisibleIndex = -1;
+ this._renderedItems = [];
+ this._anchorSelection = null;
+ this._headSelection = null;
+ this._stickToBottom = false;
+}
+
+/**
+ * @interface
+ */
+WebInspector.ViewportControl.Provider = function()
+{
+}
+
+WebInspector.ViewportControl.Provider.prototype = {
+ /**
+ * @param {number} index
+ * @return {number}
+ */
+ fastHeight: function(index) { return 0; },
+
+ /**
+ * @return {number}
+ */
+ itemCount: function() { return 0; },
+
+ /**
+ * @return {number}
+ */
+ minimumRowHeight: function() { return 0; },
+
+ /**
+ * @param {number} index
+ * @return {?WebInspector.ViewportElement}
+ */
+ itemElement: function(index) { return null; }
+}
+
+/**
+ * @interface
+ */
+WebInspector.ViewportElement = function() { }
+WebInspector.ViewportElement.prototype = {
+ cacheFastHeight: function() { },
+
+ willHide: function() { },
+
+ wasShown: function() { },
+
+ /**
+ * @return {!Element}
+ */
+ element: function() { },
+}
+
+/**
+ * @constructor
+ * @implements {WebInspector.ViewportElement}
+ * @param {!Element} element
+ */
+WebInspector.StaticViewportElement = function(element)
+{
+ this._element = element;
+}
+
+WebInspector.StaticViewportElement.prototype = {
+ cacheFastHeight: function() { },
+
+ willHide: function() { },
+
+ wasShown: function() { },
+
+ /**
+ * @return {!Element}
+ */
+ element: function()
+ {
+ return this._element;
+ },
+}
+
+WebInspector.ViewportControl.prototype = {
+ /**
+ * @param {boolean} value
+ */
+ setStickToBottom: function(value)
+ {
+ this._stickToBottom = value;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onCopy: function(event)
+ {
+ var text = this._selectedText();
+ if (!text)
+ return;
+ event.preventDefault();
+ event.clipboardData.setData("text/plain", text);
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onDragStart: function(event)
+ {
+ var text = this._selectedText();
+ if (!text)
+ return false;
+ event.dataTransfer.clearData();
+ event.dataTransfer.setData("text/plain", text);
+ event.dataTransfer.effectAllowed = "copy";
+ return true;
+ },
+
+ /**
+ * @return {!Element}
+ */
+ contentElement: function()
+ {
+ return this._contentElement;
+ },
+
+ invalidate: function()
+ {
+ delete this._cumulativeHeights;
+ this.refresh();
+ },
+
+ _rebuildCumulativeHeightsIfNeeded: function()
+ {
+ if (this._cumulativeHeights)
+ return;
+ var itemCount = this._provider.itemCount();
+ if (!itemCount)
+ return;
+ this._cumulativeHeights = new Int32Array(itemCount);
+ this._cumulativeHeights[0] = this._provider.fastHeight(0);
+ for (var i = 1; i < itemCount; ++i)
+ this._cumulativeHeights[i] = this._cumulativeHeights[i - 1] + this._provider.fastHeight(i);
+ },
+
+ /**
+ * @param {number} index
+ * @return {number}
+ */
+ _cachedItemHeight: function(index)
+ {
+ return index === 0 ? this._cumulativeHeights[0] : this._cumulativeHeights[index] - this._cumulativeHeights[index - 1];
+ },
+
+ /**
+ * @param {?Selection} selection
+ */
+ _isSelectionBackwards: function(selection)
+ {
+ if (!selection || !selection.rangeCount)
+ return false;
+ var range = document.createRange();
+ range.setStart(selection.anchorNode, selection.anchorOffset);
+ range.setEnd(selection.focusNode, selection.focusOffset);
+ return range.collapsed;
+ },
+
+ /**
+ * @param {number} itemIndex
+ * @param {!Node} node
+ * @param {number} offset
+ * @return {!{item: number, node: !Node, offset: number}}
+ */
+ _createSelectionModel: function(itemIndex, node, offset)
+ {
+ return {
+ item: itemIndex,
+ node: node,
+ offset: offset
+ };
+ },
+
+ /**
+ * @param {?Selection} selection
+ */
+ _updateSelectionModel: function(selection)
+ {
+ if (!selection || !selection.rangeCount) {
+ this._headSelection = null;
+ this._anchorSelection = null;
+ return false;
+ }
+
+ var firstSelected = Number.MAX_VALUE;
+ var lastSelected = -1;
+
+ var range = selection.getRangeAt(0);
+ var hasVisibleSelection = false;
+ for (var i = 0; i < this._renderedItems.length; ++i) {
+ if (range.intersectsNode(this._renderedItems[i].element())) {
+ var index = i + this._firstVisibleIndex;
+ firstSelected = Math.min(firstSelected, index);
+ lastSelected = Math.max(lastSelected, index);
+ hasVisibleSelection = true;
+ }
+ }
+ if (hasVisibleSelection) {
+ firstSelected = this._createSelectionModel(firstSelected, /** @type {!Node} */(range.startContainer), range.startOffset);
+ lastSelected = this._createSelectionModel(lastSelected, /** @type {!Node} */(range.endContainer), range.endOffset);
+ }
+ var topOverlap = range.intersectsNode(this._topGapElement) && this._topGapElement._active;
+ var bottomOverlap = range.intersectsNode(this._bottomGapElement) && this._bottomGapElement._active;
+ if (!topOverlap && !bottomOverlap && !hasVisibleSelection) {
+ this._headSelection = null;
+ this._anchorSelection = null;
+ return false;
+ }
+
+ if (!this._anchorSelection || !this._headSelection) {
+ this._anchorSelection = this._createSelectionModel(0, this.element, 0);
+ this._headSelection = this._createSelectionModel(this._provider.itemCount() - 1, this.element, this.element.children.length);
+ this._selectionIsBackward = false;
+ }
+
+ var isBackward = this._isSelectionBackwards(selection);
+ var startSelection = this._selectionIsBackward ? this._headSelection : this._anchorSelection;
+ var endSelection = this._selectionIsBackward ? this._anchorSelection : this._headSelection;
+ if (topOverlap && bottomOverlap && hasVisibleSelection) {
+ firstSelected = firstSelected.item < startSelection.item ? firstSelected : startSelection;
+ lastSelected = lastSelected.item > endSelection.item ? lastSelected : endSelection;
+ } else if (!hasVisibleSelection) {
+ firstSelected = startSelection;
+ lastSelected = endSelection;
+ } else if (topOverlap)
+ firstSelected = isBackward ? this._headSelection : this._anchorSelection;
+ else if (bottomOverlap)
+ lastSelected = isBackward ? this._anchorSelection : this._headSelection;
+
+ if (isBackward) {
+ this._anchorSelection = lastSelected;
+ this._headSelection = firstSelected;
+ } else {
+ this._anchorSelection = firstSelected;
+ this._headSelection = lastSelected;
+ }
+ this._selectionIsBackward = isBackward;
+ return true;
+ },
+
+ /**
+ * @param {?Selection} selection
+ */
+ _restoreSelection: function(selection)
+ {
+ var anchorElement = null;
+ var anchorOffset;
+ if (this._firstVisibleIndex <= this._anchorSelection.item && this._anchorSelection.item <= this._lastVisibleIndex) {
+ anchorElement = this._anchorSelection.node;
+ anchorOffset = this._anchorSelection.offset;
+ } else {
+ if (this._anchorSelection.item < this._firstVisibleIndex)
+ anchorElement = this._topGapElement;
+ else if (this._anchorSelection.item > this._lastVisibleIndex)
+ anchorElement = this._bottomGapElement;
+ anchorOffset = this._selectionIsBackward ? 1 : 0;
+ }
+
+ var headElement = null;
+ var headOffset;
+ if (this._firstVisibleIndex <= this._headSelection.item && this._headSelection.item <= this._lastVisibleIndex) {
+ headElement = this._headSelection.node;
+ headOffset = this._headSelection.offset;
+ } else {
+ if (this._headSelection.item < this._firstVisibleIndex)
+ headElement = this._topGapElement;
+ else if (this._headSelection.item > this._lastVisibleIndex)
+ headElement = this._bottomGapElement;
+ headOffset = this._selectionIsBackward ? 0 : 1;
+ }
+
+ selection.setBaseAndExtent(anchorElement, anchorOffset, headElement, headOffset);
+ },
+
+ refresh: function()
+ {
+ if (!this.element.clientHeight)
+ return; // Do nothing for invisible controls.
+
+ var itemCount = this._provider.itemCount();
+ if (!itemCount) {
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].cacheFastHeight();
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].willHide();
+ this._renderedItems = [];
+ this._contentElement.removeChildren();
+ this._topGapElement.style.height = "0px";
+ this._bottomGapElement.style.height = "0px";
+ this._firstVisibleIndex = -1;
+ this._lastVisibleIndex = -1;
+ return;
+ }
+
+ var selection = window.getSelection();
+ var shouldRestoreSelection = this._updateSelectionModel(selection);
+
+ var visibleFrom = this.element.scrollTop;
+ var clientHeight = this.element.clientHeight;
+ var shouldStickToBottom = this._stickToBottom && this.element.isScrolledToBottom();
+
+ if (this._cumulativeHeights && itemCount !== this._cumulativeHeights.length)
+ delete this._cumulativeHeights;
+ for (var i = 0; i < this._renderedItems.length; ++i) {
+ this._renderedItems[i].cacheFastHeight();
+ // Tolerate 1-pixel error due to double-to-integer rounding errors.
+ if (this._cumulativeHeights && Math.abs(this._cachedItemHeight(this._firstVisibleIndex + i) - this._provider.fastHeight(i + this._firstVisibleIndex)) > 1)
+ delete this._cumulativeHeights;
+ }
+ this._rebuildCumulativeHeightsIfNeeded();
+ if (shouldStickToBottom) {
+ this._lastVisibleIndex = itemCount - 1;
+ this._firstVisibleIndex = Math.max(itemCount - Math.ceil(clientHeight / this._provider.minimumRowHeight()), 0);
+ } else {
+ this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0);
+ // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
+ this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(clientHeight / this._provider.minimumRowHeight()) - 1;
+ this._lastVisibleIndex = Math.min(this._lastVisibleIndex, itemCount - 1);
+ }
+ var topGapHeight = this._cumulativeHeights[this._firstVisibleIndex - 1] || 0;
+ var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastVisibleIndex];
+
+ this._topGapElement.style.height = topGapHeight + "px";
+ this._bottomGapElement.style.height = bottomGapHeight + "px";
+ this._topGapElement._active = !!topGapHeight;
+ this._bottomGapElement._active = !!bottomGapHeight;
+
+ this._contentElement.style.setProperty("height", "10000000px");
+ for (var i = 0; i < this._renderedItems.length; ++i)
+ this._renderedItems[i].willHide();
+ this._renderedItems = [];
+ this._contentElement.removeChildren();
+ for (var i = this._firstVisibleIndex; i <= this._lastVisibleIndex; ++i) {
+ var viewportElement = this._provider.itemElement(i);
+ this._contentElement.appendChild(viewportElement.element());
+ this._renderedItems.push(viewportElement);
+ viewportElement.wasShown();
+ }
+
+ this._contentElement.style.removeProperty("height");
+ // Should be the last call in the method as it might force layout.
+ if (shouldRestoreSelection)
+ this._restoreSelection(selection);
+ if (shouldStickToBottom)
+ this.element.scrollTop = this.element.scrollHeight;
+ },
+
+ /**
+ * @return {?string}
+ */
+ _selectedText: function()
+ {
+ this._updateSelectionModel(window.getSelection());
+ if (!this._headSelection || !this._anchorSelection)
+ return null;
+
+ var startSelection = null;
+ var endSelection = null;
+ if (this._selectionIsBackward) {
+ startSelection = this._headSelection;
+ endSelection = this._anchorSelection;
+ } else {
+ startSelection = this._anchorSelection;
+ endSelection = this._headSelection;
+ }
+
+ var textLines = [];
+ for (var i = startSelection.item; i <= endSelection.item; ++i)
+ textLines.push(this._provider.itemElement(i).element().textContent);
+
+ var endSelectionElement = this._provider.itemElement(endSelection.item).element();
+ if (endSelection.node && endSelection.node.isSelfOrDescendant(endSelectionElement)) {
+ var itemTextOffset = this._textOffsetInNode(endSelectionElement, endSelection.node, endSelection.offset);
+ textLines[textLines.length - 1] = textLines.peekLast().substring(0, itemTextOffset);
+ }
+
+ var startSelectionElement = this._provider.itemElement(startSelection.item).element();
+ if (startSelection.node && startSelection.node.isSelfOrDescendant(startSelectionElement)) {
+ var itemTextOffset = this._textOffsetInNode(startSelectionElement, startSelection.node, startSelection.offset);
+ textLines[0] = textLines[0].substring(itemTextOffset);
+ }
+
+ return textLines.join("\n");
+ },
+
+ /**
+ * @param {!Element} itemElement
+ * @param {!Node} container
+ * @param {number} offset
+ * @return {number}
+ */
+ _textOffsetInNode: function(itemElement, container, offset)
+ {
+ var chars = 0;
+ var node = itemElement;
+ while ((node = node.traverseNextTextNode()) && node !== container)
+ chars += node.textContent.length;
+ return chars + offset;
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onScroll: function(event)
+ {
+ this.refresh();
+ },
+
+ /**
+ * @return {number}
+ */
+ firstVisibleIndex: function()
+ {
+ return this._firstVisibleIndex;
+ },
+
+ /**
+ * @return {number}
+ */
+ lastVisibleIndex: function()
+ {
+ return this._lastVisibleIndex;
+ },
+
+ /**
+ * @return {?Element}
+ */
+ renderedElementAt: function(index)
+ {
+ if (index < this._firstVisibleIndex)
+ return null;
+ if (index > this._lastVisibleIndex)
+ return null;
+ return this._renderedItems[index - this._firstVisibleIndex].element();
+ },
+
+ /**
+ * @param {number} index
+ * @param {boolean=} makeLast
+ */
+ scrollItemIntoView: function(index, makeLast)
+ {
+ if (index > this._firstVisibleIndex && index < this._lastVisibleIndex)
+ return;
+ if (makeLast)
+ this.forceScrollItemToBeLast(index);
+ else if (index <= this._firstVisibleIndex)
+ this.forceScrollItemToBeFirst(index);
+ else if (index >= this._lastVisibleIndex)
+ this.forceScrollItemToBeLast(index);
+ },
+
+ /**
+ * @param {number} index
+ */
+ forceScrollItemToBeFirst: function(index)
+ {
+ this._rebuildCumulativeHeightsIfNeeded();
+ this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
+ },
+
+ /**
+ * @param {number} index
+ */
+ forceScrollItemToBeLast: function(index)
+ {
+ this._rebuildCumulativeHeightsIfNeeded();
+ this.element.scrollTop = this._cumulativeHeights[index] - this.element.clientHeight;
+ }
+}
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/ui/ZoomManager.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ZoomManager.js
new file mode 100644
index 00000000000..83aa496aca5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/ZoomManager.js
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.ZoomManager = function()
+{
+ this._zoomFactor = InspectorFrontendHost.zoomFactor();
+ window.addEventListener("resize", this._onWindowResize.bind(this), true);
+};
+
+WebInspector.ZoomManager.Events = {
+ ZoomChanged: "ZoomChanged"
+};
+
+WebInspector.ZoomManager.prototype = {
+ /**
+ * @return {number}
+ */
+ zoomFactor: function()
+ {
+ return this._zoomFactor;
+ },
+
+ _onWindowResize: function()
+ {
+ var oldZoomFactor = this._zoomFactor;
+ this._zoomFactor = InspectorFrontendHost.zoomFactor();
+ if (oldZoomFactor !== this._zoomFactor)
+ this.dispatchEventToListeners(WebInspector.ZoomManager.Events.ZoomChanged, {from: oldZoomFactor, to: this._zoomFactor});
+ },
+
+ __proto__: WebInspector.Object.prototype
+};
+
+/**
+ * @type {!WebInspector.ZoomManager}
+ */
+WebInspector.zoomManager;
diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/treeoutline.js b/chromium/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
index 822664caffe..437b58e190d 100644
--- a/chromium/third_party/WebKit/Source/devtools/front_end/treeoutline.js
+++ b/chromium/third_party/WebKit/Source/devtools/front_end/ui/treeoutline.js
@@ -55,6 +55,7 @@ function TreeOutline(listNode, nonFocusable)
this._treeElementsMap = new Map();
/** @type {!Map.<!Object, boolean>} */
this._expandedStateMap = new Map();
+ this.element = listNode;
}
TreeOutline.prototype.setFocusable = function(focusable)
@@ -282,9 +283,10 @@ TreeOutline.prototype.getCachedTreeElement = function(representedObject)
/**
* @param {?Object} representedObject
+ * @param {function(!Object):?Object} getParent
* @return {?TreeElement}
*/
-TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
+TreeOutline.prototype.findTreeElement = function(representedObject, getParent)
{
if (!representedObject)
return null;
@@ -412,6 +414,9 @@ TreeOutline.prototype.collapse = function()
// this is the root, do nothing
}
+/**
+ * @return {boolean}
+ */
TreeOutline.prototype.revealed = function()
{
return true;
@@ -762,6 +767,10 @@ TreeElement.prototype.expandRecursively = function(maxDepth)
}
}
+/**
+ * @param {?TreeElement} ancestor
+ * @return {boolean}
+ */
TreeElement.prototype.hasAncestor = function(ancestor) {
if (!ancestor)
return false;
@@ -788,6 +797,9 @@ TreeElement.prototype.reveal = function()
this.onreveal();
}
+/**
+ * @return {boolean}
+ */
TreeElement.prototype.revealed = function()
{
var currentAncestor = this.parent;
@@ -845,6 +857,7 @@ TreeElement.prototype.revealAndSelect = function(omitFocus)
/**
* @param {boolean=} supressOnDeselect
+ * @return {boolean}
*/
TreeElement.prototype.deselect = function(supressOnDeselect)
{
@@ -964,6 +977,9 @@ TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, don
return this.parent;
}
+/**
+ * @return {boolean}
+ */
TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
{
// FIXME: We should not use getComputedStyle(). For that we need to get rid of using ::before for disclosure triangle. (http://webk.it/74446)