author | Wes Kocher <wkocher@mozilla.com> |
Fri, 08 Sep 2017 13:36:31 -0700 | |
changeset 379844 | ea7b55d65d76214f97aaae502d65cb26fc6f5659 |
parent 379797 | dd3736e98e4e7558af2f202803bce36278a26c66 (current diff) |
parent 379843 | ec521bf6357cf3564d5785a66da787be53be45cd (diff) |
child 379845 | 6017b2756cd5516be9f196583f13612aa490cd15 |
child 379895 | e78342f09ee6e90b78dc098742f3b0bae3b9bc84 |
push id | 50810 |
push user | kwierso@gmail.com |
push date | Fri, 08 Sep 2017 20:42:15 +0000 |
treeherder | autoland@6017b2756cd5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 57.0a1 |
first release with | nightly linux32
ea7b55d65d76
/
57.0a1
/
20170908220146
/
files
nightly linux64
ea7b55d65d76
/
57.0a1
/
20170908220146
/
files
nightly mac
ea7b55d65d76
/
57.0a1
/
20170908220146
/
files
nightly win32
ea7b55d65d76
/
57.0a1
/
20170908220146
/
files
nightly win64
ea7b55d65d76
/
57.0a1
/
20170908220146
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
57.0a1
/
20170908220146
/
pushlog to previous
nightly linux64
57.0a1
/
20170908220146
/
pushlog to previous
nightly mac
57.0a1
/
20170908220146
/
pushlog to previous
nightly win32
57.0a1
/
20170908220146
/
pushlog to previous
nightly win64
57.0a1
/
20170908220146
/
pushlog to previous
|
--- a/accessible/tests/browser/bounds/browser.ini +++ b/accessible/tests/browser/bounds/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js !/accessible/tests/browser/events.js !/accessible/tests/browser/shared-head.js !/accessible/tests/mochitest/*.js !/accessible/tests/mochitest/letters.gif [browser_test_zoom.js]
--- a/accessible/tests/browser/e10s/browser.ini +++ b/accessible/tests/browser/e10s/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js doc_treeupdate_ariadialog.html doc_treeupdate_ariaowns.html doc_treeupdate_imagemap.html doc_treeupdate_removal.xhtml doc_treeupdate_visibility.html doc_treeupdate_whitespace.html
--- a/accessible/tests/browser/events/browser.ini +++ b/accessible/tests/browser/events/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js !/accessible/tests/browser/events.js !/accessible/tests/browser/shared-head.js !/accessible/tests/mochitest/*.js [browser_test_docload.js] skip-if = e10s
--- a/accessible/tests/browser/scroll/browser.ini +++ b/accessible/tests/browser/scroll/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js !/accessible/tests/browser/events.js !/accessible/tests/browser/shared-head.js !/accessible/tests/mochitest/*.js [browser_test_zoom_text.js] skip-if = e10s && os == 'win' # bug 1372296
--- a/accessible/tests/browser/states/browser.ini +++ b/accessible/tests/browser/states/browser.ini @@ -1,10 +1,9 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js !/accessible/tests/browser/events.js !/accessible/tests/browser/shared-head.js !/accessible/tests/mochitest/*.js [browser_test_link.js] [browser_test_visibility.js]
--- a/accessible/tests/browser/tree/browser.ini +++ b/accessible/tests/browser/tree/browser.ini @@ -1,9 +1,8 @@ [DEFAULT] -skip-if = e10s && os == 'win' && release_or_beta support-files = head.js !/accessible/tests/browser/events.js !/accessible/tests/browser/shared-head.js !/accessible/tests/mochitest/*.js [browser_aria_owns.js]
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -662,19 +662,16 @@ pref("network.protocol-handler.expose.ne pref("network.protocol-handler.expose.snews", false); pref("network.protocol-handler.expose.nntp", false); pref("accessibility.typeaheadfind", false); pref("accessibility.typeaheadfind.timeout", 5000); pref("accessibility.typeaheadfind.linksonly", false); pref("accessibility.typeaheadfind.flashBar", 1); -// Tracks when accessibility is loaded into the previous session. -pref("accessibility.loadedInLastSession", false); - pref("plugins.click_to_play", true); pref("plugins.testmode", false); // Should plugins that are hidden show the infobar UI? pref("plugins.show_infobar", false); // Should dismissing the hidden plugin infobar suppress it permanently? pref("plugins.remember_infobar_dismissal", true); @@ -975,19 +972,16 @@ pref("toolkit.datacollection.infoURL", // URL for "Learn More" for Crash Reporter pref("toolkit.crashreporter.infoURL", "https://www.mozilla.org/legal/privacy/firefox.html#crash-reporter"); // base URL for web-based support pages pref("app.support.baseURL", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/"); -// a11y conflicts with e10s support page -pref("app.support.e10sAccessibilityUrl", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/accessibility-ppt"); - // base url for web-based feedback pages #ifdef MOZ_DEV_EDITION pref("app.feedback.baseURL", "https://input.mozilla.org/%LOCALE%/feedback/firefoxdev/%VERSION%/"); #else pref("app.feedback.baseURL", "https://input.mozilla.org/%LOCALE%/feedback/%APP%/%VERSION%/"); #endif // base URL for web-based marketing pages
--- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -523,23 +523,16 @@ BrowserGlue.prototype = { os.addObserver(this, "restart-in-safe-mode"); os.addObserver(this, "flash-plugin-hang"); os.addObserver(this, "xpi-signature-changed"); os.addObserver(this, "sync-ui-state:update"); os.addObserver(this, "handlersvc-store-initialized"); this._flashHangCount = 0; this._firstWindowReady = new Promise(resolve => this._firstWindowLoaded = resolve); - - if (AppConstants.platform == "macosx" || - (AppConstants.platform == "win" && AppConstants.RELEASE_OR_BETA)) { - // Handles prompting to inform about incompatibilites when accessibility - // and e10s are active together. - E10SAccessibilityCheck.init(); - } }, // cleanup (called on application shutdown) _dispose: function BG__dispose() { let os = Services.obs; os.removeObserver(this, "notifications-open-settings"); os.removeObserver(this, "prefservice:after-app-defaults"); os.removeObserver(this, "final-ui-startup"); @@ -1004,20 +997,17 @@ BrowserGlue.prototype = { }); } if (AppConstants.MOZ_CRASHREPORTER) { UnsubmittedCrashHandler.init(); } this._sanitizer.onStartup(); - E10SAccessibilityCheck.onWindowsRestored(); - this._scheduleStartupIdleTasks(); - this._lateTasksIdleObserver = (idleService, topic, data) => { if (topic == "idle") { idleService.removeIdleObserver(this._lateTasksIdleObserver, LATE_TASKS_IDLE_TIME_SEC); delete this._lateTasksIdleObserver; this._scheduleArbitrarilyLateIdleTasks(); } }; @@ -2795,141 +2785,18 @@ var DefaultBrowserCheck = { let popup = doc.getElementById(this.OPTIONPOPUP); popup.removeEventListener("command", this); popup.remove(); delete this._notification; } }, }; -var E10SAccessibilityCheck = { - // tracks when an a11y init observer fires prior to the - // first window being opening. - _wantsPrompt: false, - - init() { - Services.obs.addObserver(this, "a11y-init-or-shutdown", true); - Services.obs.addObserver(this, "quit-application-granted", true); - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), - - get forcedOn() { - try { - return Services.prefs.getBoolPref("browser.tabs.remote.force-enable"); - } catch (e) {} - return false; - }, - - observe(subject, topic, data) { - switch (topic) { - case "quit-application-granted": - // Tag the profile with a11y load state. We use this in nsAppRunner - // checks on the next start. - Services.prefs.setBoolPref("accessibility.loadedInLastSession", - Services.appinfo.accessibilityEnabled); - break; - case "a11y-init-or-shutdown": - if (data == "1") { - // Update this so users can check this while still running - Services.prefs.setBoolPref("accessibility.loadedInLastSession", true); - this._showE10sAccessibilityWarning(); - } - break; - } - }, - - onWindowsRestored() { - if (this._wantsPrompt) { - this._wantsPrompt = false; - this._showE10sAccessibilityWarning(); - } - }, - - _warnedAboutAccessibility: false, - - _showE10sAccessibilityWarning() { - // We don't prompt about a11y incompat if e10s is off. - if (!Services.appinfo.browserTabsRemoteAutostart) { - return; - } - - // If the user set the forced pref and it's true, ignore a11y init. - // If the pref doesn't exist or if it's false, prompt. - if (this.forcedOn) { - return; - } - - // Only prompt once per session - if (this._warnedAboutAccessibility) { - return; - } - this._warnedAboutAccessibility = true; - - let win = RecentWindow.getMostRecentBrowserWindow(); - if (!win || !win.gBrowser || !win.gBrowser.selectedBrowser) { - Services.console.logStringMessage( - "Accessibility support is partially disabled due to compatibility issues with new features."); - this._wantsPrompt = true; - this._warnedAboutAccessibility = false; - return; - } - let browser = win.gBrowser.selectedBrowser; - - // We disable a11y for content and prompt on the chrome side letting - // a11y users know they need to disable e10s and restart. - let promptMessage = win.gNavigatorBundle.getFormattedString( - "e10s.accessibilityNotice.mainMessage2", - [gBrandBundle.GetStringFromName("brandShortName")] - ); - let notification; - let restartCallback = function() { - let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); - Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); - if (cancelQuit.data) { - return; // somebody canceled our quit request - } - // Restart the browser - Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart); - }; - // main option: an Ok button, keeps running with content accessibility disabled - let mainAction = { - label: win.gNavigatorBundle.getString("e10s.accessibilityNotice.acceptButton.label"), - accessKey: win.gNavigatorBundle.getString("e10s.accessibilityNotice.acceptButton.accesskey"), - callback() { - // If the user invoked the button option remove the notification, - // otherwise keep the alert icon around in the address bar. - notification.remove(); - }, - dismiss: true - }; - // secondary option: a restart now button. When we restart e10s will be disabled due to - // accessibility having been loaded in the previous session. - let secondaryActions = [{ - label: win.gNavigatorBundle.getString("e10s.accessibilityNotice.enableAndRestart.label"), - accessKey: win.gNavigatorBundle.getString("e10s.accessibilityNotice.enableAndRestart.accesskey"), - callback: restartCallback, - }]; - let options = { - popupIconURL: "chrome://browser/skin/e10s-64@2x.png", - learnMoreURL: Services.urlFormatter.formatURLPref("app.support.e10sAccessibilityUrl"), - persistent: true, - persistWhileVisible: true, - }; - - notification = - win.PopupNotifications.show(browser, "a11y_enabled_with_e10s", - promptMessage, null, mainAction, - secondaryActions, options); - }, -}; - var components = [BrowserGlue, ContentPermissionPrompt]; this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components); - // Listen for UITour messages. // Do it here instead of the UITour module itself so that the UITour module is lazy loaded // when the first message is received. var globalMM = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager); globalMM.addMessageListener("UITour:onPageEvent", function(aMessage) { UITour.onPageEvent(aMessage, aMessage.data); });
--- a/browser/themes/linux/jar.mn +++ b/browser/themes/linux/jar.mn @@ -58,17 +58,14 @@ browser.jar: skin/classic/browser/preferences/preferences.css (preferences/preferences.css) * skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css) * skin/classic/browser/preferences/in-content/dialog.css (preferences/in-content/dialog.css) skin/classic/browser/preferences/applications.css (preferences/applications.css) skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png) skin/classic/browser/sync-desktopIcon.svg (../shared/sync-desktopIcon.svg) skin/classic/browser/sync-mobileIcon.svg (../shared/sync-mobileIcon.svg) -#ifdef E10S_TESTING_ONLY - skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png) -#endif [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: % override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
--- a/browser/themes/osx/jar.mn +++ b/browser/themes/osx/jar.mn @@ -82,19 +82,16 @@ browser.jar: skin/classic/browser/sync-desktopIcon.svg (../shared/sync-desktopIcon.svg) skin/classic/browser/sync-mobileIcon.svg (../shared/sync-mobileIcon.svg) skin/classic/browser/yosemite/menuPanel-customize.png (menuPanel-customize-yosemite.png) skin/classic/browser/yosemite/menuPanel-customize@2x.png (menuPanel-customize-yosemite@2x.png) skin/classic/browser/yosemite/menuPanel-exit.png (menuPanel-exit-yosemite.png) skin/classic/browser/yosemite/menuPanel-exit@2x.png (menuPanel-exit-yosemite@2x.png) skin/classic/browser/yosemite/menuPanel-help.png (menuPanel-help-yosemite.png) skin/classic/browser/yosemite/menuPanel-help@2x.png (menuPanel-help-yosemite@2x.png) -#ifdef E10S_TESTING_ONLY - skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png) -#endif [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: % override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/notification-icons/geo-detailed.svg chrome://browser/skin/notification-icons/geo.svg
--- a/browser/themes/shared/customizableui/customizeMode.inc.css +++ b/browser/themes/shared/customizableui/customizeMode.inc.css @@ -52,24 +52,23 @@ %if defined(XP_MACOSX) || defined(XP_WIN) %ifdef XP_WIN @media (-moz-windows-default-theme) { %endif .customizationmode-button { border: 1px solid #b1b1b1; - margin: 6px 10px; - padding: 2px 5px; background-color: #fcfcfd; - color: rgb(71,71,71); -moz-appearance: none; } -.customizationmode-checkbox { +.customizationmode-checkbox, +.customizationmode-button { + color: rgb(71, 71, 71); margin: 6px 10px; padding: 2px 5px; } #customization-reset-button, #customization-undo-reset-button, #customization-done-button { min-width: 10em;
deleted file mode 100644 index 1dc243865cfb412f03aa372d30fa769fd3fd5eac..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
--- a/browser/themes/windows/jar.mn +++ b/browser/themes/windows/jar.mn @@ -78,20 +78,16 @@ browser.jar: skin/classic/browser/window-controls/maximize-themes.svg (window-controls/maximize-themes.svg) skin/classic/browser/window-controls/minimize.svg (window-controls/minimize.svg) skin/classic/browser/window-controls/minimize-highcontrast.svg (window-controls/minimize-highcontrast.svg) skin/classic/browser/window-controls/minimize-themes.svg (window-controls/minimize-themes.svg) skin/classic/browser/window-controls/restore.svg (window-controls/restore.svg) skin/classic/browser/window-controls/restore-highcontrast.svg (window-controls/restore-highcontrast.svg) skin/classic/browser/window-controls/restore-themes.svg (window-controls/restore-themes.svg) -#ifdef E10S_TESTING_ONLY - skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png) -#endif - [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: % override chrome://browser/skin/page-livemarks.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png % override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png % override chrome://browser/skin/privatebrowsing-mask-tabstrip.png chrome://browser/skin/privatebrowsing-mask-tabstrip-win7.png os=WINNT osversion<=6.1
--- a/devtools/client/debugger/new/debugger.css +++ b/devtools/client/debugger/new/debugger.css @@ -415,16 +415,20 @@ body { --popup-shadow-color: #d0d0d0; } :root.theme-dark, :root .theme-dark { --search-overlays-semitransparent: rgba(42, 46, 56, 0.66); --popup-shadow-color: #5c667b; } +* { + box-sizing: border-box; +} + .debugger { display: flex; flex: 1; height: 100%; } .editor-pane { display: flex; @@ -872,22 +876,16 @@ html .arrow.expanded svg { .managed-tree .tree .node { padding: 2px 3px 2px 3px; position: relative; } .managed-tree .tree .node.focused { color: white; background-color: var(--theme-selection-background); - padding-bottom: 2px; -} - -.theme-dark .managed-tree .tree .node.focused { - background-color: var(--theme-selection-background-hover); - padding-bottom: 2px; } html:not([dir="rtl"]) .managed-tree .tree .node > div { margin-left: 10px; } html[dir="rtl"] .managed-tree .tree .node > div { margin-right: 10px; @@ -902,17 +900,17 @@ html[dir="rtl"] .managed-tree .tree .nod } .close-btn path { fill: var(--theme-comment-alt); } .close-btn .close { width: 14px; height: 14px; - transition: all 0.25s ease-in-out; + transition: all 0.15s ease-in-out; border: 1px solid transparent; border-radius: 2px; padding: 0; margin-top: 0; display: inline-flex; justify-content: center; } @@ -1262,37 +1260,39 @@ html[dir="rtl"] .managed-tree .tree .nod .toggle-search .title { font-weight: 500; font-size: 120%; } .toggle-search .text { margin-left: 1em; + cursor: default; } .toggle-search .active { color: var(--theme-selection-background); - cursor: default; } .sources-panel { + background-color: var(--theme-sidebar-background); + display: flex; flex: 1; - display: flex; flex-direction: column; overflow: hidden; position: relative; } .sources-panel * { -moz-user-select: none; user-select: none; } .sources-header { - height: 30px; + height: 29px; + background-color: var(--theme-toolbar-background); border-bottom: 1px solid var(--theme-splitter-color); padding-top: 0px; padding-bottom: 0px; line-height: 30px; font-size: 1.2em; display: flex; align-items: baseline; -moz-user-select: none; @@ -2231,17 +2231,17 @@ html[dir="rtl"] .arrow svg, * BUG https://github.com/devtools-html/debugger.html/issues/63 */ .editor-wrapper { position: absolute; height: calc(100% - 31px); width: calc(100% - 1.5px); top: 30px; left: 0px; - --editor-footer-height: 27px; + --editor-footer-height: 24px; } html[dir="rtl"] .editor-mount { direction: ltr; } .editor-wrapper .breakpoints { position: absolute; @@ -2435,34 +2435,18 @@ html[dir="rtl"] .editor-mount { left: 0; right: 0; content: ""; margin-bottom: -1px; } .cm-highlight-full::before { border: 1px solid var(--theme-comment-alt); -} - -.cm-highlight-start::before { - border-left-width: 1px; - border-left-style: solid; - border-left-color: var(--theme-comment-alt); - margin: 0 0 -1px -1px; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; -} - -.cm-highlight-end::before { - border-right-width: 1px; - border-right-style: solid; - border-right-color: var(--theme-comment-alt); - margin: 0 -1px -1px 0; - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; + border-radius: 2px; + margin: 0 -1px -1px -1px; } .breakpoints-toggle { margin: 2px 3px; } .breakpoints-list * { -moz-user-select: none; user-select: none; @@ -2561,17 +2545,17 @@ html .breakpoints-list .breakpoint.pause .breakpoint:hover .close { visibility: visible; } .input-expression { width: 100%; margin: 0px; border: 1px; - background-color: var(--theme-body-background); + background-color: var(--theme-sidebar-background); font-size: 12px; padding: 0px 20px; color: var(--theme-body-color); } .input-expression::placeholder { text-align: center; font-style: italic; @@ -2582,17 +2566,17 @@ html .breakpoints-list .breakpoint.pause .input-expression:focus { outline: none; cursor: text; } .expressions-list { /* TODO: add normalize */ margin: 0; - padding: 0.5em 0; + padding: 0; } .expression-input-container { padding: 0.5em; display: flex; } .expression-container { border: 1px; @@ -2846,41 +2830,48 @@ html .breakpoints-list .breakpoint.pause .event-listeners .listener .close { display: none; } .event-listeners .listener:hover .close { display: block; } + +:root { + --accordion-header-background: var(--theme-toolbar-background); +} + +:root.theme-dark { + --accordion-header-background: #141416; +} + .accordion { - background-color: var(--theme-body-background); + background-color: var(--theme-sidebar-background); width: 100%; } .accordion ._header { - background-color: var(--theme-toolbar-background); + background-color: var(--accordion-header-background); border-bottom: 1px solid var(--theme-splitter-color); + display: flex; font-size: 12px; - padding: 5px; + padding: 4px; transition: all 0.25s ease; width: 100%; + height: 24px; align-items: center; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } -.accordion ._header { - display: flex; -} - .accordion ._header:hover { background-color: var(--theme-toolbar-background-hover); } .accordion ._header button svg, .accordion ._header:hover button svg { fill: currentColor; height: 16px; @@ -2916,25 +2907,25 @@ html .breakpoints-list .breakpoint.pause width: 16px; height: 16px; } .accordion .header-buttons button::-moz-focus-inner { border: none; } .command-bar { - flex: 0 0 30px; + flex: 0 0 29px; border-bottom: 1px solid var(--theme-splitter-color); display: flex; - height: 30px; + height: 29px; overflow: hidden; position: sticky; top: 0; z-index: 1; - background-color: var(--theme-body-background); + background-color: var(--theme-toolbar-background); } .command-bar.vertical { width: 100vw; } html[dir="rtl"] .command-bar { border-right: 1px solid var(--theme-splitter-color); @@ -3078,41 +3069,56 @@ html .command-bar > button:disabled { height: calc(100% - 30px); position: absolute; top: 30px; left: 0; padding: 50px 0 0 0; text-align: center; font-size: 1.25em; color: var(--theme-comment-alt); - background-color: var(--theme-tab-toolbar-background); + background-color: var(--theme-toolbar-background); font-weight: lighter; z-index: 100; } +.theme-dark .welcomebox { + background-color: var(--theme-body-background); +} + .alignlabel { display: inline-block; - text-align: left; } .welcomebox .toggle-button-end { position: absolute; top: auto; bottom: 0; offset-inline-end: 0; offset-inline-start: auto; } +.shortcutKeys { + text-align: right; + float: left; + font-family: Courier; +} + +.shortcutFunction { + text-align: left; + float: left; + margin-left: 25px; +} + html .welcomebox .toggle-button-end.collapsed { bottom: 1px; } .source-header { border-bottom: 1px solid var(--theme-splitter-color); width: 100%; - height: 30px; + height: 29px; display: flex; align-items: flex-end; } .source-header * { -moz-user-select: none; user-select: none; } @@ -3142,17 +3148,17 @@ html .welcomebox .toggle-button-end.coll .source-tab { border: 1px solid transparent; border-top-left-radius: 2px; border-top-right-radius: 2px; display: inline-flex; align-items: flex-end; position: relative; - transition: all 0.25s ease; + transition: all 0.15s ease; min-width: 40px; overflow: hidden; padding: 5px; margin-inline-start: 3px; margin-top: 4px; } .source-tab:hover {
--- a/devtools/client/debugger/new/debugger.js +++ b/devtools/client/debugger/new/debugger.js @@ -1339,17 +1339,16 @@ function warning(message) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InitialState = InitialState; exports.getTextSearchResults = getTextSearchResults; -exports.getTextSearchResult = getTextSearchResult; exports.getTextSearchQuery = getTextSearchQuery; var _immutable = __webpack_require__(146); var I = _interopRequireWildcard(_immutable); var _makeRecord = __webpack_require__(230); @@ -1364,44 +1363,46 @@ function _interopRequireWildcard(obj) { * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Search reducer * @module reducers/search */ function InitialState() { - return (0, _makeRecord2.default)({ query: "", results: I.Map() })(); + return (0, _makeRecord2.default)({ query: "", results: I.List() })(); } function update() { var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : InitialState(); var action = arguments[1]; switch (action.type) { case "ADD_QUERY": return state.update("query", value => action.query); case "CLEAR_QUERY": return state.remove("query"); case "ADD_SEARCH_RESULT": - return state.updateIn(["results", action.result.sourceId], value => action.result); + var _results = state.get("results"); + return state.merge({ results: _results.push(action.result) }); + + case "CLEAR_SEARCH_RESULTS": + return state.merge({ + results: state.get("results").clear() + }); } return state; } function getTextSearchResults(state) { return state.projectTextSearch.get("results"); } -function getTextSearchResult(state, id) { - return state.projectTextSearch.getIn(["results", id]); -} - function getTextSearchQuery(state) { return state.projectTextSearch.get("query"); } exports.default = update; /***/ }), /* 32 */ @@ -1822,16 +1823,17 @@ function compose() { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addSearchQuery = addSearchQuery; exports.clearSearchQuery = clearSearchQuery; +exports.clearSearchResults = clearSearchResults; exports.searchSources = searchSources; exports.searchSource = searchSource; var _search = __webpack_require__(1115); var _selectors = __webpack_require__(242); var _sources = __webpack_require__(254); @@ -1860,59 +1862,69 @@ function clearSearchQuery() { return (_ref2) => { var dispatch = _ref2.dispatch, getState = _ref2.getState; dispatch({ type: "CLEAR_QUERY" }); }; } +function clearSearchResults() { + return (_ref3) => { + var dispatch = _ref3.dispatch, + getState = _ref3.getState; + + dispatch({ type: "CLEAR_SEARCH_RESULTS" }); + }; +} + function searchSources(query) { return (() => { - var _ref3 = _asyncToGenerator(function* (_ref4) { - var dispatch = _ref4.dispatch, - getState = _ref4.getState; - + var _ref4 = _asyncToGenerator(function* (_ref5) { + var dispatch = _ref5.dispatch, + getState = _ref5.getState; + + yield dispatch(clearSearchResults()); yield dispatch(addSearchQuery(query)); yield dispatch((0, _sources.loadAllSources)()); var sources = (0, _selectors.getSources)(getState()); var validSources = sources.valueSeq().filter(function (source) { return source.has("text"); }).toJS(); for (var source of validSources) { yield dispatch(searchSource(source, query)); } }); return function (_x) { - return _ref3.apply(this, arguments); + return _ref4.apply(this, arguments); }; })(); } function searchSource(source, query) { return (() => { - var _ref5 = _asyncToGenerator(function* (_ref6) { - var dispatch = _ref6.dispatch, - getState = _ref6.getState; + var _ref6 = _asyncToGenerator(function* (_ref7) { + var dispatch = _ref7.dispatch, + getState = _ref7.getState; var matches = yield (0, _search.findSourceMatches)(source, query); dispatch({ type: "ADD_SEARCH_RESULT", result: { sourceId: source.id, filepath: source.url, matches } }); }); return function (_x2) { - return _ref5.apply(this, arguments); + return _ref6.apply(this, arguments); }; })(); } /***/ }), /* 38 */, /* 39 */ /***/ (function(module, exports, __webpack_require__) { @@ -5956,26 +5968,26 @@ function renderRoot(_React, _ReactDOM, c // bail in test environments that do not have a mount if (!mount) { return; } var root = Root("launchpad-root theme-body"); mount.appendChild(root); + if (isDevelopment()) { + updateConfig(); + updateTheme(); + } + if (component.props || component.propTypes) { _ReactDOM.render(createElement(Provider, { store: _store }, createElement(component)), root); } else { root.appendChild(component); } - - if (isDevelopment()) { - updateConfig(); - updateTheme(); - } } function unmountRoot(_ReactDOM) { var mount = document.querySelector("#mount .launchpad-root"); _ReactDOM.unmountComponentAtNode(mount); } function getTargetFromQuery() { @@ -15930,17 +15942,17 @@ function thunk(makeArgs) { "use strict"; Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // @flow const { isDevelopment } = __webpack_require__(828); const { Services, PrefsHelper } = __webpack_require__(830); -const prefsSchemaVersion = "1.0.2"; +const prefsSchemaVersion = "1.0.3"; const pref = Services.pref; if (isDevelopment()) { pref("devtools.debugger.client-source-maps-enabled", true); pref("devtools.debugger.pause-on-exceptions", false); pref("devtools.debugger.ignore-caught-exceptions", false); pref("devtools.debugger.call-stack-visible", false); @@ -15952,17 +15964,17 @@ if (isDevelopment()) { pref("devtools.debugger.pending-selected-location", "{}"); pref("devtools.debugger.pending-breakpoints", "{}"); pref("devtools.debugger.expressions", "[]"); pref("devtools.debugger.file-search-case-sensitive", false); pref("devtools.debugger.file-search-whole-word", false); pref("devtools.debugger.file-search-regex-match", false); pref("devtools.debugger.prefs-schema-version", "1.0.1"); pref("devtools.debugger.project-text-search-enabled", true); - pref("devtools.debugger.features.async-stepping", false); + pref("devtools.debugger.features.async-stepping", true); } const prefs = new PrefsHelper("devtools", { clientSourceMapsEnabled: ["Bool", "debugger.client-source-maps-enabled"], pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"], ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"], callStackVisible: ["Bool", "debugger.call-stack-visible"], scopesVisible: ["Bool", "debugger.scopes-visible"], @@ -15971,28 +15983,24 @@ const prefs = new PrefsHelper("devtools" frameworkGroupingOn: ["Bool", "debugger.ui.framework-grouping-on"], tabs: ["Json", "debugger.tabs", []], pendingSelectedLocation: ["Json", "debugger.pending-selected-location", {}], pendingBreakpoints: ["Json", "debugger.pending-breakpoints", {}], expressions: ["Json", "debugger.expressions", []], fileSearchCaseSensitive: ["Bool", "debugger.file-search-case-sensitive"], fileSearchWholeWord: ["Bool", "debugger.file-search-whole-word"], fileSearchRegexMatch: ["Bool", "debugger.file-search-regex-match"], - debuggerPrefsSchemaVersion: ["Char", "debugger.prefs-schema-version"], - projectTextSearchEnabled: [ - "Bool", - "debugger.project-text-search-enabled", - false - ] + debuggerPrefsSchemaVersion: ["Char", "debugger.prefs-schema-version"] }); /* harmony export (immutable) */ __webpack_exports__["prefs"] = prefs; const features = new PrefsHelper("devtools.debugger.features", { - asyncStepping: ["Bool", "async-stepping", false] + asyncStepping: ["Bool", "async-stepping", false], + projectTextSearch: ["Bool", "debugger.project-text-search-enabled", true] }); /* harmony export (immutable) */ __webpack_exports__["features"] = features; if (prefs.debuggerPrefsSchemaVersion !== prefsSchemaVersion) { // clear pending Breakpoints prefs.pendingBreakpoints = {}; prefs.debuggerPrefsSchemaVersion = prefsSchemaVersion; @@ -16821,23 +16829,30 @@ function getSourceLineCount(source) { * @return String * @memberof utils/source * @static */ function getMode(source) { var contentType = source.contentType, text = source.text, - isWasm = source.isWasm; + isWasm = source.isWasm, + url = source.url; if (!text || isWasm) { return { name: "text" }; } + // if the url ends with .marko we set the name to Javascript so + // syntax highlighting works for marko too + if (url && url.match(/\.marko$/i)) { + return { name: "javascript" }; + } + // Use HTML mode for files in which the first non whitespace // character is `<` regardless of extension. var isHTMLLike = text.match(/^\s*</); if (!contentType) { if (isHTMLLike) { return { name: "htmlmixed" }; } return { name: "text" }; @@ -17044,17 +17059,17 @@ var _immutable = __webpack_require__(146 var I = _interopRequireWildcard(_immutable); var _makeRecord = __webpack_require__(230); var _makeRecord2 = _interopRequireDefault(_makeRecord); var _devtoolsSourceMap = __webpack_require__(898); -var _breakpoint2 = __webpack_require__(1057); +var _breakpoint = __webpack_require__(1057); var _reselect = __webpack_require__(993); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function initialState() { @@ -17071,17 +17086,17 @@ function update() { switch (action.type) { case "ADD_BREAKPOINT": { return addBreakpoint(state, action); } case "SYNC_BREAKPOINT": { - return addBreakpoint(state, action); + return syncBreakpoint(state, action); } case "ENABLE_BREAKPOINT": { return addBreakpoint(state, action); } case "DISABLE_BREAKPOINT": @@ -17104,80 +17119,83 @@ function update() { return remapBreakpoints(state, action); } } return state; } function addBreakpoint(state, action) { - if (action.status === "start") { + if (action.status === "start" && action.breakpoint) { var breakpoint = action.breakpoint; - var locationId = (0, _breakpoint2.makeLocationId)(breakpoint.location); + var locationId = (0, _breakpoint.makeLocationId)(breakpoint.location); return state.setIn(["breakpoints", locationId], breakpoint); } // when the action completes, we can commit the breakpoint if (action.status === "done") { - var _action$value = action.value, - _breakpoint = _action$value.breakpoint, - previousLocation = _action$value.previousLocation; - - var _locationId = (0, _breakpoint2.makeLocationId)(_breakpoint.location); - - if (previousLocation) { - return state.deleteIn(["breakpoints", (0, _breakpoint2.makeLocationId)(previousLocation)]).setIn(["breakpoints", _locationId], _breakpoint); - } - - return state.setIn(["breakpoints", _locationId], _breakpoint); + return syncBreakpoint(state, action.value); } // Remove the optimistic update - if (action.status === "error") { - var _locationId2 = (0, _breakpoint2.makeLocationId)(action.breakpoint.location); - return state.deleteIn(["breakpoints", _locationId2]); + if (action.status === "error" && action.breakpoint) { + var _locationId = (0, _breakpoint.makeLocationId)(action.breakpoint.location); + return state.deleteIn(["breakpoints", _locationId]); } return state; } +function syncBreakpoint(state, data) { + var breakpoint = data.breakpoint, + previousLocation = data.previousLocation; + + var locationId = (0, _breakpoint.makeLocationId)(breakpoint.location); + + if (previousLocation) { + return state.deleteIn(["breakpoints", (0, _breakpoint.makeLocationId)(previousLocation)]).setIn(["breakpoints", locationId], breakpoint); + } + + return state.setIn(["breakpoints", locationId], breakpoint); +} + function updateBreakpoint(state, action) { var breakpoint = action.breakpoint; - var locationId = (0, _breakpoint2.makeLocationId)(breakpoint.location); + var locationId = (0, _breakpoint.makeLocationId)(breakpoint.location); return state.setIn(["breakpoints", locationId], breakpoint); } function remapBreakpoints(state, action) { var breakpoints = action.breakpoints.reduce((updatedBreakpoints, breakpoint) => { - var locationId = (0, _breakpoint2.makeLocationId)(breakpoint.location); + var locationId = (0, _breakpoint.makeLocationId)(breakpoint.location); return _extends({}, updatedBreakpoints, { [locationId]: breakpoint }); }, {}); return state.set("breakpoints", I.Map(breakpoints)); } function removeBreakpoint(state, action) { var breakpoint = action.breakpoint; - var id = (0, _breakpoint2.makeLocationId)(breakpoint.location); + var id = (0, _breakpoint.makeLocationId)(breakpoint.location); return state.deleteIn(["breakpoints", id]); } // Selectors // TODO: these functions should be moved out of the reducer function getBreakpoints(state) { return state.breakpoints.breakpoints; } function getBreakpoint(state, location) { var breakpoints = getBreakpoints(state); - return breakpoints.get((0, _breakpoint2.makeLocationId)(location)); + return breakpoints.get((0, _breakpoint.makeLocationId)(location)); } function getBreakpointsDisabled(state) { return state.breakpoints.breakpoints.every(x => x.disabled); } function getBreakpointsLoading(state) { var breakpoints = getBreakpoints(state); @@ -17518,16 +17536,19 @@ function update() { shouldIgnoreCaughtExceptions: _shouldIgnoreCaughtExceptions }); case "COMMAND": return _extends({}, state, { command: action.value.type }); case "CLEAR_COMMAND": return _extends({}, state, { command: "" }); + + case "NAVIGATE": + return _extends({}, state, { debuggeeUrl: action.url }); } return state; } // Selectors // Unfortunately, it's really hard to make these functions accept just @@ -17606,17 +17627,17 @@ exports.default = update; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.State = undefined; -exports.getActiveSearchState = getActiveSearchState; +exports.getActiveSearch = getActiveSearch; exports.getFileSearchQueryState = getFileSearchQueryState; exports.getFileSearchModifierState = getFileSearchModifierState; exports.getSearchResults = getSearchResults; exports.getFrameworkGroupingState = getFrameworkGroupingState; exports.getSymbolSearchType = getSymbolSearchType; exports.getShownSource = getShownSource; exports.getPaneCollapse = getPaneCollapse; exports.getHighlightedLineRange = getHighlightedLineRange; @@ -17743,17 +17764,17 @@ function update() { { return state; } } } // NOTE: we'd like to have the app state fully typed // https://github.com/devtools-html/debugger.html/blob/master/src/reducers/sources.js#L179-L185 -function getActiveSearchState(state) { +function getActiveSearch(state) { return state.ui.get("activeSearch"); } function getFileSearchQueryState(state) { return state.ui.get("fileSearchQuery"); } function getFileSearchModifierState(state) { @@ -18022,42 +18043,82 @@ class App extends _react.Component { this.state = { horizontal: verticalLayoutBreakpoint.matches, startPanelSize: 0, endPanelSize: 0 }; this.getChildContext = this.getChildContext.bind(this); this.onLayoutChange = this.onLayoutChange.bind(this); + this.toggleSymbolModal = this.toggleSymbolModal.bind(this); this.renderEditorPane = this.renderEditorPane.bind(this); this.renderVerticalLayout = this.renderVerticalLayout.bind(this); + this.onEscape = this.onEscape.bind(this); } getChildContext() { return { shortcuts }; } componentDidMount() { verticalLayoutBreakpoint.addListener(this.onLayoutChange); + shortcuts.on(L10N.getStr("symbolSearch.search.key2"), this.toggleSymbolModal); + shortcuts.on("Escape", this.onEscape); } componentWillUnmount() { verticalLayoutBreakpoint.removeListener(this.onLayoutChange); + shortcuts.off(L10N.getStr("symbolSearch.search.key2"), this.toggleSymbolModal); + shortcuts.off("Escape", this.onEscape); + } + + onEscape(_, e) { + var _props = this.props, + activeSearch = _props.activeSearch, + closeActiveSearch = _props.closeActiveSearch; + + + if (activeSearch) { + e.preventDefault(); + closeActiveSearch(); + } + } + + toggleSymbolModal(_, e) { + var _props2 = this.props, + selectedSource = _props2.selectedSource, + activeSearch = _props2.activeSearch, + closeActiveSearch = _props2.closeActiveSearch, + setActiveSearch = _props2.setActiveSearch; + + + e.preventDefault(); + e.stopPropagation(); + + if (!selectedSource) { + return; + } + + if (activeSearch == "symbol") { + return closeActiveSearch(); + } + + setActiveSearch("symbol"); } onLayoutChange() { if ((0, _ui.isVisible)()) { this.setState({ horizontal: verticalLayoutBreakpoint.matches }); } } renderEditorPane() { - var _props = this.props, - startPanelCollapsed = _props.startPanelCollapsed, - endPanelCollapsed = _props.endPanelCollapsed; + var _props3 = this.props, + startPanelCollapsed = _props3.startPanelCollapsed, + endPanelCollapsed = _props3.endPanelCollapsed; var _state = this.state, horizontal = _state.horizontal, endPanelSize = _state.endPanelSize, startPanelSize = _state.startPanelSize; return _react2.default.createElement( "div", @@ -18079,19 +18140,19 @@ class App extends _react.Component { }), !this.props.selectedSource ? _react2.default.createElement(_WelcomeBox2.default, { horizontal: horizontal }) : null, _react2.default.createElement(_ProjectSearch2.default, null) ) ); } renderHorizontalLayout() { - var _props2 = this.props, - startPanelCollapsed = _props2.startPanelCollapsed, - endPanelCollapsed = _props2.endPanelCollapsed; + var _props4 = this.props, + startPanelCollapsed = _props4.startPanelCollapsed, + endPanelCollapsed = _props4.endPanelCollapsed; var horizontal = this.state.horizontal; var overflowX = endPanelCollapsed ? "hidden" : "auto"; return _react2.default.createElement(_devtoolsSplitter2.default, { style: { width: "100vw" }, initialSize: "250px", @@ -18113,19 +18174,19 @@ class App extends _react.Component { endPanel: _react2.default.createElement(_SecondaryPanes2.default, { horizontal: horizontal }), endPanelCollapsed: endPanelCollapsed, vert: horizontal }) }); } renderVerticalLayout() { - var _props3 = this.props, - startPanelCollapsed = _props3.startPanelCollapsed, - endPanelCollapsed = _props3.endPanelCollapsed; + var _props5 = this.props, + startPanelCollapsed = _props5.startPanelCollapsed, + endPanelCollapsed = _props5.endPanelCollapsed; var horizontal = this.state.horizontal; return _react2.default.createElement(_devtoolsSplitter2.default, { style: { width: "100vw" }, initialSize: "300px", minSize: 30, maxSize: "99%", @@ -18141,42 +18202,52 @@ class App extends _react.Component { startPanel: _react2.default.createElement(_PrimaryPanes2.default, { horizontal: horizontal }), endPanel: this.renderEditorPane() }), endPanel: _react2.default.createElement(_SecondaryPanes2.default, { horizontal: horizontal }), endPanelCollapsed: endPanelCollapsed }); } - render() { - var _props4 = this.props, - selectSource = _props4.selectSource, - selectedSource = _props4.selectedSource; - - + renderSymbolModal() { + var _props6 = this.props, + selectSource = _props6.selectSource, + selectedSource = _props6.selectedSource, + activeSearch = _props6.activeSearch; + + + if (activeSearch !== "symbol") { + return; + } + + return _react2.default.createElement(_SymbolModal2.default, { + selectSource: selectSource, + selectedSource: selectedSource + }); + } + + render() { return _react2.default.createElement( "div", { className: "debugger" }, this.state.horizontal ? this.renderHorizontalLayout() : this.renderVerticalLayout(), - _react2.default.createElement(_SymbolModal2.default, { - selectSource: selectSource, - selectedSource: selectedSource - }) + this.renderSymbolModal() ); } } App.displayName = "App"; App.childContextTypes = { shortcuts: _react.PropTypes.object }; exports.default = (0, _reactRedux.connect)(state => ({ selectedSource: (0, _selectors.getSelectedSource)(state), startPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "start"), - endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end") + endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end"), + activeSearch: (0, _selectors.getActiveSearch)(state) }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(App); /***/ }), /* 244 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -18220,49 +18291,42 @@ var ast = _interopRequireWildcard(_ast); var _coverage = __webpack_require__(322); var coverage = _interopRequireWildcard(_coverage); var _projectTextSearch = __webpack_require__(37); var projectTextSearch = _interopRequireWildcard(_projectTextSearch); -var _sourceSearch = __webpack_require__(1143); +var _sourceSearch = __webpack_require__(1144); var sourceSearch = _interopRequireWildcard(_sourceSearch); +var _loadSourceText = __webpack_require__(1143); + +var loadSourceText = _interopRequireWildcard(_loadSourceText); + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } -exports.default = Object.assign({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, ast, coverage, projectTextSearch, sourceSearch); +exports.default = Object.assign({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, ast, coverage, projectTextSearch, sourceSearch, loadSourceText); /***/ }), /* 245 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Redux actions for breakpoints - * @module actions/breakpoints - */ - -// this will need to be changed so that addCLientBreakpoint is removed - exports.syncBreakpoint = syncBreakpoint; exports.addBreakpoint = addBreakpoint; exports.addHiddenBreakpoint = addHiddenBreakpoint; exports.removeBreakpoint = removeBreakpoint; exports.enableBreakpoint = enableBreakpoint; exports.disableBreakpoint = disableBreakpoint; exports.toggleAllBreakpoints = toggleAllBreakpoints; @@ -18289,101 +18353,111 @@ var _remapLocations = __webpack_require_ var _remapLocations2 = _interopRequireDefault(_remapLocations); var _syncBreakpoint = __webpack_require__(1137); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Redux actions for breakpoints + * @module actions/breakpoints + */ + +// this will need to be changed so that addCLientBreakpoint is removed + /** * Syncing a breakpoint add breakpoint information that is stored, and * contact the server for more data. * * @memberof actions/breakpoints * @static * @param {String} $1.sourceId String value * @param {PendingBreakpoint} $1.location PendingBreakpoint value */ -function syncBreakpoint(source, pendingBreakpoint) { - return (_ref) => { - var dispatch = _ref.dispatch, - getState = _ref.getState, - client = _ref.client, - sourceMaps = _ref.sourceMaps; - - var sourceId = source.id; - var _pendingBreakpoint$lo = pendingBreakpoint.location, - line = _pendingBreakpoint$lo.line, - sourceUrl = _pendingBreakpoint$lo.sourceUrl, - column = _pendingBreakpoint$lo.column; - - var location = { sourceId, sourceUrl, line, column }; - var breakpoint = (0, _breakpoint.createBreakpoint)(location, pendingBreakpoint); - - var syncPromise = (0, _syncBreakpoint.syncClientBreakpoint)(getState, client, sourceMaps, source, pendingBreakpoint); - - return dispatch({ - type: "SYNC_BREAKPOINT", - breakpoint, - [_promise.PROMISE]: syncPromise - }); - }; +function syncBreakpoint(sourceId, pendingBreakpoint) { + return (() => { + var _ref = _asyncToGenerator(function* (_ref2) { + var dispatch = _ref2.dispatch, + getState = _ref2.getState, + client = _ref2.client, + sourceMaps = _ref2.sourceMaps; + + var _ref3 = yield (0, _syncBreakpoint.syncClientBreakpoint)(getState, client, sourceMaps, sourceId, pendingBreakpoint), + breakpoint = _ref3.breakpoint, + previousLocation = _ref3.previousLocation; + + return dispatch({ + type: "SYNC_BREAKPOINT", + breakpoint, + previousLocation + }); + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; + })(); } /** * Add a new breakpoint * * @memberof actions/breakpoints * @static * @param {String} $1.condition Conditional breakpoint condition value * @param {Boolean} $1.disabled Disable value for breakpoint value */ function addBreakpoint(location, condition, hidden) { var breakpoint = (0, _breakpoint.createBreakpoint)(location, { condition, hidden }); - return (_ref2) => { - var dispatch = _ref2.dispatch, - getState = _ref2.getState, - sourceMaps = _ref2.sourceMaps, - client = _ref2.client; + return (_ref4) => { + var dispatch = _ref4.dispatch, + getState = _ref4.getState, + sourceMaps = _ref4.sourceMaps, + client = _ref4.client; var action = { type: "ADD_BREAKPOINT", breakpoint }; var promise = (0, _addBreakpoint2.default)(getState, client, sourceMaps, action); return dispatch(_extends({}, action, { [_promise.PROMISE]: promise })); }; } /** * Add a new hidden breakpoint * * @memberOf actions/breakpoints * @param location * @return {function(ThunkArgs)} */ function addHiddenBreakpoint(location) { - return (_ref3) => { - var dispatch = _ref3.dispatch; + return (_ref5) => { + var dispatch = _ref5.dispatch; return dispatch(addBreakpoint(location, "", true)); }; } /** * Remove a single breakpoint * * @memberof actions/breakpoints * @static */ function removeBreakpoint(location) { - return (_ref4) => { - var dispatch = _ref4.dispatch, - getState = _ref4.getState, - client = _ref4.client; + return (_ref6) => { + var dispatch = _ref6.dispatch, + getState = _ref6.getState, + client = _ref6.client; var bp = (0, _selectors.getBreakpoint)(getState(), location); if (!bp) { throw new Error("attempt to remove breakpoint that does not exist"); } if (bp.loading) { // TODO(jwl): make this wait until the breakpoint is saved if it @@ -18415,54 +18489,54 @@ function removeBreakpoint(location) { * will reuse the existing breakpoint information that is stored. * * @memberof actions/breakpoints * @static * @param {Location} $1.location Location value */ function enableBreakpoint(location) { return (() => { - var _ref5 = _asyncToGenerator(function* (_ref6) { - var dispatch = _ref6.dispatch, - getState = _ref6.getState, - client = _ref6.client, - sourceMaps = _ref6.sourceMaps; + var _ref7 = _asyncToGenerator(function* (_ref8) { + var dispatch = _ref8.dispatch, + getState = _ref8.getState, + client = _ref8.client, + sourceMaps = _ref8.sourceMaps; var breakpoint = (0, _selectors.getBreakpoint)(getState(), location); if (!breakpoint) { throw new Error("attempted to enable a breakpoint that does not exist"); } var action = { type: "ENABLE_BREAKPOINT", breakpoint }; var promise = (0, _addBreakpoint2.default)(getState, client, sourceMaps, action); return dispatch({ type: "ENABLE_BREAKPOINT", breakpoint, [_promise.PROMISE]: promise }); }); - return function (_x) { - return _ref5.apply(this, arguments); + return function (_x2) { + return _ref7.apply(this, arguments); }; })(); } /** * Disable a single breakpoint * * @memberof actions/breakpoints * @static */ function disableBreakpoint(location) { return (() => { - var _ref7 = _asyncToGenerator(function* (_ref8) { - var dispatch = _ref8.dispatch, - getState = _ref8.getState, - client = _ref8.client; + var _ref9 = _asyncToGenerator(function* (_ref10) { + var dispatch = _ref10.dispatch, + getState = _ref10.getState, + client = _ref10.client; var bp = (0, _selectors.getBreakpoint)(getState(), location); if (!bp) { throw new Error("attempt to disable a breakpoint that does not exist"); } if (bp.loading) { @@ -18475,156 +18549,156 @@ function disableBreakpoint(location) { var newBreakpoint = _extends({}, bp, { disabled: true }); return dispatch({ type: "DISABLE_BREAKPOINT", breakpoint: newBreakpoint }); }); - return function (_x2) { - return _ref7.apply(this, arguments); + return function (_x3) { + return _ref9.apply(this, arguments); }; })(); } /** * Toggle All Breakpoints * * @memberof actions/breakpoints * @static */ function toggleAllBreakpoints(shouldDisableBreakpoints) { return (() => { - var _ref9 = _asyncToGenerator(function* (_ref10) { - var dispatch = _ref10.dispatch, - getState = _ref10.getState; + var _ref11 = _asyncToGenerator(function* (_ref12) { + var dispatch = _ref12.dispatch, + getState = _ref12.getState; var breakpoints = (0, _selectors.getBreakpoints)(getState()); - for (var _ref11 of breakpoints) { - var _ref12 = _slicedToArray(_ref11, 2); - - var breakpoint = _ref12[1]; + for (var _ref13 of breakpoints) { + var _ref14 = _slicedToArray(_ref13, 2); + + var breakpoint = _ref14[1]; if (shouldDisableBreakpoints) { yield dispatch(disableBreakpoint(breakpoint.location)); } else { yield dispatch(enableBreakpoint(breakpoint.location)); } } }); - return function (_x3) { - return _ref9.apply(this, arguments); + return function (_x4) { + return _ref11.apply(this, arguments); }; })(); } /** * Toggle Breakpoints * * @memberof actions/breakpoints * @static */ function toggleBreakpoints(shouldDisableBreakpoints, breakpoints) { return (() => { - var _ref13 = _asyncToGenerator(function* (_ref14) { - var dispatch = _ref14.dispatch; - - for (var _ref15 of breakpoints) { - var _ref16 = _slicedToArray(_ref15, 2); - - var breakpoint = _ref16[1]; + var _ref15 = _asyncToGenerator(function* (_ref16) { + var dispatch = _ref16.dispatch; + + for (var _ref17 of breakpoints) { + var _ref18 = _slicedToArray(_ref17, 2); + + var breakpoint = _ref18[1]; if (shouldDisableBreakpoints) { yield dispatch(disableBreakpoint(breakpoint.location)); } else { yield dispatch(enableBreakpoint(breakpoint.location)); } } }); - return function (_x4) { - return _ref13.apply(this, arguments); + return function (_x5) { + return _ref15.apply(this, arguments); }; })(); } /** * Removes all breakpoints * * @memberof actions/breakpoints * @static */ function removeAllBreakpoints() { return (() => { - var _ref17 = _asyncToGenerator(function* (_ref18) { - var dispatch = _ref18.dispatch, - getState = _ref18.getState; + var _ref19 = _asyncToGenerator(function* (_ref20) { + var dispatch = _ref20.dispatch, + getState = _ref20.getState; var breakpoints = (0, _selectors.getBreakpoints)(getState()); - for (var _ref19 of breakpoints) { - var _ref20 = _slicedToArray(_ref19, 2); - - var breakpoint = _ref20[1]; + for (var _ref21 of breakpoints) { + var _ref22 = _slicedToArray(_ref21, 2); + + var breakpoint = _ref22[1]; yield dispatch(removeBreakpoint(breakpoint.location)); } }); - return function (_x5) { - return _ref17.apply(this, arguments); + return function (_x6) { + return _ref19.apply(this, arguments); }; })(); } /** * Removes breakpoints * * @memberof actions/breakpoints * @static */ function removeBreakpoints(breakpoints) { return (() => { - var _ref21 = _asyncToGenerator(function* (_ref22) { - var dispatch = _ref22.dispatch; - - for (var _ref23 of breakpoints) { - var _ref24 = _slicedToArray(_ref23, 2); - - var breakpoint = _ref24[1]; + var _ref23 = _asyncToGenerator(function* (_ref24) { + var dispatch = _ref24.dispatch; + + for (var _ref25 of breakpoints) { + var _ref26 = _slicedToArray(_ref25, 2); + + var breakpoint = _ref26[1]; yield dispatch(removeBreakpoint(breakpoint.location)); } }); - return function (_x6) { - return _ref21.apply(this, arguments); + return function (_x7) { + return _ref23.apply(this, arguments); }; })(); } function remapBreakpoints(sourceId) { return (() => { - var _ref25 = _asyncToGenerator(function* (_ref26) { - var dispatch = _ref26.dispatch, - getState = _ref26.getState, - sourceMaps = _ref26.sourceMaps; + var _ref27 = _asyncToGenerator(function* (_ref28) { + var dispatch = _ref28.dispatch, + getState = _ref28.getState, + sourceMaps = _ref28.sourceMaps; var breakpoints = (0, _selectors.getBreakpoints)(getState()); var newBreakpoints = yield (0, _remapLocations2.default)(breakpoints, sourceId, sourceMaps); return dispatch({ type: "REMAP_BREAKPOINTS", breakpoints: newBreakpoints }); }); - return function (_x7) { - return _ref25.apply(this, arguments); + return function (_x8) { + return _ref27.apply(this, arguments); }; })(); } /** * Update the condition of a breakpoint. * * @throws {Error} "not implemented" @@ -18632,25 +18706,25 @@ function remapBreakpoints(sourceId) { * @static * @param {Location} location * @see DebuggerController.Breakpoints.addBreakpoint * @param {string} condition * The condition to set on the breakpoint * @param {Boolean} $1.disabled Disable value for breakpoint value */ function setBreakpointCondition(location) { - var _ref27 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - condition = _ref27.condition; + var _ref29 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + condition = _ref29.condition; return (() => { - var _ref28 = _asyncToGenerator(function* (_ref29) { - var dispatch = _ref29.dispatch, - getState = _ref29.getState, - client = _ref29.client, - sourceMaps = _ref29.sourceMaps; + var _ref30 = _asyncToGenerator(function* (_ref31) { + var dispatch = _ref31.dispatch, + getState = _ref31.getState, + client = _ref31.client, + sourceMaps = _ref31.sourceMaps; var bp = (0, _selectors.getBreakpoint)(getState(), location); if (!bp) { return dispatch(addBreakpoint(location, condition)); } if (bp.loading) { // TODO(jwl): when this function is called, make sure the action @@ -18670,28 +18744,28 @@ function setBreakpointCondition(location (0, _breakpoint.assertBreakpoint)(newBreakpoint); return dispatch({ type: "SET_BREAKPOINT_CONDITION", breakpoint: newBreakpoint }); }); - return function (_x9) { - return _ref28.apply(this, arguments); + return function (_x10) { + return _ref30.apply(this, arguments); }; })(); } function toggleBreakpoint(line, column) { - return (_ref30) => { - var dispatch = _ref30.dispatch, - getState = _ref30.getState, - client = _ref30.client, - sourceMaps = _ref30.sourceMaps; + return (_ref32) => { + var dispatch = _ref32.dispatch, + getState = _ref32.getState, + client = _ref32.client, + sourceMaps = _ref32.sourceMaps; var selectedSource = (0, _selectors.getSelectedSource)(getState()); var bp = (0, _selectors.getBreakpointAtLocation)(getState(), { line, column }); if (bp && bp.loading) { return; } @@ -18710,21 +18784,21 @@ function toggleBreakpoint(line, column) sourceUrl: selectedSource.get("url"), line: line, column: column })); }; } function addOrToggleDisabledBreakpoint(line, column) { - return (_ref31) => { - var dispatch = _ref31.dispatch, - getState = _ref31.getState, - client = _ref31.client, - sourceMaps = _ref31.sourceMaps; + return (_ref33) => { + var dispatch = _ref33.dispatch, + getState = _ref33.getState, + client = _ref33.client, + sourceMaps = _ref33.sourceMaps; var selectedSource = (0, _selectors.getSelectedSource)(getState()); var bp = (0, _selectors.getBreakpointAtLocation)(getState(), { line, column }); if (bp && bp.loading) { return; } @@ -18738,21 +18812,21 @@ function addOrToggleDisabledBreakpoint(l sourceUrl: selectedSource.get("url"), line: line, column: column })); }; } function toggleDisabledBreakpoint(line, column) { - return (_ref32) => { - var dispatch = _ref32.dispatch, - getState = _ref32.getState, - client = _ref32.client, - sourceMaps = _ref32.sourceMaps; + return (_ref34) => { + var dispatch = _ref34.dispatch, + getState = _ref34.getState, + client = _ref34.client, + sourceMaps = _ref34.sourceMaps; var bp = (0, _selectors.getBreakpointAtLocation)(getState(), { line, column }); if (bp && bp.loading) { return; } if (!bp) { throw new Error("attempt to disable breakpoint that does not exist"); @@ -19492,32 +19566,34 @@ var checkSelectedSource = (() => { var checkPendingBreakpoint = (() => { var _ref2 = _asyncToGenerator(function* (state, dispatch, pendingBreakpoint, source) { var sourceUrl = pendingBreakpoint.location.sourceUrl; var sameSource = sourceUrl && sourceUrl === source.url; if (sameSource) { - yield dispatch((0, _breakpoints.syncBreakpoint)(source, pendingBreakpoint)); + yield dispatch((0, _breakpoints.syncBreakpoint)(source.id, pendingBreakpoint)); } }); return function checkPendingBreakpoint(_x4, _x5, _x6, _x7) { return _ref2.apply(this, arguments); }; })(); var checkPendingBreakpoints = (() => { var _ref3 = _asyncToGenerator(function* (state, dispatch, source) { - var pendingBreakpoints = (0, _selectors.getPendingBreakpoints)(state); - if (!pendingBreakpoints) { - return; - } - + var pendingBreakpoints = (0, _selectors.getPendingBreakpointsForSource)(state, source.url); + if (!pendingBreakpoints.size) { + return; + } + + // load the source text if there is a pending breakpoint for it + yield dispatch((0, _loadSourceText.loadSourceText)(source)); var pendingBreakpointsArray = pendingBreakpoints.valueSeq().toJS(); for (var pendingBreakpoint of pendingBreakpointsArray) { yield checkPendingBreakpoint(state, dispatch, pendingBreakpoint, source); } }); return function checkPendingBreakpoints(_x8, _x9, _x10) { return _ref3.apply(this, arguments); @@ -19537,35 +19613,38 @@ exports.selectSourceURL = selectSourceUR exports.selectSource = selectSource; exports.jumpToMappedLocation = jumpToMappedLocation; exports.addTab = addTab; exports.moveTab = moveTab; exports.closeTab = closeTab; exports.closeTabs = closeTabs; exports.togglePrettyPrint = togglePrettyPrint; exports.toggleBlackBox = toggleBlackBox; -exports.loadSourceText = loadSourceText; exports.loadAllSources = loadAllSources; var _promise = __webpack_require__(193); var _assert = __webpack_require__(223); var _assert2 = _interopRequireDefault(_assert); var _breakpoints = __webpack_require__(245); var _ast = __webpack_require__(1059); var _projectTextSearch = __webpack_require__(37); +var _ui = __webpack_require__(321); + var _source = __webpack_require__(233); var _createPrettySource = __webpack_require__(195); +var _loadSourceText = __webpack_require__(1143); + var _prefs = __webpack_require__(226); var _editor = __webpack_require__(257); var _selectors = __webpack_require__(242); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -19718,30 +19797,30 @@ function selectSource(id) { } var source = (0, _selectors.getSource)(getState(), id); if (!source) { // If there is no source we deselect the current selected source return dispatch({ type: "CLEAR_SELECTED_SOURCE" }); } - var activeSearch = (0, _selectors.getActiveSearchState)(getState()); + var activeSearch = (0, _selectors.getActiveSearch)(getState()); if (activeSearch !== "file") { - dispatch({ type: "TOGGLE_ACTIVE_SEARCH", value: null }); + dispatch((0, _ui.closeActiveSearch)()); } dispatch(addTab(source.toJS(), 0)); return dispatch({ type: "SELECT_SOURCE", source: source.toJS(), tabIndex: options.tabIndex, line: options.line, [_promise.PROMISE]: _asyncToGenerator(function* () { - yield dispatch(loadSourceText(source.toJS())); + yield dispatch((0, _loadSourceText.loadSourceText)(source.toJS())); yield dispatch((0, _ast.setOutOfScopeLocations)()); })() }); }; } /** * @memberof actions/sources @@ -19913,90 +19992,45 @@ function toggleBlackBox(source) { return function (_x19) { return _ref21.apply(this, arguments); }; })(); } /** - * @memberof actions/sources - * @static - */ -function loadSourceText(source) { - return (() => { - var _ref23 = _asyncToGenerator(function* (_ref24) { - var dispatch = _ref24.dispatch, - getState = _ref24.getState, - client = _ref24.client, - sourceMaps = _ref24.sourceMaps; - - // Fetch the source text only once. - if (source.text) { - return Promise.resolve(source); - } - - yield dispatch({ - type: "LOAD_SOURCE_TEXT", - source: source, - [_promise.PROMISE]: _asyncToGenerator(function* () { - if (sourceMaps.isOriginalId(source.id)) { - return yield sourceMaps.getOriginalSourceText(source); - } - - var response = yield client.sourceContents(source.id); - - return { - id: source.id, - text: response.source, - contentType: response.contentType || "text/javascript" - }; - })() - }); - - yield dispatch((0, _ast.setSymbols)(source.id)); - yield dispatch((0, _ast.setEmptyLines)(source.id)); - }); - - return function (_x20) { - return _ref23.apply(this, arguments); - }; - })(); -} - -/** Load the text for all the avaliable sources * @memberof actions/sources * @static */ function loadAllSources() { return (() => { - var _ref26 = _asyncToGenerator(function* (_ref27) { - var dispatch = _ref27.dispatch, - getState = _ref27.getState; + var _ref23 = _asyncToGenerator(function* (_ref24) { + var dispatch = _ref24.dispatch, + getState = _ref24.getState; var sources = (0, _selectors.getSources)(getState()); var query = (0, _selectors.getTextSearchQuery)(getState()); - for (var _ref28 of sources) { - var _ref29 = _slicedToArray(_ref28, 2); - - var src = _ref29[1]; + for (var _ref25 of sources) { + var _ref26 = _slicedToArray(_ref25, 2); + + var src = _ref26[1]; var source = src.toJS(); - yield dispatch(loadSourceText(source)); + yield dispatch((0, _loadSourceText.loadSourceText)(source)); // If there is a current search query we search // each of the source texts as they get loaded if (query) { yield dispatch((0, _projectTextSearch.searchSource)(source, query)); } } }); - return function (_x21) { - return _ref26.apply(this, arguments); + return function (_x20) { + return _ref23.apply(this, arguments); }; })(); } /***/ }), /* 255 */ /***/ (function(module, exports, __webpack_require__) { @@ -20459,51 +20493,39 @@ function isWhitespace(query) { * Also the token function code is mainly based of work done * by the chrome devtools team. Thanks guys! :) * * @memberof utils/source-search * @static */ function searchOverlay(query, modifiers) { var regexQuery = (0, _buildQuery2.default)(query, modifiers, { - ignoreSpaces: true - }); - - var matchLength = null; - - return { - token: function (stream) { - if (stream.column() === 0) { - matchLength = null; - } - if (matchLength !== null) { - if (matchLength > 2) { - for (var i = 0; i < matchLength - 2; ++i) { - stream.next(); - } - matchLength = 1; - return "highlight"; - } - stream.next(); - matchLength = null; - return "highlight highlight-end"; - } - - var match = stream.match(regexQuery, false); - if (match) { - stream.next(); - var len = match[0].length; - if (len === 1) { - return "highlight highlight-full"; - } - matchLength = len; - return "highlight highlight-start"; - } - while (!stream.match(regexQuery, false) && stream.peek()) { - stream.next(); + ignoreSpaces: true, + // regex must be global for the overlay + isGlobal: true + }); + + return { + token: function (stream, state) { + // set the last index to be the current stream position + // this acts as an offset + regexQuery.lastIndex = stream.pos; + var match = regexQuery.exec(stream.string); + if (match && match.index === stream.pos) { + // if we have a match at the current stream position + // set the class for a match + stream.pos += match[0].length || 1; + return "highlight highlight-full"; + } else if (match) { + // if we have a match somewhere in the line, go to that point in the + // stream + stream.pos = match.index; + } else { + // if we have no matches in this line, skip to the end of the line + stream.skipToEnd(); } } }; } /** * @memberof utils/source-search * @static @@ -20553,16 +20575,17 @@ function doSearch(ctx, rev, query, keepS if (!cm) { return; } var defaultIndex = { line: -1, ch: -1 }; return cm.operation(function () { if (!query || isWhitespace(query)) { + clearSearch(cm, query, modifiers); return; } var state = getSearchState(cm, query, modifiers); var isNewQuery = state.query !== query; state.query = query; updateOverlay(cm, state, query, modifiers); @@ -21413,46 +21436,49 @@ function pauseOnExceptions(shouldPauseOn /** * Debugger commands like stepOver, stepIn, stepUp * * @param string $0.type * @memberof actions/pause * @static */ -function command(_ref5) { - var type = _ref5.type; - - return (_ref6) => { - var dispatch = _ref6.dispatch, - client = _ref6.client; - - // execute debugger thread command e.g. stepIn, stepOver - client[type]().then(() => dispatch({ type: "CLEAR_COMMAND" })); - - return dispatch({ - type: "COMMAND", - value: { type } - }); - }; +function command(type) { + return (() => { + var _ref5 = _asyncToGenerator(function* (_ref6) { + var dispatch = _ref6.dispatch, + client = _ref6.client; + + // execute debugger thread command e.g. stepIn, stepOver + dispatch({ type: "COMMAND", value: { type } }); + + yield client[type](); + + dispatch({ type: "CLEAR_COMMAND" }); + }); + + return function (_x2) { + return _ref5.apply(this, arguments); + }; + })(); } /** * StepIn * @memberof actions/pause * @static * @returns {Function} {@link command} */ function stepIn() { return (_ref7) => { var dispatch = _ref7.dispatch, getState = _ref7.getState; if ((0, _selectors.getPause)(getState())) { - return dispatch(astCommand("stepIn")); + return dispatch(command("stepIn")); } }; } /** * stepOver * @memberof actions/pause * @static @@ -21476,34 +21502,34 @@ function stepOver() { * @returns {Function} {@link command} */ function stepOut() { return (_ref9) => { var dispatch = _ref9.dispatch, getState = _ref9.getState; if ((0, _selectors.getPause)(getState())) { - return dispatch(astCommand("stepOut")); + return dispatch(command("stepOut")); } }; } /** * resume * @memberof actions/pause * @static * @returns {Function} {@link command} */ function resume() { return (_ref10) => { var dispatch = _ref10.dispatch, getState = _ref10.getState; if ((0, _selectors.getPause)(getState())) { - return dispatch(command({ type: "resume" })); + return dispatch(command("resume")); } }; } /** * Debugger breakOnNext command. * It's different from the comand action because we also want to * highlight the pause icon. @@ -21542,17 +21568,17 @@ function selectFrame(frame) { dispatch({ type: "SELECT_FRAME", frame, scopes }); }); - return function (_x2) { + return function (_x3) { return _ref12.apply(this, arguments); }; })(); } /** * @memberof actions/pause * @static @@ -21586,38 +21612,41 @@ function loadObjectProperties(object) { function astCommand(stepType) { return (() => { var _ref15 = _asyncToGenerator(function* (_ref16) { var dispatch = _ref16.dispatch, getState = _ref16.getState, sourceMaps = _ref16.sourceMaps; if (!_prefs.features.asyncStepping) { - return dispatch(command({ type: stepType })); + return dispatch(command(stepType)); } var pauseInfo = (0, _selectors.getPause)(getState()); var source = (0, _selectors.getSelectedSource)(getState()).toJS(); var currentHiddenBreakpointLocation = (0, _breakpoints2.getHiddenBreakpointLocation)(getState()); + if (currentHiddenBreakpointLocation) { dispatch((0, _breakpoints.removeBreakpoint)(currentHiddenBreakpointLocation)); } + var pausedPosition = yield (0, _pause.getPausedPosition)(pauseInfo, sourceMaps); - var _ref17 = yield parser.getNextStep(source, stepType, pausedPosition), - nextStepType = _ref17.nextStepType, - nextHiddenBreakpointLocation = _ref17.nextHiddenBreakpointLocation; - - if (nextHiddenBreakpointLocation) { - yield dispatch((0, _breakpoints.addHiddenBreakpoint)(nextHiddenBreakpointLocation)); - } - return dispatch(command({ type: nextStepType })); - }); - - return function (_x3) { + if (stepType == "stepOver") { + var nextLocation = yield parser.getNextStep(source, pausedPosition); + if (nextLocation) { + yield dispatch((0, _breakpoints.addHiddenBreakpoint)(nextLocation)); + return dispatch(command("resume")); + } + } + + return dispatch(command(stepType)); + }); + + return function (_x4) { return _ref15.apply(this, arguments); }; })(); } /***/ }), /* 320 */ /***/ (function(module, exports, __webpack_require__) { @@ -21663,16 +21692,17 @@ function willNavigate(_, event) { getState = _ref2.getState, client = _ref2.client, sourceMaps = _ref2.sourceMaps; yield sourceMaps.clearSourceMaps(); (0, _wasm.clearWasmStates)(); (0, _editor.clearDocuments)(); (0, _parser.clearSymbols)(); + (0, _parser.clearASTs)(); dispatch(navigate(event.url)); }); return function (_x) { return _ref.apply(this, arguments); }; })(); @@ -21735,55 +21765,69 @@ exports.updateSearchResults = updateSear exports.toggleFileSearchModifier = toggleFileSearchModifier; exports.showSource = showSource; exports.togglePaneCollapse = togglePaneCollapse; exports.highlightLineRange = highlightLineRange; exports.clearHighlightLineRange = clearHighlightLineRange; var _selectors = __webpack_require__(242); +var _sourceSearch = __webpack_require__(1144); + function closeActiveSearch() { - return { - type: "TOGGLE_ACTIVE_SEARCH", - value: null - }; -} + return (_ref) => { + var getState = _ref.getState, + dispatch = _ref.dispatch; + + var activeSearch = (0, _selectors.getActiveSearch)(getState()); + + if (activeSearch == "source") { + dispatch((0, _sourceSearch.clearSourceSearchQuery)()); + } + + dispatch({ + type: "TOGGLE_ACTIVE_SEARCH", + value: null + }); + }; +} + function setActiveSearch(activeSearch) { - return (_ref) => { - var dispatch = _ref.dispatch, - getState = _ref.getState; - - var activeSearchState = (0, _selectors.getActiveSearchState)(getState()); + return (_ref2) => { + var dispatch = _ref2.dispatch, + getState = _ref2.getState; + + var activeSearchState = (0, _selectors.getActiveSearch)(getState()); if (activeSearchState === activeSearch) { return; } dispatch({ type: "TOGGLE_ACTIVE_SEARCH", value: activeSearch }); }; } function toggleFrameworkGrouping(toggleValue) { - return (_ref2) => { - var dispatch = _ref2.dispatch, - getState = _ref2.getState; + return (_ref3) => { + var dispatch = _ref3.dispatch, + getState = _ref3.getState; dispatch({ type: "TOGGLE_FRAMEWORK_GROUPING", value: toggleValue }); }; } function setSelectedSymbolType(symbolType) { - return (_ref3) => { - var dispatch = _ref3.dispatch, - getState = _ref3.getState; + return (_ref4) => { + var dispatch = _ref4.dispatch, + getState = _ref4.getState; dispatch({ type: "SET_SYMBOL_SEARCH_TYPE", symbolType }); }; } @@ -21801,19 +21845,19 @@ function updateSearchResults(results) { }; } function toggleFileSearchModifier(modifier) { return { type: "TOGGLE_FILE_SEARCH_MODIFIER", modifier }; } function showSource(sourceId) { - return (_ref4) => { - var dispatch = _ref4.dispatch, - getState = _ref4.getState; + return (_ref5) => { + var dispatch = _ref5.dispatch, + getState = _ref5.getState; var source = (0, _selectors.getSource)(getState(), sourceId); dispatch({ type: "SHOW_SOURCE", sourceUrl: "" }); @@ -24364,19 +24408,19 @@ var isMacOS = appinfo.OS === "Darwin"; * * For Win/Lin this replaces CommandOrControl or CmdOrCtrl with Ctrl * * @memberof utils/text * @static */ function formatKeyShortcut(shortcut) { if (isMacOS) { - return shortcut.replace(/Shift\+/g, "\u21E7+").replace(/Command\+|Cmd\+/g, "\u2318+").replace(/CommandOrControl\+|CmdOrCtrl\+/g, "\u2318+").replace(/Alt\+/g, "\u2325+"); - } - return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, `${L10N.getStr("ctrl")}+`); + return shortcut.replace(/Shift\+/g, "\u21E7 ").replace(/Command\+|Cmd\+/g, "\u2318 ").replace(/CommandOrControl\+|CmdOrCtrl\+/g, "\u2318 ").replace(/Alt\+/g, "\u2325 "); + } + return shortcut.replace(/CommandOrControl\+|CmdOrCtrl\+/g, `${L10N.getStr("ctrl")} `).replace(/Shift\+/g, "Shift "); } exports.formatKeyShortcut = formatKeyShortcut; /***/ }), /* 390 */, /* 391 */, /* 392 */, @@ -24450,16 +24494,20 @@ class ManagedTree extends _react.Compone if (listItems && listItems != this.props.listItems && listItems.length) { this.expandListItems(listItems); } var highlightItems = nextProps.highlightItems; if (highlightItems && highlightItems != this.props.highlightItems && highlightItems.length) { this.highlightItem(highlightItems); } + + if (nextProps.focused && nextProps.focused !== this.props.focused) { + this.focusItem(nextProps.focused); + } } setExpanded(item, isExpanded) { var expanded = this.state.expanded; var itemPath = this.props.getPath(item); if (isExpanded) { expanded.add(itemPath); } else { @@ -24473,17 +24521,17 @@ class ManagedTree extends _react.Compone this.props.onCollapse(item); } } expandListItems(listItems) { var expanded = this.state.expanded; listItems.forEach(item => expanded.add(this.props.getPath(item))); this.focusItem(listItems[0]); - this.setState({ expanded: expanded }); + this.setState({ expanded }); } highlightItem(highlightItems) { var expanded = this.state.expanded; // This file is visible, so we highlight it. if (expanded.has(this.props.getPath(highlightItems[0]))) { this.focusItem(highlightItems[0]); @@ -24662,17 +24710,17 @@ var _HitMarker2 = _interopRequireDefault var _CallSites = __webpack_require__(1159); var _CallSites2 = _interopRequireDefault(_CallSites); var _DebugLine = __webpack_require__(313); var _DebugLine2 = _interopRequireDefault(_DebugLine); -var _EmptyLines = __webpack_require__(1144); +var _EmptyLines = __webpack_require__(1146); var _EmptyLines2 = _interopRequireDefault(_EmptyLines); var _editor = __webpack_require__(257); __webpack_require__(905); __webpack_require__(906); @@ -25341,17 +25389,17 @@ exports.default = (0, _reactRedux.connec var selectedLocation = (0, _selectors.getSelectedLocation)(state); var sourceId = selectedLocation && selectedLocation.sourceId; var selectedSource = (0, _selectors.getSelectedSource)(state); return { selectedLocation, selectedSource, highlightedLineRange: (0, _selectors.getHighlightedLineRange)(state), - searchOn: (0, _selectors.getActiveSearchState)(state) === "file", + searchOn: (0, _selectors.getActiveSearch)(state) === "file", loadedObjects: (0, _selectors.getLoadedObjects)(state), breakpoints: (0, _selectors.getVisibleBreakpoints)(state), hitCount: (0, _selectors.getHitCountForSource)(state, sourceId), selectedFrame: (0, _selectors.getSelectedFrame)(state), pauseData: (0, _selectors.getPause)(state), coverageOn: (0, _selectors.getCoverageEnabled)(state), query: (0, _selectors.getFileSearchQueryState)(state), searchModifiers: (0, _selectors.getFileSearchModifierState)(state), @@ -25494,19 +25542,19 @@ class SourceFooter extends _react.PureCo if (!(0, _devtoolsConfig.isEnabled)("codeCoverage")) { return; } return _react2.default.createElement( "button", { className: "coverage action", - title: "Code Coverage", + title: L10N.getStr("sourceFooter.codeCoverage"), onClick: () => recordCoverage(), - "aria-label": "Code Coverage" + "aria-label": L10N.getStr("sourceFooter.codeCoverage") }, "C" ); } renderToggleButton() { if (this.props.horizontal) { return; @@ -25668,18 +25716,16 @@ var _actions = __webpack_require__(244); var _actions2 = _interopRequireDefault(_actions); var _selectors = __webpack_require__(242); var _editor = __webpack_require__(257); var _search = __webpack_require__(1115); -var _source = __webpack_require__(233); - var _resultList = __webpack_require__(343); var _classnames = __webpack_require__(175); var _classnames2 = _interopRequireDefault(_classnames); var _lodash = __webpack_require__(2); @@ -25765,65 +25811,48 @@ class SearchBar extends _react.Component shortcuts.on("Escape", (_, e) => this.onEscape(e)); shortcuts.on(shiftSearchAgainShortcut, (_, e) => this.traverseResults(e, true)); shortcuts.on(searchAgainShortcut, (_, e) => this.traverseResults(e, false)); } componentDidUpdate(prevProps, prevState) { - var _props = this.props, - selectedSource = _props.selectedSource, - query = _props.query, - modifiers = _props.modifiers, - searchOn = _props.searchOn; - var searchInput = this.searchInput(); if (searchInput) { searchInput.focus(); } if (this.refs.resultList && this.refs.resultList.refs) { (0, _resultList.scrollList)(this.refs.resultList.refs, this.state.selectedResultIndex); } - - var hasLoaded = selectedSource && (0, _source.isLoaded)(selectedSource.toJS()); - var wasLoading = prevProps.selectedSource && (0, _source.isLoaded)(prevProps.selectedSource.toJS()); - - var doneLoading = wasLoading && hasLoaded; - var changedFiles = selectedSource != prevProps.selectedSource && hasLoaded; - var modifiersUpdated = modifiers && !modifiers.equals(prevProps.modifiers); - - if (searchOn && (doneLoading || changedFiles || modifiersUpdated)) { - this.doSearch(query); - } } onEscape(e) { this.closeSearch(e); } clearSearch() { - var _props2 = this.props, - ed = _props2.editor, - query = _props2.query, - modifiers = _props2.modifiers; + var _props = this.props, + ed = _props.editor, + query = _props.query, + modifiers = _props.modifiers; if (ed && modifiers) { var ctx = { ed, cm: ed.codeMirror }; (0, _editor.removeOverlay)(ctx, query, modifiers.toJS()); } } closeSearch(e) { - var _props3 = this.props, - editor = _props3.editor, - setFileSearchQuery = _props3.setFileSearchQuery, - searchOn = _props3.searchOn; + var _props2 = this.props, + editor = _props2.editor, + setFileSearchQuery = _props2.setFileSearchQuery, + searchOn = _props2.searchOn; if (editor && searchOn) { setFileSearchQuery(""); this.clearSearch(); this.props.setActiveSearch(); this.props.clearHighlightLineRange(); e.stopPropagation(); @@ -25875,19 +25904,19 @@ class SearchBar extends _react.Component if (input instanceof HTMLInputElement) { return input; } } return null; } doSearch(query) { - var _props4 = this.props, - selectedSource = _props4.selectedSource, - setFileSearchQuery = _props4.setFileSearchQuery; + var _props3 = this.props, + selectedSource = _props3.selectedSource, + setFileSearchQuery = _props3.setFileSearchQuery; if (!selectedSource || !selectedSource.get("text")) { return; } setFileSearchQuery(query); this.searchContents(query); @@ -25902,20 +25931,20 @@ class SearchBar extends _react.Component index: characterIndex }); } searchContents(query) { var _this = this; return _asyncToGenerator(function* () { - var _props5 = _this.props, - selectedSource = _props5.selectedSource, - modifiers = _props5.modifiers, - ed = _props5.editor; + var _props4 = _this.props, + selectedSource = _props4.selectedSource, + modifiers = _props4.modifiers, + ed = _props4.editor; if (!query || !ed || !selectedSource || !selectedSource.get("text") || !modifiers) { return; } var ctx = { ed, cm: ed.codeMirror }; @@ -25936,20 +25965,20 @@ class SearchBar extends _react.Component var ed = this.props.editor; if (!ed) { return; } var ctx = { ed, cm: ed.codeMirror }; - var _props6 = this.props, - query = _props6.query, - modifiers = _props6.modifiers, - matches = _props6.searchResults.matches; + var _props5 = this.props, + query = _props5.query, + modifiers = _props5.modifiers, + matches = _props5.searchResults.matches; if (query === "") { this.props.setActiveSearch("file"); } if (modifiers) { var matchedLocations = matches || []; @@ -25973,22 +26002,22 @@ class SearchBar extends _react.Component return; } this.traverseResults(e, e.shiftKey); e.preventDefault(); } // Renderers buildSummaryMsg() { - var _props7 = this.props, - _props7$searchResults = _props7.searchResults, - matchIndex = _props7$searchResults.matchIndex, - count = _props7$searchResults.count, - index = _props7$searchResults.index, - query = _props7.query; + var _props6 = this.props, + _props6$searchResults = _props6.searchResults, + matchIndex = _props6$searchResults.matchIndex, + count = _props6$searchResults.count, + index = _props6$searchResults.index, + query = _props6.query; if (query.trim() == "") { return ""; } if (count == 0) { return L10N.getStr("editor.noResults"); @@ -25997,19 +26026,19 @@ class SearchBar extends _react.Component if (index == -1) { return L10N.getFormatStr("sourceSearch.resultsSummary1", count); } return L10N.getFormatStr("editor.searchResults", matchIndex + 1, count); } renderSearchModifiers() { - var _props8 = this.props, - modifiers = _props8.modifiers, - toggleFileSearchModifier = _props8.toggleFileSearchModifier; + var _props7 = this.props, + modifiers = _props7.modifiers, + toggleFileSearchModifier = _props7.toggleFileSearchModifier; function SearchModBtn(_ref2) { var modVal = _ref2.modVal, className = _ref2.className, svgName = _ref2.svgName, tooltip = _ref2.tooltip; @@ -26067,20 +26096,20 @@ class SearchBar extends _react.Component onClick: () => this.props.setActiveSearch("symbol") }, L10N.getStr("symbolSearch.search.functionsPlaceholder") ) ); } render() { - var _props9 = this.props, - count = _props9.searchResults.count, - query = _props9.query, - searchOn = _props9.searchOn; + var _props8 = this.props, + count = _props8.searchResults.count, + query = _props8.query, + searchOn = _props8.searchOn; if (!searchOn) { return _react2.default.createElement("div", null); } return _react2.default.createElement( "div", @@ -26108,17 +26137,17 @@ class SearchBar extends _react.Component SearchBar.displayName = "SearchBar"; SearchBar.contextTypes = { shortcuts: _react.PropTypes.object }; exports.default = (0, _reactRedux.connect)(state => { return { - searchOn: (0, _selectors.getActiveSearchState)(state) === "file", + searchOn: (0, _selectors.getActiveSearch)(state) === "file", query: (0, _selectors.getFileSearchQueryState)(state), modifiers: (0, _selectors.getFileSearchModifierState)(state), searchResults: (0, _selectors.getSearchResults)(state) }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SearchBar); /***/ }), /* 434 */, @@ -26711,22 +26740,23 @@ function getMenuItems(event, _ref) { var copySourceUrl = { id: "node-menu-copy-source-url", label: copySourceUrlLabel, accesskey: copySourceUrlKey, disabled: false, click: () => (0, _clipboard.copyToTheClipboard)(selectedSource.get("url")) }; + var selectionText = codeMirror.getSelection().trim(); var copySource = { id: "node-menu-copy-source", label: copySourceLabel, accesskey: copySourceKey, - disabled: false, - click: () => (0, _clipboard.copyToTheClipboard)(codeMirror.getSelection()) + disabled: selectionText.length === 0, + click: () => (0, _clipboard.copyToTheClipboard)(selectionText) }; var _codeMirror$coordsCha = codeMirror.coordsChar({ left: event.clientX, top: event.clientY }), line = _codeMirror$coordsCha.line, ch = _codeMirror$coordsCha.ch; @@ -26766,20 +26796,16 @@ function getMenuItems(event, _ref) { var showSourceMenuItem = { id: "node-menu-show-source", label: revealInTreeLabel, accesskey: revealInTreeKey, disabled: false, click: () => showSource(selectedSource.get("id")) }; - if (selectedSource && selectedSource.get("isBlackBoxed")) { - return [blackBoxMenuItem]; - } - var menuItems = [copySource, copySourceUrl, jumpLabel, showSourceMenuItem, blackBoxMenuItem]; if (textSelected) { menuItems.push(watchExpressionLabel); } return menuItems; } @@ -27404,17 +27430,17 @@ var _devtoolsSplitter2 = _interopRequire var _Frames = __webpack_require__(1012); var _Frames2 = _interopRequireDefault(_Frames); var _EventListeners = __webpack_require__(736); var _EventListeners2 = _interopRequireDefault(_EventListeners); -var _Workers = __webpack_require__(1147); +var _Workers = __webpack_require__(1149); var _Workers2 = _interopRequireDefault(_Workers); var _Accordion = __webpack_require__(739); var _Accordion2 = _interopRequireDefault(_Accordion); var _CommandBar = __webpack_require__(742); @@ -28240,16 +28266,18 @@ exports.default = (0, _reactRedux.connec Object.defineProperty(exports, "__esModule", { value: true }); var _react = __webpack_require__(0); +var _react2 = _interopRequireDefault(_react); + var _reactImmutableProptypes = __webpack_require__(150); var _reactImmutableProptypes2 = _interopRequireDefault(_reactImmutableProptypes); var _redux = __webpack_require__(3); var _reactRedux = __webpack_require__(151); @@ -28334,48 +28362,48 @@ class Scopes extends _react.Component { } renderItem(item, depth, focused, _, expanded, _ref) { var setExpanded = _ref.setExpanded; var notEnumberable = false; var objectValue = ""; - return React.createElement( + return _react2.default.createElement( "div", { className: (0, _classnames2.default)("node object-node", { focused: false, "not-enumerable": notEnumberable }), style: { marginLeft: depth * 15 }, key: item.path, onClick: e => { e.stopPropagation(); setExpanded(item, !expanded); } }, - React.createElement(_Svg2.default, { + _react2.default.createElement(_Svg2.default, { name: "arrow", className: (0, _classnames2.default)({ expanded, hidden: nodeIsPrimitive(item) }) }), - React.createElement( + _react2.default.createElement( "span", { className: "object-label" }, item.name ), - React.createElement( + _react2.default.createElement( "span", { className: "object-delimiter" }, objectValue ? ": " : "" ), - React.createElement( + _react2.default.createElement( "span", { className: "object-value" }, objectValue || "" ) ); } getObjectProperties(item) { @@ -28435,33 +28463,33 @@ class Scopes extends _react.Component { }); } render() { var pauseInfo = this.props.pauseInfo; if (!pauseInfo) { - return React.createElement( + return _react2.default.createElement( "div", { className: (0, _classnames2.default)("pane", "scopes-list") }, - React.createElement( + _react2.default.createElement( "div", { className: "pane-info" }, L10N.getStr("scopes.notPaused") ) ); } var roots = this.getRoots(); - return React.createElement( + return _react2.default.createElement( "div", { className: (0, _classnames2.default)("pane", "scopes-list") }, - React.createElement(_ManagedTree2.default, { + _react2.default.createElement(_ManagedTree2.default, { itemHeight: 20, getParent: item => null, getChildren: this.getChildren, getRoots: () => roots, getPath: item => item.path, autoExpand: 0, autoExpandDepth: 1, autoExpandAll: false, @@ -29265,19 +29293,16 @@ var _text = __webpack_require__(389); var _PaneToggle = __webpack_require__(428); var _PaneToggle2 = _interopRequireDefault(_PaneToggle); __webpack_require__(922); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _require = __webpack_require__(828), - isEnabled = _require.isEnabled; - class WelcomeBox extends _react.Component { renderToggleButton() { var _props = this.props, horizontal = _props.horizontal, endPanelCollapsed = _props.endPanelCollapsed, togglePaneCollapse = _props.togglePaneCollapse; @@ -29289,53 +29314,69 @@ class WelcomeBox extends _react.Componen position: "end", collapsed: !endPanelCollapsed, horizontal: horizontal, handleClick: togglePaneCollapse }); } render() { - var keyCombinationOne = (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2")); - - var keyCombinationTwo = (0, _text.formatKeyShortcut)(L10N.getStr("projectTextSearch.key")); + var searchSourcesShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2")); + + var searchProjectShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("projectTextSearch.key")); + var searchFunctionsShortcut = (0, _text.formatKeyShortcut)(L10N.getStr("functionSearch.key")); var searchSourcesLabel = L10N.getStr("welcome.search").substring(2); var searchProjectLabel = L10N.getStr("welcome.findInFiles").substring(2); - - var searchProjectLabelComp = _react2.default.createElement( - "div", - null, - _react2.default.createElement( - "b", - null, - keyCombinationTwo - ), - searchProjectLabel - ); - - var searchSourcesLabelComp = _react2.default.createElement( - "div", - null, - _react2.default.createElement( - "b", - null, - keyCombinationOne - ), - searchSourcesLabel - ); + var searchFunctionLabel = L10N.getStr("welcome.searchFunction").substring(2); return _react2.default.createElement( "div", { className: "welcomebox" }, _react2.default.createElement( "div", { className: "alignlabel" }, - searchSourcesLabelComp, - isEnabled("searchNav") ? searchProjectLabelComp : null, + _react2.default.createElement( + "div", + { className: "shortcutKeys" }, + _react2.default.createElement( + "p", + null, + searchSourcesShortcut + ), + _react2.default.createElement( + "p", + null, + searchProjectShortcut + ), + _react2.default.createElement( + "p", + null, + searchFunctionsShortcut + ) + ), + _react2.default.createElement( + "div", + { className: "shortcutFunction" }, + _react2.default.createElement( + "p", + null, + searchSourcesLabel + ), + _react2.default.createElement( + "p", + null, + searchProjectLabel + ), + _react2.default.createElement( + "p", + null, + searchFunctionLabel + ) + ), this.renderToggleButton() ) ); } } WelcomeBox.displayName = "WelcomeBox"; @@ -29637,24 +29678,21 @@ class SourceTabs extends _react.PureComp toggleSourcesDropdown(e) { this.setState({ dropdownShown: !this.state.dropdownShown }); } renderDropdownSource(source) { - var moveTab = this.props.moveTab; + var selectSource = this.props.selectSource; var filename = (0, _source.getFilename)(source.toJS()); - var onClick = () => { - var tabIndex = 0; - moveTab(source.get("url"), tabIndex); - }; + var onClick = () => selectSource(source.get("id")); return _react2.default.createElement( "li", { key: source.get("id"), onClick: onClick }, filename ); } renderTabs() { @@ -29847,18 +29885,18 @@ class SourceTabs extends _react.PureComp SourceTabs.displayName = "SourceTabs"; exports.default = (0, _reactRedux.connect)(state => { return { selectedSource: (0, _selectors.getSelectedSource)(state), searchTabs: (0, _selectors.getSearchTabs)(state), sourceTabs: (0, _selectors.getSourcesForTabs)(state), - activeSearch: (0, _selectors.getActiveSearchState)(state), - searchOn: (0, _selectors.getActiveSearchState)(state) === "source" + activeSearch: (0, _selectors.getActiveSearch)(state), + searchOn: (0, _selectors.getActiveSearch)(state) === "source" }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SourceTabs); /***/ }), /* 751 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -30230,23 +30268,27 @@ PreviewFunction.displayName = "PreviewFu Object.defineProperty(exports, "__esModule", { value: true }); exports.findScopeByName = exports.getASTLocation = undefined; var getASTLocation = exports.getASTLocation = (() => { var _ref = _asyncToGenerator(function* (source, location) { var symbols = yield (0, _parser.getSymbols)(source); - var functions = [].concat(_toConsumableArray(symbols.functions), _toConsumableArray(symbols.memberExpressions)); + var functions = [].concat(_toConsumableArray(symbols.functions)); var scope = findClosestScope(functions, location); if (scope) { + // we only record the line, but at some point we may + // also do column offsets var line = location.line - scope.location.start.line; - var column = location.column; - return { name: scope.name, offset: { line, column } }; + return { + name: scope.name, + offset: { line } + }; } return { name: undefined, offset: location }; }); return function getASTLocation(_x, _x2) { return _ref.apply(this, arguments); }; })(); @@ -30279,17 +30321,20 @@ function findClosestScope(functions, loc if (currNode.name === "anonymous" || !(0, _contains.containsPosition)(currNode.location, location)) { return found; } if (!found) { return currNode; } - if (found.location.start.line > currNode.location.start.line || found.location.start.column > currNode.location.start.column) { + if (found.location.start.line > currNode.location.start.line) { + return found; + } + if (found.location.start.line === currNode.location.start.line && found.location.start.column > currNode.location.start.column) { return found; } return currNode; }, null); } /***/ }), @@ -30715,32 +30760,33 @@ exports.default = (0, _reactRedux.connec /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getEmptyLines = exports.getNextStep = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined; +exports.getEmptyLines = exports.getNextStep = exports.clearASTs = exports.clearSymbols = exports.getOutOfScopeLocations = exports.getVariablesInScope = exports.getSymbols = exports.getClosestExpression = exports.stopParserWorker = exports.startParserWorker = undefined; var _devtoolsUtils = __webpack_require__(900); var WorkerDispatcher = _devtoolsUtils.workerUtils.WorkerDispatcher; var dispatcher = new WorkerDispatcher(); var startParserWorker = exports.startParserWorker = dispatcher.start.bind(dispatcher); var stopParserWorker = exports.stopParserWorker = dispatcher.stop.bind(dispatcher); var getClosestExpression = exports.getClosestExpression = dispatcher.task("getClosestExpression"); var getSymbols = exports.getSymbols = dispatcher.task("getSymbols"); var getVariablesInScope = exports.getVariablesInScope = dispatcher.task("getVariablesInScope"); var getOutOfScopeLocations = exports.getOutOfScopeLocations = dispatcher.task("getOutOfScopeLocations"); var clearSymbols = exports.clearSymbols = dispatcher.task("clearSymbols"); +var clearASTs = exports.clearASTs = dispatcher.task("clearASTs"); var getNextStep = exports.getNextStep = dispatcher.task("getNextStep"); var getEmptyLines = exports.getEmptyLines = dispatcher.task("getEmptyLines"); /***/ }), /* 828 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -31978,28 +32024,32 @@ var onConnect = (() => { var commands = client.clientCommands; var _bootstrapStore = (0, _bootstrap.bootstrapStore)(commands, services), store = _bootstrapStore.store, actions = _bootstrapStore.actions, selectors = _bootstrapStore.selectors; (0, _bootstrap.bootstrapWorkers)(); - yield client.onConnect(connection, actions); + + var _ref2 = yield client.onConnect(connection, actions), + bpClients = _ref2.bpClients; + yield loadFromPrefs(actions); window.getGlobalsForTesting = function () { return { store, actions, selectors, client: client.clientCommands, prefs: _prefs.prefs, features: _prefs.features, - connection + connection, + bpClients }; }; if (!(0, _devtoolsConfig.isFirefoxPanel)()) { console.group("Development Notes"); var baseUrl = "https://devtools-html.github.io/debugger.html"; var localDevelopmentUrl = `${baseUrl}/docs/local-development.html`; console.log("Debugging Tips", localDevelopmentUrl); @@ -32068,27 +32118,28 @@ var onConnect = exports.onConnect = (() var _ref = _asyncToGenerator(function* (connection, actions) { var _connection$tabConnec = connection.tabConnection, tabTarget = _connection$tabConnec.tabTarget, threadClient = _connection$tabConnec.threadClient, debuggerClient = _connection$tabConnec.debuggerClient; if (!tabTarget || !threadClient || !debuggerClient) { - return; + return { bpClients: {} }; } var supportsWasm = (0, _devtoolsConfig.isEnabled)("wasm") && !!debuggerClient.mainRoot.traits.wasmBinarySource; - (0, _commands.setupCommands)({ + var _setupCommands = (0, _commands.setupCommands)({ threadClient, tabTarget, debuggerClient, supportsWasm - }); + }), + bpClients = _setupCommands.bpClients; if (actions) { (0, _events.setupEvents)({ threadClient, actions, supportsWasm }); } tabTarget.on("will-navigate", actions.willNavigate); tabTarget.on("navigate", actions.navigated); @@ -32108,16 +32159,18 @@ var onConnect = exports.onConnect = (() yield actions.newSources(sources); // If the threadClient is already paused, make sure to show a // paused state. var pausedPacket = threadClient.getLastPausePacket(); if (pausedPacket) { _events.clientEvents.paused("paused", pausedPacket); } + + return { bpClients }; }); return function onConnect(_x, _x2) { return _ref.apply(this, arguments); }; })(); var _commands = __webpack_require__(890); @@ -32204,16 +32257,18 @@ var debuggerClient = void 0; var supportsWasm = void 0; function setupCommands(dependencies) { threadClient = dependencies.threadClient; tabTarget = dependencies.tabTarget; debuggerClient = dependencies.debuggerClient; supportsWasm = dependencies.supportsWasm; bpClients = {}; + + return { bpClients }; } function resume() { return new Promise(resolve => { threadClient.resume(resolve); }); } @@ -38171,17 +38226,17 @@ module.exports = { supportsObject, maxLengthMap }; /***/ }), /* 960 */ /***/ (function(module, exports) { -module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the\n# context menu to copy the source URL of file open.\ncopySourceUrl=Copy Source Url\ncopySourceUrl.accesskey=u\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy Stack Trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step Over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step In %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step Out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event Listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove Breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call Stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not Paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse Rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand Rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=no results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next Result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous Result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add Breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable Breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable Breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove Breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit Breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add Conditional Breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable Framework Grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable Framework Grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add Watch Expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close others\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in Tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.copyLink): Editor source tab context menu item\n# for copying a link address.\nsourceTabs.copyLink=Copy Link Address\nsourceTabs.copyLink.accesskey=l\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty Print Source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox Source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox Source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed Source\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes Unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not Paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch Expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search Sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText2): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText2=Error loading this URL: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous Sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n" +module.exports = "# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n# LOCALIZATION NOTE These strings are used inside the Debugger\n# which is available from the Web Developer sub-menu -> 'Debugger'.\n# The correct localization of this file might be to keep it in\n# English, or another language commonly spoken among web developers.\n# You want to make that choice consistent across the developer tools.\n# A good criteria is the language in which you'd find the best\n# documentation on web development on the web.\n\n# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button\n# that collapses the left and right panes in the debugger UI.\ncollapsePanes=Collapse panes\n\n# LOCALIZATION NOTE (copySource): This is the text that appears in the\n# context menu to copy the selected source of file open.\ncopySource=Copy\ncopySource.accesskey=y\n\n# LOCALIZATION NOTE (copySourceUrl): This is the text that appears in the\n# context menu to copy the source URL of file open.\ncopySourceUrl=Copy Source Url\ncopySourceUrl.accesskey=u\n\n# LOCALIZATION NOTE (copyStackTrace): This is the text that appears in the\n# context menu to copy the stack trace methods, file names and row number.\ncopyStackTrace=Copy Stack Trace\ncopyStackTrace.accesskey=c\n\n# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button\n# that expands the left and right panes in the debugger UI.\nexpandPanes=Expand panes\n\n# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause\n# button when the debugger is in a running state.\npauseButtonTooltip=Pause %S\n\n# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for\n# the pause button after it's been clicked but before the next JavaScript to run.\npausePendingButtonTooltip=Waiting for next execution\n\n# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause\n# button when the debugger is in a paused state.\nresumeButtonTooltip=Resume %S\n\n# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the\n# button that steps over a function call.\nstepOverTooltip=Step Over %S\n\n# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the\n# button that steps into a function call.\nstepInTooltip=Step In %S\n\n# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the\n# button that steps out of a function call.\nstepOutTooltip=Step Out %S\n\n# LOCALIZATION NOTE (workersHeader): The text to display in the events\n# header.\nworkersHeader=Workers\n\n# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list\n# when there are no workers.\nnoWorkersText=This page has no workers.\n\n# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list\n# when there are no sources.\nnoSourcesText=This page has no sources.\n\n# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab\n# when there are no events.\nnoEventListenersText=No event listeners to display\n\n# LOCALIZATION NOTE (eventListenersHeader): The text to display in the events\n# header.\neventListenersHeader=Event Listeners\n\n# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab\n# when there are no stack frames.\nnoStackFramesText=No stack frames to display\n\n# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when\n# the user hovers over the checkbox used to toggle an event breakpoint.\neventCheckboxTooltip=Toggle breaking on this event\n\n# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab\n# for every event item, between the event type and event selector.\neventOnSelector=on\n\n# LOCALIZATION NOTE (eventInSource): The text to display in the events tab\n# for every event item, between the event selector and listener's owner source.\neventInSource=in\n\n# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when\n# an event is listened on more than one target node.\neventNodes=%S nodes\n\n# LOCALIZATION NOTE (eventNative): The text to display in the events tab when\n# a listener is added from plugins, thus getting translated to native code.\neventNative=[native code]\n\n# LOCALIZATION NOTE (*Events): The text to display in the events tab for\n# each group of sub-level event entries.\nanimationEvents=Animation\naudioEvents=Audio\nbatteryEvents=Battery\nclipboardEvents=Clipboard\ncompositionEvents=Composition\ndeviceEvents=Device\ndisplayEvents=Display\ndragAndDropEvents=Drag and Drop\ngamepadEvents=Gamepad\nindexedDBEvents=IndexedDB\ninteractionEvents=Interaction\nkeyboardEvents=Keyboard\nmediaEvents=HTML5 Media\nmouseEvents=Mouse\nmutationEvents=Mutation\nnavigationEvents=Navigation\npointerLockEvents=Pointer Lock\nsensorEvents=Sensor\nstorageEvents=Storage\ntimeEvents=Time\ntouchEvents=Touch\notherEvents=Other\n\n# LOCALIZATION NOTE (blackboxCheckboxTooltip2): The tooltip text to display when\n# the user hovers over the checkbox used to toggle blackboxing its associated\n# source.\nblackboxCheckboxTooltip2=Toggle blackboxing\n\n# LOCALIZATION NOTE (sources.search.key2): Key shortcut to open the search for\n# searching all the source files the debugger has seen.\nsources.search.key2=CmdOrCtrl+P\n\n# LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the\n# search for searching all the source files the debugger has seen.\nsources.search.alt.key=CmdOrCtrl+O\n\n# LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the\n# full project text search for searching all the files the debugger has seen.\nprojectTextSearch.key=CmdOrCtrl+Shift+F\n\n# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the\n# modal for searching functions in a file.\nfunctionSearch.key=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown\n# when searching across all of the files in a project.\nprojectTextSearch.placeholder=Find in files…\n\n# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger\n# does not have any sources.\nsources.noSourcesAvailable=This page has no sources\n\n# LOCALIZATION NOTE (sourceSearch.search.key2): Key shortcut to open the search\n# for searching within a the currently opened files in the editor\nsourceSearch.search.key2=CmdOrCtrl+F\n\n# LOCALIZATION NOTE (sourceSearch.search.placeholder): placeholder text in\n# the source search input bar\nsourceSearch.search.placeholder=Search in file…\n\n# LOCALIZATION NOTE (sourceSearch.search.again.key2): Key shortcut to highlight\n# the next occurrence of the last search triggered from a source search\nsourceSearch.search.again.key2=CmdOrCtrl+G\n\n# LOCALIZATION NOTE (sourceSearch.search.againPrev.key2): Key shortcut to highlight\n# the previous occurrence of the last search triggered from a source search\nsourceSearch.search.againPrev.key2=CmdOrCtrl+Shift+G\n\n# LOCALIZATION NOTE (sourceSearch.resultsSummary1): Shows a summary of\n# the number of matches for autocomplete\nsourceSearch.resultsSummary1=%d results\n\n# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the\n# global search results when there are no matching strings after filtering.\nnoMatchingStringsText=No matches found\n\n# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the\n# filter text box when it is empty and the scripts container is selected.\nemptySearchText=Search scripts (%S)\n\n# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that\n# appears in the filter text box for the variables view container.\nemptyVariablesFilterText=Filter variables\n\n# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that\n# appears in the filter text box for the editor's variables view bubble.\nemptyPropertiesFilterText=Filter properties\n\n# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the\n# filter panel popup for the filter scripts operation.\nsearchPanelFilter=Filter scripts (%S)\n\n# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the\n# filter panel popup for the global search operation.\nsearchPanelGlobal=Search in all files (%S)\n\n# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the\n# filter panel popup for the function search operation.\nsearchPanelFunction=Search for function definition (%S)\n\n# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the\n# filter panel popup for the token search operation.\nsearchPanelToken=Find in this file (%S)\n\n# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the\n# filter panel popup for the line search operation.\nsearchPanelGoToLine=Go to line (%S)\n\n# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the\n# filter panel popup for the variables search operation.\nsearchPanelVariable=Filter variables (%S)\n\n# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that\n# are displayed in the breakpoints menu item popup.\nbreakpointMenuItem.setConditional=Configure conditional breakpoint\nbreakpointMenuItem.enableSelf=Enable breakpoint\nbreakpointMenuItem.enableSelf.accesskey=E\nbreakpointMenuItem.disableSelf=Disable breakpoint\nbreakpointMenuItem.disableSelf.accesskey=D\nbreakpointMenuItem.deleteSelf=Remove breakpoint\nbreakpointMenuItem.deleteSelf.accesskey=R\nbreakpointMenuItem.enableOthers=Enable others\nbreakpointMenuItem.enableOthers.accesskey=o\nbreakpointMenuItem.disableOthers=Disable others\nbreakpointMenuItem.disableOthers.accesskey=s\nbreakpointMenuItem.deleteOthers=Remove others\nbreakpointMenuItem.deleteOthers.accesskey=h\nbreakpointMenuItem.enableAll=Enable all breakpoints\nbreakpointMenuItem.enableAll.accesskey=b\nbreakpointMenuItem.disableAll=Disable all breakpoints\nbreakpointMenuItem.disableAll.accesskey=k\nbreakpointMenuItem.deleteAll=Remove all breakpoints\nbreakpointMenuItem.deleteAll.accesskey=a\n\n# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header.\nbreakpoints.header=Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are\n# no breakpoints present\nbreakpoints.none=No Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.enable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.enable=Enable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.disable): The text that may appear as a tooltip\n# when hovering over the 'disable breakpoints' switch button in right sidebar\nbreakpoints.disable=Disable Breakpoints\n\n# LOCALIZATION NOTE (breakpoints.removeBreakpointTooltip): The tooltip that is displayed\n# for remove breakpoint button in right sidebar\nbreakpoints.removeBreakpointTooltip=Remove Breakpoint\n\n# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header.\ncallStack.header=Call Stack\n\n# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane\n# message when not paused.\ncallStack.notPaused=Not Paused\n\n# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane\n# message to hide some of the frames that are shown.\ncallStack.collapse=Collapse Rows\n\n# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane\n# message to show more of the frames.\ncallStack.expand=Expand Rows\n\n# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message\n# for the summarizing the selected search result. e.g. 5 of 10 results.\neditor.searchResults=%d of %d results\n\n# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.\neditor.singleResult=1 result\n\n# LOCALIZATION NOTE (editor.noResults): Editor Search bar message\n# for when no results found.\neditor.noResults=no results\n\n# LOCALIZATION NOTE (editor.searchResults.nextResult): Editor Search bar\n# tooltip for traversing to the Next Result\neditor.searchResults.nextResult=Next Result\n\n# LOCALIZATION NOTE (editor.searchResults.prevResult): Editor Search bar\n# tooltip for traversing to the Previous Result\neditor.searchResults.prevResult=Previous Result\n\n# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for\n# toggling search type buttons(function search, variable search)\neditor.searchTypeToggleTitle=Search for:\n\n# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item\n# for adding a breakpoint on a line.\neditor.addBreakpoint=Add Breakpoint\n\n# LOCALIZATION NOTE (editor.disableBreakpoint): Editor gutter context menu item\n# for disabling a breakpoint on a line.\neditor.disableBreakpoint=Disable Breakpoint\n\n# LOCALIZATION NOTE (editor.enableBreakpoint): Editor gutter context menu item\n# for enabling a breakpoint on a line.\neditor.enableBreakpoint=Enable Breakpoint\n\n# LOCALIZATION NOTE (editor.removeBreakpoint): Editor gutter context menu item\n# for removing a breakpoint on a line.\neditor.removeBreakpoint=Remove Breakpoint\n\n# LOCALIZATION NOTE (editor.editBreakpoint): Editor gutter context menu item\n# for setting a breakpoint condition on a line.\neditor.editBreakpoint=Edit Breakpoint\n\n# LOCALIZATION NOTE (editor.addConditionalBreakpoint): Editor gutter context\n# menu item for adding a breakpoint condition on a line.\neditor.addConditionalBreakpoint=Add Conditional Breakpoint\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Placeholder text for\n# input element inside ConditionalPanel component\neditor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true\n\n# LOCALIZATION NOTE (editor.conditionalPanel.placeholder): Tooltip text for\n# close button inside ConditionalPanel component\neditor.conditionalPanel.close=Cancel edit breakpoint and close\n\n# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item\n# for navigating to a source mapped location\neditor.jumpToMappedLocation1=Jump to %S location\n\n# LOCALIZATION NOTE (framework.disableGrouping): This is the text that appears in the\n# context menu to disable framework grouping.\nframework.disableGrouping=Disable Framework Grouping\nframework.disableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (framework.enableGrouping): This is the text that appears in the\n# context menu to enable framework grouping.\nframework.enableGrouping=Enable Framework Grouping\nframework.enableGrouping.accesskey=u\n\n# LOCALIZATION NOTE (generated): Source Map term for a server source location\ngenerated=generated\n\n# LOCALIZATION NOTE (original): Source Map term for a debugger UI source location\noriginal=original\n\n# LOCALIZATION NOTE (expressions.placeholder): Placeholder text for expression\n# input element\nexpressions.placeholder=Add Watch Expression\n\n# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item\n# for closing the selected tab below the mouse.\nsourceTabs.closeTab=Close tab\nsourceTabs.closeTab.accesskey=c\n\n# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item\n# for closing the other tabs.\nsourceTabs.closeOtherTabs=Close others\nsourceTabs.closeOtherTabs.accesskey=o\n\n# LOCALIZATION NOTE (sourceTabs.closeTabsToEnd): Editor source tab context menu item\n# for closing the tabs to the end (the right for LTR languages) of the selected tab.\nsourceTabs.closeTabsToEnd=Close tabs to the right\nsourceTabs.closeTabsToEnd.accesskey=e\n\n# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item\n# for closing all tabs.\nsourceTabs.closeAllTabs=Close all tabs\nsourceTabs.closeAllTabs.accesskey=a\n\n# LOCALIZATION NOTE (sourceTabs.revealInTree): Editor source tab context menu item\n# for revealing source in tree.\nsourceTabs.revealInTree=Reveal in Tree\nsourceTabs.revealInTree.accesskey=r\n\n# LOCALIZATION NOTE (sourceTabs.copyLink): Editor source tab context menu item\n# for copying a link address.\nsourceTabs.copyLink=Copy Link Address\nsourceTabs.copyLink.accesskey=l\n\n# LOCALIZATION NOTE (sourceTabs.prettyPrint): Editor source tab context menu item\n# for pretty printing the source.\nsourceTabs.prettyPrint=Pretty Print Source\nsourceTabs.prettyPrint.accesskey=p\n\n# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.blackbox=Blackbox Source\nsourceFooter.blackbox.accesskey=B\n\n# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated\n# with the blackbox button\nsourceFooter.unblackbox=Unblackbox Source\nsourceFooter.unblackbox.accesskey=b\n\n# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated\n# with a blackboxed source\nsourceFooter.blackboxed=Blackboxed Source\n\n# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated\n# with a code coverage button\nsourceFooter.codeCoverage=Code Coverage\n\n# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed\n# for close tab button in source tabs.\nsourceTabs.closeTabButtonTooltip=Close tab\n\n# LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for\n# new tab button in source tabs.\nsourceTabs.newTabButtonTooltip=Search for sources (%S)\n\n# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.\nscopes.header=Scopes\n\n# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message\n# for when the debugger is paused, but there isn't pause data.\nscopes.notAvailable=Scopes Unavailable\n\n# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message\n# for when the debugger is not paused.\nscopes.notPaused=Not Paused\n\n# LOCALIZATION NOTE (scopes.block): Refers to a block of code in\n# the scopes pane when the debugger is paused.\nscopes.block=Block\n\n# LOCALIZATION NOTE (sources.header): Sources left sidebar header\nsources.header=Sources\n\n# LOCALIZATION NOTE (outline.header): Outline left sidebar header\noutline.header=Outline\n\n# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt\n# e.g. Cmd+P to search. On a mac, we use the command unicode character.\n# On windows, it's ctrl.\nsources.search=%S to search\n\n# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar\n# pane header.\nwatchExpressions.header=Watch Expressions\n\n# LOCALIZATION NOTE (watchExpressions.refreshButton): Watch Expressions header\n# button for refreshing the expressions.\nwatchExpressions.refreshButton=Refresh\n\n# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's\n# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on\n# a mac we use the unicode character.\nwelcome.search=%S to search for sources\n\n# LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's\n# search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on\n# a mac we use the unicode character.\nwelcome.findInFiles=%S to find in files\n\n# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome\n# panel. %S is replaced by the keyboard shortcut to search for functions.\nwelcome.searchFunction=%S to search for functions in file\n\n# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search\n# prompt for searching for files.\nsourceSearch.search=Search sources…\n\n# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search\n# message when the query did not match any of the sources.\nsourceSearch.noResults2=No results found\n\n# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip\n# when the debugger will not pause on exceptions.\nignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions\n\n# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button\n# tooltip when the debugger will pause on uncaught exceptions.\npauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions\n\n# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip\n# when the debugger will pause on all exceptions.\npauseOnExceptions=Pause on all exceptions. Click to ignore exceptions\n\n# LOCALIZATION NOTE (loadingText): The text that is displayed in the script\n# editor when the loading process has started but there is no file to display\n# yet.\nloadingText=Loading\\u2026\n\n# LOCALIZATION NOTE (errorLoadingText2): The text that is displayed in the debugger\n# viewer when there is an error loading a file\nerrorLoadingText2=Error loading this URL: %S\n\n# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the\n# watch expressions list to add a new item.\naddWatchExpressionText=Add watch expression\n\n# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the\n# variables view popup.\naddWatchExpressionButton=Watch\n\n# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the\n# variables pane when there are no variables to display.\nemptyVariablesText=No variables to display\n\n# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables\n# pane as a header for each variable scope (e.g. \"Global scope, \"With scope\",\n# etc.).\nscopeLabel=%S scope\n\n# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch\n# expressions scope. This text is displayed in the variables pane as a header for\n# the watch expressions scope.\nwatchExpressionsScopeLabel=Watch expressions\n\n# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text\n# is added to scopeLabel and displayed in the variables pane as a header for\n# the global scope.\nglobalScopeLabel=Global\n\n# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is\n# shown before the stack trace in an error.\nvariablesViewErrorStacktrace=Stack trace:\n\n# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed\n# when you have an object preview that does not show all of the elements. At the end of the list\n# you see \"N more...\" in the web console output.\n# This is a semi-colon list of plural forms.\n# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals\n# #1 number of remaining items in the object\n# example: 3 more…\nvariablesViewMoreObjects=#1 more…;#1 more…\n\n# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed\n# in the variables list on an item with an editable name.\nvariablesEditableNameTooltip=Double click to edit\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in the variables list on an item with an editable value.\nvariablesEditableValueTooltip=Click to change value\n\n# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed\n# in the variables list on an item which can be removed.\nvariablesCloseButtonTooltip=Click to remove\n\n# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed\n# in the variables list on a getter or setter which can be edited.\nvariablesEditButtonTooltip=Click to set value\n\n# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed\n# in a tooltip on the \"open in inspector\" button in the the variables list for a\n# DOMNode item.\nvariablesDomNodeValueTooltip=Click to select the node in the inspector\n\n# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed\n# in the variables list on certain variables or properties as tooltips.\n# Expanations of what these represent can be found at the following links:\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n# It's probably best to keep these in English.\nconfigurableTooltip=configurable\nenumerableTooltip=enumerable\nwritableTooltip=writable\nfrozenTooltip=frozen\nsealedTooltip=sealed\nextensibleTooltip=extensible\noverriddenTooltip=overridden\nWebIDLTooltip=WebIDL\n\n# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed\n# in the variables list as a separator between the name and value.\nvariablesSeparatorLabel=:\n\n# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed\n# in the watch expressions list as a separator between the code and evaluation.\nwatchExpressionsSeparatorLabel2=\\u0020→\n\n# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed\n# in the functions search panel as a separator between function's inferred name\n# and its real name (if available).\nfunctionSearchSeparatorLabel=←\n\n# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder\n# text displayed when the user searches for functions in a file\nsymbolSearch.search.functionsPlaceholder=Search functions…\n\n# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder\n# text displayed when the user searches for variables in a file\nsymbolSearch.search.variablesPlaceholder=Search variables…\n\n# LOCALIZATION NOTE(symbolSearch.search.key2): The Key Shortcut for\n# searching for a function or variable\nsymbolSearch.search.key2=CmdOrCtrl+Shift+O\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.modifiersLabel): A label\n# preceding the group of modifiers\nsymbolSearch.searchModifier.modifiersLabel=Modifiers:\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.regex=Regex\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.caseSensitive=Case sensitive\n\n# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option\n# when searching text in a file\nsymbolSearch.searchModifier.wholeWord=Whole word\n\n# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears\n# as a description in the notification panel popup, when multiple debuggers are\n# open in separate tabs and the user tries to resume them in the wrong order.\n# The substitution parameter is the URL of the last paused window that must be\n# resumed first.\nresumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S\n\nvariablesViewOptimizedOut=(optimized away)\nvariablesViewUninitialized=(uninitialized)\nvariablesViewMissingArgs=(unavailable)\n\nanonymousSourcesLabel=Anonymous Sources\n\nexperimental=This is an experimental feature\n\n# LOCALIZATION NOTE (whyPaused.debuggerStatement): The text that is displayed\n# in a info block explaining how the debugger is currently paused due to a `debugger`\n# statement in the code\nwhyPaused.debuggerStatement=Paused on debugger statement\n\n# LOCALIZATION NOTE (whyPaused.breakpoint): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a breakpoint\nwhyPaused.breakpoint=Paused on breakpoint\n\n# LOCALIZATION NOTE (whyPaused.exception): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an exception\nwhyPaused.exception=Paused on exception\n\n# LOCALIZATION NOTE (whyPaused.resumeLimit): The text that is displayed\n# in a info block explaining how the debugger is currently paused while stepping\n# in or out of the stack\nwhyPaused.resumeLimit=Paused while stepping\n\n# LOCALIZATION NOTE (whyPaused.pauseOnDOMEvents): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# dom event\nwhyPaused.pauseOnDOMEvents=Paused on event listener\n\n# LOCALIZATION NOTE (whyPaused.breakpointConditionThrown): The text that is displayed\n# in an info block when evaluating a conditional breakpoint throws an error\nwhyPaused.breakpointConditionThrown=Error with conditional breakpoint\n\n# LOCALIZATION NOTE (whyPaused.xhr): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# xml http request\nwhyPaused.xhr=Paused on XMLHttpRequest\n\n# LOCALIZATION NOTE (whyPaused.promiseRejection): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# promise rejection\nwhyPaused.promiseRejection=Paused on promise rejection\n\n# LOCALIZATION NOTE (whyPaused.assert): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an\n# assert\nwhyPaused.assert=Paused on assertion\n\n# LOCALIZATION NOTE (whyPaused.debugCommand): The text that is displayed\n# in a info block explaining how the debugger is currently paused on a\n# debugger statement\nwhyPaused.debugCommand=Paused on debugged function\n\n# LOCALIZATION NOTE (whyPaused.other): The text that is displayed\n# in a info block explaining how the debugger is currently paused on an event\n# listener breakpoint set\nwhyPaused.other=Debugger paused\n\n# LOCALIZATION NOTE (ctrl): The text that is used for documenting\n# keyboard shortcuts that use the control key\nctrl=Ctrl\n" /***/ }), /* 961 */, /* 962 */ /***/ (function(module, exports) { // removed by extract-text-webpack-plugin @@ -41790,22 +41845,25 @@ function breakpointExists(state, locatio return currentBp && !currentBp.disabled; } function createBreakpoint(location) { var overrides = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var condition = overrides.condition, disabled = overrides.disabled, hidden = overrides.hidden, - generatedLocation = overrides.generatedLocation; + generatedLocation = overrides.generatedLocation, + astLocation = overrides.astLocation; + var properties = { condition: condition || null, disabled: disabled || false, hidden: hidden || false, + astLocation: astLocation || { offset: location }, generatedLocation: generatedLocation || location, location }; return properties; } function createPendingLocation(location) { @@ -41821,16 +41879,17 @@ function createPendingBreakpoint(bp) { var pendingGeneratedLocation = createPendingLocation(bp.generatedLocation); assertPendingLocation(pendingLocation); return { condition: bp.condition, disabled: bp.disabled, location: pendingLocation, + astLocation: bp.astLocation, generatedLocation: pendingGeneratedLocation }; } /***/ }), /* 1058 */ /***/ (function(module, exports, __webpack_require__) { @@ -42242,90 +42301,99 @@ var _SearchInput = __webpack_require__(3 var _SearchInput2 = _interopRequireDefault(_SearchInput); __webpack_require__(866); var _sourcesTree = __webpack_require__(39); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } - class TextSearch extends _react.Component { constructor(props) { super(props); this.state = { inputValue: this.props.query || "" }; - this.focused = null; + this.focusedItem = null; + this.inputFocused = false; this.inputOnChange = this.inputOnChange.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onEnterPress = this.onEnterPress.bind(this); - this.close = this.close.bind(this); this.selectMatchItem = this.selectMatchItem.bind(this); } - close() { - this.props.closeActiveSearch(); + componentDidMount() { + var shortcuts = this.context.shortcuts; + shortcuts.on("Enter", this.onEnterPress); + } + + componentWillUnmount() { + var shortcuts = this.context.shortcuts; + shortcuts.off("Enter", this.onEnterPress); + } + + selectMatchItem(matchItem) { + this.props.selectSource(matchItem.sourceId, { line: matchItem.line }); + } + + getResults() { + var results = this.props.results; + + return results.filter(result => result.filepath && result.matches.length > 0); + } + + getResultCount() { + var results = this.getResults(); + return results.reduce((count, file) => count + (file.matches ? file.matches.length : 0), 0); } onKeyDown(e) { - var _this = this; - - return _asyncToGenerator(function* () { - if (e.key !== "Enter") { - return; - } - _this.props.searchSources(_this.state.inputValue); - })(); + if (e.key === "Escape") { + return; + } + + e.stopPropagation(); + + if (e.key !== "Enter") { + return; + } + this.focusedItem = null; + this.props.searchSources(this.state.inputValue); } onEnterPress() { - if (this.focused) { - var _focused = this.focused, - setExpanded = _focused.setExpanded, - file = _focused.file, - expanded = _focused.expanded, - match = _focused.match; + if (this.focusedItem && !this.inputFocused) { + var _focusedItem = this.focusedItem, + setExpanded = _focusedItem.setExpanded, + file = _focusedItem.file, + expanded = _focusedItem.expanded, + match = _focusedItem.match; if (setExpanded) { setExpanded(file, !expanded); } else { this.selectMatchItem(match); } } } - componentWillUnmount() { - var shortcuts = this.context.shortcuts; - shortcuts.off("Enter", this.onEnterPress); - } - - componentDidMount() { - var shortcuts = this.context.shortcuts; - shortcuts.on("Enter", this.onEnterPress); - } - inputOnChange(e) { var inputValue = e.target.value; this.setState({ inputValue }); } - selectMatchItem(matchItem) { - this.props.selectSource(matchItem.sourceId, { line: matchItem.line }); - } - renderFile(file, focused, expanded, setExpanded) { if (focused) { - this.focused = { setExpanded, file, expanded }; - } - - var matches = ` (${file.matches.length} match${file.matches.length > 1 ? "es" : ""})`; + this.focusedItem = { setExpanded, file, expanded }; + } + + var matchesLength = file.matches.length; + var matches = ` (${matchesLength} match${matchesLength > 1 ? "es" : ""})`; return _react2.default.createElement( "div", { className: (0, _classnames2.default)("file-result", { focused }), key: file.sourceId, onClick: e => setExpanded(file, !expanded) }, @@ -42341,133 +42409,109 @@ class TextSearch extends _react.Componen { className: "matches-summary" }, matches ) ); } renderMatch(match, focused) { if (focused) { - this.focused = { match }; + this.focusedItem = { match }; } return _react2.default.createElement( "div", { className: (0, _classnames2.default)("result", { focused }), onClick: () => setTimeout(() => this.selectMatchItem(match), 50) }, _react2.default.createElement( "span", { className: "line-number", key: match.line }, match.line ), - this.renderMatchValue(match.value) - ); - } - - renderMatchValue(value) { - var inputValue = this.state.inputValue; - - var match = void 0; - var len = inputValue.length; - var matchIndexes = []; - var matches = []; - var re = new RegExp((0, _lodash.escapeRegExp)(inputValue), "g"); - while ((match = re.exec(value)) !== null) { - matchIndexes.push(match.index); - } - - matchIndexes.forEach((matchIndex, index) => { - if (matchIndex > 0 && index === 0) { - matches.push(_react2.default.createElement( - "span", - { className: "line-match", key: `case1-${index}` }, - value.slice(0, matchIndex) - )); - } - if (matchIndex > matchIndexes[index - 1] + len) { - matches.push(_react2.default.createElement( - "span", - { className: "line-match", key: `case2-${index}` }, - value.slice(matchIndexes[index - 1] + len, matchIndex) - )); - } - matches.push(_react2.default.createElement( - "span", - { className: "query-match", key: index }, - value.substr(matchIndex, len) - )); - if (index === matchIndexes.length - 1) { - matches.push(_react2.default.createElement( - "span", - { className: "line-match", key: `case3-${index}` }, - value.slice(matchIndex + len, value.length) - )); - } - }); + this.renderMatchValue(match) + ); + } + + renderMatchValue(lineMatch) { + var value = lineMatch.value, + column = lineMatch.column, + match = lineMatch.match; + + var len = match.length; return _react2.default.createElement( "span", { className: "line-value" }, - matches - ); - } - - getResults() { - var results = this.props.results; - - return results.filter(result => result.filepath && result.matches.length > 0); + _react2.default.createElement( + "span", + { className: "line-match", key: 0 }, + value.slice(0, column) + ), + _react2.default.createElement( + "span", + { className: "query-match", key: 1 }, + value.substr(column, len) + ), + _react2.default.createElement( + "span", + { className: "line-match", key: 2 }, + value.slice(column + len, value.length) + ) + ); } renderResults() { var results = this.getResults(); results = results.filter(result => result.matches.length > 0); - function getFilePath(item) { - return item.filepath ? `${item.sourceId}` : `${item.sourceId}-${item.line}-${item.column}`; + function getFilePath(item, index) { + return item.filepath ? `${item.sourceId}-${index}` : `${item.sourceId}-${item.line}-${item.column}-${index}`; } var renderItem = (item, depth, focused, _, expanded, _ref) => { var setExpanded = _ref.setExpanded; return item.filepath ? this.renderFile(item, focused, expanded, setExpanded) : this.renderMatch(item, focused); }; + var getFocusedItem = () => { + if (this.focusedItem === null) { + return results[0] ? results[0].matches[0] : null; + } + return this.focusedItem.file || this.focusedItem.match; + }; + return _react2.default.createElement(_ManagedTree2.default, { getRoots: () => results, getChildren: file => file.matches || [], itemHeight: 24, autoExpand: 1, autoExpandDepth: 1, - focused: results[0], + focused: getFocusedItem(), getParent: item => null, getPath: getFilePath, renderItem: renderItem }); } - resultCount() { - var results = this.getResults(); - return results.reduce((count, file) => count + (file.matches ? file.matches.length : 0), 0); - } - renderInput() { - var resultCount = this.resultCount(); + var resultCount = this.getResultCount(); var summaryMsg = L10N.getFormatStr("sourceSearch.resultsSummary1", resultCount); return _react2.default.createElement(_SearchInput2.default, { query: this.state.inputValue, count: resultCount, placeholder: L10N.getStr("projectTextSearch.placeholder"), size: "big", summaryMsg: summaryMsg, onChange: e => this.inputOnChange(e), - onFocus: () => this.setState({ focused: true }), - onBlur: () => this.setState({ focused: false }), + onFocus: () => this.inputFocused = true, + onBlur: () => this.inputFocused = false, onKeyDown: e => this.onKeyDown(e), - handleClose: this.close, + handleClose: this.props.closeActiveSearch, ref: "searchInput" }); } render() { var searchBottomBar = this.props.searchBottomBar; return _react2.default.createElement( @@ -42754,16 +42798,17 @@ exports.containsPosition = containsPosit exports.containsLocation = containsLocation; exports.nodeContainsPosition = nodeContainsPosition; function containsPosition(a, b) { var startsBefore = a.start.line < b.line || a.start.line === b.line && a.start.column <= b.column; var endsAfter = a.end.line > b.line || a.end.line === b.line && a.end.column >= b.column; return startsBefore && endsAfter; } + function containsLocation(a, b) { return containsPosition(a, b.start) && containsPosition(a, b.end); } function nodeContainsPosition(node, position) { return containsPosition(node.loc, position); } @@ -42994,16 +43039,17 @@ function getSourceSearchQuery(state) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initialState = initialState; exports.getPendingBreakpoints = getPendingBreakpoints; +exports.getPendingBreakpointsForSource = getPendingBreakpointsForSource; var _immutable = __webpack_require__(146); var I = _interopRequireWildcard(_immutable); var _makeRecord = __webpack_require__(230); var _makeRecord2 = _interopRequireDefault(_makeRecord); @@ -43038,17 +43084,17 @@ function update() { switch (action.type) { case "ADD_BREAKPOINT": { return addBreakpoint(state, action); } case "SYNC_BREAKPOINT": { - return addBreakpoint(state, action); + return syncBreakpoint(state, action); } case "ENABLE_BREAKPOINT": { return addBreakpoint(state, action); } case "DISABLE_BREAKPOINT": @@ -43079,16 +43125,30 @@ function addBreakpoint(state, action) { var breakpoint = action.value.breakpoint; var locationId = (0, _breakpoint.makePendingLocationId)(breakpoint.location); var pendingBreakpoint = (0, _breakpoint.createPendingBreakpoint)(breakpoint); return state.setIn(["pendingBreakpoints", locationId], pendingBreakpoint); } +function syncBreakpoint(state, action) { + var breakpoint = action.breakpoint, + previousLocation = action.previousLocation; + + var locationId = (0, _breakpoint.makePendingLocationId)(breakpoint.location); + var pendingBreakpoint = (0, _breakpoint.createPendingBreakpoint)(breakpoint); + + if (previousLocation) { + return state.deleteIn(["pendingBreakpoints", (0, _breakpoint.makePendingLocationId)(previousLocation)]).setIn(["pendingBreakpoints", locationId], pendingBreakpoint); + } + + return state.setIn(["pendingBreakpoints", locationId], pendingBreakpoint); +} + function updateBreakpoint(state, action) { var breakpoint = action.breakpoint; var locationId = (0, _breakpoint.makePendingLocationId)(breakpoint.location); var pendingBreakpoint = (0, _breakpoint.createPendingBreakpoint)(breakpoint); return state.setIn(["pendingBreakpoints", locationId], pendingBreakpoint); } @@ -43103,16 +43163,21 @@ function removeBreakpoint(state, action) // Selectors // TODO: these functions should be moved out of the reducer function getPendingBreakpoints(state) { return state.pendingBreakpoints.pendingBreakpoints; } +function getPendingBreakpointsForSource(state, sourceUrl) { + var pendingBreakpoints = state.pendingBreakpoints.pendingBreakpoints || []; + return pendingBreakpoints.filter(pendingBreakpoint => pendingBreakpoint.location.sourceUrl === sourceUrl); +} + function restorePendingBreakpoints() { return I.Map(_prefs.prefs.pendingBreakpoints); } exports.default = update; /***/ }), /* 1134 */ @@ -43275,18 +43340,19 @@ function _asyncToGenerator(fn) { return exports.default = (() => { var _ref = _asyncToGenerator(function* (getState, client, sourceMaps, _ref2) { var breakpoint = _ref2.breakpoint; var state = getState(); var source = (0, _selectors.getSource)(state, breakpoint.location.sourceId); + var sourceRecord = source.toJS(); var location = _extends({}, breakpoint.location, { sourceUrl: source.get("url") }); - var generatedLocation = yield (0, _sourceMaps.getGeneratedLocation)(state, source.toJS(), location, sourceMaps); + var generatedLocation = yield (0, _sourceMaps.getGeneratedLocation)(state, sourceRecord, location, sourceMaps); (0, _breakpoint.assertLocation)(location); (0, _breakpoint.assertLocation)(generatedLocation); if ((0, _breakpoint.breakpointExists)(state, location)) { var _newBreakpoint = _extends({}, breakpoint, { location, generatedLocation }); (0, _breakpoint.assertBreakpoint)(_newBreakpoint); return { breakpoint: _newBreakpoint }; @@ -43295,23 +43361,26 @@ exports.default = (() => { var _ref3 = yield client.setBreakpoint(generatedLocation, breakpoint.condition, sourceMaps.isOriginalId(location.sourceId)), id = _ref3.id, hitCount = _ref3.hitCount, actualLocation = _ref3.actualLocation; var newGeneratedLocation = actualLocation || generatedLocation; var newLocation = yield sourceMaps.getOriginalLocation(newGeneratedLocation); + var astLocation = yield (0, _breakpoint.getASTLocation)(sourceRecord, location); + var newBreakpoint = { id, disabled: false, hidden: breakpoint.hidden, loading: false, condition: breakpoint.condition, location: newLocation, + astLocation, hitCount, generatedLocation: newGeneratedLocation }; (0, _breakpoint.assertBreakpoint)(newBreakpoint); var previousLocation = (0, _breakpoint.locationMoved)(location, newLocation) ? location : null; @@ -43337,107 +43406,117 @@ exports.default = (() => { Object.defineProperty(exports, "__esModule", { value: true }); exports.syncClientBreakpoint = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +var makeScopedLocation = (() => { + var _ref = _asyncToGenerator(function* (_ref2, location, source) { + var name = _ref2.name, + offset = _ref2.offset; + + var scope = yield (0, _breakpoint.findScopeByName)(source, name); + // fallback onto the location line, if the scope is not found + // note: we may at some point want to delete the breakpoint if the scope + // disappears + var line = scope ? scope.location.start.line + offset.line : location.line; + return { + line, + column: location.column, + sourceUrl: source.url, + sourceId: source.id + }; + }); + + return function makeScopedLocation(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +})(); + // we have three forms of syncing: disabled syncing, existing server syncing // and adding a new breakpoint var syncClientBreakpoint = exports.syncClientBreakpoint = (() => { - var _ref = _asyncToGenerator(function* (getState, client, sourceMaps, source, pendingBreakpoint) { - var sourceId = source.id; + var _ref3 = _asyncToGenerator(function* (getState, client, sourceMaps, sourceId, pendingBreakpoint) { + (0, _breakpoint.assertPendingBreakpoint)(pendingBreakpoint); + + var source = (0, _selectors.getSource)(getState(), sourceId).toJS(); var generatedSourceId = sourceMaps.isOriginalId(sourceId) ? (0, _devtoolsSourceMap.originalToGeneratedId)(sourceId) : sourceId; + var location = pendingBreakpoint.location, + astLocation = pendingBreakpoint.astLocation; + + var previousLocation = _extends({}, location, { sourceId }); + + var scopedLocation = yield makeScopedLocation(astLocation, previousLocation, source); + + var scopedGeneratedLocation = yield (0, _sourceMaps.getGeneratedLocation)(getState(), source, scopedLocation, sourceMaps); + // this is the generatedLocation of the pending breakpoint, with // the source id updated to reflect the new connection var generatedLocation = _extends({}, pendingBreakpoint.generatedLocation, { sourceId: generatedSourceId }); - var location = _extends({}, pendingBreakpoint.location, { - sourceId - }); - - (0, _breakpoint3.assertPendingBreakpoint)(pendingBreakpoint); - - /** ******* CASE 1: Disabled ***********/ - // early return if breakpoint is disabled, send overrides to update - // the id as expected - if (pendingBreakpoint.disabled) { - var _newLocation = yield sourceMaps.getOriginalLocation(generatedLocation); - - var _breakpoint = _extends({}, pendingBreakpoint, { - id: (0, _breakpoint3.makeLocationId)(_newLocation), - generatedLocation, - location: _newLocation - }); - - var previousLocation = (0, _breakpoint3.locationMoved)(location, _newLocation) ? location : null; - - (0, _breakpoint3.assertBreakpoint)(_breakpoint); - return { breakpoint: _breakpoint, previousLocation }; - } - - /** ******* CASE 2: Merge Server Breakpoint ***********/ - // early return if breakpoint exists on the server, send overrides - // to update the id as expected + var isSameLocation = !(0, _breakpoint.locationMoved)(generatedLocation, scopedGeneratedLocation); + var existingClient = client.getBreakpointByLocation(generatedLocation); + /** ******* CASE 1: No server change ***********/ + // early return if breakpoint is disabled or we are in the sameLocation + // send update only to redux + if (pendingBreakpoint.disabled || existingClient && isSameLocation) { + return createSyncData(pendingBreakpoint, scopedLocation, scopedGeneratedLocation); + } + + // clear server breakpoints if they exist and we have moved if (existingClient) { - var _newGeneratedLocation = yield (0, _sourceMaps.getGeneratedLocation)(getState(), source, location, sourceMaps); - - if ((0, _breakpoint3.locationMoved)(generatedLocation, _newGeneratedLocation)) { - yield client.removeBreakpoint(generatedLocation); - yield client.setBreakpoint(_newGeneratedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId)); - } - - var _breakpoint2 = _extends({}, pendingBreakpoint, { - id: (0, _breakpoint3.makeLocationId)(location), - generatedLocation: _newGeneratedLocation, - location: location - }); - - (0, _breakpoint3.assertBreakpoint)(_breakpoint2); - return { breakpoint: _breakpoint2, previousLocation: location }; - } - - /** ******* CASE 3: Add New Breakpoint ***********/ + yield client.removeBreakpoint(generatedLocation); + } + + /** ******* Case 2: Add New Breakpoint ***********/ // If we are not disabled, set the breakpoint on the server and get // that info so we can set it on our breakpoints. - var clientBreakpoint = yield client.setBreakpoint(generatedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId)); - + var clientBreakpoint = yield client.setBreakpoint(scopedGeneratedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId)); + + // the breakpoint might have slid server side, so we want to get the location + // based on the server's return value var newGeneratedLocation = clientBreakpoint.actualLocation; var newLocation = yield sourceMaps.getOriginalLocation(newGeneratedLocation); - var breakpoint = _extends({}, pendingBreakpoint, { - id: (0, _breakpoint3.makeLocationId)(newGeneratedLocation), - generatedLocation: newGeneratedLocation, - location: newLocation - }); - - (0, _breakpoint3.assertBreakpoint)(breakpoint); - return { breakpoint, previousLocation: location }; - }); - - return function syncClientBreakpoint(_x, _x2, _x3, _x4, _x5) { - return _ref.apply(this, arguments); + return createSyncData(pendingBreakpoint, newLocation, newGeneratedLocation, previousLocation); + }); + + return function syncClientBreakpoint(_x5, _x6, _x7, _x8, _x9) { + return _ref3.apply(this, arguments); }; })(); -var _breakpoint3 = __webpack_require__(1057); +var _breakpoint = __webpack_require__(1057); var _sourceMaps = __webpack_require__(797); var _devtoolsSourceMap = __webpack_require__(898); +var _selectors = __webpack_require__(242); + function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } +function createSyncData(pendingBreakpoint, location, generatedLocation) { + var previousLocation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + + var overrides = _extends({}, pendingBreakpoint, { generatedLocation }); + var breakpoint = (0, _breakpoint.createBreakpoint)(location, overrides); + + (0, _breakpoint.assertBreakpoint)(breakpoint); + return { breakpoint, previousLocation }; +} + /***/ }), /* 1138 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { @@ -43459,17 +43538,17 @@ function _interopRequireDefault(obj) { r */ function ignoreWhiteSpace(str) { return (/^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str ); } function wholeMatch(query, wholeWord) { - if (query == "" || !wholeWord) { + if (query === "" || !wholeWord) { return query; } return `\\b${query}\\b`; } function buildFlags(caseSensitive, isGlobal) { if (caseSensitive && isGlobal) { @@ -43492,17 +43571,17 @@ function buildQuery(originalQuery, modif isGlobal = _ref$isGlobal === undefined ? false : _ref$isGlobal, _ref$ignoreSpaces = _ref.ignoreSpaces, ignoreSpaces = _ref$ignoreSpaces === undefined ? false : _ref$ignoreSpaces; var caseSensitive = modifiers.caseSensitive, regexMatch = modifiers.regexMatch, wholeWord = modifiers.wholeWord; - if (originalQuery == "") { + if (originalQuery === "") { return new RegExp(originalQuery); } var query = originalQuery; if (ignoreSpaces) { query = ignoreWhiteSpace(query); } @@ -43582,29 +43661,28 @@ class ProjectSearch extends _react.Compo } componentWillUnmount() { var shortcuts = this.context.shortcuts; shortcuts.off(L10N.getStr("projectTextSearch.key"), this.toggleProjectTextSearch); var searchKeys = [L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key")]; searchKeys.forEach(key => shortcuts.off(key, this.toggleSourceSearch)); - shortcuts.off("Escape", this.onEscape); } toggleProjectTextSearch(key, e) { var _props = this.props, closeActiveSearch = _props.closeActiveSearch, setActiveSearch = _props.setActiveSearch; if (e) { e.preventDefault(); } - if (!_prefs.prefs.projectTextSearchEnabled) { + if (!_prefs.features.projectTextSearch) { return; } if (this.isProjectSearchEnabled()) { return closeActiveSearch(); } return setActiveSearch("project"); } @@ -43659,17 +43737,17 @@ class ProjectSearch extends _react.Compo searchSources = _props4.searchSources, closeActiveSearch = _props4.closeActiveSearch, selectSource = _props4.selectSource, textSearchQuery = _props4.textSearchQuery; return _react2.default.createElement(_TextSearch2.default, { sources: sources, - results: results.valueSeq().toJS(), + results: results.toJS(), searchSources: searchSources, closeActiveSearch: closeActiveSearch, selectSource: selectSource, query: textSearchQuery, searchBottomBar: _react2.default.createElement(_ToggleSearch2.default, { kind: "project", toggle: this.toggleSourceSearch }) }); } @@ -43703,17 +43781,17 @@ ProjectSearch.propTypes = { ProjectSearch.contextTypes = { shortcuts: _react.PropTypes.object }; ProjectSearch.displayName = "ProjectSearch"; exports.default = (0, _reactRedux.connect)(state => ({ sources: (0, _selectors.getSources)(state), - activeSearch: (0, _selectors.getActiveSearchState)(state), + activeSearch: (0, _selectors.getActiveSearch)(state), results: (0, _selectors.getTextSearchResults)(state), textSearchQuery: (0, _selectors.getTextSearchQuery)(state), sourceSearchQuery: (0, _selectors.getSourceSearchQuery)(state) }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(ProjectSearch); /***/ }), /* 1140 */, /* 1141 */ @@ -43737,69 +43815,38 @@ var _utils = __webpack_require__(234); var _Autocomplete = __webpack_require__(342); var _Autocomplete2 = _interopRequireDefault(_Autocomplete); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class SourceSearch extends _react.Component { - constructor(props) { - super(props); - - this.close = this.close.bind(this); - } - - componentWillUnmount() { - var shortcuts = this.context.shortcuts; - shortcuts.off("Escape", this.onEscape); - } - - componentDidMount() { - var shortcuts = this.context.shortcuts; - shortcuts.on("Escape", this.onEscape); - } - - onEscape(shortcut, e) { - if (this.isProjectSearchEnabled()) { - e.preventDefault(); - this.close(); - } - } - searchResults(sourceMap) { return sourceMap.valueSeq().toJS().filter(source => !(0, _source.isPretty)(source)).map(source => ({ value: (0, _source.getSourcePath)(source), title: (0, _source.getSourcePath)(source).split("/").pop(), subtitle: (0, _utils.endTruncateStr)((0, _source.getSourcePath)(source), 100), id: source.id })); } - close() { - this.props.clearQuery(); - this.props.closeActiveSearch(); - } - render() { var _props = this.props, sources = _props.sources, searchBottomBar = _props.searchBottomBar, selectSource = _props.selectSource, query = _props.query, setQuery = _props.setQuery; return _react2.default.createElement( _Autocomplete2.default, { - selectItem: (e, result) => { - selectSource(result.id); - this.close(); - }, - close: this.close, + selectItem: (e, result) => selectSource(result.id), + close: this.props.closeActiveSearch, items: this.searchResults(sources), inputValue: query, placeholder: L10N.getStr("sourceSearch.search"), onChangeHandler: setQuery, size: "big" }, searchBottomBar ); @@ -43873,36 +43920,40 @@ class PrimaryPanes extends _react.Compon this.setState({ selectedPane }); } renderOutlineTabs() { if (!(0, _devtoolsConfig.isEnabled)("outline")) { return; } + var sources = (0, _text.formatKeyShortcut)(L10N.getStr("sources.header")); + + var outline = (0, _text.formatKeyShortcut)(L10N.getStr("outline.header")); + return [_react2.default.createElement( "div", { className: (0, _classnames2.default)("tab", { active: this.state.selectedPane === "sources" }), onClick: () => this.showPane("sources"), key: "sources-tab" }, - "Sources View" + sources ), _react2.default.createElement( "div", { className: (0, _classnames2.default)("tab", { active: this.state.selectedPane === "outline" }), onClick: () => this.showPane("outline"), key: "outline-tab" }, - "Outline View" + outline )]; } renderFooter() { return _react2.default.createElement( "div", { className: "source-footer" }, this.renderOutlineTabs() @@ -43957,29 +44008,92 @@ class PrimaryPanes extends _react.Compon ); } } PrimaryPanes.displayName = "PrimaryPanes"; exports.default = (0, _reactRedux.connect)(state => ({ sources: (0, _selectors.getSources)(state), - sourceSearchOn: (0, _selectors.getActiveSearchState)(state) === "source" + sourceSearchOn: (0, _selectors.getActiveSearch)(state) === "source" }), dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(PrimaryPanes); /***/ }), /* 1143 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.loadSourceText = loadSourceText; + +var _promise = __webpack_require__(193); + +var _ast = __webpack_require__(1059); + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +/** + * @memberof actions/sources + * @static + */ +function loadSourceText(source) { + return (() => { + var _ref = _asyncToGenerator(function* (_ref2) { + var dispatch = _ref2.dispatch, + getState = _ref2.getState, + client = _ref2.client, + sourceMaps = _ref2.sourceMaps; + + // Fetch the source text only once. + if (source.text) { + return Promise.resolve(source); + } + + yield dispatch({ + type: "LOAD_SOURCE_TEXT", + source: source, + [_promise.PROMISE]: _asyncToGenerator(function* () { + if (sourceMaps.isOriginalId(source.id)) { + return yield sourceMaps.getOriginalSourceText(source); + } + + var response = yield client.sourceContents(source.id); + + return { + id: source.id, + text: response.source, + contentType: response.contentType || "text/javascript" + }; + })() + }); + + yield dispatch((0, _ast.setSymbols)(source.id)); + yield dispatch((0, _ast.setEmptyLines)(source.id)); + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; + })(); +} + +/***/ }), +/* 1144 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); exports.setSourceSearchQuery = setSourceSearchQuery; exports.clearSourceSearchQuery = clearSourceSearchQuery; function setSourceSearchQuery(queryString) { return (_ref) => { var dispatch = _ref.dispatch, getState = _ref.getState; dispatch({ @@ -43996,96 +44110,16 @@ function clearSourceSearchQuery() { dispatch({ type: "CLEAR_QUERY_STRING" }); }; } /***/ }), -/* 1144 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _reactRedux = __webpack_require__(151); - -var _redux = __webpack_require__(3); - -var _react = __webpack_require__(0); - -var _actions = __webpack_require__(244); - -var _actions2 = _interopRequireDefault(_actions); - -var _selectors = __webpack_require__(242); - -__webpack_require__(1146); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class EmptyLines extends _react.Component { - - componentDidMount() { - this.disableEmptyLines(); - } - - componentDidUpdate() { - this.disableEmptyLines(); - } - - componentWillUnmount() { - var _props = this.props, - emptyLines = _props.emptyLines, - editor = _props.editor; - - - if (!emptyLines) { - return; - } - editor.codeMirror.operation(() => { - emptyLines.forEach(line => editor.codeMirror.removeLineClass(line, "line", "empty-line")); - }); - } - - disableEmptyLines() { - var _props2 = this.props, - emptyLines = _props2.emptyLines, - editor = _props2.editor; - - - if (!emptyLines) { - return; - } - editor.codeMirror.operation(() => { - emptyLines.forEach(line => editor.codeMirror.addLineClass(line, "line", "empty-line")); - }); - } - - render() { - return null; - } -} - -EmptyLines.displayName = "EmptyLines"; - -exports.default = (0, _reactRedux.connect)(state => { - var selectedSource = (0, _selectors.getSelectedSource)(state); - return { - selectedSource, - emptyLines: selectedSource ? (0, _selectors.getEmptyLines)(state, selectedSource.toJS()) : [] - }; -}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EmptyLines); - -/***/ }), /* 1145 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true @@ -44132,27 +44166,28 @@ class Outline extends _react.Component { } var selectedSourceId = selectedSource.get("id"); var startLine = location.start.line; selectSource(selectedSourceId, { line: startLine }); } renderFunction(func) { var name = func.name, - location = func.location; + location = func.location, + parameterNames = func.parameterNames; return _react2.default.createElement( "li", { key: `${name}:${location.start.line}:${location.start.column}`, className: "outline-list__element", onClick: () => this.selectItem(location) }, - _react2.default.createElement(_PreviewFunction2.default, { func: { name } }) + _react2.default.createElement(_PreviewFunction2.default, { func: { name, parameterNames } }) ); } renderFunctions() { var symbols = this.props.symbols; return symbols.functions.filter(func => func.name != "anonymous").map(func => this.renderFunction(func)); @@ -44185,82 +44220,96 @@ exports.default = (0, _reactRedux.connec return { symbols: (0, _selectors.getSymbols)(state, selectedSource && selectedSource.toJS()), selectedSource }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(Outline); /***/ }), /* 1146 */ -/***/ (function(module, exports) { - -// removed by extract-text-webpack-plugin - -/***/ }), -/* 1147 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Workers = undefined; - -var _react = __webpack_require__(0); - -var _react2 = _interopRequireDefault(_react); - -__webpack_require__(1149); +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); var _reactRedux = __webpack_require__(151); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class Workers extends _react.PureComponent { - renderWorkers(workers) { - return workers.map(w => _react2.default.createElement( - "div", - null, - w - )); - } - - renderNoWorkersPlaceholder() { - return L10N.getStr("noWorkersText"); - } - - render() { - var workers = this.props.workers; - - return _react2.default.createElement( - "div", - { className: "pane" }, - _react2.default.createElement( - "div", - { className: "pane-info" }, - workers && workers.length > 0 ? this.renderWorkers(workers) : this.renderNoWorkersPlaceholder() - ) - ); - } -} - -exports.Workers = Workers; -Workers.displayName = "Workers"; -Workers.propTypes = { - workers: _react.PropTypes.array.isRequired -}; - -function mapStateToProps(state) { - return { workers: [] }; -} -exports.default = (0, _reactRedux.connect)(mapStateToProps)(Workers); - -/***/ }), +var _redux = __webpack_require__(3); + +var _react = __webpack_require__(0); + +var _actions = __webpack_require__(244); + +var _actions2 = _interopRequireDefault(_actions); + +var _selectors = __webpack_require__(242); + +__webpack_require__(1161); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class EmptyLines extends _react.Component { + + componentDidMount() { + this.disableEmptyLines(); + } + + componentDidUpdate() { + this.disableEmptyLines(); + } + + componentWillUnmount() { + var _props = this.props, + emptyLines = _props.emptyLines, + editor = _props.editor; + + + if (!emptyLines) { + return; + } + editor.codeMirror.operation(() => { + emptyLines.forEach(line => editor.codeMirror.removeLineClass(line, "line", "empty-line")); + }); + } + + disableEmptyLines() { + var _props2 = this.props, + emptyLines = _props2.emptyLines, + editor = _props2.editor; + + + if (!emptyLines) { + return; + } + editor.codeMirror.operation(() => { + emptyLines.forEach(line => editor.codeMirror.addLineClass(line, "line", "empty-line")); + }); + } + + render() { + return null; + } +} + +EmptyLines.displayName = "EmptyLines"; + +exports.default = (0, _reactRedux.connect)(state => { + var selectedSource = (0, _selectors.getSelectedSource)(state); + return { + selectedSource, + emptyLines: selectedSource ? (0, _selectors.getEmptyLines)(state, selectedSource.toJS()) : [] + }; +}, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(EmptyLines); + +/***/ }), +/* 1147 */, /* 1148 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true @@ -44564,19 +44613,74 @@ exports.default = (0, _reactRedux.connec shownSource: (0, _selectors.getShownSource)(state), selectedSource: (0, _selectors.getSelectedSource)(state), debuggeeUrl: (0, _selectors.getDebuggeeUrl)(state) }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SourcesTree); /***/ }), /* 1149 */ -/***/ (function(module, exports) { - -// removed by extract-text-webpack-plugin +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Workers = undefined; + +var _react = __webpack_require__(0); + +var _react2 = _interopRequireDefault(_react); + +__webpack_require__(1162); + +var _reactRedux = __webpack_require__(151); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Workers extends _react.PureComponent { + renderWorkers(workers) { + return workers.map(w => _react2.default.createElement( + "div", + null, + w + )); + } + + renderNoWorkersPlaceholder() { + return L10N.getStr("noWorkersText"); + } + + render() { + var workers = this.props.workers; + + return _react2.default.createElement( + "div", + { className: "pane" }, + _react2.default.createElement( + "div", + { className: "pane-info" }, + workers && workers.length > 0 ? this.renderWorkers(workers) : this.renderNoWorkersPlaceholder() + ) + ); + } +} + +exports.Workers = Workers; +Workers.displayName = "Workers"; +Workers.propTypes = { + workers: _react.PropTypes.array.isRequired +}; + +function mapStateToProps(state) { + return { workers: [] }; +} +exports.default = (0, _reactRedux.connect)(mapStateToProps)(Workers); /***/ }), /* 1150 */, /* 1151 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45830,18 +45934,28 @@ exports.default = (0, _reactRedux.connec selectedSource, callSites: getCallSites(symbols, breakpoints), breakpoints: breakpoints }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(CallSites); /***/ }), /* 1160 */, -/* 1161 */, -/* 1162 */, +/* 1161 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }), +/* 1162 */ +/***/ (function(module, exports) { + +// removed by extract-text-webpack-plugin + +/***/ }), /* 1163 */, /* 1164 */, /* 1165 */, /* 1166 */, /* 1167 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46015,48 +46129,32 @@ class SymbolModal extends _react.Compone self.onChange = this.onChange.bind(this); self.onKeyUp = this.onKeyUp.bind(this); self.updateResults = this.updateResults.bind(this); self.traverseResults = this.traverseResults.bind(this); self.renderResults = this.renderResults.bind(this); self.buildSummaryMsg = this.buildSummaryMsg.bind(this); self.buildPlaceHolder = this.buildPlaceHolder.bind(this); self.selectResultItem = this.selectResultItem.bind(this); - self.openSymbolModal = this.openSymbolModal.bind(this); - } - - componentWillUnmount() { - var shortcuts = this.context.shortcuts; - shortcuts.off(L10N.getStr("symbolSearch.search.key2")); - shortcuts.off("Escape"); } componentDidMount() { - var shortcuts = this.context.shortcuts; - shortcuts.on(L10N.getStr("symbolSearch.search.key2"), this.openSymbolModal); - shortcuts.on("Escape", this.closeModal); this.updateResults(this.state.query); } componentDidUpdate(prevProps, prevState) { if (this.refs.resultList && this.refs.resultList.refs) { (0, _resultList.scrollList)(this.refs.resultList.refs, this.state.resultsIndex); } if (!prevProps.enabled && this.props.enabled) { this.updateResults(this.state.query); } } - openSymbolModal(_, e) { - e.preventDefault(); - e.stopPropagation(); - this.props.setActiveSearch("symbol"); - } - onClick(e) { e.stopPropagation(); } onChange(e) { var selectedSource = this.props.selectedSource; if (!selectedSource || !selectedSource.get("text")) { @@ -46065,17 +46163,16 @@ class SymbolModal extends _react.Compone this.setState({ query: e.target.value }); return this.updateResults(e.target.value); } closeModal() { this.props.closeActiveSearch(); this.props.clearHighlightLineRange(); - this.setState({ query: "" }); } selectResultItem(e, item) { var _props = this.props, selectSource = _props.selectSource, selectedSource = _props.selectedSource; @@ -46269,26 +46366,26 @@ function _getFormattedSymbols(state, sou variables: variables.map(formatSymbol), functions: functions.map(formatSymbol) }; } exports.default = (0, _reactRedux.connect)(state => { var source = (0, _selectors.getSelectedSource)(state); return { - enabled: Boolean((0, _selectors.getActiveSearchState)(state) === "symbol" && source), + enabled: Boolean((0, _selectors.getActiveSearch)(state) === "symbol" && source), symbolType: (0, _selectors.getSymbolSearchType)(state), symbols: _getFormattedSymbols(state, source) }; }, dispatch => (0, _redux.bindActionCreators)(_actions2.default, dispatch))(SymbolModal); /***/ }), /* 1171 */, /* 1172 */, /* 1173 */, /* 1174 */ /***/ (function(module, exports) { module.exports = "<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\" viewBox=\"0 0 400 400\" xml:space=\"preserve\" id=\"svg2\" version=\"1.1\"><metadata id=\"metadata8\"><rdf:RDF><cc:Work rdf:about><dc:format>image/svg+xml</dc:format><dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"></dc></cc:Work></rdf:RDF></metadata><defs id=\"defs6\"></defs><g transform=\"matrix(1.3333333,0,0,-1.3333333,0,400)\" id=\"g10\"><g transform=\"translate(178.0626,235.0086)\" id=\"g12\"><path id=\"path14\" style=\"fill:#41b883;fill-opacity:1;fill-rule:nonzero;stroke:none\" d=\"M 0,0 -22.669,-39.264 -45.338,0 h -75.491 L -22.669,-170.017 75.491,0 Z\"></path></g><g transform=\"translate(178.0626,235.0086)\" id=\"g16\"><path id=\"path18\" style=\"fill:#34495e;fill-opacity:1;fill-rule:nonzero;stroke:none\" d=\"M 0,0 -22.669,-39.264 -45.338,0 H -81.565 L -22.669,-102.01 36.227,0 Z\"></path></g></g></svg>" /***/ }) /******/ ]); -}); +}); \ No newline at end of file
--- a/devtools/client/debugger/new/parser-worker.js +++ b/devtools/client/debugger/new/parser-worker.js @@ -4121,55 +4121,17 @@ var baseCreate = (function() { return result; }; }()); module.exports = baseCreate; /***/ }), -/* 404 */ -/***/ (function(module, exports, __webpack_require__) { - -var isArrayLike = __webpack_require__(220), - isObjectLike = __webpack_require__(14); - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -module.exports = isArrayLikeObject; - - -/***/ }), +/* 404 */, /* 405 */, /* 406 */ /***/ (function(module, exports, __webpack_require__) { var assignValue = __webpack_require__(114), baseAssignValue = __webpack_require__(115); /** @@ -28512,63 +28474,61 @@ module.exports = basePropertyDeep; /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); + +var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + exports.getNextStep = getNextStep; var _debuggerHtml = __webpack_require__(843); var _types = __webpack_require__(844); var _closest = __webpack_require__(1055); -var _contains = __webpack_require__(1127); - var _helpers = __webpack_require__(1052); -function getNextStep(source, stepType, pausedPosition) { +function getNextStep(source, pausedPosition) { + var awaitExpression = getAwaitExpression(source, pausedPosition); + if (!awaitExpression) { + return null; + } + var awaitStatement = awaitExpression.getStatementParent(); + return getLocationAfterAwaitExpression(awaitStatement, pausedPosition); +} + +function getAwaitExpression(source, pausedPosition) { var closestPath = (0, _closest.getClosestPath)(source, pausedPosition); + if (!closestPath) { - return { nextStepType: stepType }; - } - if ((0, _helpers.isAwaitExpression)(closestPath, pausedPosition)) { - var nextHiddenBreakpointLocation = getLocationAfterAwaitExpression(closestPath, pausedPosition); - return { nextStepType: "resume", nextHiddenBreakpointLocation }; - } - return { nextStepType: stepType }; -} - -function getLocationAfterAwaitExpression(path, position) { - var children = getFunctionBodyChildren(path); - if (!children) { - return; - } - for (var i = 0; i !== children.length; i++) { - var child = children[i]; - if ((0, _contains.containsPosition)(child.loc, position)) { - var nextChild = children[++i]; - var nextLocation = nextChild.loc.start; - nextLocation.sourceId = position.sourceId; - return nextLocation; - } - } -} - -function getFunctionBodyChildren(path) { - var blockScope = path.scope.block; - if (!blockScope) { - return; - } - var children = blockScope.body.body; - return children; + return null; + } + + if ((0, _helpers.isAwaitExpression)(closestPath)) { + return closestPath; + } + + return closestPath.find(p => p.isAwaitExpression()); +} + +function getLocationAfterAwaitExpression(statement, position) { + var nextStatement = statement.getSibling(statement.key + 1); + if (nextStatement.node) { + return _extends({}, nextStatement.node.loc.start, { + sourceId: position.sourceId + }); + } + + return null; } /***/ }), /* 843 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -28932,16 +28892,18 @@ module.exports = { var _closest = __webpack_require__(1055); var _scopes = __webpack_require__(1049); var _getSymbols = __webpack_require__(1050); var _getSymbols2 = _interopRequireDefault(_getSymbols); +var _ast = __webpack_require__(1051); + var _getOutOfScopeLocations = __webpack_require__(1072); var _getOutOfScopeLocations2 = _interopRequireDefault(_getOutOfScopeLocations); var _steps = __webpack_require__(842); var _getEmptyLines = __webpack_require__(845); @@ -28954,16 +28916,17 @@ function _interopRequireDefault(obj) { r var workerHandler = _devtoolsUtils.workerUtils.workerHandler; self.onmessage = workerHandler({ getClosestExpression: _closest.getClosestExpression, getOutOfScopeLocations: _getOutOfScopeLocations2.default, getSymbols: _getSymbols2.default, clearSymbols: _getSymbols.clearSymbols, + clearASTs: _ast.clearASTs, getVariablesInScope: _scopes.getVariablesInScope, getNextStep: _steps.getNextStep, getEmptyLines: _getEmptyLines2.default }); /***/ }), /* 962 */, /* 963 */ @@ -29740,16 +29703,17 @@ function clearSymbols() { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAst = getAst; +exports.clearASTs = clearASTs; exports.traverseAst = traverseAst; var _parseScriptTags = __webpack_require__(1023); var _parseScriptTags2 = _interopRequireDefault(_parseScriptTags); var _babylon = __webpack_require__(435); @@ -29817,16 +29781,20 @@ function getAst(source) { } else if (source.contentType == "text/javascript") { ast = parse(source.text); } ASTs.set(source.id, ast); return ast; } +function clearASTs() { + ASTs = new Map(); +} + function traverseAst(source, visitor) { var ast = getAst(source); if ((0, _isEmpty2.default)(ast)) { return null; } (0, _babelTraverse2.default)(ast, visitor); return ast; @@ -32837,33 +32805,34 @@ exports.containsPosition = containsPosit exports.containsLocation = containsLocation; exports.nodeContainsPosition = nodeContainsPosition; function containsPosition(a, b) { var startsBefore = a.start.line < b.line || a.start.line === b.line && a.start.column <= b.column; var endsAfter = a.end.line > b.line || a.end.line === b.line && a.end.column >= b.column; return startsBefore && endsAfter; } + function containsLocation(a, b) { return containsPosition(a, b.start) && containsPosition(a, b.end); } function nodeContainsPosition(node, position) { return containsPosition(node.loc, position); } /***/ }), /* 1128 */, /* 1129 */ /***/ (function(module, exports, __webpack_require__) { var baseDifference = __webpack_require__(1131), baseFlatten = __webpack_require__(707), baseRest = __webpack_require__(411), - isArrayLikeObject = __webpack_require__(404); + isArrayLikeObject = __webpack_require__(1155); /** * Creates an array of `array` values not included in the other given arrays * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. The order and references of result values are * determined by the first array. * * **Note:** Unlike `_.pullAll`, this method returns a new array. @@ -32959,11 +32928,73 @@ function baseDifference(array, values, i } } return result; } module.exports = baseDifference; +/***/ }), +/* 1132 */, +/* 1133 */, +/* 1134 */, +/* 1135 */, +/* 1136 */, +/* 1137 */, +/* 1138 */, +/* 1139 */, +/* 1140 */, +/* 1141 */, +/* 1142 */, +/* 1143 */, +/* 1144 */, +/* 1145 */, +/* 1146 */, +/* 1147 */, +/* 1148 */, +/* 1149 */, +/* 1150 */, +/* 1151 */, +/* 1152 */, +/* 1153 */, +/* 1154 */, +/* 1155 */ +/***/ (function(module, exports, __webpack_require__) { + +var isArrayLike = __webpack_require__(220), + isObjectLike = __webpack_require__(14); + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +module.exports = isArrayLikeObject; + + /***/ }) /******/ ]); }); \ No newline at end of file
--- a/devtools/client/debugger/new/search-worker.js +++ b/devtools/client/debugger/new/search-worker.js @@ -312,17 +312,17 @@ function _interopRequireDefault(obj) { r */ function ignoreWhiteSpace(str) { return (/^\s{0,2}$/.test(str) ? "(?!\\s*.*)" : str ); } function wholeMatch(query, wholeWord) { - if (query == "" || !wholeWord) { + if (query === "" || !wholeWord) { return query; } return `\\b${query}\\b`; } function buildFlags(caseSensitive, isGlobal) { if (caseSensitive && isGlobal) { @@ -345,17 +345,17 @@ function buildQuery(originalQuery, modif isGlobal = _ref$isGlobal === undefined ? false : _ref$isGlobal, _ref$ignoreSpaces = _ref.ignoreSpaces, ignoreSpaces = _ref$ignoreSpaces === undefined ? false : _ref$ignoreSpaces; var caseSensitive = modifiers.caseSensitive, regexMatch = modifiers.regexMatch, wholeWord = modifiers.wholeWord; - if (originalQuery == "") { + if (originalQuery === "") { return new RegExp(originalQuery); } var query = originalQuery; if (ignoreSpaces) { query = ignoreWhiteSpace(query); } @@ -438,36 +438,30 @@ Object.defineProperty(exports, "__esModu exports.default = getMatches; var _buildQuery = __webpack_require__(1138); var _buildQuery2 = _interopRequireDefault(_buildQuery); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var MAX_LENGTH = 100000; - function getMatches(query, text, modifiers) { if (!query || !text || !modifiers) { return []; } var regexQuery = (0, _buildQuery2.default)(query, modifiers, { isGlobal: true }); var matchedLocations = []; var lines = text.split("\n"); for (var i = 0; i < lines.length; i++) { var singleMatch = void 0; var line = lines[i]; - if (line.length <= MAX_LENGTH) { - while ((singleMatch = regexQuery.exec(line)) !== null) { - matchedLocations.push({ line: i, ch: singleMatch.index }); - } - } else { - return []; + while ((singleMatch = regexQuery.exec(line)) !== null) { + matchedLocations.push({ line: i, ch: singleMatch.index }); } } return matchedLocations; } /***/ }), /***/ 121: @@ -868,23 +862,30 @@ function getSourceLineCount(source) { * @return String * @memberof utils/source * @static */ function getMode(source) { var contentType = source.contentType, text = source.text, - isWasm = source.isWasm; + isWasm = source.isWasm, + url = source.url; if (!text || isWasm) { return { name: "text" }; } + // if the url ends with .marko we set the name to Javascript so + // syntax highlighting works for marko too + if (url && url.match(/\.marko$/i)) { + return { name: "javascript" }; + } + // Use HTML mode for files in which the first non whitespace // character is `<` regardless of extension. var isHTMLLike = text.match(/^\s*</); if (!contentType) { if (isHTMLLike) { return { name: "htmlmixed" }; } return { name: "text" };
--- a/devtools/client/debugger/new/test/mochitest/browser.ini +++ b/devtools/client/debugger/new/test/mochitest/browser.ini @@ -43,16 +43,17 @@ support-files = examples/script-switching-02.js examples/script-switching-01.js examples/times2.js [browser_dbg-async-stepping.js] [browser_dbg-breaking.js] [browser_dbg-breaking-from-console.js] [browser_dbg-breakpoints.js] +[browser_dbg-breakpoints-toggle.js] [browser_dbg-breakpoints-reloading.js] skip-if = true # Bug 1383576 [browser_dbg-breakpoints-cond.js] [browser_dbg-call-stack.js] [browser_dbg-expressions.js] [browser_dbg-scopes.js] [browser_dbg-chrome-create.js] [browser_dbg-chrome-debugging.js]
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-async-stepping.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-async-stepping.js @@ -1,15 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests async stepping will: -// 1. step over await statements -// 2. step into async functions -// 3. step out of async functions +// Tests async stepping will step over await statements add_task(async function test() { Services.prefs.setBoolPref("devtools.debugger.features.async-stepping", true); const dbg = await initDebugger("doc-async.html", "async"); await selectSource(dbg, "async"); await addBreakpoint(dbg, "async", 8); invokeInTab("main");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking-from-console.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking-from-console.js @@ -4,30 +4,30 @@ // Tests that `debugger` statements are hit before the debugger even // initializes and it properly highlights the right location in the // debugger. async function waitOnToolbox(toolbox, event) { return new Promise(resolve => toolbox.on(event, resolve)); } -add_task(function*() { +add_task(async function() { const url = EXAMPLE_URL + "doc-script-switching.html"; - const toolbox = yield openNewTabAndToolbox(url, "webconsole"); + const toolbox = await openNewTabAndToolbox(url, "webconsole"); // Type "debugger" into console let jsterm = toolbox.getPanel("webconsole").hud.jsterm; jsterm.execute("debugger"); // Wait for the debugger to be selected and make sure it's paused - yield waitOnToolbox(toolbox, "jsdebugger-selected"); + await waitOnToolbox(toolbox, "jsdebugger-selected"); is(toolbox.threadClient.state, "paused"); // Create a dbg context const dbg = createDebuggerContext(toolbox); const { selectors: { getSelectedSource }, getState } = dbg; // Make sure the thread is paused in the right source and location - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); is(dbg.win.cm.getValue(), "debugger"); const source = getSelectedSource(getState()).toJS(); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js @@ -1,32 +1,32 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests the breakpoints are hit in various situations. -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getSelectedSource }, getState } = dbg; // Make sure we can set a top-level breakpoint and it will be hit on // reload. - yield addBreakpoint(dbg, "scripts.html", 18); + await addBreakpoint(dbg, "scripts.html", 18); reload(dbg); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); const paused = waitForPaused(dbg); // Create an eval script that pauses itself. invokeInTab("doEval"); - yield paused; - yield resume(dbg); + await paused; + await resume(dbg); const source = getSelectedSource(getState()).toJS(); ok(!source.url, "It is an eval source"); - yield addBreakpoint(dbg, source, 5); + await addBreakpoint(dbg, source, 5); invokeInTab("evaledFunc"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js @@ -19,56 +19,54 @@ function assertEditorBreakpoint(dbg, lin exists === shouldExist, "Breakpoint " + (shouldExist ? "exists" : "does not exist") + " on line " + line ); } -function setConditionalBreakpoint(dbg, index, condition) { - return Task.spawn(function*() { - rightClickElement(dbg, "gutter", index); - selectMenuItem(dbg, 2); - yield waitForElement(dbg, ".conditional-breakpoint-panel input"); - findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus(); - // Position cursor reliably at the end of the text. - pressKey(dbg, "End"); - type(dbg, condition); - pressKey(dbg, "Enter"); - }); +async function setConditionalBreakpoint(dbg, index, condition) { + rightClickElement(dbg, "gutter", index); + selectMenuItem(dbg, 2); + await waitForElement(dbg, ".conditional-breakpoint-panel input"); + findElementWithSelector(dbg, ".conditional-breakpoint-panel input").focus(); + // Position cursor reliably at the end of the text. + pressKey(dbg, "End"); + type(dbg, condition); + pressKey(dbg, "Enter"); } -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); - yield selectSource(dbg, "simple2"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); + await selectSource(dbg, "simple2"); // Adding a conditional Breakpoint - yield setConditionalBreakpoint(dbg, 5, "1"); - yield waitForDispatch(dbg, "ADD_BREAKPOINT"); + await setConditionalBreakpoint(dbg, 5, "1"); + await waitForDispatch(dbg, "ADD_BREAKPOINT"); let bp = findBreakpoint(dbg, "simple2", 5); is(bp.condition, "1", "breakpoint is created with the condition"); assertEditorBreakpoint(dbg, 5, true); // Editing a conditional Breakpoint - yield setConditionalBreakpoint(dbg, 5, "2"); - yield waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION"); + await setConditionalBreakpoint(dbg, 5, "2"); + await waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION"); bp = findBreakpoint(dbg, "simple2", 5); is(bp.condition, "12", "breakpoint is created with the condition"); assertEditorBreakpoint(dbg, 5, true); // Removing a conditional breakpoint clickElement(dbg, "gutter", 5); - yield waitForDispatch(dbg, "REMOVE_BREAKPOINT"); + await waitForDispatch(dbg, "REMOVE_BREAKPOINT"); bp = findBreakpoint(dbg, "simple2", 5); is(bp, null, "breakpoint was removed"); assertEditorBreakpoint(dbg, 5, false); // Adding a condition to a breakpoint clickElement(dbg, "gutter", 5); - yield waitForDispatch(dbg, "ADD_BREAKPOINT"); - yield setConditionalBreakpoint(dbg, 5, "1"); - yield waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION"); + await waitForDispatch(dbg, "ADD_BREAKPOINT"); + await setConditionalBreakpoint(dbg, 5, "1"); + await waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION"); bp = findBreakpoint(dbg, "simple2", 5); is(bp.condition, "1", "breakpoint is created with the condition"); assertEditorBreakpoint(dbg, 5, true); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-reloading.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-reloading.js @@ -18,27 +18,27 @@ function addBreakpoint(dbg, line) { return waitForDispatch(dbg, "ADD_BREAKPOINT"); } function assertEditorBreakpoint(dbg, line) { const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint"); ok(exists, `Breakpoint exists on line ${line}`); } -add_task(function*() { +add_task(async function() { requestLongerTimeout(3); - const dbg = yield initDebugger("doc-scripts.html"); + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getBreakpoints, getBreakpoint }, getState } = dbg; const source = findSource(dbg, "simple1.js"); - yield selectSource(dbg, source.url); - yield addBreakpoint(dbg, 5); - yield addBreakpoint(dbg, 4); + await selectSource(dbg, source.url); + await addBreakpoint(dbg, 5); + await addBreakpoint(dbg, 4); const syncedBps = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2); - yield reload(dbg, "simple1"); - yield waitForSelectedSource(dbg); - yield syncedBps; + await reload(dbg, "simple1"); + await waitForSelectedSource(dbg); + await syncedBps; assertEditorBreakpoint(dbg, 4); assertEditorBreakpoint(dbg, 5); });
new file mode 100644 --- /dev/null +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-toggle.js @@ -0,0 +1,87 @@ +function toggleBreakpoint(dbg, index) { + const bp = findElement(dbg, "breakpointItem", index); + const input = bp.querySelector("input"); + input.click(); +} + +async function removeBreakpoint(dbg, index) { + const removed = waitForDispatch(dbg, "REMOVE_BREAKPOINT"); + const bp = findElement(dbg, "breakpointItem", index); + bp.querySelector(".close-btn").click(); + await removed; +} + +async function disableBreakpoint(dbg, index) { + const disabled = waitForDispatch(dbg, "DISABLE_BREAKPOINT"); + toggleBreakpoint(dbg, index); + await disabled; +} + +async function enableBreakpoint(dbg, index) { + const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT"); + toggleBreakpoint(dbg, index); + await enabled; +} + +function toggleBreakpoints(dbg, count) { + clickElement(dbg, "toggleBreakpoints"); +} + +function disableBreakpoints(dbg, count) { + const toggled = waitForDispatch(dbg, "DISABLE_BREAKPOINT", count); + toggleBreakpoints(dbg); + return toggled; +} + +function enableBreakpoints(dbg, count) { + const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT", count); + toggleBreakpoints(dbg); + return enabled; +} + +function findBreakpoint(dbg, url, line) { + const { selectors: { getBreakpoint }, getState } = dbg; + const source = findSource(dbg, url); + return getBreakpoint(getState(), { sourceId: source.id, line }); +} + +function findBreakpoints(dbg) { + const { selectors: { getBreakpoints }, getState } = dbg; + return getBreakpoints(getState()); +} + +// toggle all breakpoints +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html", "simple2"); + + // Create two breakpoints + await selectSource(dbg, "simple2"); + await addBreakpoint(dbg, "simple2", 3); + await addBreakpoint(dbg, "simple2", 5); + + // Disable all of the breakpoints + await disableBreakpoints(dbg, 2); + let bp1 = findBreakpoint(dbg, "simple2", 3); + let bp2 = findBreakpoint(dbg, "simple2", 5); + + if (!bp2) { + debugger; + } + + is(bp1.disabled, true, "first breakpoint is disabled"); + is(bp2.disabled, true, "second breakpoint is disabled"); + + // Enable all of the breakpoints + await enableBreakpoints(dbg, 2); + bp1 = findBreakpoint(dbg, "simple2", 3); + bp2 = findBreakpoint(dbg, "simple2", 5); + + is(bp1.disabled, false, "first breakpoint is enabled"); + is(bp2.disabled, false, "second breakpoint is enabled"); + + // Remove the breakpoints + await removeBreakpoint(dbg, 1); + await removeBreakpoint(dbg, 1); + const bps = findBreakpoints(dbg); + is(bps.size, 0, "breakpoints are removed"); +});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints.js @@ -2,106 +2,75 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ function toggleBreakpoint(dbg, index) { const bp = findElement(dbg, "breakpointItem", index); const input = bp.querySelector("input"); input.click(); } -function removeBreakpoint(dbg, index) { - return Task.spawn(function*() { - const bp = findElement(dbg, "breakpointItem", index); - bp.querySelector(".close-btn").click(); - yield waitForDispatch(dbg, "REMOVE_BREAKPOINT"); - }); +async function removeBreakpoint(dbg, index) { + const removed = waitForDispatch(dbg, "REMOVE_BREAKPOINT"); + const bp = findElement(dbg, "breakpointItem", index); + bp.querySelector(".close-btn").click(); + await removed; } -function disableBreakpoint(dbg, index) { - return Task.spawn(function*() { - toggleBreakpoint(dbg, index); - yield waitForDispatch(dbg, "DISABLE_BREAKPOINT"); - }); +async function disableBreakpoint(dbg, index) { + const disabled = waitForDispatch(dbg, "DISABLE_BREAKPOINT"); + toggleBreakpoint(dbg, index); + await disabled; } -function enableBreakpoint(dbg, index) { - return Task.spawn(function*() { - toggleBreakpoint(dbg, index); - yield waitForDispatch(dbg, "ENABLE_BREAKPOINT"); - }); +async function enableBreakpoint(dbg, index) { + const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT"); + toggleBreakpoint(dbg, index); + await enabled; } function toggleBreakpoints(dbg, count) { clickElement(dbg, "toggleBreakpoints"); } function disableBreakpoints(dbg, count) { + const toggled = waitForDispatch(dbg, "DISABLE_BREAKPOINT", count); toggleBreakpoints(dbg); - return waitForDispatch(dbg, "DISABLE_BREAKPOINT", count); + return toggled; } function enableBreakpoints(dbg, count) { + const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT", count); toggleBreakpoints(dbg); - return waitForDispatch(dbg, "ENABLE_BREAKPOINT", count); + return enabled; } function findBreakpoint(dbg, url, line) { const { selectors: { getBreakpoint }, getState } = dbg; const source = findSource(dbg, url); return getBreakpoint(getState(), { sourceId: source.id, line }); } function findBreakpoints(dbg) { const { selectors: { getBreakpoints }, getState } = dbg; return getBreakpoints(getState()); } -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); // Create two breakpoints - yield selectSource(dbg, "simple2"); - yield addBreakpoint(dbg, "simple2", 3); - yield addBreakpoint(dbg, "simple2", 5); + await selectSource(dbg, "simple2"); + await addBreakpoint(dbg, "simple2", 3); + await addBreakpoint(dbg, "simple2", 5); // Disable the first one - yield disableBreakpoint(dbg, 1); + await disableBreakpoint(dbg, 1); let bp1 = findBreakpoint(dbg, "simple2", 3); let bp2 = findBreakpoint(dbg, "simple2", 5); is(bp1.disabled, true, "first breakpoint is disabled"); is(bp2.disabled, false, "second breakpoint is enabled"); // Disable and Re-Enable the second one - yield disableBreakpoint(dbg, 2); - yield enableBreakpoint(dbg, 2); + await disableBreakpoint(dbg, 2); + await enableBreakpoint(dbg, 2); bp2 = findBreakpoint(dbg, "simple2", 5); is(bp2.disabled, false, "second breakpoint is enabled"); }); - -// toggle all -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); - - // Create two breakpoints - yield selectSource(dbg, "simple2"); - yield addBreakpoint(dbg, "simple2", 3); - yield addBreakpoint(dbg, "simple2", 5); - - // Disable all of the breakpoints - yield disableBreakpoints(dbg, 2); - let bp1 = findBreakpoint(dbg, "simple2", 3); - let bp2 = findBreakpoint(dbg, "simple2", 5); - is(bp1.disabled, true, "first breakpoint is disabled"); - is(bp2.disabled, true, "second breakpoint is disabled"); - - // Enable all of the breakpoints - yield enableBreakpoints(dbg, 2); - bp1 = findBreakpoint(dbg, "simple2", 3); - bp2 = findBreakpoint(dbg, "simple2", 5); - is(bp1.disabled, false, "first breakpoint is enabled"); - is(bp2.disabled, false, "second breakpoint is enabled"); - - // Remove the breakpoints - yield removeBreakpoint(dbg, 1); - yield removeBreakpoint(dbg, 1); - const bps = findBreakpoints(dbg); - is(bps.size, 0, "breakpoints are removed"); -});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-call-stack.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-call-stack.js @@ -12,40 +12,40 @@ function isFrameSelected(dbg, index, tit return elSelected && titleSelected; } function toggleButton(dbg) { const callStackBody = findElement(dbg, "callStackBody"); return callStackBody.querySelector(".show-more"); } -add_task(function* () { - const dbg = yield initDebugger("doc-script-switching.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html"); toggleCallStack(dbg); const notPaused = findElement(dbg, "callStackBody").innerText; is(notPaused, "Not Paused", "Not paused message is shown"); invokeInTab("firstCall"); - yield waitForPaused(dbg); + await waitForPaused(dbg); ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected"); let button = toggleButton(dbg); ok(!button, "toggle button shouldn't be there"); }); -add_task(function* () { - const dbg = yield initDebugger("doc-frames.html"); +add_task(async function() { + const dbg = await initDebugger("doc-frames.html"); toggleCallStack(dbg); invokeInTab("startRecursion"); - yield waitForPaused(dbg); + await waitForPaused(dbg); ok(isFrameSelected(dbg, 1, "recurseA"), "the first frame is selected"); // check to make sure that the toggle button isn't there let button = toggleButton(dbg); let frames = findAllElements(dbg, "frames"); is(button.innerText, "Expand Rows", "toggle button should be expand"); is(frames.length, 7, "There should be at most seven frames");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-chrome-create.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-chrome-create.js @@ -37,22 +37,22 @@ function onClose() { finish(); } registerCleanupFunction(function() { Services.prefs.clearUserPref("devtools.debugger.remote-enabled"); gProcess = null; }); -add_task(function*() { +add_task(async function() { // Windows XP and 8.1 test slaves are terribly slow at this test. requestLongerTimeout(5); Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true); - gProcess = yield initChromeDebugger(); + gProcess = await initChromeDebugger(); ok( gProcess._dbgProcess, "The remote debugger process wasn't created properly!" ); ok( gProcess._dbgProcess.exitCode == null, "The remote debugger process isn't running!" @@ -76,10 +76,10 @@ add_task(function*() { is( gProcess._dbgProfilePath, OS.Path.join(OS.Constants.Path.profileDir, "chrome_debugger_profile"), "The remote debugger profile isn't where we expect it!" ); info("profile path: " + gProcess._dbgProfilePath); - yield gProcess.close(); + await gProcess.close(); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-chrome-debugging.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-chrome-debugging.js @@ -63,26 +63,26 @@ registerCleanupFunction(function() { gThreadClient = null; gNewGlobal = null; gNewChromeSource = null; customLoader = null; DebuggerServer = null; }); -add_task(function*() { +add_task(async function() { gClient = initDebuggerClient(); - const [type] = yield gClient.connect(); + const [type] = await gClient.connect(); is(type, "browser", "Root actor should identify itself as a browser."); - const response = yield gClient.getProcess(); + const response = await gClient.getProcess(); let actor = response.form.actor; - gThreadClient = yield attachThread(gClient, actor); + gThreadClient = await attachThread(gClient, actor); gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:mozilla"); // listen for a new source and global gThreadClient.addListener("newSource", onNewSource); gClient.addListener("newGlobal", onNewGlobal); - yield promise.all([gNewGlobal.promise, gNewChromeSource.promise]); + await promise.all([gNewGlobal.promise, gNewChromeSource.promise]); - yield resumeAndCloseConnection(); + await resumeAndCloseConnection(); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js @@ -20,26 +20,27 @@ function getSplitConsole(dbg) { toolbox.getPanelWhenReady("webconsole").then(() => { ok(toolbox.splitConsole, "Split console is shown."); let jsterm = toolbox.getPanel("webconsole").hud.jsterm; resolve(jsterm); }); }); } -add_task(function* () { +add_task(async function() { Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); - const dbg = yield initDebugger("doc-script-switching.html"); + const dbg = await initDebugger("doc-script-switching.html"); - yield selectSource(dbg, "switching-01"); + await selectSource(dbg, "switching-01"); // open the console - yield getSplitConsole(dbg); + await getSplitConsole(dbg); ok(dbg.toolbox.splitConsole, "Split console is shown."); // close the console - clickElement(dbg, "codeMirror"); + await clickElement(dbg, "codeMirror"); // First time to focus out of text area pressKey(dbg, "Escape"); + // Second time to hide console pressKey(dbg, "Escape"); ok(!dbg.toolbox.splitConsole, "Split console is hidden."); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-debugger-buttons.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-debugger-buttons.js @@ -19,36 +19,36 @@ function clickStepOut(dbg) { /** * Test debugger buttons * 1. resume * 2. stepOver * 3. stepIn * 4. stepOver to the end of a function * 5. stepUp at the end of a function */ -add_task(function*() { - const dbg = yield initDebugger("doc-debugger-statements.html"); +add_task(async function() { + const dbg = await initDebugger("doc-debugger-statements.html"); - yield reload(dbg); - yield waitForPaused(dbg); + await reload(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // resume clickElement(dbg, "resume"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // step over - yield clickStepOver(dbg); + await clickStepOver(dbg); assertPausedLocation(dbg); // step into - yield clickStepIn(dbg); + await clickStepIn(dbg); assertPausedLocation(dbg); // step over - yield clickStepOver(dbg); + await clickStepOver(dbg); assertPausedLocation(dbg); // step out - yield clickStepOut(dbg); + await clickStepOut(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-gutter.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-gutter.js @@ -20,27 +20,27 @@ function assertEditorBreakpoint(dbg, lin exists === shouldExist, "Breakpoint " + (shouldExist ? "exists" : "does not exist") + " on line " + line ); } -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getBreakpoints, getBreakpoint }, getState } = dbg; const source = findSource(dbg, "simple1.js"); - yield selectSource(dbg, source.url); + await selectSource(dbg, source.url); // Make sure that clicking the gutter creates a breakpoint icon. clickGutter(dbg, 4); - yield waitForDispatch(dbg, "ADD_BREAKPOINT"); + await waitForDispatch(dbg, "ADD_BREAKPOINT"); is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); assertEditorBreakpoint(dbg, 4, true); // Make sure clicking at the same place removes the icon. clickGutter(dbg, 4); - yield waitForDispatch(dbg, "REMOVE_BREAKPOINT"); + await waitForDispatch(dbg, "REMOVE_BREAKPOINT"); is(getBreakpoints(getState()).size, 0, "No breakpoints exist"); assertEditorBreakpoint(dbg, 4, false); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-highlight.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-highlight.js @@ -1,51 +1,51 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that the editor will always highight the right line, no // matter if the source text doesn't exist yet or even if the source // doesn't exist. -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getSource }, getState } = dbg; const sourceUrl = EXAMPLE_URL + "long.js"; // The source itself doesn't even exist yet, and using // `selectSourceURL` will set a pending request to load this source // and highlight a specific line. dbg.actions.selectSourceURL(sourceUrl, { line: 66 }); // Wait for the source text to load and make sure we're in the right // place. - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); // TODO: revisit highlighting lines when the debugger opens //assertHighlightLocation(dbg, "long.js", 66); // Jump to line 16 and make sure the editor scrolled. - yield selectSource(dbg, "long.js", 16); + await selectSource(dbg, "long.js", 16); assertHighlightLocation(dbg, "long.js", 16); // Make sure only one line is ever highlighted and the flash // animation is cancelled on old lines. - yield selectSource(dbg, "long.js", 17); - yield selectSource(dbg, "long.js", 18); + await selectSource(dbg, "long.js", 17); + await selectSource(dbg, "long.js", 18); assertHighlightLocation(dbg, "long.js", 18); is( findAllElements(dbg, "highlightLine").length, 1, "Only 1 line is highlighted" ); // Test jumping to a line in a source that exists but hasn't been // loaded yet. selectSource(dbg, "simple1.js", 6); // Make sure the source is in the loading state, wait for it to be // fully loaded, and check the highlighted line. const simple1 = findSource(dbg, "simple1.js"); ok(getSource(getState(), simple1.id).get("loadedState")); - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); ok(getSource(getState(), simple1.id).get("text")); assertHighlightLocation(dbg, "simple1.js", 6); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-mode.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-mode.js @@ -1,14 +1,14 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that the editor sets the correct mode for different file // types -add_task(function* () { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); - yield selectSource(dbg, "simple1.js"); + await selectSource(dbg, "simple1.js"); is(dbg.win.cm.getOption("mode").name, "javascript", "Mode is correct"); - yield selectSource(dbg, "doc-scripts.html"); + await selectSource(dbg, "doc-scripts.html"); is(dbg.win.cm.getOption("mode").name, "htmlmixed", "Mode is correct"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-select.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-select.js @@ -6,49 +6,49 @@ // checks to see if the first breakpoint is visible function isElementVisible(dbg, elementName) { const bpLine = findElement(dbg, elementName); const cm = findElement(dbg, "codeMirror"); return bpLine && isVisibleWithin(cm, bpLine); } -add_task(function*() { +add_task(async function() { // This test runs too slowly on linux debug. I'd like to figure out // which is the slowest part of this and make it run faster, but to // fix a frequent failure allow a longer timeout. requestLongerTimeout(2); - const dbg = yield initDebugger("doc-scripts.html"); + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getSelectedSource }, getState } = dbg; const simple1 = findSource(dbg, "simple1.js"); const simple2 = findSource(dbg, "simple2.js"); // Set the initial breakpoint. - yield addBreakpoint(dbg, simple1, 4); + await addBreakpoint(dbg, simple1, 4); ok(!getSelectedSource(getState()), "No selected source"); // Call the function that we set a breakpoint in. invokeInTab("main"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // Step through to another file and make sure it's paused in the // right place. - yield stepIn(dbg); + await stepIn(dbg); assertPausedLocation(dbg); // Step back out to the initial file. - yield stepOut(dbg); - yield stepOut(dbg); + await stepOut(dbg); + await stepOut(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); // Make sure that we can set a breakpoint on a line out of the // viewport, and that pausing there scrolls the editor to it. let longSrc = findSource(dbg, "long.js"); - yield addBreakpoint(dbg, longSrc, 66); + await addBreakpoint(dbg, longSrc, 66); invokeInTab("testModel"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); ok(isElementVisible(dbg, "breakpoint"), "Breakpoint is visible"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-expressions.js @@ -48,37 +48,37 @@ async function editExpression(dbg, input dblClickElement(dbg, "expressionNode", 1); // Position cursor reliably at the end of the text. pressKey(dbg, "End"); type(dbg, input); pressKey(dbg, "Enter"); await waitForDispatch(dbg, "EVALUATE_EXPRESSION"); } -add_task(function*() { - const dbg = yield initDebugger("doc-script-switching.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html"); invokeInTab("firstCall"); - yield waitForPaused(dbg); + await waitForPaused(dbg); - yield addExpression(dbg, "f"); + await addExpression(dbg, "f"); is(getLabel(dbg, 1), "f"); is(getValue(dbg, 1), "(unavailable)"); - yield editExpression(dbg, "oo"); + await editExpression(dbg, "oo"); is(getLabel(dbg, 1), "foo()"); // There is no "value" element for functions. assertEmptyValue(dbg, 1); - yield addExpression(dbg, "location"); + await addExpression(dbg, "location"); is(getLabel(dbg, 2), "location"); ok(getValue(dbg, 2).includes("Location"), "has a value"); // can expand an expression toggleExpression(dbg, 2); - yield waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES"); + await waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES"); - yield deleteExpression(dbg, "foo"); - yield deleteExpression(dbg, "location"); + await deleteExpression(dbg, "foo"); + await deleteExpression(dbg, "location"); is(findAllElements(dbg, "expressionNodes").length, 0); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-iframes.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-iframes.js @@ -1,26 +1,26 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Test debugging a page with iframes * 1. pause in the main thread * 2. pause in the iframe */ -add_task(function*() { - const dbg = yield initDebugger("doc-iframes.html"); +add_task(async function() { + const dbg = await initDebugger("doc-iframes.html"); // test pausing in the main thread - yield reload(dbg); - yield waitForPaused(dbg); + await reload(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // test pausing in the iframe - yield resume(dbg); - yield waitForPaused(dbg); + await resume(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // test pausing in the iframe - yield resume(dbg); - yield waitForPaused(dbg); + await resume(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-navigation.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-navigation.js @@ -5,46 +5,48 @@ function countSources(dbg) { const sources = dbg.selectors.getSources(dbg.getState()); return sources.size; } /** * Test navigating * navigating while paused will reset the pause state and sources */ -add_task(function*() { - const dbg = yield initDebugger("doc-script-switching.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html"); const { selectors: { getSelectedSource, getPause }, getState } = dbg; invokeInTab("firstCall"); - yield waitForPaused(dbg); + await waitForPaused(dbg); - yield navigate(dbg, "doc-scripts.html", "simple1.js"); - yield addBreakpoint(dbg, "simple1.js", 4); + await navigate(dbg, "doc-scripts.html", "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 4); invokeInTab("main"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); is(countSources(dbg), 4, "4 sources are loaded."); - yield navigate(dbg, "about:blank"); - yield waitForDispatch(dbg, "NAVIGATE"); + await navigate(dbg, "about:blank"); + await waitForDispatch(dbg, "NAVIGATE"); is(countSources(dbg), 0, "0 sources are loaded."); ok(!getPause(getState()), "No pause state exists"); - yield navigate( + await navigate( dbg, "doc-scripts.html", "simple1.js", "simple2.js", "long.js", "scripts.html" ); is(countSources(dbg), 4, "4 sources are loaded."); // Test that the current select source persists across reloads - yield selectSource(dbg, "long.js"); - yield reload(dbg, "long.js"); + await selectSource(dbg, "long.js"); + await reload(dbg, "long.js"); ok( - getSelectedSource(getState()).get("url").includes("long.js"), + getSelectedSource(getState()) + .get("url") + .includes("long.js"), "Selected source is long.js" ); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pause-exceptions.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pause-exceptions.js @@ -11,35 +11,35 @@ function caughtException() { /* Tests Pausing on exception 1. skip an uncaught exception 2. pause on an uncaught exception 3. pause on a caught error 4. skip a caught error */ -add_task(function*() { - const dbg = yield initDebugger("doc-exceptions.html"); +add_task(async function() { + const dbg = await initDebugger("doc-exceptions.html"); // test skipping an uncaught exception - yield uncaughtException(); + await uncaughtException(); ok(!isPaused(dbg)); // Test pausing on an uncaught exception - yield togglePauseOnExceptions(dbg, true, false); + await togglePauseOnExceptions(dbg, true, false); uncaughtException(); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); // Test pausing on a caught Error caughtException(); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); // Test skipping a caught error - yield togglePauseOnExceptions(dbg, true, true); + await togglePauseOnExceptions(dbg, true, true); caughtException(); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-paused.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-paused.js @@ -1,23 +1,23 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests pretty-printing a source that is currently paused. -add_task(function*() { - const dbg = yield initDebugger("doc-minified.html"); +add_task(async function() { + const dbg = await initDebugger("doc-minified.html"); - yield selectSource(dbg, "math.min.js"); - yield addBreakpoint(dbg, "math.min.js", 2); + await selectSource(dbg, "math.min.js"); + await addBreakpoint(dbg, "math.min.js", 2); invokeInTab("arithmetic"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); clickElement(dbg, "prettyPrintButton"); - yield waitForDispatch(dbg, "SELECT_SOURCE"); + await waitForDispatch(dbg, "SELECT_SOURCE"); // this doesnt work yet // assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print.js @@ -1,35 +1,35 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests basic pretty-printing functionality. -add_task(function*() { - const dbg = yield initDebugger("doc-minified.html"); +add_task(async function() { + const dbg = await initDebugger("doc-minified.html"); - yield selectSource(dbg, "math.min.js", 2); + await selectSource(dbg, "math.min.js", 2); clickElement(dbg, "prettyPrintButton"); - yield waitForSource(dbg, "math.min.js:formatted"); + await waitForSource(dbg, "math.min.js:formatted"); const ppSrc = findSource(dbg, "math.min.js:formatted"); ok(ppSrc, "Pretty-printed source exists"); // this is not implemented yet // assertHighlightLocation(dbg, "math.min.js:formatted", 18); - yield addBreakpoint(dbg, ppSrc, 18); + await addBreakpoint(dbg, ppSrc, 18); invokeInTab("arithmetic"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield stepOver(dbg); + await stepOver(dbg); assertPausedLocation(dbg); - yield resume(dbg); + await resume(dbg); // The pretty-print button should go away in the pretty-printed // source. ok(!findElement(dbg, "editorFooter"), "Footer is hidden"); - yield selectSource(dbg, "math.min.js"); + await selectSource(dbg, "math.min.js"); ok(findElement(dbg, "editorFooter"), "Footer is hidden"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-scopes-mutations.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-scopes-mutations.js @@ -18,74 +18,74 @@ function expandNode(dbg, index) { function toggleScopes(dbg) { return findElement(dbg, "scopesHeader").click(); } function onLoadObjectProperties(dbg) { return waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES"); } -add_task(function*() { - const dbg = yield initDebugger("doc-script-mutate.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-mutate.html"); toggleScopes(dbg); let onPaused = waitForPaused(dbg); invokeInTab("mutate"); - yield onPaused; + await onPaused; is( getScopeNodeLabel(dbg, 2), "<this>", 'The second element in the scope panel is "<this>"' ); is( getScopeNodeLabel(dbg, 3), "phonebook", 'The third element in the scope panel is "phonebook"' ); info("Expand `phonebook`"); - yield expandNode(dbg, 3); + await expandNode(dbg, 3); is( getScopeNodeLabel(dbg, 4), "S", 'The fourth element in the scope panel is "S"' ); info("Expand `S`"); - yield expandNode(dbg, 4); + await expandNode(dbg, 4); is( getScopeNodeLabel(dbg, 5), "sarah", 'The fifth element in the scope panel is "sarah"' ); is( getScopeNodeLabel(dbg, 6), "serena", 'The sixth element in the scope panel is "serena"' ); info("Expand `sarah`"); - yield expandNode(dbg, 5); + await expandNode(dbg, 5); is( getScopeNodeLabel(dbg, 6), "lastName", 'The sixth element in the scope panel is now "lastName"' ); is( getScopeNodeValue(dbg, 6), '"Doe"', 'The "lastName" element has the expected "Doe" value' ); info("Resuming"); onPaused = waitForPaused(dbg); - yield resume(dbg); - yield onPaused; + await resume(dbg); + await onPaused; is( getScopeNodeLabel(dbg, 2), "<this>", 'The second element in the scope panel is "<this>"' ); is( getScopeNodeLabel(dbg, 3),
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-scopes.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-scopes.js @@ -4,28 +4,28 @@ function toggleNode(dbg, index) { clickElement(dbg, "scopeNode", index); } function getLabel(dbg, index) { return findElement(dbg, "scopeNode", index).innerText; } -add_task(function*() { - const dbg = yield initDebugger("doc-script-switching.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html"); toggleScopes(dbg); invokeInTab("firstCall"); - yield waitForPaused(dbg); + await waitForPaused(dbg); is(getLabel(dbg, 1), "secondCall"); is(getLabel(dbg, 2), "<this>"); is(getLabel(dbg, 4), "foo()"); toggleNode(dbg, 4); - yield waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES"); + await waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES"); is(getLabel(dbg, 5), "arguments"); - yield stepOver(dbg); + await stepOver(dbg); is(getLabel(dbg, 4), "foo()"); is(getLabel(dbg, 5), "Window"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-file.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-file.js @@ -7,40 +7,40 @@ function waitForSearchState(dbg) { return waitForState(dbg, () => getCM(dbg).state.search); } function getFocusedEl(dbg) { let doc = dbg.win.document; return doc.activeElement; } -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); const { selectors: { getBreakpoints, getBreakpoint, getActiveSearch }, getState } = dbg; const source = findSource(dbg, "simple1.js"); - yield selectSource(dbg, source.url); + await selectSource(dbg, source.url); const cm = getCM(dbg); pressKey(dbg, "fileSearch"); - is(dbg.selectors.getActiveSearchState(dbg.getState()), "file"); + is(dbg.selectors.getActiveSearch(dbg.getState()), "file"); // test closing and re-opening pressKey(dbg, "Escape"); - is(dbg.selectors.getActiveSearchState(dbg.getState()), null); + is(dbg.selectors.getActiveSearch(dbg.getState()), null); pressKey(dbg, "fileSearch"); const el = getFocusedEl(dbg); type(dbg, "con"); - yield waitForSearchState(dbg); + await waitForSearchState(dbg); const state = cm.state.search; pressKey(dbg, "Enter"); is(state.posFrom.line, 3); pressKey(dbg, "Enter"); is(state.posFrom.line, 4); @@ -50,12 +50,12 @@ add_task(function*() { pressKey(dbg, "fileSearch"); type(dbg, "fun"); pressKey(dbg, "Enter"); is(state.posFrom.line, 4); // selecting another source keeps search open - yield selectSource(dbg, "simple2"); + await selectSource(dbg, "simple2"); pressKey(dbg, "Enter"); is(state.posFrom.line, 0); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js @@ -1,68 +1,67 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ function openProjectSearch(dbg) { synthesizeKeyShortcut("CmdOrCtrl+Shift+F"); return waitForState( dbg, - state => dbg.selectors.getActiveSearchState(state) === "project" + state => dbg.selectors.getActiveSearch(state) === "project" ); } function closeProjectSearch(dbg) { pressKey(dbg, "Escape"); - return waitForState(dbg, state => !dbg.selectors.getActiveSearchState(state)); -} - -function getResult(dbg) { - return findElementWithSelector(dbg, ".managed-tree .result"); + return waitForState(dbg, state => !dbg.selectors.getActiveSearch(state)); } async function selectResult(dbg) { - const item = getResult(dbg); - const select = waitForDispatch(dbg, "SELECT_SOURCE"); - item.click(); + const select = waitForState( + dbg, + () => !dbg.selectors.getActiveSearch(dbg.getState()) + ); + await clickElement(dbg, "fileMatch"); return select; } function getResultsCount(dbg) { const matches = dbg.selectors .getTextSearchResults(dbg.getState()) .valueSeq() .map(file => file.matches) .toJS(); return [...matches].length; } // Testing project search -add_task(function*() { +add_task(async function() { Services.prefs.setBoolPref( "devtools.debugger.project-text-search-enabled", true ); - const dbg = yield initDebugger("doc-script-switching.html", "switching-01"); + const dbg = await initDebugger("doc-script-switching.html", "switching-01"); - yield selectSource(dbg, "switching-01"); + await selectSource(dbg, "switching-01"); // test opening and closing - yield openProjectSearch(dbg); - yield closeProjectSearch(dbg); + await openProjectSearch(dbg); + await closeProjectSearch(dbg); - yield openProjectSearch(dbg); + await openProjectSearch(dbg); type(dbg, "first"); pressKey(dbg, "Enter"); - yield waitForState(dbg, () => getResultsCount(dbg) === 1); + await waitForState(dbg, () => getResultsCount(dbg) === 1); - yield selectResult(dbg); - is(dbg.selectors.getActiveSearchState(dbg.getState()), null); + await selectResult(dbg); + + is(dbg.selectors.getActiveSearch(dbg.getState()), null); const selectedSource = dbg.selectors.getSelectedSource(dbg.getState()); ok(selectedSource.get("url").includes("switching-01")); }); registerCleanupFunction(() => { Services.prefs.clearUserPref( "devtools.debugger.project-text-search-enabled",
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-sources.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-sources.js @@ -1,34 +1,34 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Testing source search -add_task(function*() { - const dbg = yield initDebugger("doc-script-switching.html"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html"); // test opening and closing pressKey(dbg, "sourceSearch"); - is(dbg.selectors.getActiveSearchState(dbg.getState()), "source"); + is(dbg.selectors.getActiveSearch(dbg.getState()), "source"); pressKey(dbg, "Escape"); - is(dbg.selectors.getActiveSearchState(dbg.getState()), null); + is(dbg.selectors.getActiveSearch(dbg.getState()), null); pressKey(dbg, "sourceSearch"); - yield waitForElement(dbg, "input"); + await waitForElement(dbg, "input"); findElementWithSelector(dbg, "input").focus(); type(dbg, "sw"); pressKey(dbg, "Enter"); - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); let source = dbg.selectors.getSelectedSource(dbg.getState()); ok(source.get("url").match(/switching-01/), "first source is selected"); // 2. arrow keys and check to see if source is selected pressKey(dbg, "sourceSearch"); findElementWithSelector(dbg, "input").focus(); type(dbg, "sw"); pressKey(dbg, "Down"); pressKey(dbg, "Enter"); - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); source = dbg.selectors.getSelectedSource(dbg.getState()); ok(source.get("url").match(/switching-02/), "second source is selected"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-symbols.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-symbols.js @@ -6,25 +6,25 @@ async function openFunctionSearch(dbg) { return new Promise(r => setTimeout(r, 200)); } function resultCount(dbg) { return findAllElements(dbg, "resultItems").length; } // Testing function search -add_task(function*() { - const dbg = yield initDebugger("doc-script-switching.html", "switching-01"); +add_task(async function() { + const dbg = await initDebugger("doc-script-switching.html", "switching-01"); - yield selectSource(dbg, "switching-01"); + await selectSource(dbg, "switching-01"); // test opening and closing - yield openFunctionSearch(dbg); - is(dbg.selectors.getActiveSearchState(dbg.getState()), "symbol"); + await openFunctionSearch(dbg); + is(dbg.selectors.getActiveSearch(dbg.getState()), "symbol"); pressKey(dbg, "Escape"); - is(dbg.selectors.getActiveSearchState(dbg.getState()), null); + is(dbg.selectors.getActiveSearch(dbg.getState()), null); - yield openFunctionSearch(dbg); + await openFunctionSearch(dbg); is(resultCount(dbg), 1); type(dbg, "x"); is(resultCount(dbg), 0); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-bogus.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-bogus.js @@ -1,26 +1,26 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Test that an error while loading a sourcemap does not break // debugging. -add_task(function*() { +add_task(async function() { // NOTE: the CORS call makes the test run times inconsistent requestLongerTimeout(2); - const dbg = yield initDebugger("doc-sourcemap-bogus.html"); + const dbg = await initDebugger("doc-sourcemap-bogus.html"); const { selectors: { getSources }, getState } = dbg; - yield selectSource(dbg, "bogus-map.js"); + await selectSource(dbg, "bogus-map.js"); // We should still be able to set breakpoints and pause in the // generated source. - yield addBreakpoint(dbg, "bogus-map.js", 4); + await addBreakpoint(dbg, "bogus-map.js", 4); invokeInTab("runCode"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); // Make sure that only the single generated source exists. The // sourcemap failed to download. is(getSources(getState()).size, 1, "Only 1 source exists"); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-reloading.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps-reloading.js @@ -1,43 +1,43 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -add_task(function*() { +add_task(async function() { // NOTE: the CORS call makes the test run times inconsistent requestLongerTimeout(2); - const dbg = yield initDebugger("doc-sourcemaps.html"); + const dbg = await initDebugger("doc-sourcemaps.html"); const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; - yield waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); + await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); ok(true, "Original sources exist"); const entrySrc = findSource(dbg, "entry.js"); - yield selectSource(dbg, entrySrc); + await selectSource(dbg, entrySrc); ok( dbg.win.cm.getValue().includes("window.keepMeAlive"), "Original source text loaded correctly" ); // Test that breakpoint sliding is not attempted. The breakpoint // should not move anywhere. - yield addBreakpoint(dbg, entrySrc, 13); + await addBreakpoint(dbg, entrySrc, 13); is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); ok( getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }), "Breakpoint has correct line" ); - yield addBreakpoint(dbg, entrySrc, 15); - yield disableBreakpoint(dbg, entrySrc, 15); + await addBreakpoint(dbg, entrySrc, 15); + await disableBreakpoint(dbg, entrySrc, 15); // Test reloading the debugger - yield reload(dbg, "opts.js"); - yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); + await reload(dbg, "opts.js"); + await waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); is(getBreakpoints(getState()).size, 2, "One breakpoint exists"); ok( getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }), "Breakpoint has correct line" );
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js @@ -28,61 +28,61 @@ function getLineEl(dbg, line) { const lines = dbg.win.document.querySelectorAll(".CodeMirror-code > div"); return lines[line - 1]; } function clickGutter(dbg, line) { clickElement(dbg, "gutter", line); } -add_task(function*() { +add_task(async function() { // NOTE: the CORS call makes the test run times inconsistent requestLongerTimeout(2); - const dbg = yield initDebugger("doc-sourcemaps.html"); + const dbg = await initDebugger("doc-sourcemaps.html"); const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; - yield waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); + await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); ok(true, "Original sources exist"); const bundleSrc = findSource(dbg, "bundle.js"); - yield selectSource(dbg, bundleSrc); + await selectSource(dbg, bundleSrc); - yield clickGutter(dbg, 13); - yield waitForDispatch(dbg, "ADD_BREAKPOINT"); + await clickGutter(dbg, 13); + await waitForDispatch(dbg, "ADD_BREAKPOINT"); assertEditorBreakpoint(dbg, 13, true); - yield clickGutter(dbg, 13); - yield waitForDispatch(dbg, "REMOVE_BREAKPOINT"); + await clickGutter(dbg, 13); + await waitForDispatch(dbg, "REMOVE_BREAKPOINT"); is(getBreakpoints(getState()).size, 0, "No breakpoints exists"); const entrySrc = findSource(dbg, "entry.js"); - yield selectSource(dbg, entrySrc); + await selectSource(dbg, entrySrc); ok( dbg.win.cm.getValue().includes("window.keepMeAlive"), "Original source text loaded correctly" ); // Test that breakpoint sliding is not attempted. The breakpoint // should not move anywhere. - yield addBreakpoint(dbg, entrySrc, 13); + await addBreakpoint(dbg, entrySrc, 13); is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); assertBreakpointExists(dbg, entrySrc, 13); // Test breaking on a breakpoint - yield addBreakpoint(dbg, "entry.js", 15); + await addBreakpoint(dbg, "entry.js", 15); is(getBreakpoints(getState()).size, 2, "Two breakpoints exist"); assertBreakpointExists(dbg, entrySrc, 15); invokeInTab("keepMeAlive"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield stepIn(dbg); + await stepIn(dbg); assertPausedLocation(dbg); - yield stepOver(dbg); + await stepOver(dbg); assertPausedLocation(dbg); - yield stepOut(dbg); - yield stepOut(dbg); + await stepOut(dbg); + await stepOut(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js @@ -1,35 +1,35 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests loading sourcemapped sources, setting breakpoints, and // stepping in them. // This source map does not have source contents, so it's fetched separately -add_task(function*() { +add_task(async function() { // NOTE: the CORS call makes the test run times inconsistent requestLongerTimeout(2); - const dbg = yield initDebugger("doc-sourcemaps2.html"); + const dbg = await initDebugger("doc-sourcemaps2.html"); const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; - yield waitForSources(dbg, "main.js", "main.min.js"); + await waitForSources(dbg, "main.js", "main.min.js"); ok(true, "Original sources exist"); const mainSrc = findSource(dbg, "main.js"); - yield selectSource(dbg, mainSrc); + await selectSource(dbg, mainSrc); // Test that breakpoint is not off by a line. - yield addBreakpoint(dbg, mainSrc, 4); + await addBreakpoint(dbg, mainSrc, 4); is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); ok( getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4, column: 2 }), "Breakpoint has correct line" ); invokeInTab("logMessage"); - yield waitForPaused(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js @@ -1,89 +1,91 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that the source tree works. -function* waitForSourceCount(dbg, i) { +async function waitForSourceCount(dbg, i) { // We are forced to wait until the DOM nodes appear because the // source tree batches its rendering. - yield waitUntil(() => { + await waitUntil(() => { return findAllElements(dbg, "sourceNodes").length === i; }); } -add_task(function*() { - const dbg = yield initDebugger("doc-sources.html"); +add_task(async function() { + const dbg = await initDebugger("doc-sources.html"); const { selectors: { getSelectedSource }, getState } = dbg; - yield waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js"); + await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js"); // Expand nodes and make sure more sources appear. is(findAllElements(dbg, "sourceNodes").length, 2); - clickElement(dbg, "sourceArrow", 2); + await clickElement(dbg, "sourceArrow", 2); is(findAllElements(dbg, "sourceNodes").length, 7); - clickElement(dbg, "sourceArrow", 3); + await clickElement(dbg, "sourceArrow", 3); is(findAllElements(dbg, "sourceNodes").length, 8); // Select a source. ok( !findElementWithSelector(dbg, ".sources-list .focused"), "Source is not focused" ); const selected = waitForDispatch(dbg, "SELECT_SOURCE"); - clickElement(dbg, "sourceNode", 4); - yield selected; + await clickElement(dbg, "sourceNode", 4); + await selected; ok( findElementWithSelector(dbg, ".sources-list .focused"), "Source is focused" ); ok( - getSelectedSource(getState()).get("url").includes("nested-source.js"), + getSelectedSource(getState()) + .get("url") + .includes("nested-source.js"), "The right source is selected" ); // Make sure new sources appear in the list. ContentTask.spawn(gBrowser.selectedBrowser, null, function() { const script = content.document.createElement("script"); script.src = "math.min.js"; content.document.body.appendChild(script); }); - yield waitForSourceCount(dbg, 9); + await waitForSourceCount(dbg, 9); is( findElement(dbg, "sourceNode", 7).textContent, "math.min.js", "The dynamic script exists" ); // Make sure named eval sources appear in the list. }); -add_task(function*() { - const dbg = yield initDebugger("doc-sources.html"); +add_task(async function() { + const dbg = await initDebugger("doc-sources.html"); const { selectors: { getSelectedSource }, getState } = dbg; - yield waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js"); + await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js"); ContentTask.spawn(gBrowser.selectedBrowser, null, function() { content.eval("window.evaledFunc = function() {} //# sourceURL=evaled.js"); }); - yield waitForSourceCount(dbg, 3); + await waitForSourceCount(dbg, 3); is( findElement(dbg, "sourceNode", 3).textContent, "(no domain)", "the folder exists" ); // work around: the folder is rendered at the bottom, so we close the // root folder and open the (no domain) folder - clickElement(dbg, "sourceArrow", 3); - yield waitForSourceCount(dbg, 4); + await clickElement(dbg, "sourceArrow", 3); + await waitForSourceCount(dbg, 4); is( findElement(dbg, "sourceNode", 4).textContent, "evaled.js", "the eval script exists" ); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js @@ -2,38 +2,38 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests adding and removing tabs function countTabs(dbg) { return findElement(dbg, "sourceTabs").children.length; } -add_task(function*() { - let dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + let dbg = await initDebugger("doc-scripts.html"); - yield selectSource(dbg, "simple1"); - yield selectSource(dbg, "simple2"); + await selectSource(dbg, "simple1"); + await selectSource(dbg, "simple2"); is(countTabs(dbg), 2); // Test reloading the debugger - yield reload(dbg, "simple1", "simple2"); + await reload(dbg, "simple1", "simple2"); is(countTabs(dbg), 2); - yield waitForSelectedSource(dbg); + await waitForSelectedSource(dbg); // Test reloading the debuggee a second time - yield reload(dbg, "simple1", "simple2"); + await reload(dbg, "simple1", "simple2"); is(countTabs(dbg), 2); - yield waitForSelectedSource(dbg); + await waitForSelectedSource(dbg); }); -add_task(function*() { - let dbg = yield initDebugger("doc-scripts.html", "simple1", "simple2"); +add_task(async function() { + let dbg = await initDebugger("doc-scripts.html", "simple1", "simple2"); - yield selectSource(dbg, "simple1"); - yield selectSource(dbg, "simple2"); + await selectSource(dbg, "simple1"); + await selectSource(dbg, "simple2"); closeTab(dbg, "simple1"); closeTab(dbg, "simple2"); // Test reloading the debugger - yield reload(dbg, "simple1", "simple2"); + await reload(dbg, "simple1", "simple2"); is(countTabs(dbg), 0); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js @@ -20,19 +20,19 @@ function getSplitConsole(dbg) { toolbox.getPanelWhenReady("webconsole").then(() => { ok(toolbox.splitConsole, "Split console is shown."); let jsterm = toolbox.getPanel("webconsole").hud.jsterm; resolve(jsterm); }); }); } -add_task(function*() { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); - yield selectSource(dbg, "long"); + await selectSource(dbg, "long"); dbg.win.cm.scrollTo(0, 284); pressKey(dbg, "inspector"); pressKey(dbg, "debugger"); is(dbg.win.cm.getScrollInfo().top, 284); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg_keyboard-shortcuts.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg_keyboard-shortcuts.js @@ -20,27 +20,27 @@ function pressStepIn(dbg) { return waitForPaused(dbg); } function pressStepOut(dbg) { pressKey(dbg, "stepOutKey"); return waitForPaused(dbg); } -add_task(function*() { - const dbg = yield initDebugger("doc-debugger-statements.html"); +add_task(async function() { + const dbg = await initDebugger("doc-debugger-statements.html"); - yield reload(dbg); - yield waitForPaused(dbg); + await reload(dbg); + await waitForPaused(dbg); assertPausedLocation(dbg); - yield pressResume(dbg); + await pressResume(dbg); assertPausedLocation(dbg); - yield pressStepIn(dbg); + await pressStepIn(dbg); assertPausedLocation(dbg); - yield pressStepOut(dbg); + await pressStepOut(dbg); assertPausedLocation(dbg); - yield pressStepOver(dbg); + await pressStepOver(dbg); assertPausedLocation(dbg); });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg_keyboard_navigation.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg_keyboard_navigation.js @@ -1,29 +1,38 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that keyboard navigation into and out of debugger code editor -add_task(function* () { - const dbg = yield initDebugger("doc-scripts.html"); +add_task(async function() { + const dbg = await initDebugger("doc-scripts.html"); let doc = dbg.win.document; - yield selectSource(dbg, "simple2"); + await selectSource(dbg, "simple2"); - yield waitForElement(dbg, ".CodeMirror"); + await waitForElement(dbg, ".CodeMirror"); findElementWithSelector(dbg, ".CodeMirror").focus(); // Enter code editor pressKey(dbg, "Enter"); - is(findElementWithSelector(dbg, "textarea"), doc.activeElement, - "Editor is enabled"); + is( + findElementWithSelector(dbg, "textarea"), + doc.activeElement, + "Editor is enabled" + ); // Exit code editor and focus on container pressKey(dbg, "Escape"); - is(findElementWithSelector(dbg, ".CodeMirror"), doc.activeElement, - "Focused on container"); + is( + findElementWithSelector(dbg, ".CodeMirror"), + doc.activeElement, + "Focused on container" + ); // Enter code editor pressKey(dbg, "Tab"); - is(findElementWithSelector(dbg, "textarea"), doc.activeElement, - "Editor is enabled"); + is( + findElementWithSelector(dbg, "textarea"), + doc.activeElement, + "Editor is enabled" + ); });
--- a/devtools/client/debugger/new/test/mochitest/examples/doc-async.html +++ b/devtools/client/debugger/new/test/mochitest/examples/doc-async.html @@ -4,10 +4,12 @@ <html> <head> <meta charset="utf-8"/> <title>Async</title> <script src="async.js"></script> </head> <body> + + <button onclick="main()">Main</button> </body> </html>
--- a/devtools/client/debugger/new/test/mochitest/head.js +++ b/devtools/client/debugger/new/test/mochitest/head.js @@ -206,18 +206,19 @@ function waitForSources(dbg, ...sources) */ function waitForSource(dbg, url) { return waitForState(dbg, state => { const sources = dbg.selectors.getSources(state); return sources.find(s => (s.get("url") || "").includes(url)); }); } -function waitForElement(dbg, selector) { - return waitUntil(() => findElementWithSelector(dbg, selector)); +async function waitForElement(dbg, selector) { + await waitUntil(() => findElementWithSelector(dbg, selector)); + return findElementWithSelector(dbg, selector); } function waitForSelectedSource(dbg, sourceId) { return waitForState(dbg, state => { const source = dbg.selectors.getSelectedSource(state); const isLoaded = source && source.has("loadedState") && sourceUtils.isLoaded(source); if (sourceId) { @@ -285,17 +286,19 @@ function assertHighlightLocation(dbg, so // Check the highlight line const lineEl = findElement(dbg, "highlightLine"); ok(lineEl, "Line is highlighted"); ok( isVisibleWithin(findElement(dbg, "codeMirror"), lineEl), "Highlighted line is visible" ); ok( - getCM(dbg).lineInfo(line - 1).wrapClass.includes("highlight-line"), + getCM(dbg) + .lineInfo(line - 1) + .wrapClass.includes("highlight-line"), "Line is highlighted" ); } /** * Returns boolean for whether the debugger is paused. * * @memberof mochitest/asserts @@ -725,17 +728,18 @@ const selectors = { stepIn: ".stepIn.active", toggleBreakpoints: ".breakpoints-toggle", prettyPrintButton: ".prettyPrint", sourcesFooter: ".sources-panel .source-footer", editorFooter: ".editor-pane .source-footer", sourceNode: i => `.sources-list .tree-node:nth-child(${i})`, sourceNodes: ".sources-list .tree-node", sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`, - resultItems: `.result-list .result-item` + resultItems: `.result-list .result-item`, + fileMatch: `.managed-tree .result` }; function getSelector(elementName, ...args) { let selector = selectors[elementName]; if (!selector) { throw new Error(`The selector ${elementName} is not defined`); } @@ -765,22 +769,27 @@ function findAllElements(dbg, elementNam * * @memberof mochitest/helpers * @param {Object} dbg * @param {String} elementName * @param {Array} args * @return {Promise} * @static */ -function clickElement(dbg, elementName, ...args) { +async function clickElement(dbg, elementName, ...args) { const selector = getSelector(elementName, ...args); - const el = findElement(dbg, elementName, ...args); + const el = await waitForElement(dbg, selector); + el.scrollIntoView(); - return EventUtils.synthesizeMouseAtCenter( + return clickElementWithSelector(dbg, selector); +} + +function clickElementWithSelector(dbg, selector) { + EventUtils.synthesizeMouseAtCenter( findElementWithSelector(dbg, selector), {}, dbg.win ); } function dblClickElement(dbg, elementName, ...args) { const selector = getSelector(elementName, ...args);
--- a/devtools/client/inspector/layout/components/Accordion.css +++ b/devtools/client/inspector/layout/components/Accordion.css @@ -21,16 +21,17 @@ .accordion { background-color: var(--theme-sidebar-background); width: 100%; } .accordion ._header { background-color: var(--accordion-header-background); border-bottom: 1px solid var(--theme-splitter-color); + color: var(--theme-toolbar-color); cursor: pointer; font-size: 12px; padding: 4px; transition: all 0.25s ease; width: 100%; align-items: center; display: flex;
--- a/devtools/client/locales/en-US/debugger.properties +++ b/devtools/client/locales/en-US/debugger.properties @@ -138,16 +138,20 @@ sources.search.key2=CmdOrCtrl+P # LOCALIZATION NOTE (sources.search.alt.key): A second key shortcut to open the # search for searching all the source files the debugger has seen. sources.search.alt.key=CmdOrCtrl+O # LOCALIZATION NOTE (projectTextSearch.key): A key shortcut to open the # full project text search for searching all the files the debugger has seen. projectTextSearch.key=CmdOrCtrl+Shift+F +# LOCALIZATION NOTE (functionSearch.key): A key shortcut to open the +# modal for searching functions in a file. +functionSearch.key=CmdOrCtrl+Shift+O + # LOCALIZATION NOTE (projectTextSearch.placeholder): A placeholder shown # when searching across all of the files in a project. projectTextSearch.placeholder=Find in files… # LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger # does not have any sources. sources.noSourcesAvailable=This page has no sources @@ -390,16 +394,20 @@ sourceFooter.blackbox.accesskey=B # with the blackbox button sourceFooter.unblackbox=Unblackbox Source sourceFooter.unblackbox.accesskey=b # LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated # with a blackboxed source sourceFooter.blackboxed=Blackboxed Source +# LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated +# with a code coverage button +sourceFooter.codeCoverage=Code Coverage + # LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed # for close tab button in source tabs. sourceTabs.closeTabButtonTooltip=Close tab # LOCALIZATION NOTE (sourceTabs.newTabButtonTooltip): The tooltip that is displayed for # new tab button in source tabs. sourceTabs.newTabButtonTooltip=Search for sources (%S) @@ -416,16 +424,19 @@ scopes.notPaused=Not Paused # LOCALIZATION NOTE (scopes.block): Refers to a block of code in # the scopes pane when the debugger is paused. scopes.block=Block # LOCALIZATION NOTE (sources.header): Sources left sidebar header sources.header=Sources +# LOCALIZATION NOTE (outline.header): Outline left sidebar header +outline.header=Outline + # LOCALIZATION NOTE (sources.search): Sources left sidebar prompt # e.g. Cmd+P to search. On a mac, we use the command unicode character. # On windows, it's ctrl. sources.search=%S to search # LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar # pane header. watchExpressions.header=Watch Expressions @@ -439,19 +450,23 @@ watchExpressions.refreshButton=Refresh # a mac we use the unicode character. welcome.search=%S to search for sources # LOCALIZATION NOTE (welcome.findInFiles): The center pane welcome panel's # search prompt. e.g. cmd+f to search for files. On windows, it's ctrl+shift+f, on # a mac we use the unicode character. welcome.findInFiles=%S to find in files +# LOCALIZATION NOTE (welcome.searchFunction): Label displayed in the welcome +# panel. %S is replaced by the keyboard shortcut to search for functions. +welcome.searchFunction=%S to search for functions in file + # LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search # prompt for searching for files. -sourceSearch.search=Search Sources… +sourceSearch.search=Search sources… # LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search # message when the query did not match any of the sources. sourceSearch.noResults2=No results found # LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip # when the debugger will not pause on exceptions. ignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions
--- a/devtools/client/preferences/debugger.js +++ b/devtools/client/preferences/debugger.js @@ -33,10 +33,10 @@ pref("devtools.debugger.start-panel-coll pref("devtools.debugger.end-panel-collapsed", false); pref("devtools.debugger.tabs", "[]"); pref("devtools.debugger.pending-selected-location", "{}"); pref("devtools.debugger.pending-breakpoints", "{}"); pref("devtools.debugger.expressions", "[]"); pref("devtools.debugger.file-search-case-sensitive", false); pref("devtools.debugger.file-search-whole-word", false); pref("devtools.debugger.file-search-regex-match", false); -pref("devtools.debugger.features.async-stepping", false); +pref("devtools.debugger.features.async-stepping", true); pref("devtools.debugger.project-text-search-enabled", true);
--- a/devtools/client/shared/components/tabs/tabs.css +++ b/devtools/client/shared/components/tabs/tabs.css @@ -76,17 +76,17 @@ border-bottom: 1px solid var(--theme-splitter-color); background: var(--theme-tab-toolbar-background); } .theme-dark .tabs .tabs-menu-item, .theme-light .tabs .tabs-menu-item { margin: 0; padding: 0; - color: var(--theme-content-color1); + color: var(--theme-toolbar-color); } .theme-dark .tabs .tabs-menu-item:last-child, .theme-light:not(.theme-firebug) .tabs .tabs-menu-item:last-child { border-inline-end-width: 1px; } .theme-dark .tabs .tabs-menu-item a,
--- a/devtools/client/themes/animationinspector.css +++ b/devtools/client/themes/animationinspector.css @@ -104,17 +104,16 @@ html { body { margin: 0; padding: 0; display : flex; flex-direction: column; height: 100%; overflow: hidden; - color: var(--theme-content-color3); } /* The top toolbar, containing the toggle-all button. And the timeline toolbar, containing playback control buttons, shown only when there are animations displayed in the timeline */ #global-toolbar, #timeline-toolbar {
--- a/devtools/client/themes/rules.css +++ b/devtools/client/themes/rules.css @@ -217,18 +217,19 @@ color: #0000FF; } .ruleview-rule-source:not([unselectable]):hover { text-decoration: underline; } .ruleview-header { - background-color: var(--rule-header-background-color); + background: var(--rule-header-background-color); border-bottom: 1px solid var(--theme-splitter-color); + color: var(--theme-toolbar-color); font-size: 12px; padding: 4px; width: 100%; align-items: center; display: flex; -moz-user-select: none; }
--- a/devtools/client/themes/toolbox.css +++ b/devtools/client/themes/toolbox.css @@ -135,22 +135,18 @@ min-width: 24px; } /* Save space on the tab-strip in Firebug theme */ .theme-firebug .devtools-tab { -moz-box-flex: initial; } -.theme-dark .devtools-tab { - color: var(--theme-body-color-alt); -} - -.theme-light .devtools-tab { - color: var(--theme-body-color); +.devtools-tab { + color: var(--theme-toolbar-color); } .theme-dark .devtools-tab:hover { color: #ced3d9; } .devtools-tab:hover { background-color: var(--theme-toolbar-hover);
--- a/devtools/client/themes/variables.css +++ b/devtools/client/themes/variables.css @@ -19,16 +19,17 @@ :root.theme-light { --theme-body-background: white; --theme-sidebar-background: white; --theme-contrast-background: #e6b064; /* Toolbar */ --theme-tab-toolbar-background: var(--grey-10); --theme-toolbar-background: var(--grey-10); + --theme-toolbar-color: var(--grey-90); --theme-toolbar-background-hover: rgba(221, 225, 228, 0.66); --theme-toolbar-background-alt: #f5f5f5; --theme-toolbar-hover: rgba(170, 170, 170, .2); --theme-toolbar-hover-active: rgba(170, 170, 170, .4); /* Selection */ --theme-selection-background: var(--blue-55); --theme-selection-background-hover: #F0F9FE; @@ -36,17 +37,17 @@ /* Border color that splits the toolbars/panels/headers. * This needs to be sync with commandline.css and commandline-browser.css. */ --theme-splitter-color: #e0e0e1; --theme-comment: #696969; --theme-comment-alt: #ccd1d5; - --theme-body-color: #393f4c; + --theme-body-color: var(--grey-60); --theme-body-color-alt: #585959; --theme-body-color-inactive: #999797; --theme-content-color1: #292e33; --theme-content-color2: #8fa1b2; --theme-content-color3: #667380; --theme-highlight-green: #2cbb0f; --theme-highlight-blue: #0088cc; @@ -94,16 +95,17 @@ :root.theme-dark { --theme-body-background: var(--grey-80); --theme-sidebar-background: var(--grey-90); --theme-contrast-background: #ffb35b; /* Toolbar */ --theme-tab-toolbar-background: var(--grey-90); --theme-toolbar-background: var(--grey-90); + --theme-toolbar-color: var(--grey-40); --theme-toolbar-background-hover: #20232B; --theme-toolbar-background-alt: #2F343E; --theme-toolbar-hover: rgba(110, 120, 130, 0.1); --theme-toolbar-hover-active: rgba(110, 120, 130, 0.2); /* Selection */ --theme-selection-background: #204E8A; --theme-selection-background-hover: #353B48; @@ -111,21 +113,21 @@ /* Border color that splits the toolbars/panels/headers. * This needs to be sync with commandline.css and commandline-browser.css. */ --theme-splitter-color: #3c3c3d; --theme-comment: #757873; --theme-comment-alt: #5a6375; - --theme-body-color: #8fa1b2; + --theme-body-color: var(--grey-40); --theme-body-color-alt: #b6babf; - --theme-body-color-inactive: #8fa1b2; + --theme-body-color-inactive: var(--grey-40); --theme-content-color1: #a9bacb; - --theme-content-color2: #8fa1b2; + --theme-content-color2: var(--grey-40); --theme-content-color3: #5f7387; --theme-highlight-green: #00ff7f; --theme-highlight-blue: #46afe3; --theme-highlight-bluegrey: #5e88b0; --theme-highlight-purple: #bcb8db; --theme-highlight-lightorange: #d99b28; --theme-highlight-orange: #d96629;
--- a/dom/base/nsCopySupport.cpp +++ b/dom/base/nsCopySupport.cpp @@ -835,27 +835,30 @@ nsCopySupport::FireClipboardEvent(EventM InternalClipboardEvent evt(true, originalEventMessage); evt.mClipboardData = clipboardData; EventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt, nullptr, &status); // If the event was cancelled, don't do the clipboard operation doDefault = (status != nsEventStatus_eConsumeNoDefault); } + // When this function exits, the event dispatch is over. We want to disconnect + // our DataTransfer, which means setting its mode to `Protected` and clearing + // all stored data, before we return. + auto clearAfter = MakeScopeExit([&] { + if (clipboardData) { + clipboardData->SetMode(DataTransfer::Mode::Protected); + clipboardData->ClearAll(); + } + }); + // No need to do anything special during a paste. Either an event listener // took care of it and cancelled the event, or the caller will handle it. // Return true to indicate that the event wasn't cancelled. if (originalEventMessage == ePaste) { - // Clear and mark the clipboardData as readonly. This prevents someone - // from reading the clipboard contents after the paste event has fired. - if (clipboardData) { - clipboardData->ClearAll(); - clipboardData->SetReadOnly(); - } - if (aActionTaken) { *aActionTaken = true; } return doDefault; } // Update the presentation in case the event handler modified the selection, // see bug 602231.
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -4529,17 +4529,17 @@ void nsPIDOMWindowInner::UpdateWebSocketCount(int32_t aDelta) { MOZ_ASSERT(NS_IsMainThread()); if (aDelta == 0) { return; } - if (!IsTopInnerWindow()) { + if (mTopInnerWindow && !IsTopInnerWindow()) { mTopInnerWindow->UpdateWebSocketCount(aDelta); } MOZ_DIAGNOSTIC_ASSERT( aDelta > 0 || ((aDelta + mNumOfOpenWebSockets) < mNumOfOpenWebSockets)); mNumOfOpenWebSockets += aDelta; } @@ -4557,17 +4557,17 @@ void nsPIDOMWindowInner::UpdateUserMediaCount(int32_t aDelta) { MOZ_ASSERT(NS_IsMainThread()); if (aDelta == 0) { return; } - if (!IsTopInnerWindow()) { + if (mTopInnerWindow && !IsTopInnerWindow()) { mTopInnerWindow->UpdateUserMediaCount(aDelta); } MOZ_DIAGNOSTIC_ASSERT( aDelta > 0 || ((aDelta + mNumOfActiveUserMedia) < mNumOfActiveUserMedia)); mNumOfActiveUserMedia += aDelta; }
--- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -16,16 +16,17 @@ class nsIAtom; class nsIURI; class nsRuleWalker; class nsAttrValue; class nsAttrName; class nsTextFragment; class nsIFrame; class nsXBLBinding; +class nsITextControlElement; namespace mozilla { class EventChainPreVisitor; struct URLExtraData; namespace dom { class ShadowRoot; } // namespace dom namespace widget { @@ -975,16 +976,21 @@ public: virtual nsresult GetEventTargetParent( mozilla::EventChainPreVisitor& aVisitor) override; virtual bool IsPurple() = 0; virtual void RemovePurple() = 0; virtual bool OwnedOnlyByTheDOMTree() { return false; } + virtual already_AddRefed<nsITextControlElement> GetAsTextControlElement() + { + return nullptr; + } + protected: /** * Hook for implementing GetID. This is guaranteed to only be * called if HasID() is true. */ nsIAtom* DoGetID() const; // Returns base URI without considering xml:base.
--- a/dom/base/nsRange.h +++ b/dom/base/nsRange.h @@ -594,18 +594,24 @@ protected: AsRaw() const { return RangeBoundaryBase<nsINode*, nsIContent*>(*this); } template<typename A, typename B> RangeBoundaryBase& operator=(const RangeBoundaryBase<A,B>& aOther) { - mParent = aOther.mParent; - mRef = aOther.mRef; + // Since the member variables may be nsCOMPtrs, better to try to avoid + // extra Release/AddRef calls. + if (mParent != aOther.mParent) { + mParent = aOther.mParent; + } + if (mRef != aOther.mRef) { + mRef = aOther.mRef; + } mOffset = aOther.mOffset; return *this; } private: ParentType mParent; RefType mRef;
--- a/dom/cache/TypeUtils.cpp +++ b/dom/cache/TypeUtils.cpp @@ -338,17 +338,17 @@ TypeUtils::ToInternalRequest(const Cache internalRequest->Headers()->Fill(*internalHeaders, result); MOZ_DIAGNOSTIC_ASSERT(!result.Failed()); internalRequest->Headers()->SetGuard(aIn.headersGuard(), result); MOZ_DIAGNOSTIC_ASSERT(!result.Failed()); nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body()); - internalRequest->SetBody(stream); + internalRequest->SetBody(stream, -1); return internalRequest.forget(); } already_AddRefed<Request> TypeUtils::ToRequest(const CacheRequest& aIn) { RefPtr<InternalRequest> internalRequest = ToInternalRequest(aIn);
--- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -76,40 +76,56 @@ const char DataTransfer::sEffects[8][9] }; // Used for custom clipboard types. enum CustomClipboardTypeId { eCustomClipboardTypeId_None, eCustomClipboardTypeId_String }; +static DataTransfer::Mode +ModeForEvent(EventMessage aEventMessage) +{ + switch (aEventMessage) { + case eCut: + case eCopy: + case eDragStart: + // For these events, we want to be able to add data to the data transfer, + // Otherwise, the data is already present. + return DataTransfer::Mode::ReadWrite; + case eDrop: + case ePaste: + case ePasteNoFormatting: + // For these events we want to be able to read the data which is stored in + // the DataTransfer, rather than just the type information. + return DataTransfer::Mode::ReadOnly; + default: + return DataTransfer::Mode::Protected; + } +} + DataTransfer::DataTransfer(nsISupports* aParent, EventMessage aEventMessage, bool aIsExternal, int32_t aClipboardType) : mParent(aParent) , mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE) , mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED) , mEventMessage(aEventMessage) , mCursorState(false) - , mReadOnly(true) + , mMode(ModeForEvent(aEventMessage)) , mIsExternal(aIsExternal) , mUserCancelled(false) , mIsCrossDomainSubFrameDrop(false) , mClipboardType(aClipboardType) , mDragImageX(0) , mDragImageY(0) { mItems = new DataTransferItemList(this, aIsExternal); - // For these events, we want to be able to add data to the data transfer, so - // clear the readonly state. Otherwise, the data is already present. For - // external usage, cache the data from the native clipboard or drag. - if (aEventMessage == eCut || - aEventMessage == eCopy || - aEventMessage == eDragStart) { - mReadOnly = false; - } else if (mIsExternal) { + + // For external usage, cache the data from the native clipboard or drag. + if (mIsExternal && mMode != Mode::ReadWrite) { if (aEventMessage == ePasteNoFormatting) { mEventMessage = ePaste; CacheExternalClipboardFormats(true); } else if (aEventMessage == ePaste) { CacheExternalClipboardFormats(false); } else if (aEventMessage >= eDragDropEventFirst && aEventMessage <= eDragDropEventLast) { CacheExternalDragFormats(); @@ -129,17 +145,17 @@ DataTransfer::DataTransfer(nsISupports* Element* aDragImage, uint32_t aDragImageX, uint32_t aDragImageY) : mParent(aParent) , mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE) , mEffectAllowed(aEffectAllowed) , mEventMessage(aEventMessage) , mCursorState(aCursorState) - , mReadOnly(true) + , mMode(ModeForEvent(aEventMessage)) , mIsExternal(aIsExternal) , mUserCancelled(aUserCancelled) , mIsCrossDomainSubFrameDrop(aIsCrossDomainSubFrameDrop) , mClipboardType(aClipboardType) , mDragImage(aDragImage) , mDragImageX(aDragImageX) , mDragImageY(aDragImageY) { @@ -424,17 +440,17 @@ DataTransfer::SetData(const nsAString& a aRv = SetDataAtInternal(aFormat, variant, 0, &aSubjectPrincipal); } void DataTransfer::ClearData(const Optional<nsAString>& aFormat, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { - if (mReadOnly) { + if (IsReadOnly()) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; } if (MozItemCount() == 0) { return; } @@ -654,26 +670,45 @@ DataTransfer::PrincipalMaySetData(const } void DataTransfer::TypesListMayHaveChanged() { DataTransferBinding::ClearCachedTypesValue(this); } +already_AddRefed<DataTransfer> +DataTransfer::MozCloneForEvent(const nsAString& aEvent, ErrorResult& aRv) +{ + nsCOMPtr<nsIAtom> atomEvt = NS_Atomize(aEvent); + if (!atomEvt) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + EventMessage eventMessage = nsContentUtils::GetEventMessage(atomEvt); + + RefPtr<DataTransfer> dt; + nsresult rv = Clone(mParent, eventMessage, false, false, getter_AddRefs(dt)); + if (NS_FAILED(rv)) { + aRv.Throw(rv); + return nullptr; + } + return dt.forget(); +} + nsresult DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aSubjectPrincipal) { if (aFormat.IsEmpty()) { return NS_OK; } - if (mReadOnly) { + if (IsReadOnly()) { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; } // Specifying an index less than the current length will replace an existing // item. Specifying an index equal to the current length will add a new item. if (aIndex > MozItemCount()) { return NS_ERROR_DOM_INDEX_SIZE_ERR; } @@ -711,17 +746,17 @@ DataTransfer::MozSetDataAt(JSContext* aC } } void DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { - if (mReadOnly) { + if (IsReadOnly()) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; } if (aIndex >= MozItemCount()) { aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return; } @@ -748,32 +783,32 @@ DataTransfer::MozClearDataAt(const nsASt } } void DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { - MOZ_ASSERT(!mReadOnly); + MOZ_ASSERT(!IsReadOnly()); MOZ_ASSERT(aIndex < MozItemCount()); MOZ_ASSERT(aIndex == 0 || (mEventMessage != eCut && mEventMessage != eCopy && mEventMessage != ePaste)); nsAutoString format; GetRealFormat(aFormat, format); mItems->MozRemoveByTypeAt(format, aIndex, aSubjectPrincipal, aRv); } void DataTransfer::SetDragImage(Element& aImage, int32_t aX, int32_t aY) { - if (!mReadOnly) { + if (!IsReadOnly()) { mDragImage = &aImage; mDragImageX = aX; mDragImageY = aY; } } NS_IMETHODIMP DataTransfer::SetDragImage(nsIDOMElement* aImage, int32_t aX, int32_t aY) @@ -843,17 +878,17 @@ DataTransfer::GetFiles(bool aRecursiveFl { // Currently we don't support directories. return GetFilesAndDirectories(aSubjectPrincipal, aRv); } void DataTransfer::AddElement(Element& aElement, ErrorResult& aRv) { - if (mReadOnly) { + if (IsReadOnly()) { aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; } mDragTarget = &aElement; } NS_IMETHODIMP
--- a/dom/events/DataTransfer.h +++ b/dom/events/DataTransfer.h @@ -56,23 +56,32 @@ public: friend class mozilla::EventStateManager; static DataTransfer* Cast(nsIDOMDataTransfer* aArg) { return static_cast<DataTransfer*>(aArg); } + /// An enum which represents which "Drag Data Store Mode" the DataTransfer is + /// in according to the spec. + enum class Mode : uint8_t { + ReadWrite, + ReadOnly, + Protected, + }; + protected: // hide the default constructor DataTransfer(); // this constructor is used only by the Clone method to copy the fields as // needed to a new data transfer. + // NOTE: Do not call this method directly. DataTransfer(nsISupports* aParent, EventMessage aEventMessage, const uint32_t aEffectAllowed, bool aCursorState, bool aIsExternal, bool aUserCancelled, bool aIsCrossDomainSubFrameDrop, int32_t aClipboardType, @@ -209,23 +218,35 @@ public: nsresult GetDataAtNoSecurityCheck(const nsAString& aFormat, uint32_t aIndex, nsIVariant** aData); DataTransferItemList* Items() const { return mItems; } - // a readonly dataTransfer cannot have new data added or existing data - // removed. Only the dropEffect and effectAllowed may be modified. + // Returns the current "Drag Data Store Mode" of the DataTransfer. This + // determines what modifications may be performed on the DataTransfer, and + // what data may be read from it. + Mode GetMode() const { + return mMode; + } + void SetMode(Mode aMode) { + mMode = aMode; + } + + // Helper method. Is true if the DataTransfer's mode is ReadOnly or Protected, + // which means that the DataTransfer cannot be modified. bool IsReadOnly() const { - return mReadOnly; + return mMode != Mode::ReadWrite; } - void SetReadOnly() { - mReadOnly = true; + // Helper method. Is true if the DataTransfer's mode is Protected, which means + // that DataTransfer type information may be read, but data may not be. + bool IsProtected() const { + return mMode == Mode::Protected; } int32_t ClipboardType() const { return mClipboardType; } EventMessage GetEventMessage() const { return mEventMessage; } @@ -273,16 +294,22 @@ public: // returns a weak reference to the drag image Element* GetDragImage(int32_t* aX, int32_t* aY) const { *aX = mDragImageX; *aY = mDragImageY; return mDragImage; } + // This method makes a copy of the DataTransfer object, with a few properties + // changed, and the mode updated to reflect the correct mode for the given + // event. This method is used during the drag operation to generate the + // DataTransfer objects for each event after `dragstart`. Event objects will + // lazily clone the DataTransfer stored in the DragSession (which is a clone + // of the DataTransfer used in the `dragstart` event) when requested. nsresult Clone(nsISupports* aParent, EventMessage aEventMessage, bool aUserCancelled, bool aIsCrossDomainSubFrameDrop, DataTransfer** aResult); // converts some formats used for compatibility in aInFormat into aOutFormat. // Text and text/unicode become text/plain, and URL becomes text/uri-list void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat) const; @@ -290,16 +317,21 @@ public: nsIVariant* aData, nsIPrincipal* aPrincipal); // Notify the DataTransfer that the list returned from GetTypes may have // changed. This can happen due to items we care about for purposes of // GetTypes being added or removed or changing item kinds. void TypesListMayHaveChanged(); + // Testing method used to emulate internal DataTransfer management. + // NOTE: Please don't use this. See the comments in the webidl for more. + already_AddRefed<DataTransfer> MozCloneForEvent(const nsAString& aEvent, + ErrorResult& aRv); + protected: // caches text and uri-list data formats that exist in the drag service or // clipboard for retrieval later. nsresult CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal, bool aHidden); // caches the formats that exist in the drag service that were added by an @@ -338,19 +370,18 @@ protected: // the event message this data transfer is for. This will correspond to an // event->mMessage value. EventMessage mEventMessage; // Indicates the behavior of the cursor during drag operations bool mCursorState; - // readonly data transfers may not be modified except the drop effect and - // effect allowed. - bool mReadOnly; + // The current "Drag Data Store Mode" which the DataTransfer is in. + Mode mMode; // true for drags started without a data transfer, for example, those from // another application. bool mIsExternal; // true if the user cancelled the drag. Used only for the dragend event. bool mUserCancelled;
--- a/dom/events/DataTransferItem.cpp +++ b/dom/events/DataTransferItem.cpp @@ -498,24 +498,30 @@ DataTransferItem::DataNoSecurityCheck() return data.forget(); } already_AddRefed<nsIVariant> DataTransferItem::Data(nsIPrincipal* aPrincipal, ErrorResult& aRv) { MOZ_ASSERT(aPrincipal); - nsCOMPtr<nsIVariant> variant = DataNoSecurityCheck(); - // If the inbound principal is system, we can skip the below checks, as // they will trivially succeed. if (nsContentUtils::IsSystemPrincipal(aPrincipal)) { - return variant.forget(); + return DataNoSecurityCheck(); } + // We should not allow raw data to be accessed from a Protected DataTransfer. + // We don't prevent this access if the accessing document is Chrome. + if (mDataTransfer->IsProtected()) { + return nullptr; + } + + nsCOMPtr<nsIVariant> variant = DataNoSecurityCheck(); + MOZ_ASSERT(!ChromeOnly(), "Non-chrome code shouldn't see a ChromeOnly DataTransferItem"); if (ChromeOnly()) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return nullptr; } bool checkItemPrincipal = mDataTransfer->IsCrossDomainSubFrameDrop() || (mDataTransfer->GetEventMessage() != eDrop &&
--- a/dom/events/DataTransferItemList.cpp +++ b/dom/events/DataTransferItemList.cpp @@ -557,16 +557,24 @@ DataTransferItemList::RegenerateFiles() } void DataTransferItemList::GenerateFiles(FileList* aFiles, nsIPrincipal* aFilesPrincipal) { MOZ_ASSERT(aFiles); MOZ_ASSERT(aFilesPrincipal); + + // For non-system principals, the Files list should be empty if the + // DataTransfer is protected. + if (!nsContentUtils::IsSystemPrincipal(aFilesPrincipal) && + mDataTransfer->IsProtected()) { + return; + } + uint32_t count = Length(); for (uint32_t i = 0; i < count; i++) { bool found; RefPtr<DataTransferItem> item = IndexedGetter(i, found); MOZ_ASSERT(found); if (item->Kind() == DataTransferItem::KIND_FILE) { IgnoredErrorResult rv;
--- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -1767,16 +1767,22 @@ EventStateManager::GenerateDragGesture(n } nsCOMPtr<nsPIDOMWindowOuter> window = docshell->GetWindow(); if (!window) return; RefPtr<DataTransfer> dataTransfer = new DataTransfer(window, eDragStart, false, -1); + auto protectDataTransfer = MakeScopeExit([&] { + if (dataTransfer) { + dataTransfer->SetMode(DataTransfer::Mode::Protected); + dataTransfer->ClearAll(); + } + }); nsCOMPtr<nsISelection> selection; nsCOMPtr<nsIContent> eventContent, targetContent; mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent)); if (eventContent) DetermineDragTargetAndDefaultData(window, eventContent, dataTransfer, getter_AddRefs(selection), getter_AddRefs(targetContent)); @@ -1834,21 +1840,16 @@ EventStateManager::GenerateDragGesture(n mozilla::services::GetObserverService(); // Emit observer event to allow addons to modify the DataTransfer object. if (observerService) { observerService->NotifyObservers(dataTransfer, "on-datatransfer-available", nullptr); } - // now that the dataTransfer has been updated in the dragstart and - // draggesture events, make it read only so that the data doesn't - // change during the drag. - dataTransfer->SetReadOnly(); - if (status != nsEventStatus_eConsumeNoDefault) { bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer, targetContent, selection); if (dragStarted) { sActiveESM = nullptr; aEvent->StopPropagation(); } } @@ -2001,29 +2002,41 @@ EventStateManager::DoDefaultDragStart(ns int32_t imageX, imageY; Element* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY); nsCOMPtr<nsIArray> transArray = aDataTransfer->GetTransferables(dragTarget->AsDOMNode()); if (!transArray) return false; + // After this function returns, the DataTransfer will be cleared so it appears + // empty to content. We need to pass a DataTransfer into the Drag Session, so + // we need to make a copy. + RefPtr<DataTransfer> dataTransfer; + aDataTransfer->Clone(aDragTarget, eDrop, aDataTransfer->MozUserCancelled(), + false, getter_AddRefs(dataTransfer)); + + // Copy over the drop effect, as Clone doesn't copy it for us. + uint32_t dropEffect; + aDataTransfer->GetDropEffectInt(&dropEffect); + dataTransfer->SetDropEffectInt(dropEffect); + // XXXndeakin don't really want to create a new drag DOM event // here, but we need something to pass to the InvokeDragSession // methods. RefPtr<DragEvent> event = NS_NewDOMDragEvent(dragTarget, aPresContext, aDragEvent); // Use InvokeDragSessionWithSelection if a selection is being dragged, // such that the image can be generated from the selected text. However, // use InvokeDragSessionWithImage if a custom image was set or something // other than a selection is being dragged. if (!dragImage && aSelection) { dragService->InvokeDragSessionWithSelection(aSelection, transArray, - action, event, aDataTransfer); + action, event, dataTransfer); } else { // if dragging within a XUL tree and no custom drag image was // set, the region argument to InvokeDragSessionWithImage needs // to be set to the area encompassing the selected rows of the // tree to ensure that the drag feedback gets clipped to those // rows. For other content, region should be null. nsCOMPtr<nsIScriptableRegion> region; @@ -2040,17 +2053,17 @@ EventStateManager::DoDefaultDragStart(ns } #endif dragService->InvokeDragSessionWithImage(dragTarget->AsDOMNode(), transArray, region, action, dragImage ? dragImage->AsDOMNode() : nullptr, imageX, imageY, event, - aDataTransfer); + dataTransfer); } return true; } nsresult EventStateManager::GetContentViewer(nsIContentViewer** aCv) {
--- a/dom/events/test/test_DataTransferItemList.html +++ b/dom/events/test/test_DataTransferItemList.html @@ -125,16 +125,19 @@ var dragenterFired = 0; over.addEventListener('dragenter', onDragEnter); function onDragEnter(e) { over.removeEventListener('dragenter', onDragEnter); var dt = e.dataTransfer; dragenterFired++; + // NOTE: This test is run with chrome privileges. + // For back-compat reasons, protected mode acts like readonly mode for + // chrome documents. readOnly(e); } var dropFired = 0; over.addEventListener('drop', onDrop); function onDrop(e) { over.removeEventListener('drop', onDrop);
--- a/dom/events/test/test_bug1327798.html +++ b/dom/events/test/test_bug1327798.html @@ -29,18 +29,18 @@ SimpleTest.waitForFocus(() => { // does the clipboard contain text/unicode data ? ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard), "clipboard contains unicode text"); // does the clipboard contain text/html data ? ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard), "clipboard contains html text"); window.addEventListener("paste", (e) => { - ok(e.clipboardData.types.indexOf('text/html'), -1, "clipboardData shouldn't have text/html"); - ok(e.clipboardData.getData('text/plain'), "Formatted Text", "getData(text/plain) should return plain text"); + is(e.clipboardData.types.indexOf('text/html'), -1, "clipboardData shouldn't have text/html"); + is(e.clipboardData.getData('text/plain'), "Formatted Text", "getData(text/plain) should return plain text"); SimpleTest.finish(); }); SpecialPowers.doCommand(window, "cmd_pasteNoFormatting"); }); </script> </pre> </body>
--- a/dom/events/test/test_bug508479.html +++ b/dom/events/test/test_bug508479.html @@ -69,17 +69,17 @@ function runTests() is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (1)"); // reset gGotHandlingDrop = false; gGotNotHandlingDrop = false; SpecialPowers.addChromeEventListener("drop", chromeListener, true, false); var targetNotHandling = document.getElementById("nothandling_target"); - fireDrop(targetNotHandling, true, true); + fireDrop(targetNotHandling, false, true); SpecialPowers.removeChromeEventListener("drop", chromeListener, true); ok(chromeGotEvent, "Chrome should have got drop event!"); is(gGotHandlingDrop, false, "Didn't get drop on accepting element (2)"); is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (2)"); SimpleTest.finish(); }
--- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -364,22 +364,25 @@ FetchDriver::HttpFetch() // void string if no header was set. #ifdef DEBUG bool hasContentTypeHeader = mRequest->Headers()->Has(NS_LITERAL_CSTRING("content-type"), result); MOZ_ASSERT(!result.Failed()); MOZ_ASSERT_IF(!hasContentTypeHeader, contentType.IsVoid()); #endif // DEBUG + int64_t bodyLength; nsCOMPtr<nsIInputStream> bodyStream; - mRequest->GetBody(getter_AddRefs(bodyStream)); + mRequest->GetBody(getter_AddRefs(bodyStream), &bodyLength); if (bodyStream) { nsAutoCString method; mRequest->GetMethod(method); - rv = uploadChan->ExplicitSetUploadStream(bodyStream, contentType, -1, method, false /* aStreamHasHeaders */); + rv = uploadChan->ExplicitSetUploadStream(bodyStream, contentType, + bodyLength, method, + false /* aStreamHasHeaders */); NS_ENSURE_SUCCESS(rv, rv); } } // If preflight is required, start a "CORS preflight fetch" // https://fetch.spec.whatwg.org/#cors-preflight-fetch-0. All the // implementation is handled by the http channel calling into // nsCORSListenerProxy. We just inform it which unsafe headers are included
--- a/dom/fetch/InternalRequest.cpp +++ b/dom/fetch/InternalRequest.cpp @@ -25,16 +25,17 @@ InternalRequest::GetRequestConstructorCo { MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(), "Internal Request's urlList should not be empty when copied from constructor."); RefPtr<InternalRequest> copy = new InternalRequest(mURLList.LastElement(), mFragment); copy->SetMethod(mMethod); copy->mHeaders = new InternalHeaders(*mHeaders); copy->SetUnsafeRequest(); copy->mBodyStream = mBodyStream; + copy->mBodyLength = mBodyLength; copy->mForceOriginHeader = true; // The "client" is not stored in our implementation. Fetch API users should // use the appropriate window/document/principal and other Gecko security // mechanisms as appropriate. copy->mSameOriginDataURL = true; copy->mPreserveContentCodings = true; copy->mReferrer = mReferrer; copy->mReferrerPolicy = mReferrerPolicy; @@ -74,16 +75,17 @@ InternalRequest::Clone() mBodyStream.swap(replacementBody); } return clone.forget(); } InternalRequest::InternalRequest(const nsACString& aURL, const nsACString& aFragment) : mMethod("GET") , mHeaders(new InternalHeaders(HeadersGuardEnum::None)) + , mBodyLength(InternalResponse::UNKNOWN_BODY_SIZE) , mContentPolicyType(nsIContentPolicy::TYPE_FETCH) , mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR)) , mReferrerPolicy(ReferrerPolicy::_empty) , mEnvironmentReferrerPolicy(net::RP_Unset) , mMode(RequestMode::No_cors) , mCredentialsMode(RequestCredentials::Omit) , mResponseTainting(LoadTainting::Basic) , mCacheMode(RequestCache::Default)
--- a/dom/fetch/InternalRequest.h +++ b/dom/fetch/InternalRequest.h @@ -457,30 +457,35 @@ public: void UnsetSameOriginDataURL() { mSameOriginDataURL = false; } void - SetBody(nsIInputStream* aStream) + SetBody(nsIInputStream* aStream, int64_t aBodyLength) { // A request's body may not be reset once set. MOZ_ASSERT_IF(aStream, !mBodyStream); mBodyStream = aStream; + mBodyLength = aBodyLength; } // Will return the original stream! // Use a tee or copy if you don't want to erase the original. void - GetBody(nsIInputStream** aStream) + GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr) { nsCOMPtr<nsIInputStream> s = mBodyStream; s.forget(aStream); + + if (aBodyLength) { + *aBodyLength = mBodyLength; + } } // The global is used as the client for the new object. already_AddRefed<InternalRequest> GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const; bool WasCreatedByFetchEvent() const @@ -549,16 +554,17 @@ private: static bool IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType); nsCString mMethod; // mURLList: a list of one or more fetch URLs nsTArray<nsCString> mURLList; RefPtr<InternalHeaders> mHeaders; nsCOMPtr<nsIInputStream> mBodyStream; + int64_t mBodyLength; nsContentPolicyType mContentPolicyType; // Empty string: no-referrer // "about:client": client (default) // URL: an URL nsString mReferrer; ReferrerPolicy mReferrerPolicy;
--- a/dom/fetch/InternalResponse.h +++ b/dom/fetch/InternalResponse.h @@ -207,17 +207,17 @@ public: Type() == ResponseType::Opaqueredirect) { *aStream = nullptr; if (aBodySize) { *aBodySize = UNKNOWN_BODY_SIZE; } return; } - return GetUnfilteredBody(aStream, aBodySize); + GetUnfilteredBody(aStream, aBodySize); } void SetBody(nsIInputStream* aBody, int64_t aBodySize) { if (mWrappedResponse) { return mWrappedResponse->SetBody(aBody, aBodySize); }
--- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -575,21 +575,21 @@ Request::Constructor(const GlobalObject& } if (aInit.mBody.WasPassed()) { const Nullable<fetch::OwningBodyInit>& bodyInitNullable = aInit.mBody.Value(); if (!bodyInitNullable.IsNull()) { const fetch::OwningBodyInit& bodyInit = bodyInitNullable.Value(); nsCOMPtr<nsIInputStream> stream; nsAutoCString contentTypeWithCharset; - uint64_t contentLengthUnused; + uint64_t contentLength = 0; aRv = ExtractByteStreamFromBody(bodyInit, getter_AddRefs(stream), contentTypeWithCharset, - contentLengthUnused); + contentLength); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } nsCOMPtr<nsIInputStream> temporaryBody = stream; if (!contentTypeWithCharset.IsVoid() && !requestHeaders->Has(NS_LITERAL_CSTRING("Content-Type"), aRv)) { @@ -599,32 +599,32 @@ Request::Constructor(const GlobalObject& if (NS_WARN_IF(aRv.Failed())) { return nullptr; } request->ClearCreatedByFetchEvent(); if (hasCopiedBody) { - request->SetBody(nullptr); + request->SetBody(nullptr, 0); } - request->SetBody(temporaryBody); + request->SetBody(temporaryBody, contentLength); } } RefPtr<Request> domRequest = new Request(global, request, signal); domRequest->SetMimeType(); if (aInput.IsRequest()) { RefPtr<Request> inputReq = &aInput.GetAsRequest(); nsCOMPtr<nsIInputStream> body; inputReq->GetBody(getter_AddRefs(body)); if (body) { - inputReq->SetBody(nullptr); + inputReq->SetBody(nullptr, 0); inputReq->SetBodyUsed(aGlobal.Context(), aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } } return domRequest.forget(); }
--- a/dom/fetch/Request.h +++ b/dom/fetch/Request.h @@ -121,23 +121,29 @@ public: InternalHeaders* GetInternalHeaders() const { return mRequest->Headers(); } Headers* Headers_(); - void - GetBody(nsIInputStream** aStream) { return mRequest->GetBody(aStream); } - using FetchBody::GetBody; void - SetBody(nsIInputStream* aStream) { return mRequest->SetBody(aStream); } + GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr) + { + mRequest->GetBody(aStream, aBodyLength); + } + + void + SetBody(nsIInputStream* aStream, int64_t aBodyLength) + { + mRequest->SetBody(aStream, aBodyLength); + } static already_AddRefed<Request> Constructor(const GlobalObject& aGlobal, const RequestOrUSVString& aInput, const RequestInit& aInit, ErrorResult& rv); nsIGlobalObject* GetParentObject() const { return mOwner;
--- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -100,17 +100,20 @@ public: GetPrincipalInfo() const { return mInternalResponse->GetPrincipalInfo(); } Headers* Headers_(); void - GetBody(nsIInputStream** aStream) { return mInternalResponse->GetBody(aStream); } + GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr) + { + mInternalResponse->GetBody(aStream, aBodyLength); + } using FetchBody::GetBody; static already_AddRefed<Response> Error(const GlobalObject& aGlobal); static already_AddRefed<Response> Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, uint16_t aStatus, ErrorResult& aRv);
--- a/dom/file/ipc/IPCBlobInputStream.cpp +++ b/dom/file/ipc/IPCBlobInputStream.cpp @@ -4,32 +4,37 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "IPCBlobInputStream.h" #include "IPCBlobInputStreamChild.h" #include "IPCBlobInputStreamStorage.h" #include "mozilla/ipc/InputStreamParams.h" #include "nsIAsyncInputStream.h" +#include "nsIStreamTransportService.h" +#include "nsITransport.h" +#include "nsNetCID.h" namespace mozilla { namespace dom { namespace { -class CallbackRunnable final : public CancelableRunnable +static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID); + +class InputStreamCallbackRunnable final : public CancelableRunnable { public: static void Execute(nsIInputStreamCallback* aCallback, nsIEventTarget* aEventTarget, IPCBlobInputStream* aStream) { - RefPtr<CallbackRunnable> runnable = - new CallbackRunnable(aCallback, aStream); + RefPtr<InputStreamCallbackRunnable> runnable = + new InputStreamCallbackRunnable(aCallback, aStream); nsCOMPtr<nsIEventTarget> target = aEventTarget; if (!target) { target = NS_GetCurrentThread(); } target->Dispatch(runnable, NS_DISPATCH_NORMAL); } @@ -39,43 +44,86 @@ public: { mCallback->OnInputStreamReady(mStream); mCallback = nullptr; mStream = nullptr; return NS_OK; } private: - CallbackRunnable(nsIInputStreamCallback* aCallback, - IPCBlobInputStream* aStream) - : CancelableRunnable("dom::CallbackRunnable") + InputStreamCallbackRunnable(nsIInputStreamCallback* aCallback, + IPCBlobInputStream* aStream) + : CancelableRunnable("dom::InputStreamCallbackRunnable") , mCallback(aCallback) , mStream(aStream) { MOZ_ASSERT(mCallback); MOZ_ASSERT(mStream); } nsCOMPtr<nsIInputStreamCallback> mCallback; RefPtr<IPCBlobInputStream> mStream; }; +class FileMetadataCallbackRunnable final : public CancelableRunnable +{ +public: + static void + Execute(nsIFileMetadataCallback* aCallback, + nsIEventTarget* aEventTarget, + IPCBlobInputStream* aStream) + { + RefPtr<FileMetadataCallbackRunnable> runnable = + new FileMetadataCallbackRunnable(aCallback, aStream); + + nsCOMPtr<nsIEventTarget> target = aEventTarget; + if (!target) { + target = NS_GetCurrentThread(); + } + + target->Dispatch(runnable, NS_DISPATCH_NORMAL); + } + + NS_IMETHOD + Run() override + { + mCallback->OnFileMetadataReady(mStream); + mCallback = nullptr; + mStream = nullptr; + return NS_OK; + } + +private: + FileMetadataCallbackRunnable(nsIFileMetadataCallback* aCallback, + IPCBlobInputStream* aStream) + : CancelableRunnable("dom::FileMetadataCallbackRunnable") + , mCallback(aCallback) + , mStream(aStream) + { + MOZ_ASSERT(mCallback); + MOZ_ASSERT(mStream); + } + + nsCOMPtr<nsIFileMetadataCallback> mCallback; + RefPtr<IPCBlobInputStream> mStream; +}; + } // anonymous NS_IMPL_ADDREF(IPCBlobInputStream); NS_IMPL_RELEASE(IPCBlobInputStream); NS_INTERFACE_MAP_BEGIN(IPCBlobInputStream) NS_INTERFACE_MAP_ENTRY(nsIInputStream) NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStream) NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback) NS_INTERFACE_MAP_ENTRY(nsICloneableInputStream) NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, IsSeekableStream()) - NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileMetadata, IsFileMetadata()) + NS_INTERFACE_MAP_ENTRY(nsIFileMetadata) + NS_INTERFACE_MAP_ENTRY(nsIAsyncFileMetadata) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream) NS_INTERFACE_MAP_END IPCBlobInputStream::IPCBlobInputStream(IPCBlobInputStreamChild* aActor) : mActor(aActor) , mState(eInit) { MOZ_ASSERT(aActor); @@ -104,50 +152,81 @@ IPCBlobInputStream::Available(uint64_t* // We don't have a remoteStream yet. Let's return the full known size. if (mState == eInit || mState == ePending) { *aLength = mActor->Size(); return NS_OK; } if (mState == eRunning) { MOZ_ASSERT(mRemoteStream); - return mRemoteStream->Available(aLength); + + // This will go away eventually: an async input stream can return 0 in + // Available(), but this is not currently fully supported in the rest of + // gecko. + if (!mAsyncRemoteStream) { + *aLength = mActor->Size(); + return NS_OK; + } + + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(mAsyncRemoteStream); + return mAsyncRemoteStream->Available(aLength); } MOZ_ASSERT(mState == eClosed); return NS_BASE_STREAM_CLOSED; } NS_IMETHODIMP IPCBlobInputStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aReadCount) { // Read is not available is we don't have a remoteStream. if (mState == eInit || mState == ePending) { return NS_BASE_STREAM_WOULD_BLOCK; } if (mState == eRunning) { - return mRemoteStream->Read(aBuffer, aCount, aReadCount); + MOZ_ASSERT(mRemoteStream); + + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(mAsyncRemoteStream); + return mAsyncRemoteStream->Read(aBuffer, aCount, aReadCount); } MOZ_ASSERT(mState == eClosed); return NS_BASE_STREAM_CLOSED; } NS_IMETHODIMP IPCBlobInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t *aResult) { // ReadSegments is not available is we don't have a remoteStream. if (mState == eInit || mState == ePending) { return NS_BASE_STREAM_WOULD_BLOCK; } if (mState == eRunning) { - return mRemoteStream->ReadSegments(aWriter, aClosure, aCount, aResult); + MOZ_ASSERT(mRemoteStream); + + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(mAsyncRemoteStream); + return mAsyncRemoteStream->ReadSegments(aWriter, aClosure, aCount, aResult); } MOZ_ASSERT(mState == eClosed); return NS_BASE_STREAM_CLOSED; } NS_IMETHODIMP IPCBlobInputStream::IsNonBlocking(bool* aNonBlocking) @@ -159,22 +238,31 @@ IPCBlobInputStream::IsNonBlocking(bool* NS_IMETHODIMP IPCBlobInputStream::Close() { if (mActor) { mActor->ForgetStream(this); mActor = nullptr; } + if (mAsyncRemoteStream) { + mAsyncRemoteStream->Close(); + mAsyncRemoteStream = nullptr; + } + if (mRemoteStream) { mRemoteStream->Close(); mRemoteStream = nullptr; } - mCallback = nullptr; + mInputStreamCallback = nullptr; + mInputStreamCallbackEventTarget = nullptr; + + mFileMetadataCallback = nullptr; + mFileMetadataCallbackEventTarget = nullptr; mState = eClosed; return NS_OK; } // nsICloneableInputStream interface NS_IMETHODIMP @@ -217,36 +305,36 @@ IPCBlobInputStream::AsyncWait(nsIInputSt { // See IPCBlobInputStream.h for more information about this state machine. switch (mState) { // First call, we need to retrieve the stream from the parent actor. case eInit: MOZ_ASSERT(mActor); - mCallback = aCallback; - mCallbackEventTarget = aEventTarget; + mInputStreamCallback = aCallback; + mInputStreamCallbackEventTarget = aEventTarget; mState = ePending; mActor->StreamNeeded(this, aEventTarget); return NS_OK; // We are still waiting for the remote inputStream case ePending: - if (mCallback && aCallback) { + if (mInputStreamCallback && aCallback) { return NS_ERROR_FAILURE; } - mCallback = aCallback; - mCallbackEventTarget = aEventTarget; + mInputStreamCallback = aCallback; + mInputStreamCallbackEventTarget = aEventTarget; return NS_OK; // We have the remote inputStream, let's check if we can execute the callback. case eRunning: - return MaybeExecuteCallback(aCallback, aEventTarget); + return MaybeExecuteInputStreamCallback(aCallback, aEventTarget); // Stream is closed. default: MOZ_ASSERT(mState == eClosed); return NS_BASE_STREAM_CLOSED; } } @@ -260,93 +348,103 @@ IPCBlobInputStream::StreamReady(nsIInput } return; } // If aInputStream is null, it means that the serialization went wrong or the // stream is not available anymore. We keep the state as pending just to block // any additional operation. - nsCOMPtr<nsIInputStreamCallback> callback; - callback.swap(mCallback); + if (!aInputStream) { + return; + } + + mRemoteStream = aInputStream; - nsCOMPtr<nsIEventTarget> callbackEventTarget; - callbackEventTarget.swap(mCallbackEventTarget); + MOZ_ASSERT(mState == ePending); + mState = eRunning; + + nsCOMPtr<nsIFileMetadataCallback> fileMetadataCallback; + fileMetadataCallback.swap(mFileMetadataCallback); + + nsCOMPtr<nsIEventTarget> fileMetadataCallbackEventTarget; + fileMetadataCallbackEventTarget.swap(mFileMetadataCallbackEventTarget); - if (aInputStream && callback) { - MOZ_ASSERT(mState == ePending); + if (fileMetadataCallback) { + FileMetadataCallbackRunnable::Execute(fileMetadataCallback, + fileMetadataCallbackEventTarget, + this); + } - mRemoteStream = aInputStream; - mState = eRunning; + nsCOMPtr<nsIInputStreamCallback> inputStreamCallback; + inputStreamCallback.swap(mInputStreamCallback); - MaybeExecuteCallback(callback, callbackEventTarget); + nsCOMPtr<nsIEventTarget> inputStreamCallbackEventTarget; + inputStreamCallbackEventTarget.swap(mInputStreamCallbackEventTarget); + + if (inputStreamCallback) { + MaybeExecuteInputStreamCallback(inputStreamCallback, + inputStreamCallbackEventTarget); } } nsresult -IPCBlobInputStream::MaybeExecuteCallback(nsIInputStreamCallback* aCallback, - nsIEventTarget* aCallbackEventTarget) +IPCBlobInputStream::MaybeExecuteInputStreamCallback(nsIInputStreamCallback* aCallback, + nsIEventTarget* aCallbackEventTarget) { MOZ_ASSERT(mState == eRunning); MOZ_ASSERT(mRemoteStream); - // If the stream supports nsIAsyncInputStream, we need to call its AsyncWait - // and wait for OnInputStreamReady. - nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mRemoteStream); - if (asyncStream) { - // If the callback has been already set, we return an error. - if (mCallback && aCallback) { - return NS_ERROR_FAILURE; - } - - mCallback = aCallback; - mCallbackEventTarget = aCallbackEventTarget; - - if (!mCallback) { - return NS_OK; - } - - RefPtr<nsIEventTarget> target = GetCurrentThreadEventTarget(); - return asyncStream->AsyncWait(this, 0, 0, target); + // If the callback has been already set, we return an error. + if (mInputStreamCallback && aCallback) { + return NS_ERROR_FAILURE; } - MOZ_ASSERT(!mCallback); - MOZ_ASSERT(!mCallbackEventTarget); + mInputStreamCallback = aCallback; + mInputStreamCallbackEventTarget = aCallbackEventTarget; - if (!aCallback) { + if (!mInputStreamCallback) { return NS_OK; } - CallbackRunnable::Execute(aCallback, aCallbackEventTarget, this); - return NS_OK; + nsresult rv = EnsureAsyncRemoteStream(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + MOZ_ASSERT(mAsyncRemoteStream); + + return mAsyncRemoteStream->AsyncWait(this, 0, 0, aCallbackEventTarget); } // nsIInputStreamCallback NS_IMETHODIMP IPCBlobInputStream::OnInputStreamReady(nsIAsyncInputStream* aStream) { // We have been closed in the meantime. if (mState == eClosed) { return NS_OK; } MOZ_ASSERT(mState == eRunning); - MOZ_ASSERT(mRemoteStream == aStream); + MOZ_ASSERT(mAsyncRemoteStream == aStream); // The callback has been canceled in the meantime. - if (!mCallback) { + if (!mInputStreamCallback) { return NS_OK; } - CallbackRunnable::Execute(mCallback, mCallbackEventTarget, this); + nsCOMPtr<nsIInputStreamCallback> callback; + callback.swap(mInputStreamCallback); - mCallback = nullptr; - mCallbackEventTarget = nullptr; - + nsCOMPtr<nsIEventTarget> callbackEventTarget; + callbackEventTarget.swap(mInputStreamCallbackEventTarget); + + InputStreamCallbackRunnable::Execute(callback, callbackEventTarget, this); return NS_OK; } // nsIIPCSerializableInputStream void IPCBlobInputStream::Serialize(mozilla::ipc::InputStreamParams& aParams, FileDescriptorArray& aFileDescriptors) @@ -366,27 +464,60 @@ IPCBlobInputStream::Deserialize(const mo } mozilla::Maybe<uint64_t> IPCBlobInputStream::ExpectedSerializedLength() { return mozilla::Nothing(); } -// nsIFileMetadata +// nsIAsyncFileMetadata -bool -IPCBlobInputStream::IsFileMetadata() const +NS_IMETHODIMP +IPCBlobInputStream::AsyncWait(nsIFileMetadataCallback* aCallback, + nsIEventTarget* aEventTarget) { - // We are nsIFileMetadata only if we have the remote stream and that is a - // nsIFileMetadata. - nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream); - return !!fileMetadata; + // See IPCBlobInputStream.h for more information about this state machine. + + switch (mState) { + // First call, we need to retrieve the stream from the parent actor. + case eInit: + MOZ_ASSERT(mActor); + + mFileMetadataCallback = aCallback; + mFileMetadataCallbackEventTarget = aEventTarget; + mState = ePending; + + mActor->StreamNeeded(this, aEventTarget); + return NS_OK; + + // We are still waiting for the remote inputStream + case ePending: + if (mFileMetadataCallback && aCallback) { + return NS_ERROR_FAILURE; + } + + mFileMetadataCallback = aCallback; + mFileMetadataCallbackEventTarget = aEventTarget; + return NS_OK; + + // We have the remote inputStream, let's check if we can execute the callback. + case eRunning: + FileMetadataCallbackRunnable::Execute(aCallback, aEventTarget, this); + return NS_OK; + + // Stream is closed. + default: + MOZ_ASSERT(mState == eClosed); + return NS_BASE_STREAM_CLOSED; + } } +// nsIFileMetadata + NS_IMETHODIMP IPCBlobInputStream::GetSize(int64_t* aRetval) { nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream); if (!fileMetadata) { return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE; } @@ -410,50 +541,66 @@ IPCBlobInputStream::GetFileDescriptor(PR nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream); if (!fileMetadata) { return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE; } return fileMetadata->GetFileDescriptor(aRetval); } -// nsISeekableStream - -bool -IPCBlobInputStream::IsSeekableStream() const +nsresult +IPCBlobInputStream::EnsureAsyncRemoteStream() { - // We are nsISeekableStream only if we have the remote stream and that is a - // nsISeekableStream. - nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(mRemoteStream); - return !!seekableStream; -} + if (!mRemoteStream) { + return NS_ERROR_FAILURE; + } -NS_IMETHODIMP -IPCBlobInputStream::Seek(int32_t aWhence, int64_t aOffset) -{ - nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(mRemoteStream); - if (!seekableStream) { - return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE; + // We already have an async remote stream. + if (mAsyncRemoteStream) { + return NS_OK; + } + + // If the stream is blocking, we want to make it unblocking using a pipe. + bool nonBlocking = false; + nsresult rv = mRemoteStream->IsNonBlocking(&nonBlocking); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } - return seekableStream->Seek(aWhence, aOffset); -} + nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mRemoteStream); + if (!asyncStream || !nonBlocking) { + nsCOMPtr<nsIStreamTransportService> sts = + do_GetService(kStreamTransportServiceCID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } -NS_IMETHODIMP -IPCBlobInputStream::Tell(int64_t *aResult) -{ - nsCOMPtr<nsISeekableStream> seekableStream = do_QueryInterface(mRemoteStream); - if (!seekableStream) { - return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE; + nsCOMPtr<nsITransport> transport; + rv = sts->CreateInputTransport(mRemoteStream, + /* aStartOffset */ 0, + /* aReadLimit */ -1, + /* aCloseWhenDone */ true, + getter_AddRefs(transport)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsCOMPtr<nsIInputStream> wrapper; + rv = transport->OpenInputStream(/* aFlags */ 0, + /* aSegmentSize */ 0, + /* aSegmentCount */ 0, + getter_AddRefs(wrapper)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + asyncStream = do_QueryInterface(wrapper); } - return seekableStream->Tell(aResult); -} + MOZ_ASSERT(asyncStream); + mAsyncRemoteStream = asyncStream; -NS_IMETHODIMP -IPCBlobInputStream::SetEOF() -{ - // This is a read-only stream. - return NS_ERROR_FAILURE; + return NS_OK; + } } // namespace dom } // namespace mozilla
--- a/dom/file/ipc/IPCBlobInputStream.h +++ b/dom/file/ipc/IPCBlobInputStream.h @@ -6,58 +6,53 @@ #ifndef mozilla_dom_ipc_IPCBlobInputStream_h #define mozilla_dom_ipc_IPCBlobInputStream_h #include "nsIAsyncInputStream.h" #include "nsICloneableInputStream.h" #include "nsIFileStreams.h" #include "nsIIPCSerializableInputStream.h" -#include "nsISeekableStream.h" #include "nsCOMPtr.h" namespace mozilla { namespace dom { class IPCBlobInputStreamChild; class IPCBlobInputStream final : public nsIAsyncInputStream , public nsIInputStreamCallback , public nsICloneableInputStream , public nsIIPCSerializableInputStream - , public nsISeekableStream - , public nsIFileMetadata + , public nsIAsyncFileMetadata { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINPUTSTREAM NS_DECL_NSIASYNCINPUTSTREAM NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSICLONEABLEINPUTSTREAM NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM - NS_DECL_NSISEEKABLESTREAM NS_DECL_NSIFILEMETADATA + NS_DECL_NSIASYNCFILEMETADATA explicit IPCBlobInputStream(IPCBlobInputStreamChild* aActor); void StreamReady(nsIInputStream* aInputStream); private: ~IPCBlobInputStream(); nsresult - MaybeExecuteCallback(nsIInputStreamCallback* aCallback, - nsIEventTarget* aEventTarget); + MaybeExecuteInputStreamCallback(nsIInputStreamCallback* aCallback, + nsIEventTarget* aEventTarget); - bool - IsSeekableStream() const; - - bool - IsFileMetadata() const; + nsresult + EnsureAsyncRemoteStream(); RefPtr<IPCBlobInputStreamChild> mActor; // This is the list of possible states. enum { // The initial state. Only ::Available() can be used without receiving an // error. The available size is known by the actor. eInit, @@ -73,18 +68,23 @@ private: // If Close() or CloseWithStatus() is called, we move to this state. // mRemoveStream is released and any method will return // NS_BASE_STREAM_CLOSED. eClosed, } mState; nsCOMPtr<nsIInputStream> mRemoteStream; + nsCOMPtr<nsIAsyncInputStream> mAsyncRemoteStream; // These 2 values are set only if mState is ePending. - nsCOMPtr<nsIInputStreamCallback> mCallback; - nsCOMPtr<nsIEventTarget> mCallbackEventTarget; + nsCOMPtr<nsIInputStreamCallback> mInputStreamCallback; + nsCOMPtr<nsIEventTarget> mInputStreamCallbackEventTarget; + + // These 2 values are set only if mState is ePending. + nsCOMPtr<nsIFileMetadataCallback> mFileMetadataCallback; + nsCOMPtr<nsIEventTarget> mFileMetadataCallbackEventTarget; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_ipc_IPCBlobInputStream_h
--- a/dom/flyweb/HttpServer.cpp +++ b/dom/flyweb/HttpServer.cpp @@ -682,17 +682,17 @@ HttpServer::Connection::ConsumeLine(cons getter_AddRefs(output), 0, // Segment size UINT32_MAX, // Unlimited buffer size false, // not nonBlockingInput true); // nonBlockingOutput NS_ENSURE_SUCCESS(rv, rv); mCurrentRequestBody = do_QueryInterface(output); - mPendingReq->SetBody(input); + mPendingReq->SetBody(input, -1); } else { LOG_V("HttpServer::Connection::ConsumeLine(%p) - No body", this); mState = eRequestLine; } mPendingRequests.AppendElement(PendingRequest(mPendingReq, nullptr)); LOG_V("HttpServer::Connection::ConsumeLine(%p) - Fire OnRequest", this);
--- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -338,16 +338,22 @@ public: return mSelectionProperties; } bool HasPatternAttribute() const { return mHasPatternAttribute; } + virtual already_AddRefed<nsITextControlElement> GetAsTextControlElement() override + { + nsCOMPtr<nsITextControlElement> txt = this; + return txt.forget(); + } + // nsIConstraintValidation bool IsTooLong(); bool IsTooShort(); bool IsValueMissing() const; bool HasTypeMismatch() const; bool HasPatternMismatch() const; bool IsRangeOverflow() const; bool IsRangeUnderflow() const;
--- a/dom/html/HTMLTextAreaElement.h +++ b/dom/html/HTMLTextAreaElement.h @@ -163,16 +163,22 @@ public: NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLTextAreaElement, nsGenericHTMLFormElementWithState) + virtual already_AddRefed<nsITextControlElement> GetAsTextControlElement() override + { + nsCOMPtr<nsITextControlElement> txt = this; + return txt.forget(); + } + // nsIConstraintValidation bool IsTooLong(); bool IsTooShort(); bool IsValueMissing() const; void UpdateTooLongValidityState(); void UpdateTooShortValidityState(); void UpdateValueMissingValidityState(); void UpdateBarredFromConstraintValidation();
--- a/dom/indexedDB/ActorsChild.cpp +++ b/dom/indexedDB/ActorsChild.cpp @@ -1472,16 +1472,17 @@ DispatchFileHandleSuccessEvent(FileHandl /******************************************************************************* * Actor class declarations ******************************************************************************/ // CancelableRunnable is used to make workers happy. class BackgroundRequestChild::PreprocessHelper final : public CancelableRunnable , public nsIInputStreamCallback + , public nsIFileMetadataCallback { typedef std::pair<nsCOMPtr<nsIInputStream>, nsCOMPtr<nsIInputStream>> StreamPair; nsCOMPtr<nsIEventTarget> mOwningEventTarget; nsTArray<StreamPair> mStreamPairs; nsTArray<RefPtr<JS::WasmModule>> mModuleSet; BackgroundRequestChild* mActor; @@ -1555,19 +1556,23 @@ private: ProcessCurrentStreamPair(); nsresult WaitForStreamReady(nsIInputStream* aInputStream); void ContinueWithStatus(nsresult aStatus); + nsresult + DataIsReady(nsIInputStream* aInputStream); + NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIRUNNABLE NS_DECL_NSIINPUTSTREAMCALLBACK + NS_DECL_NSIFILEMETADATACALLBACK virtual nsresult Cancel() override; }; /******************************************************************************* * Local class implementations ******************************************************************************/ @@ -3513,16 +3518,27 @@ PreprocessHelper::ProcessCurrentStreamPa nsresult BackgroundRequestChild:: PreprocessHelper::WaitForStreamReady(nsIInputStream* aInputStream) { MOZ_ASSERT(!IsOnOwningThread()); MOZ_ASSERT(aInputStream); + nsCOMPtr<nsIAsyncFileMetadata> asyncFileMetadata = + do_QueryInterface(aInputStream); + if (asyncFileMetadata) { + nsresult rv = asyncFileMetadata->AsyncWait(this, mTaskQueueEventTarget); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; + } + nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aInputStream); if (!asyncStream) { return NS_ERROR_NO_INTERFACE; } nsresult rv = asyncStream->AsyncWait(this, 0, 0, mTaskQueueEventTarget); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -3559,17 +3575,18 @@ PreprocessHelper::ContinueWithStatus(nsr eventTarget = mTaskQueueEventTarget; } nsresult rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL); Unused << NS_WARN_IF(NS_FAILED(rv)); } NS_IMPL_ISUPPORTS_INHERITED(BackgroundRequestChild::PreprocessHelper, - CancelableRunnable, nsIInputStreamCallback) + CancelableRunnable, nsIInputStreamCallback, + nsIFileMetadataCallback) NS_IMETHODIMP BackgroundRequestChild:: PreprocessHelper::Run() { if (IsOnOwningThread()) { RunOnOwningThread(); } else { @@ -3578,16 +3595,33 @@ PreprocessHelper::Run() return NS_OK; } NS_IMETHODIMP BackgroundRequestChild:: PreprocessHelper::OnInputStreamReady(nsIAsyncInputStream* aStream) { + return DataIsReady(aStream); +} + +NS_IMETHODIMP +BackgroundRequestChild:: +PreprocessHelper::OnFileMetadataReady(nsIAsyncFileMetadata* aObject) +{ + nsCOMPtr<nsIInputStream> stream = do_QueryInterface(aObject); + MOZ_ASSERT(stream, "It was a stream before!"); + + return DataIsReady(stream); +} + +nsresult +BackgroundRequestChild:: +PreprocessHelper::DataIsReady(nsIInputStream* aStream) +{ MOZ_ASSERT(!IsOnOwningThread()); MOZ_ASSERT(aStream); MOZ_ASSERT(!mStreamPairs.IsEmpty()); // We still don't have the current bytecode FileDesc. if (!mCurrentBytecodeFileDesc) { mCurrentBytecodeFileDesc = GetFileDescriptorFromStream(aStream); if (!mCurrentBytecodeFileDesc) {
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -263,21 +263,16 @@ #include "mozilla/CodeCoverageHandler.h" #endif // For VP9Benchmark::sBenchmarkFpsPref #include "Benchmark.h" static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID); -#if defined(XP_WIN) -// e10s forced enable pref, defined in nsAppRunner.cpp -extern const char* kForceEnableE10sPref; -#endif - using base::ChildPrivileges; using base::KillProcess; #ifdef MOZ_CRASHREPORTER using namespace CrashReporter; #endif using namespace mozilla::dom::power; using namespace mozilla::media; @@ -1306,23 +1301,18 @@ ContentParent::Init() obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", cpId.get()); } #ifdef ACCESSIBILITY // If accessibility is running in chrome process then start it in content // process. if (nsIPresShell::IsAccessibilityActive()) { #if defined(XP_WIN) -#if defined(RELEASE_OR_BETA) - // On Windows we currently only enable a11y in the content process - // for testing purposes. - if (Preferences::GetBool(kForceEnableE10sPref, false)) -#endif - Unused << SendActivateA11y(::GetCurrentThreadId(), - a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); + Unused << SendActivateA11y(::GetCurrentThreadId(), + a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); #else Unused << SendActivateA11y(0, 0); #endif } #endif #ifdef MOZ_GECKO_PROFILER Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid())); @@ -2846,23 +2836,18 @@ ContentParent::Observe(nsISupports* aSub Unused << SendLastPrivateDocShellDestroyed(); } #ifdef ACCESSIBILITY else if (aData && !strcmp(aTopic, "a11y-init-or-shutdown")) { if (*aData == '1') { // Make sure accessibility is running in content process when // accessibility gets initiated in chrome process. #if defined(XP_WIN) -#if defined(RELEASE_OR_BETA) - // On Windows we currently only enable a11y in the content process - // for testing purposes. - if (Preferences::GetBool(kForceEnableE10sPref, false)) -#endif - Unused << SendActivateA11y(::GetCurrentThreadId(), - a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); + Unused << SendActivateA11y(::GetCurrentThreadId(), + a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); #else Unused << SendActivateA11y(0, 0); #endif } else { // If possible, shut down accessibility in content process when // accessibility gets shutdown in chrome process. Unused << SendShutdownA11y(); }
--- a/dom/tests/mochitest/general/test_clipboard_events.html +++ b/dom/tests/mochitest/general/test_clipboard_events.html @@ -654,32 +654,29 @@ function compareSynthetic(event, eventty function checkCachedDataTransfer(cd, eventtype) { var testprefix = "cached " + eventtype + " dataTransfer"; setClipboardText("Some Clipboard Text"); var oldtext = cd.getData("text/plain"); - ok(oldtext != "Some Clipboard Text", "clipboard get using " + testprefix); + ok(!oldtext, "clipboard get using " + testprefix); - var exh = false; - try { cd.mozSetDataAt("text/plain", "Test Cache Data", 0); } catch (ex) { exh = true; } - ok(eventtype == "paste" ? exh : !exh, "exception occured setting " + testprefix); - - var newtext = (eventtype == "paste") ? cd.getData("text/plain") : - cd.mozGetDataAt("text/plain", 0); - is(newtext, (eventtype == "paste") ? oldtext : "Test Cache Data", - " clipboardData not changed using " + testprefix); + try { + cd.mozSetDataAt("text/plain", "Test Cache Data", 0); + } catch (ex) {} + ok(!cd.getData("text/plain"), "clipboard set using " + testprefix); is(getClipboardText(), "Some Clipboard Text", "clipboard not changed using " + testprefix); - var exh = false; - try { cd.mozClearDataAt("text/plain", 0); } catch (ex) { exh = true; } - ok(eventtype == "paste" ? exh : !exh, "exception occured clearing " + testprefix); + try { + cd.mozClearDataAt("text/plain", 0); + } catch (ex) {} + ok(!cd.getData("text/plain"), "clipboard clear using " + testprefix); is(getClipboardText(), "Some Clipboard Text", "clipboard not changed using " + testprefix); } function test_input_cut_disallowed_types_dataTransfer() { selectContentInput(); let oncutExecuted = false; contentInput.oncut = function(event) {
--- a/dom/webidl/DataTransfer.webidl +++ b/dom/webidl/DataTransfer.webidl @@ -150,9 +150,21 @@ partial interface DataTransfer { readonly attribute boolean mozUserCancelled; /** * The node that the mouse was pressed over to begin the drag. For external * drags, or if the caller cannot access this node, this will be null. */ [UseCounter] readonly attribute Node? mozSourceNode; + + /** + * Copy the given DataTransfer for the given event. Used by testing code for + * creating emulated Drag and Drop events in the UI. + * + * NOTE: Don't expose a DataTransfer produced with this method to the web or + * use this for non-testing purposes. It can easily be used to get the + * DataTransfer into an invalid state, and is an unstable implementation + * detail of EventUtils.synthesizeDrag. + */ + [Throws, ChromeOnly] + DataTransfer mozCloneForEvent(DOMString event); };
--- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -204,18 +204,24 @@ FileReaderSync::ReadAsText(Blob& aBlob, return; } aRv = multiplexStream->AppendStream(sniffStringStream); if (NS_WARN_IF(aRv.Failed())) { return; } + uint64_t blobSize = aBlob.GetSize(aRv); + if (NS_WARN_IF(aRv.Failed())){ + return; + } + nsCOMPtr<nsIInputStream> syncStream; - aRv = ConvertAsyncToSyncStream(stream, getter_AddRefs(syncStream)); + aRv = ConvertAsyncToSyncStream(blobSize - sniffBuf.Length(), stream, + getter_AddRefs(syncStream)); if (NS_WARN_IF(aRv.Failed())) { return; } // ConvertAsyncToSyncStream returns a null syncStream if the stream has been // already closed or there is nothing to read. if (syncStream) { aRv = multiplexStream->AppendStream(syncStream); @@ -250,35 +256,35 @@ FileReaderSync::ReadAsDataURL(Blob& aBlo scratchResult.AppendLiteral(";base64,"); nsCOMPtr<nsIInputStream> stream; aBlob.GetInternalStream(getter_AddRefs(stream), aRv); if (NS_WARN_IF(aRv.Failed())){ return; } + uint64_t blobSize = aBlob.GetSize(aRv); + if (NS_WARN_IF(aRv.Failed())){ + return; + } + nsCOMPtr<nsIInputStream> syncStream; - aRv = ConvertAsyncToSyncStream(stream, getter_AddRefs(syncStream)); + aRv = ConvertAsyncToSyncStream(blobSize, stream, getter_AddRefs(syncStream)); if (NS_WARN_IF(aRv.Failed())) { return; } MOZ_ASSERT(syncStream); uint64_t size; aRv = syncStream->Available(&size); if (NS_WARN_IF(aRv.Failed())) { return; } - uint64_t blobSize = aBlob.GetSize(aRv); - if (NS_WARN_IF(aRv.Failed())){ - return; - } - // The file is changed in the meantime? if (blobSize != size) { return; } nsAutoString encodedData; aRv = Base64EncodeInputStream(syncStream, encodedData, size); if (NS_WARN_IF(aRv.Failed())){ @@ -461,49 +467,39 @@ FileReaderSync::SyncRead(nsIInputStream* return NS_ERROR_DOM_INVALID_STATE_ERR; } // Now, we can try to read again. return SyncRead(aStream, aBuffer, aBufferSize, aRead); } nsresult -FileReaderSync::ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, +FileReaderSync::ConvertAsyncToSyncStream(uint64_t aStreamSize, + nsIInputStream* aAsyncStream, nsIInputStream** aSyncStream) { // If the stream is not async, we just need it to be bufferable. nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aAsyncStream); if (!asyncStream) { return NS_NewBufferedInputStream(aSyncStream, aAsyncStream, 4096); } - uint64_t length; - nsresult rv = aAsyncStream->Available(&length); - if (rv == NS_BASE_STREAM_CLOSED) { - // The stream has already been closed. Nothing to do. - *aSyncStream = nullptr; - return NS_OK; + nsAutoCString buffer; + if (!buffer.SetLength(aStreamSize, fallible)) { + return NS_ERROR_OUT_OF_MEMORY; } + uint32_t read; + nsresult rv = + SyncRead(aAsyncStream, buffer.BeginWriting(), aStreamSize, &read); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - nsAutoCString buffer; - if (!buffer.SetLength(length, fallible)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - uint32_t read; - rv = SyncRead(aAsyncStream, buffer.BeginWriting(), length, &read); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - if (read != length) { + if (read != aStreamSize) { return NS_ERROR_FAILURE; } rv = NS_NewCStringInputStream(aSyncStream, buffer); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
--- a/dom/workers/FileReaderSync.h +++ b/dom/workers/FileReaderSync.h @@ -27,17 +27,18 @@ private: // Private destructor, to discourage deletion outside of Release(): ~FileReaderSync() { } nsresult ConvertStream(nsIInputStream *aStream, const char *aCharset, nsAString &aResult); - nsresult ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream, + nsresult ConvertAsyncToSyncStream(uint64_t aStreamSize, + nsIInputStream* aAsyncStream, nsIInputStream** aSyncStream); nsresult SyncRead(nsIInputStream* aStream, char* aBuffer, uint32_t aBufferSize, uint32_t* aRead); public: static already_AddRefed<FileReaderSync> Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
--- a/dom/workers/ServiceWorkerPrivate.cpp +++ b/dom/workers/ServiceWorkerPrivate.cpp @@ -1598,17 +1598,17 @@ private: mCacheMode, mRequestMode, mRequestRedirect, mRequestCredentials, NS_ConvertUTF8toUTF16(mReferrer), mReferrerPolicy, mContentPolicyType, mIntegrity); - internalReq->SetBody(mUploadStream); + internalReq->SetBody(mUploadStream, -1); // For Telemetry, note that this Request object was created by a Fetch event. internalReq->SetCreatedByFetchEvent(); nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(globalObj.GetAsSupports()); if (NS_WARN_IF(!global)) { return false; }
--- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -641,16 +641,18 @@ public: } if (aFontEntry->mFamilyName.IsEmpty()) { aFontEntry->mFamilyName = Name(); } else { MOZ_ASSERT(aFontEntry->mFamilyName.Equals(Name())); } aFontEntry->mSkipDefaultFeatureSpaceCheck = mSkipDefaultFeatureSpaceCheck; mAvailableFonts.AppendElement(aFontEntry); + mIsSimpleFamily = false; // CheckForSimpleFamily may set this later, + // but at this point we're not sure } // note that the styles for this family have been added bool HasStyles() { return mHasStyles; } void SetHasStyles(bool aHasStyles) { mHasStyles = aHasStyles; } // choose a specific face to match a style using CSS font matching // rules (weight matching occurs here). may return a face that doesn't
--- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -178,24 +178,27 @@ MacOSFontEntry::ReadCMAP(FontInfoData *a } if (NS_SUCCEEDED(rv) && !HasGraphiteTables()) { // We assume a Graphite font knows what it's doing, // and provides whatever shaping is needed for the // characters it supports, so only check/clear the // complex-script ranges for non-Graphite fonts - // for layout support, check for the presence of mort/morx and/or + // for layout support, check for the presence of mort/morx/kerx and/or // opentype layout tables bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) || HasFontTable(TRUETYPE_TAG('m','o','r','t')); + bool hasAppleKerning = HasFontTable(TRUETYPE_TAG('k','e','r','x')); bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B')); bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S')); - if (hasAATLayout && !(hasGSUB || hasGPOS)) { - mRequiresAAT = true; // prefer CoreText if font has no OTL tables + if ((hasAATLayout && !(hasGSUB || hasGPOS)) || hasAppleKerning) { + mRequiresAAT = true; // prefer CoreText if font has no OTL tables, + // or if it uses the Apple-specific 'kerx' + // variant of kerning table } for (const ScriptRange* sr = gfxPlatformFontList::sComplexScriptRanges; sr->rangeStart; sr++) { // check to see if the cmap includes complex script codepoints if (charmap->TestRange(sr->rangeStart, sr->rangeEnd)) { if (hasAATLayout) { // prefer CoreText for Apple's complex-script fonts,
--- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -969,37 +969,38 @@ js::Nursery::maybeResizeNursery(JS::gcre } #ifdef JS_GC_ZEAL // This zeal mode disabled nursery resizing. if (runtime()->hasZealMode(ZealMode::GenerationalGC)) return; #endif - bool canUsePromotionRate; - const float promotionRate = calcPromotionRate(&canUsePromotionRate); + /* + * This incorrect promotion rate results in better nursery sizing + * decisions, however we should to better tuning based on the real + * promotion rate in the future. + */ + const float promotionRate = + float(previousGC.tenuredBytes) / float(previousGC.nurseryCapacity); newMaxNurseryChunks = runtime()->gc.tunables.gcMaxNurseryBytes() >> ChunkShift; if (newMaxNurseryChunks != maxNurseryChunks_) { maxNurseryChunks_ = newMaxNurseryChunks; /* The configured maximum nursery size is changing */ const int extraChunks = numChunks() - newMaxNurseryChunks; if (extraChunks > 0) { /* We need to shrink the nursery */ shrinkAllocableSpace(extraChunks); - if (canUsePromotionRate) - previousPromotionRate_ = promotionRate; + previousPromotionRate_ = promotionRate; return; } } - if (!canUsePromotionRate) - return; - if (promotionRate > GrowThreshold) growAllocableSpace(); else if (promotionRate < ShrinkThreshold && previousPromotionRate_ < ShrinkThreshold) shrinkAllocableSpace(1); previousPromotionRate_ = promotionRate; }
--- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -5,23 +5,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/DebugOnly.h" #include "jit/BaselineIC.h" #include "jit/CacheIRCompiler.h" #include "jit/IonCaches.h" #include "jit/IonIC.h" - +#include "jit/JSJitFrameIter.h" #include "jit/Linker.h" #include "jit/SharedICHelpers.h" #include "proxy/Proxy.h" #include "jscompartmentinlines.h" +#include "jit/JSJitFrameIter-inl.h" #include "jit/MacroAssembler-inl.h" #include "vm/TypeInference-inl.h" using namespace js; using namespace js::jit; using mozilla::DebugOnly; @@ -319,16 +320,31 @@ void CacheRegisterAllocator::restoreIonLiveRegisters(MacroAssembler& masm, LiveRegisterSet liveRegs) { masm.PopRegsInMask(liveRegs); availableRegs_.set() = GeneralRegisterSet(); availableRegsAfterSpill_.set() = GeneralRegisterSet::All(); } +static void* +GetReturnAddressToIonCode(JSContext* cx) +{ + JSJitFrameIter frame(cx); + MOZ_ASSERT(frame.type() == JitFrame_Exit, + "An exit frame is expected as update functions are called with a VMFunction."); + + void* returnAddr = frame.returnAddress(); +#ifdef DEBUG + ++frame; + MOZ_ASSERT(frame.isIonJS()); +#endif + return returnAddr; +} + void IonCacheIRCompiler::prepareVMCall(MacroAssembler& masm) { uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_IonJS, IonICCallFrameLayout::Size()); pushStubCodePointer(); masm.Push(Imm32(descriptor)); masm.Push(ImmPtr(GetReturnAddressToIonCode(cx_)));
--- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -21,17 +21,16 @@ # include "jit/PerfSpewer.h" #endif #include "jit/VMFunctions.h" #include "js/Proxy.h" #include "proxy/Proxy.h" #include "vm/Shape.h" #include "vm/Stack.h" -#include "jit/JitFrames-inl.h" #include "jit/MacroAssembler-inl.h" #include "jit/shared/Lowering-shared-inl.h" #include "vm/Interpreter-inl.h" #include "vm/Shape-inl.h" using namespace js; using namespace js::jit; @@ -80,23 +79,8 @@ CodeLocationLabel::repoint(JitCode* code void CodeOffsetJump::fixup(MacroAssembler* masm) { #ifdef JS_SMALL_BRANCH jumpTableIndex_ = masm->actualIndex(jumpTableIndex_); #endif } - -void* -jit::GetReturnAddressToIonCode(JSContext* cx) -{ - JSJitFrameIter frame(cx); - MOZ_ASSERT(frame.type() == JitFrame_Exit, - "An exit frame is expected as update functions are called with a VMFunction."); - - void* returnAddr = frame.returnAddress(); -#ifdef DEBUG - ++frame; - MOZ_ASSERT(frame.isIonJS()); -#endif - return returnAddr; -}
--- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -18,17 +18,9 @@ #endif #include "jit/JitCompartment.h" #include "jit/Registers.h" #include "jit/shared/Assembler-shared.h" #include "js/TrackedOptimizationInfo.h" #include "vm/TypedArrayObject.h" -namespace js { -namespace jit { - -void* GetReturnAddressToIonCode(JSContext* cx); - -} // namespace jit -} // namespace js - #endif /* jit_IonCaches_h */
--- a/js/src/jit/arm/AtomicOperations-arm.h +++ b/js/src/jit/arm/AtomicOperations-arm.h @@ -4,16 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef jit_arm_AtomicOperations_arm_h #define jit_arm_AtomicOperations_arm_h #include "jit/arm/Architecture-arm.h" +#include "vm/ArrayBufferObject.h" + // For documentation, see jit/AtomicOperations.h // NOTE, this file is *not* used with the ARM simulator, only when compiling for // actual ARM hardware. The simulators get the files that are appropriate for // the hardware the simulator is running on. See the comments before the // #include nest at the bottom of jit/AtomicOperations.h for more information. // Firefox requires gcc > 4.8, so we will always have the __atomic intrinsics @@ -147,24 +149,48 @@ inline T js::jit::AtomicOperations::loadSafeWhenRacy(T* addr) { MOZ_ASSERT(tier1Constraints(addr)); T v; __atomic_load(addr, &v, __ATOMIC_RELAXED); return v; } +namespace js { namespace jit { + +template<> +inline uint8_clamped +js::jit::AtomicOperations::loadSafeWhenRacy(uint8_clamped* addr) +{ + uint8_t v; + __atomic_load(&addr->val, &v, __ATOMIC_RELAXED); + return uint8_clamped(v); +} + +} } + template<typename T> inline void js::jit::AtomicOperations::storeSafeWhenRacy(T* addr, T val) { MOZ_ASSERT(tier1Constraints(addr)); __atomic_store(addr, &val, __ATOMIC_RELAXED); } +namespace js { namespace jit { + +template<> +inline void +js::jit::AtomicOperations::storeSafeWhenRacy(uint8_clamped* addr, uint8_clamped val) +{ + __atomic_store(&addr->val, &val.val, __ATOMIC_RELAXED); +} + +} } + inline void js::jit::AtomicOperations::memcpySafeWhenRacy(void* dest, const void* src, size_t nbytes) { MOZ_ASSERT(!((char*)dest <= (char*)src && (char*)src < (char*)dest+nbytes)); MOZ_ASSERT(!((char*)src <= (char*)dest && (char*)dest < (char*)src+nbytes)); memcpy(dest, src, nbytes); }
--- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -1810,17 +1810,18 @@ PresShell::Initialize(nscoord aWidth, ns if (root) { { nsAutoCauseReflowNotifier reflowNotifier(this); mFrameConstructor->BeginUpdate(); // Have the style sheet processor construct frame for the root // content object down - mFrameConstructor->ContentInserted(nullptr, root, nullptr, false); + mFrameConstructor->ContentInserted( + nullptr, root, nullptr, nsCSSFrameConstructor::InsertionKind::Sync); VERIFY_STYLE_TREE; // Something in mFrameConstructor->ContentInserted may have caused // Destroy() to get called, bug 337586. NS_ENSURE_STATE(!mHaveShutDown); mFrameConstructor->EndUpdate(); } @@ -4432,17 +4433,20 @@ PresShell::ContentAppended(nsIDocument * nsAutoCauseReflowNotifier crNotifier(this); // Call this here so it only happens for real content mutations and // not cases when the frame constructor calls its own methods to force // frame reconstruction. mPresContext->RestyleManager()->ContentAppended(aContainer, aFirstNewContent); - mFrameConstructor->ContentAppended(aContainer, aFirstNewContent, true); + mFrameConstructor->ContentAppended( + aContainer, + aFirstNewContent, + nsCSSFrameConstructor::InsertionKind::Async); VERIFY_STYLE_TREE; } void PresShell::ContentInserted(nsIDocument* aDocument, nsIContent* aMaybeContainer, nsIContent* aChild, @@ -4458,17 +4462,21 @@ PresShell::ContentInserted(nsIDocument* nsAutoCauseReflowNotifier crNotifier(this); // Call this here so it only happens for real content mutations and // not cases when the frame constructor calls its own methods to force // frame reconstruction. mPresContext->RestyleManager()->ContentInserted(container, aChild); - mFrameConstructor->ContentInserted(aMaybeContainer, aChild, nullptr, true); + mFrameConstructor->ContentInserted( + aMaybeContainer, + aChild, + nullptr, + nsCSSFrameConstructor::InsertionKind::Async); if (aChild->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE) { MOZ_ASSERT(container == aDocument); NotifyFontSizeInflationEnabledIsDirty(); } VERIFY_STYLE_TREE; } @@ -4561,17 +4569,17 @@ PresShell::ReconstructFrames() mDocument->FlushPendingNotifications(FlushType::Style); if (mIsDestroying) { return; } nsAutoCauseReflowNotifier crNotifier(this); mFrameConstructor->BeginUpdate(); - mFrameConstructor->ReconstructDocElementHierarchy(); + mFrameConstructor->ReconstructDocElementHierarchy(nsCSSFrameConstructor::InsertionKind::Sync); VERIFY_STYLE_TREE; mFrameConstructor->EndUpdate(); } void nsIPresShell::RestyleForCSSRuleChanges() { if (mIsDestroying) { @@ -8256,16 +8264,33 @@ PresShell::HandleEventInternal(WidgetEve } case eMouseUp: // reset the capturing content now that the mouse button is up SetCapturingContent(nullptr, 0); break; case eMouseMove: nsIPresShell::AllowMouseCapture(false); break; + case eDrag: + case eDragEnd: + case eDragEnter: + case eDragExit: + case eDragLeave: + case eDragOver: + case eDrop: { + // After any drag event other than dragstart (which is handled separately, + // as we need to collect the data first), the DataTransfer needs to be + // made protected, and then disconnected. + DataTransfer* dataTransfer = aEvent->AsDragEvent()->mDataTransfer; + if (dataTransfer) { + dataTransfer->SetMode(DataTransfer::Mode::Protected); + dataTransfer->ClearAll(); + } + break; + } default: break; } if (aEvent->IsTrusted() && aEvent->mTimeStamp > mLastOSWake) { switch (aEvent->mMessage) { case eKeyPress: case eKeyDown: