Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions locales/en-US/app.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,122 @@ MenuButtons--publish--renderCheckbox-label-private-browsing-warning-image =
MenuButtons--publish--renderCheckbox-label-argument-values = Include JavaScript execution tracing function argument values
MenuButtons--publish--renderCheckbox-label-argument-values-warning-image =
.title = This profile contains function argument values recorded from the page, which may include personal data
MenuButtons--publish--renderCheckbox-label-source-code = Include source code
# This is shown next to the "Include source code" checkbox while it is
# unchecked, so that the amount of source code on offer is visible without
# having to turn the option on.
# Variables:
# $fileCount (Number) - Number of source files that could be shared
# $size (String) - Pretty-printed total size of those files, e.g. "12 kB"
MenuButtons--publish--source-code-available =
Comment thread
canova marked this conversation as resolved.
{ $fileCount ->
[one] ({ $fileCount } file available, { $size })
*[other] ({ $fileCount } files available, { $size })
}
# Same place as the previous string, when some of the files haven't been
# downloaded yet. Only downloaded files can be included.
# Variables:
# $fileCount (Number) - Number of source files whose contents we have
# $totalFileCount (Number) - Number of source files that could be shared
# $size (String) - Pretty-printed total size of the files we have, e.g. "12 kB"
MenuButtons--publish--source-code-partially-downloaded =
{ $totalFileCount ->
[one] ({ $fileCount } of { $totalFileCount } file downloaded, { $size })
*[other] ({ $fileCount } of { $totalFileCount } files downloaded, { $size })
}
# Same place as the previous string, when none of the files have been downloaded
# yet. The checkbox is disabled in that case.
# Variables:
# $totalFileCount (Number) - Number of source files that could be shared
MenuButtons--publish--source-code-none-downloaded =
Comment thread
canova marked this conversation as resolved.
{ $totalFileCount ->
[one] ({ $totalFileCount } file, none downloaded yet)
*[other] ({ $totalFileCount } files, none downloaded yet)
}
# Shown in the size column of the file tree for files whose contents we don't
# have yet. They are downloaded when sharing, if picked.
MenuButtons--publish--source-code-not-downloaded = Not downloaded
# Shown in the size column of the file tree for files that we tried to download
# during this session and couldn't.
MenuButtons--publish--source-code-download-failed = Download failed
# Shown in the size column of the file tree for files that can't be downloaded
# from here.
MenuButtons--publish--source-code-unavailable = Unavailable
.title = Downloading this file requires the browser that recorded the profile or a local symbol server.
# This labels the row of ready-made file selections shown above the file tree of
# the "Include source code" option.
MenuButtons--publish--source-code-preset-legend = Include:
# Selects only the source file that the source view is currently showing.
MenuButtons--publish--source-code-preset-current-file = Current file
# Selects the source files that the currently selected threads run code from.
MenuButtons--publish--source-code-preset-selected-threads = Selected threads
# Selects every source file that was fetched or came with the profile, and that
# can be shared.
MenuButtons--publish--source-code-preset-all-available-files = All available files
# A checkbox next to the presets. When checked, "Selected threads" and "All
# available files" only pick files whose contents are already downloaded, so
# that sharing doesn't download anything more.
MenuButtons--publish--source-code-downloaded-only = Only already downloaded files
# Not something the user can pick. This is shown as the selected option once the
# user has edited the file tree so that it no longer matches any of the others.
MenuButtons--publish--source-code-preset-custom = Custom
# Shown under the "Include source code" checkbox in the upload panel, next to a
# warning icon, since the uploaded profile is public.
MenuButtons--publish--source-code-rights-notice = These files will be public. Only include code you have the right to share.
# The status line underneath the file tree of the "Include source code"
# option: how much source code the picked files add to the shared profile.
# Variables:
# $fileCount (Number) - Number of picked source files whose contents we have
# $size (String) - Pretty-printed total size of those contents, e.g. "12 kB"
MenuButtons--publish--source-code-status =
{ $fileCount ->
[one] { $fileCount } file, { $size } uncompressed.
*[other] { $fileCount } files, { $size } uncompressed.
}
# Shown on a line of its own under the previous string when some of the picked
# files still have to be downloaded. A "Download now" button comes after it.
# Variables:
# $fileCount (Number) - Number of picked source files whose contents we don't have
MenuButtons--publish--source-code-status-to-download =
{ $fileCount ->
[one] { $fileCount } file will be downloaded when sharing.
*[other] { $fileCount } files will be downloaded when sharing.
}
MenuButtons--publish--source-code-download-now = Download now
# Replaces the status line while the download is underway.
# Variables:
# $completedCount (Number) - Number of source files downloaded so far
# $totalCount (Number) - Number of source files being downloaded
MenuButtons--publish--source-code-downloading = Downloading source files… ({ $completedCount } of { $totalCount })
MenuButtons--publish--source-code-cancel-download = Cancel
# Shown under the upload error message when the upload stopped because some of
# the picked source files couldn't be downloaded.
# Variables:
# $failedCount (Number) - Number of picked source files that couldn't be downloaded
MenuButtons--publish--source-code-fetch-failed =
{ $failedCount ->
[one] { $failedCount } of the picked source files could not be downloaded. It has been left out, so uploading again will share the rest.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"could not be downloaded`: is this correct, or should it be uploaded?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's correct, we first download some sources that are not available before uploading.

*[other] { $failedCount } of the picked source files could not be downloaded. They have been left out, so uploading again will share the rest.
}
# A sentence in the tooltip of an info icon at the end of the status line, when
# some of the listed files can't be picked because they can't be downloaded
# from here. It can be followed by the next string, on a line of its own.
# Variables:
# $unavailableCount (Number) - Number of listed files that can't be downloaded from here
MenuButtons--publish--source-code-left-out-unavailable =
{ $unavailableCount ->
[one] { $unavailableCount } file can’t be downloaded from here. Downloading it requires the browser that recorded the profile or a local symbol server.
*[other] { $unavailableCount } files can’t be downloaded from here. Downloading them requires the browser that recorded the profile or a local symbol server.
}
# A sentence in the same tooltip as the previous string, when some sampled files
# aren't listed because anybody can download them.
# Variables:
# $publicCount (Number) - Number of files left out because anybody can download them
MenuButtons--publish--source-code-left-out-public =
{ $publicCount ->
[one] { $publicCount } file is available on the web and isn’t included.
*[other] { $publicCount } files are available on the web and aren’t included.
}
MenuButtons--publish--share-performance-profile = Share Performance Profile
MenuButtons--publish--reshare-performance-profile = Re-share Performance Profile
MenuButtons--publish--save-performance-profile = Save Performance Profile
Expand Down
22 changes: 22 additions & 0 deletions res/css/photon/checkbox.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
background-color: var(--clickable-checked-background-color);
}

