Skip to content

Commit

Permalink
Deploy Sept 16, 2024 (#5128)
Browse files Browse the repository at this point in the history
[Florian Quèze] differential timestamp compression when serializing processed profiles (#5033)
[joshuaobrien] Zip file viewer: omit profile extension if it is .json (#5079)
[Paul Adenot] Allow typing '?' in `contenteditable` elements without having the help menu pop in (#5124)
[Julien Wajsberg] Enable the Friulian locale (#5127)

Thanks also to our localizers!
fur: Fabio Tomat
nl: simonmeulenbeek
tr: Grk, Nazım Can Altınova
  • Loading branch information
julienw authored Sep 16, 2024
2 parents 7b8ce3b + 6b8d13c commit 4e46c23
Show file tree
Hide file tree
Showing 17 changed files with 1,830 additions and 100 deletions.
4 changes: 4 additions & 0 deletions docs-developer/CHANGELOG-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Note that this is not an exhaustive list. Processed profile format upgraders can

## Processed profile format

### Version 50

The serialized format can now optionally store sample and counter sample times as time deltas instead of absolute timestamps to reduce the JSON size. The unserialized version is unchanged.

### Version 49

A new `sanitized-string` marker schema format type has been added, allowing markers to carry arbitrary strings containing PII that will be sanitized along with URLs and FilePaths.
Expand Down
629 changes: 629 additions & 0 deletions locales/fur/app.ftl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion locales/nl/app.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ MenuButtons--index--share-re-upload =
MenuButtons--index--share-error-uploading =
.label = Fout bij uploaden
MenuButtons--index--revert = Terug naar origineel profiel
MenuButtons--index--docs = Documenten
MenuButtons--index--docs = Documentatie
MenuButtons--permalink--button =
.label = Permalink
Expand Down
898 changes: 898 additions & 0 deletions locales/tr/app.ftl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/app-logic/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const GECKO_PROFILE_VERSION = 30;
// The current version of the "processed" profile format.
// Please don't forget to update the processed profile format changelog in
// `docs-developer/CHANGELOG-formats.md`.
export const PROCESSED_PROFILE_VERSION = 49;
export const PROCESSED_PROFILE_VERSION = 50;

// The following are the margin sizes for the left and right of the timeline. Independent
// components need to share these values.
Expand Down
1 change: 1 addition & 0 deletions src/app-logic/l10n.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const AVAILABLE_LOCALES_TO_LOCALIZED_NAMES = {
'es-CL': 'Español', // Use "Español (CL)" once we have more spanish versions
fr: 'Français',
'fy-NL': 'Frysk',
fur: 'Furlan',
ia: 'Interlingua',
it: 'Italiano',
nl: 'Nederlands',
Expand Down
3 changes: 2 additions & 1 deletion src/components/app/KeyboardShortcut.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ export class KeyboardShortcut extends React.PureComponent<Props, State> {
if (
target.tagName === 'INPUT' ||
target.tagName === 'TEXTAREA' ||
target.tagName === 'SELECT'
target.tagName === 'SELECT' ||
target.isContentEditable
) {
// Ignore this from input-like things.
return;
Expand Down
52 changes: 50 additions & 2 deletions src/profile-logic/process-profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import type {
GCMajorAborted,
PhaseTimes,
SerializableProfile,
SerializableCounter,
ExternalMarkersData,
MarkerSchema,
ProfileMeta,
Expand Down Expand Up @@ -1717,19 +1718,54 @@ export function processGeckoProfile(geckoProfile: GeckoProfile): Profile {
return result;
}

function _serializeSamples({ time, ...restOfSamples }): any {
let lastTime = 0;
return {
timeDeltas: time.map((t) => {
const timeDelta = t - lastTime;
lastTime = t;
return timeDelta;
}),
...restOfSamples,
};
}

function _unserializeSamples({ timeDeltas, time, ...restOfSamples }): any {
let lastTime = 0;
return {
time:
time ||
ensureExists(timeDeltas).map((delta) => {
lastTime = lastTime + delta;
return lastTime;
}),
...restOfSamples,
};
}

/**
* The UniqueStringArray is a class, and is not serializable. This function turns
* a profile into the serializable variant.
*/
export function makeProfileSerializable({
threads,
counters,
...restOfProfile
}: Profile): SerializableProfile {
return {
...restOfProfile,
threads: threads.map(({ stringTable, ...restOfThread }) => {
counters: counters
? counters.map(({ samples, ...restOfCounter }) => {
return {
...restOfCounter,
samples: _serializeSamples(samples),
};
})
: counters,
threads: threads.map(({ stringTable, samples, ...restOfThread }) => {
return {
...restOfThread,
samples: _serializeSamples(samples),
stringArray: stringTable.serializeToArray(),
};
}),
Expand All @@ -1750,13 +1786,25 @@ export function serializeProfile(profile: Profile): string {
*/
function _unserializeProfile({
threads,
counters,
...restOfProfile
}: SerializableProfile): Profile {
return {
...restOfProfile,
threads: threads.map(({ stringArray, ...restOfThread }) => {
counters: counters
? ((counters: any[]): SerializableCounter[]).map(
({ samples, ...restOfCounter }) => {
return {
...restOfCounter,
samples: _unserializeSamples(samples),
};
}
)
: counters,
threads: threads.map(({ stringArray, samples, ...restOfThread }) => {
return {
...restOfThread,
samples: _unserializeSamples(samples),
stringTable: new UniqueStringArray(stringArray),
};
}),
Expand Down
6 changes: 6 additions & 0 deletions src/profile-logic/processed-profile-versioning.js
Original file line number Diff line number Diff line change
Expand Up @@ -2267,6 +2267,12 @@ const _upgraders = {
[49]: (_) => {
// The 'sanitized-string' marker schema format type has been added.
},
[50]: (_) => {
// The serialized format can now optionally store sample and counter sample
// times as time deltas instead of absolute timestamps to reduce the JSON size.
// The unserialized version is unchanged, and because the upgraders run
// after unserialization they see no difference.
},
// If you add a new upgrader here, please document the change in
// `docs-developer/CHANGELOG-formats.md`.
};
Expand Down
11 changes: 10 additions & 1 deletion src/profile-logic/zip-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,17 @@ export class ZipFileTree {
encodeURIComponent(this._zipFileTable.path[zipTableIndex]);
}

let name = this._zipFileTable.partName[zipTableIndex];
const EXTENSIONS_TO_OMIT = ['.json'];
const matchedExtension = EXTENSIONS_TO_OMIT.find((extension) =>
name.endsWith(extension)
);
if (matchedExtension) {
name = name.slice(0, name.length - matchedExtension.length);
}

displayData = {
name: this._zipFileTable.partName[zipTableIndex],
name,
url,
zipTableIndex,
};
Expand Down
36 changes: 30 additions & 6 deletions src/test/components/ZipFileTree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ describe('calltree/ZipFileTree', function () {
'baz/profile3.json',
// Use a file with a big depth to test the automatic expansion at load time.
'boat/ship/new/anything/explore/yes/profile4.json',
'not/a/profile.pdf',
]);

const renderResult = render(
Expand All @@ -52,30 +53,53 @@ describe('calltree/ZipFileTree', function () {
expect(container.firstChild).toMatchSnapshot();
});

// getByText is an assertion, but eslint doesn't know that.
// eslint-disable-next-line jest/expect-expect
it('contains a list of all the files', async () => {
await setup();

// We're looping through all expected files and check if we can find an
// element with the file name as text content.
// getByText throws if it doesn't find an element with this text content.
[
'foo',
'bar',
'profile1',
'profile2',
'baz',
'profile3',
'profile4',
].forEach((fileName) =>
expect(screen.getByText(fileName)).toBeInTheDocument()
);
});

it('removes .json extensions', async () => {
await setup();

['profile1', 'profile2', 'profile3', 'profile4'].forEach((fileName) =>
expect(screen.getByText(fileName)).toBeInTheDocument()
);

[
'profile1.json',
'profile2.json',
'baz',
'profile3.json',
].forEach((fileName) => screen.getByText(fileName));
'profile4.json',
].forEach((fileName) =>
expect(screen.queryByText(fileName)).not.toBeInTheDocument()
);
});

it('preserves extensions other than .json', async () => {
await setup();

expect(screen.getByText('profile.pdf')).toBeInTheDocument();
});

describe('clicking on a profile link', function () {
const setupClickingTest = async () => {
const setupResult = await setup();
const { store, container } = setupResult;

const profile1OpenLink = screen.getByText('profile1.json');
const profile1OpenLink = screen.getByText('profile1');

const waitUntilDoneProcessingZip = () =>
act(() =>
Expand Down
5 changes: 5 additions & 0 deletions src/test/components/__snapshots__/FooterLinks.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ exports[`correctly renders the FooterLinks component 1`] = `
>
Frysk
</option>
<option
value="fur"
>
Furlan
</option>
<option
value="ia"
>
Expand Down
93 changes: 87 additions & 6 deletions src/test/components/__snapshots__/ZipFileTree.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
>
<div
class="treeViewBodyInner treeViewBodyInner0"
style="height: 420px;"
style="height: 510px;"
>
<div
class="treeViewBodyInner treeViewBodyInner0TopSpacer"
Expand Down Expand Up @@ -97,11 +97,23 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
class="treeViewRow treeViewRowFixedColumns even"
style="height: 30px; line-height: 30px;"
/>
<div
class="treeViewRow treeViewRowFixedColumns odd"
style="height: 30px; line-height: 30px;"
/>
<div
class="treeViewRow treeViewRowFixedColumns even"
style="height: 30px; line-height: 30px;"
/>
<div
class="treeViewRow treeViewRowFixedColumns odd"
style="height: 30px; line-height: 30px;"
/>
</div>
</div>
<div
class="treeViewBodyInner treeViewBodyInner1"
style="height: 420px; min-width: 3000px;"
style="height: 510px; min-width: 3000px;"
>
<div
class="treeViewBodyInner treeViewBodyInner1TopSpacer"
Expand Down Expand Up @@ -175,7 +187,7 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
<a
href="http://localhost/from-url//calltree/?file=foo%2Fbar%2Fprofile1.json"
>
profile1.json
profile1
</a>
</span>
</div>
Expand All @@ -200,7 +212,7 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
<a
href="http://localhost/from-url//calltree/?file=foo%2Fprofile2.json"
>
profile2.json
profile2
</a>
</span>
</div>
Expand Down Expand Up @@ -247,7 +259,7 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
<a
href="http://localhost/from-url//calltree/?file=baz%2Fprofile3.json"
>
profile3.json
profile3
</a>
</span>
</div>
Expand Down Expand Up @@ -404,7 +416,76 @@ exports[`calltree/ZipFileTree renders a zip file tree 1`] = `
<a
href="http://localhost/from-url//calltree/?file=boat%2Fship%2Fnew%2Fanything%2Fexplore%2Fyes%2Fprofile4.json"
>
profile4.json
profile4
</a>
</span>
</div>
<div
aria-expanded="true"
aria-level="1"
aria-selected="false"
class="treeViewRow treeViewRowScrolledColumns odd"
id="treeViewRow-13"
role="treeitem"
style="height: 30px; line-height: 30px;"
>
<span
class="treeRowIndentSpacer"
style="width: 0px;"
/>
<span
class="treeRowToggleButton expanded canBeExpanded"
/>
<span
class="treeViewRowColumn treeViewMainColumn name"
>
not
</span>
</div>
<div
aria-expanded="true"
aria-level="2"
aria-selected="false"
class="treeViewRow treeViewRowScrolledColumns even"
id="treeViewRow-14"
role="treeitem"
style="height: 30px; line-height: 30px;"
>
<span
class="treeRowIndentSpacer"
style="width: 15px;"
/>
<span
class="treeRowToggleButton expanded canBeExpanded"
/>
<span
class="treeViewRowColumn treeViewMainColumn name"
>
a
</span>
</div>
<div
aria-level="3"
aria-selected="false"
class="treeViewRow treeViewRowScrolledColumns odd"
id="treeViewRow-15"
role="treeitem"
style="height: 30px; line-height: 30px;"
>
<span
class="treeRowIndentSpacer"
style="width: 30px;"
/>
<span
class="treeRowToggleButton collapsed leaf"
/>
<span
class="treeViewRowColumn treeViewMainColumn name"
>
<a
href="http://localhost/from-url//calltree/?file=not%2Fa%2Fprofile.pdf"
>
profile.pdf
</a>
</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/test/store/__snapshots__/profile-view.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
"preprocessedProfileVersion": 49,
"preprocessedProfileVersion": 50,
"processType": 0,
"product": "Firefox",
"sourceURL": "",
Expand Down
Loading

0 comments on commit 4e46c23

Please sign in to comment.