/* Only the DOM `indeterminate` property sets this, there is no HTML attribute. */
.photon-checkbox:indeterminate:not([disabled]) {
border: none;
background-color: var(--clickable-checked-background-color);
}

.photon-checkbox:hover:active:not([disabled]) {
background-color: var(--clickable-active-background-color);
}
Expand All @@ -47,14 +53,30 @@
background-image: url(../../img/svg/checkbox-check-16.svg);
}

.photon-checkbox-default:indeterminate:not([disabled]) {
background-image: url(../../img/svg/checkbox-indeterminate-16.svg);
}

.photon-checkbox-micro:checked:not([disabled]) {
background-image: url(../../img/svg/checkbox-check-13.svg);
}

.photon-checkbox-micro:indeterminate:not([disabled]) {
background-image: url(../../img/svg/checkbox-indeterminate-13.svg);
}

.photon-checkbox:checked:hover:not([disabled]) {
background-color: var(--clickable-checked-hover-background-color);
}

.photon-checkbox:indeterminate:hover:not([disabled]) {
background-color: var(--clickable-checked-hover-background-color);
}

.photon-checkbox:checked:hover:active:not([disabled]) {
background-color: var(--clickable-checked-hover-background-color);
}

.photon-checkbox:indeterminate:hover:active:not([disabled]) {
background-color: var(--clickable-checked-hover-background-color);
}
3 changes: 3 additions & 0 deletions res/img/svg/checkbox-indeterminate-13.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions res/img/svg/checkbox-indeterminate-16.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
114 changes: 106 additions & 8 deletions src/actions/code.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,137 @@
/* 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/. */
import {
getProfile,
getSourceAddressProofs,
} from 'firefox-profiler/selectors/profile';
import { getBrowserConnection } from 'firefox-profiler/selectors/app';
import { getSymbolServerUrl } from 'firefox-profiler/selectors/url-state';
import { getSourceCodeCacheGeneration } from 'firefox-profiler/selectors/code';
import {
fetchSource,
type FetchSourceResult,
} from 'firefox-profiler/utils/fetch-source';
import { RegularExternalCommunicationDelegate } from 'firefox-profiler/utils/query-api';
import { assertExhaustiveCheck } from 'firefox-profiler/utils/types';
import type {
Action,
ThunkAction,
SourceCodeLoadingError,
ApiQueryError,
DecodedInstruction,
IndexIntoSourceTable,
FetchedSourceCodeOrigin,
} from 'firefox-profiler/types';

// The `generation` argument of these is the source code cache generation from
// when the fetch started, see SourceCodeCacheState.

export function beginLoadingSourceCodeFromUrl(
sourceIndex: IndexIntoSourceTable,
url: string
url: string,
generation: number
): Action {
return { type: 'SOURCE_CODE_LOADING_BEGIN_URL', sourceIndex, url };
return {
type: 'SOURCE_CODE_LOADING_BEGIN_URL',
sourceIndex,
url,
generation,
};
}

export function beginLoadingSourceCodeFromBrowserConnection(
sourceIndex: IndexIntoSourceTable
sourceIndex: IndexIntoSourceTable,
generation: number
): Action {
return { type: 'SOURCE_CODE_LOADING_BEGIN_BROWSER_CONNECTION', sourceIndex };
return {
type: 'SOURCE_CODE_LOADING_BEGIN_BROWSER_CONNECTION',
sourceIndex,
generation,
};
}

export function finishLoadingSourceCode(
sourceIndex: IndexIntoSourceTable,
code: string
code: string,
origin: FetchedSourceCodeOrigin,
generation: number
): Action {
return { type: 'SOURCE_CODE_LOADING_SUCCESS', sourceIndex, code };
return {
type: 'SOURCE_CODE_LOADING_SUCCESS',
sourceIndex,
code,
origin,
generation,
};
}

export function failLoadingSourceCode(
sourceIndex: IndexIntoSourceTable,
errors: SourceCodeLoadingError[]
errors: SourceCodeLoadingError[],
generation: number
): Action {
return { type: 'SOURCE_CODE_LOADING_ERROR', sourceIndex, errors };
return { type: 'SOURCE_CODE_LOADING_ERROR', sourceIndex, errors, generation };
}

/**
* Fetch the contents of a source file into the source code cache, from the
* browser, a symbol server or the web, whichever can serve it.
*
* This always fetches, so callers need to skip sources that are already in the
* cache or embedded in the profile. Callers should keep one archiveCache across
* their fetches, so that each archive is only downloaded once.
*/
export function fetchSourceCode(
sourceIndex: IndexIntoSourceTable,
archiveCache: Map<string, Promise<Uint8Array>>
): ThunkAction<Promise<FetchSourceResult>> {
return async (dispatch, getState) => {
const state = getState();
const { sources, stringArray } = getProfile(state).shared;
// Read once here, so that the reducer can drop everything this fetch
// dispatches after another profile got loaded.
const generation = getSourceCodeCacheGeneration(state);
const delegate = new RegularExternalCommunicationDelegate(
getBrowserConnection(state),
{
onBeginUrlRequest: (url) => {
dispatch(beginLoadingSourceCodeFromUrl(sourceIndex, url, generation));
},
onBeginBrowserConnectionQuery: () => {
dispatch(
beginLoadingSourceCodeFromBrowserConnection(sourceIndex, generation)
);
},
}
);
const result = await fetchSource(
stringArray[sources.filename[sourceIndex]],
sources.id[sourceIndex],
getSymbolServerUrl(state),
getSourceAddressProofs(state).get(sourceIndex) ?? null,
archiveCache,
delegate
);
switch (result.type) {
case 'SUCCESS':
dispatch(
finishLoadingSourceCode(
sourceIndex,
result.source,
result.origin,
generation
)
);
break;
case 'ERROR':
dispatch(failLoadingSourceCode(sourceIndex, result.errors, generation));
break;
default:
throw assertExhaustiveCheck(result);
}
return result;
};
}

export function beginLoadingAssemblyCodeFromUrl(
Expand Down
Loading
Loading