diff --git a/core/test/fixtures/user-flows/reports/sample-flow-result.json b/core/test/fixtures/user-flows/reports/sample-flow-result.json index 7fa1b54128fc..8a22b774836d 100644 --- a/core/test/fixtures/user-flows/reports/sample-flow-result.json +++ b/core/test/fixtures/user-flows/reports/sample-flow-result.json @@ -6984,9 +6984,9 @@ "dropdownDarkTheme": "Toggle Dark Theme", "dropdownPrintExpanded": "Print Expanded", "dropdownPrintSummary": "Print Summary", - "dropdownSaveGist": "Save as Gist", "dropdownSaveHTML": "Save as HTML", "dropdownSaveJSON": "Save as JSON", + "dropdownShareableURL": "Upload for Shareable URL", "dropdownViewer": "Open in Viewer", "dropdownViewUnthrottledTrace": "View Unthrottled Trace", "errorLabel": "Error!", @@ -11824,9 +11824,9 @@ "dropdownDarkTheme": "Toggle Dark Theme", "dropdownPrintExpanded": "Print Expanded", "dropdownPrintSummary": "Print Summary", - "dropdownSaveGist": "Save as Gist", "dropdownSaveHTML": "Save as HTML", "dropdownSaveJSON": "Save as JSON", + "dropdownShareableURL": "Upload for Shareable URL", "dropdownViewer": "Open in Viewer", "dropdownViewUnthrottledTrace": "View Unthrottled Trace", "errorLabel": "Error!", @@ -16820,9 +16820,9 @@ "dropdownDarkTheme": "Toggle Dark Theme", "dropdownPrintExpanded": "Print Expanded", "dropdownPrintSummary": "Print Summary", - "dropdownSaveGist": "Save as Gist", "dropdownSaveHTML": "Save as HTML", "dropdownSaveJSON": "Save as JSON", + "dropdownShareableURL": "Upload for Shareable URL", "dropdownViewer": "Open in Viewer", "dropdownViewUnthrottledTrace": "View Unthrottled Trace", "errorLabel": "Error!", @@ -24591,9 +24591,9 @@ "dropdownDarkTheme": "Toggle Dark Theme", "dropdownPrintExpanded": "Print Expanded", "dropdownPrintSummary": "Print Summary", - "dropdownSaveGist": "Save as Gist", "dropdownSaveHTML": "Save as HTML", "dropdownSaveJSON": "Save as JSON", + "dropdownShareableURL": "Upload for Shareable URL", "dropdownViewer": "Open in Viewer", "dropdownViewUnthrottledTrace": "View Unthrottled Trace", "errorLabel": "Error!", diff --git a/core/test/results/sample_v2.json b/core/test/results/sample_v2.json index ed08b43588a6..8f0563b4eef6 100644 --- a/core/test/results/sample_v2.json +++ b/core/test/results/sample_v2.json @@ -9266,9 +9266,9 @@ "dropdownDarkTheme": "Toggle Dark Theme", "dropdownPrintExpanded": "Print Expanded", "dropdownPrintSummary": "Print Summary", - "dropdownSaveGist": "Save as Gist", "dropdownSaveHTML": "Save as HTML", "dropdownSaveJSON": "Save as JSON", + "dropdownShareableURL": "Upload for Shareable URL", "dropdownViewer": "Open in Viewer", "dropdownViewUnthrottledTrace": "View Unthrottled Trace", "errorLabel": "Error!", diff --git a/flow-report/src/topbar.tsx b/flow-report/src/topbar.tsx index 75e80a614826..5e12d0c004dd 100644 --- a/flow-report/src/topbar.tsx +++ b/flow-report/src/topbar.tsx @@ -52,7 +52,7 @@ const Topbar: FunctionComponent<{onMenuClick: JSX.MouseEventHandler @@ -74,11 +74,11 @@ const Topbar: FunctionComponent<{onMenuClick: JSX.MouseEventHandler{strings.save} } { - saveAsGist && + uploadForPermalink && saveAsGist(flowResult)} + onClick={() => uploadForPermalink(flowResult)} label="Button that saves the report to a gist" - >{strings.dropdownSaveGist} + >{strings.dropdownShareableURL} }
{ ); }); -it('provides save as gist option if defined', async () => { - const saveAsGist = jestMock.fn(); - options = {saveAsGist}; +it('provides permalink option if defined', async () => { + const uploadForPermalink = jestMock.fn(); + options = {uploadForPermalink}; const root = render( {}}/>, {wrapper}); - const saveButton = root.getByText('Save as Gist'); + const saveButton = root.getByText('Upload for Shareable URL'); saveButton.click(); - expect(saveAsGist).toHaveBeenCalledWith(flowResult); + expect(uploadForPermalink).toHaveBeenCalledWith(flowResult); }); it('toggles help dialog', async () => { diff --git a/flow-report/types/flow-report.d.ts b/flow-report/types/flow-report.d.ts index cf10513ef2a2..3b343342a84d 100644 --- a/flow-report/types/flow-report.d.ts +++ b/flow-report/types/flow-report.d.ts @@ -23,7 +23,7 @@ declare global { export interface FlowReportOptions { getReportHtml?: (flowResult: FlowResult_) => string; - saveAsGist?: (flowResult: FlowResult_) => void; + uploadForPermalink?: (flowResult: FlowResult_) => void; } export interface HashState { diff --git a/proto/lighthouse-result.proto b/proto/lighthouse-result.proto index 8126d66d6598..7d0e9c2026b8 100644 --- a/proto/lighthouse-result.proto +++ b/proto/lighthouse-result.proto @@ -564,7 +564,7 @@ message I18n { // Option in a dropdown menu that saves the current report as a new GitHub // Gist. - string dropdown_save_gist = 38; + string dropdown_save_gist = 38 [deprecated = true]; // Option in a dropdown menu that saves the Lighthouse report HTML locally // to the system as a '.html' file. @@ -668,6 +668,9 @@ message I18n { // Descriptive label that this analysis considers a snapshot of the page at a single point in time string runtime_analysis_window_snapshot = 66; + + // Option in a dropdown menu that gets a shareable URL for the current report. + string dropdown_shareable_URL = 67; } // The message holding all formatted strings used in the renderer. diff --git a/report/assets/templates.html b/report/assets/templates.html index 9972999d9b5f..f3c94720a15f 100644 --- a/report/assets/templates.html +++ b/report/assets/templates.html @@ -265,8 +265,8 @@ background-color: var(--color-gray-200); outline: none; } - /* save-gist option hidden in report. */ - .lh-tools__dropdown a[data-action='save-gist'] { + /* upload-for-permalink option hidden in report. */ + .lh-tools__dropdown a[data-action='upload-for-permalink'] { display: none; } @@ -350,7 +350,7 @@ - + diff --git a/report/renderer/components.js b/report/renderer/components.js index ded0268d5773..0c3d1597e554 100644 --- a/report/renderer/components.js +++ b/report/renderer/components.js @@ -515,7 +515,7 @@ function createStylesComponent(dom) { function createTopbarComponent(dom) { const el0 = dom.createFragment(); const el1 = dom.createElement("style"); - el1.append("\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 270px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* save-gist option hidden in report. */\n .lh-tools__dropdown a[data-action='save-gist'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n "); + el1.append("\n .lh-topbar {\n position: sticky;\n top: 0;\n left: 0;\n right: 0;\n z-index: 1000;\n display: flex;\n align-items: center;\n height: var(--topbar-height);\n padding: var(--topbar-padding);\n font-size: var(--report-font-size-secondary);\n background-color: var(--topbar-background-color);\n border-bottom: 1px solid var(--color-gray-200);\n }\n\n .lh-topbar__logo {\n width: var(--topbar-logo-size);\n height: var(--topbar-logo-size);\n user-select: none;\n flex: none;\n }\n\n .lh-topbar__url {\n margin: var(--topbar-padding);\n text-decoration: none;\n color: var(--report-text-color);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n }\n\n .lh-tools {\n display: flex;\n align-items: center;\n margin-left: auto;\n will-change: transform;\n min-width: var(--report-icon-size);\n }\n .lh-tools__button {\n width: var(--report-icon-size);\n min-width: 24px;\n height: var(--report-icon-size);\n cursor: pointer;\n margin-right: 5px;\n /* This is actually a button element, but we want to style it like a transparent div. */\n display: flex;\n background: none;\n color: inherit;\n border: none;\n padding: 0;\n font: inherit;\n outline: inherit;\n }\n .lh-tools__button svg {\n fill: var(--tools-icon-color);\n }\n .lh-dark .lh-tools__button svg {\n filter: invert(1);\n }\n .lh-tools__button.lh-active + .lh-tools__dropdown {\n opacity: 1;\n clip: rect(-1px, 194px, 270px, -3px);\n visibility: visible;\n }\n .lh-tools__dropdown {\n position: absolute;\n background-color: var(--report-background-color);\n border: 1px solid var(--report-border-color);\n border-radius: 3px;\n padding: calc(var(--default-padding) / 2) 0;\n cursor: pointer;\n top: 36px;\n right: 0;\n box-shadow: 1px 1px 3px #ccc;\n min-width: 125px;\n clip: rect(0, 164px, 0, 0);\n visibility: hidden;\n opacity: 0;\n transition: all 200ms cubic-bezier(0,0,0.2,1);\n }\n .lh-tools__dropdown a {\n color: currentColor;\n text-decoration: none;\n white-space: nowrap;\n padding: 0 6px;\n line-height: 2;\n }\n .lh-tools__dropdown a:hover,\n .lh-tools__dropdown a:focus {\n background-color: var(--color-gray-200);\n outline: none;\n }\n /* upload-for-permalink option hidden in report. */\n .lh-tools__dropdown a[data-action='upload-for-permalink'] {\n display: none;\n }\n\n .lh-locale-selector {\n width: 100%;\n color: var(--report-text-color);\n background-color: var(--locale-selector-background-color);\n padding: 2px;\n }\n .lh-tools-locale {\n display: flex;\n align-items: center;\n flex-direction: row-reverse;\n }\n .lh-tools-locale__selector-wrapper {\n transition: opacity 0.15s;\n opacity: 0;\n max-width: 200px;\n }\n .lh-button.lh-tool-locale__button {\n height: var(--topbar-height);\n color: var(--tools-icon-color);\n padding: calc(var(--default-padding) / 2);\n }\n .lh-tool-locale__button.lh-active + .lh-tools-locale__selector-wrapper {\n opacity: 1;\n clip: rect(-1px, 194px, 242px, -3px);\n visibility: visible;\n margin: 0 4px;\n }\n\n @media screen and (max-width: 964px) {\n .lh-tools__dropdown {\n right: 0;\n left: initial;\n }\n }\n @media print {\n .lh-topbar {\n position: static;\n margin-left: 0;\n }\n\n .lh-tools__dropdown {\n display: none;\n }\n }\n "); el0.append(el1); const el2 = dom.createElement("div", "lh-topbar"); const el3 = dom.createElementNS("http://www.w3.org/2000/svg", "svg", "lh-topbar__logo"); @@ -628,8 +628,8 @@ function createTopbarComponent(dom) { el26.setAttribute('role', 'menuitem'); el26.setAttribute('tabindex', '-1'); el26.setAttribute('href', '#'); - el26.setAttribute('data-i18n', 'dropdownSaveGist'); - el26.setAttribute('data-action', 'save-gist'); + el26.setAttribute('data-i18n', 'dropdownShareableURL'); + el26.setAttribute('data-action', 'upload-for-permalink'); const el27 = dom.createElement("a", "lh-report-icon lh-report-icon--open lh-hidden"); el27.setAttribute('role', 'menuitem'); el27.setAttribute('tabindex', '-1'); diff --git a/report/renderer/drop-down-menu.js b/report/renderer/drop-down-menu.js index 5f7b65b31178..003aaa87e9d0 100644 --- a/report/renderer/drop-down-menu.js +++ b/report/renderer/drop-down-menu.js @@ -173,12 +173,12 @@ export class DropDownMenu { return false; } - // 'Save as Gist' option may be disabled. + // 'Upload for Shareable URL' option may be disabled. if (node.hasAttribute('disabled')) { return false; } - // 'Save as Gist' option may have display none. + // 'Upload for Shareable URL' option may have display none. if (window.getComputedStyle(node).display === 'none') { return false; } diff --git a/report/renderer/report-ui-features.js b/report/renderer/report-ui-features.js index e9c0994fe705..daf0d739e3b6 100644 --- a/report/renderer/report-ui-features.js +++ b/report/renderer/report-ui-features.js @@ -173,10 +173,11 @@ export class ReportUIFeatures { /** * Save json as a gist. Unimplemented in base UI features. + * TODO: i think it can be in base now.. */ - saveAsGist() { + uploadForPermalink() { // TODO ? - throw new Error('Cannot save as gist from base report'); + throw new Error('Cannot Upload for Shareable URL from base report'); } _enableFireworks() { diff --git a/report/renderer/report-utils.js b/report/renderer/report-utils.js index bdf8d2cb70b1..21e5e9a56df9 100644 --- a/report/renderer/report-utils.js +++ b/report/renderer/report-utils.js @@ -411,8 +411,8 @@ const UIStrings = { dropdownSaveJSON: 'Save as JSON', /** Option in a dropdown menu that opens the current report in the Lighthouse Viewer Application. */ dropdownViewer: 'Open in Viewer', - /** Option in a dropdown menu that saves the current report as a new GitHub Gist. */ - dropdownSaveGist: 'Save as Gist', + /** Option in a dropdown menu that gets a shareable URL for the current report. */ + dropdownShareableURL: 'Upload for Shareable URL', /** Option in a dropdown menu that toggles the themeing of the report between Light(default) and Dark themes. */ dropdownDarkTheme: 'Toggle Dark Theme', /** Option in a dropdown menu that opens the trace of the page without throttling. "Unthrottled" can be replaced with "Original". */ diff --git a/report/renderer/topbar-features.js b/report/renderer/topbar-features.js index d7d5fbf2498d..f9a60241b5d5 100644 --- a/report/renderer/topbar-features.js +++ b/report/renderer/topbar-features.js @@ -106,8 +106,8 @@ export class TopbarFeatures { } break; } - case 'save-gist': { - this._reportUIFeatures.saveAsGist(); + case 'upload-for-permalink': { + this._reportUIFeatures.uploadForPermalink(); break; } case 'toggle-dark': { diff --git a/shared/localization/locales/ar-XB.json b/shared/localization/locales/ar-XB.json index de5fec95b105..ed92784623eb 100644 --- a/shared/localization/locales/ar-XB.json +++ b/shared/localization/locales/ar-XB.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "‏‮Print‬‏ ‏‮Summary‬‏" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "‏‮Save‬‏ ‏‮as‬‏ ‏‮Gist‬‏" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "‏‮Save‬‏ ‏‮as‬‏ ‏‮HTML‬‏" }, diff --git a/shared/localization/locales/ar.json b/shared/localization/locales/ar.json index 314f5aa2686d..352bbd031569 100644 --- a/shared/localization/locales/ar.json +++ b/shared/localization/locales/ar.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "طباعة ملخّص التقرير" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "حفظ بتنسيق Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "حفظ بتنسيق HTML" }, diff --git a/shared/localization/locales/bg.json b/shared/localization/locales/bg.json index 6835a63c9f54..847dab7040aa 100644 --- a/shared/localization/locales/bg.json +++ b/shared/localization/locales/bg.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Отпечатване на обобщен отчет" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Запазване като Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Запазване като HTML" }, diff --git a/shared/localization/locales/ca.json b/shared/localization/locales/ca.json index db7a58af9b17..1d259f249b59 100644 --- a/shared/localization/locales/ca.json +++ b/shared/localization/locales/ca.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Resum d'impressió" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Desa com a Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Desa com a HTML" }, diff --git a/shared/localization/locales/cs.json b/shared/localization/locales/cs.json index 9ddb3ecbf85e..ecb48b7efb2d 100644 --- a/shared/localization/locales/cs.json +++ b/shared/localization/locales/cs.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Vytisknout souhrn" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Uložit jako gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Uložit jako HTML" }, diff --git a/shared/localization/locales/da.json b/shared/localization/locales/da.json index 2e622db0ec8f..7b1df0ae56ff 100644 --- a/shared/localization/locales/da.json +++ b/shared/localization/locales/da.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Udskriftsoversigt" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gem som Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Gem som HTML" }, diff --git a/shared/localization/locales/de.json b/shared/localization/locales/de.json index d7dd3af528e0..025b43bd07ea 100644 --- a/shared/localization/locales/de.json +++ b/shared/localization/locales/de.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Zusammenfassung drucken" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Als Gist speichern" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Als HTML speichern" }, diff --git a/shared/localization/locales/el.json b/shared/localization/locales/el.json index f523d29ff13e..4ff18337b00d 100644 --- a/shared/localization/locales/el.json +++ b/shared/localization/locales/el.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Συνοπτική εκτύπωση" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Αποθήκευση ως Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Αποθήκευση ως HTML" }, diff --git a/shared/localization/locales/en-GB.json b/shared/localization/locales/en-GB.json index 8d2000a7d15f..b2df25f6f2f1 100644 --- a/shared/localization/locales/en-GB.json +++ b/shared/localization/locales/en-GB.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Print summary" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Save as gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Save as HTML" }, diff --git a/shared/localization/locales/en-US.json b/shared/localization/locales/en-US.json index 5c46889f1a06..ca38dd2f8b05 100644 --- a/shared/localization/locales/en-US.json +++ b/shared/localization/locales/en-US.json @@ -3302,15 +3302,15 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Print Summary" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Save as Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Save as HTML" }, "report/renderer/report-utils.js | dropdownSaveJSON": { "message": "Save as JSON" }, + "report/renderer/report-utils.js | dropdownShareableURL": { + "message": "Upload for Shareable URL" + }, "report/renderer/report-utils.js | dropdownViewer": { "message": "Open in Viewer" }, diff --git a/shared/localization/locales/en-XA.json b/shared/localization/locales/en-XA.json index fc6e0fc1aa7a..5be8f93158bc 100644 --- a/shared/localization/locales/en-XA.json +++ b/shared/localization/locales/en-XA.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "[Þŕîñţ Šûmmåŕý one two]" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "[Šåvé åš Ĝîšţ one two]" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "[Šåvé åš ĤŢMĻ one two]" }, diff --git a/shared/localization/locales/en-XL.json b/shared/localization/locales/en-XL.json index aa21a2054b59..b9c95376bba2 100644 --- a/shared/localization/locales/en-XL.json +++ b/shared/localization/locales/en-XL.json @@ -3302,15 +3302,15 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "P̂ŕîńt̂ Śûḿm̂ár̂ý" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Ŝáv̂é âś Ĝíŝt́" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Ŝáv̂é âś ĤT́M̂Ĺ" }, "report/renderer/report-utils.js | dropdownSaveJSON": { "message": "Ŝáv̂é âś ĴŚÔŃ" }, + "report/renderer/report-utils.js | dropdownShareableURL": { + "message": "Ûṕl̂óâd́ f̂ór̂ Śĥár̂éâb́l̂é ÛŔL̂" + }, "report/renderer/report-utils.js | dropdownViewer": { "message": "Ôṕêń îń V̂íêẃêŕ" }, diff --git a/shared/localization/locales/es-419.json b/shared/localization/locales/es-419.json index 230edfcbb15f..4559eeb3f8dd 100644 --- a/shared/localization/locales/es-419.json +++ b/shared/localization/locales/es-419.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Resumen de impresión" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Guardar como Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Guardar como HTML" }, diff --git a/shared/localization/locales/es.json b/shared/localization/locales/es.json index 780db0758f5b..3bdf03dc9431 100644 --- a/shared/localization/locales/es.json +++ b/shared/localization/locales/es.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Imprimir resumen" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Guardar como gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Guardar como HTML" }, diff --git a/shared/localization/locales/fi.json b/shared/localization/locales/fi.json index 8180bfa6af06..42510e4463cf 100644 --- a/shared/localization/locales/fi.json +++ b/shared/localization/locales/fi.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Tulosta yhteenveto" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Tallenna Gistinä" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Tallenna HTML-muodossa" }, diff --git a/shared/localization/locales/fil.json b/shared/localization/locales/fil.json index 92abde4cc8eb..1ea1950c4320 100644 --- a/shared/localization/locales/fil.json +++ b/shared/localization/locales/fil.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Buod sa Pag-print" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "I-save bilang Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "I-save bilang HTML" }, diff --git a/shared/localization/locales/fr.json b/shared/localization/locales/fr.json index 2ad008007e18..114c8afe3fdb 100644 --- a/shared/localization/locales/fr.json +++ b/shared/localization/locales/fr.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Imprimer le résumé" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Enregistrer en tant que Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Enregistrer au format HTML" }, diff --git a/shared/localization/locales/he.json b/shared/localization/locales/he.json index 6a1bf45f9b1d..97cd84b833e3 100644 --- a/shared/localization/locales/he.json +++ b/shared/localization/locales/he.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "סיכום הדפסות" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "שמירה כ-Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "שמירה כ-HTML" }, diff --git a/shared/localization/locales/hi.json b/shared/localization/locales/hi.json index 67cbd9542e8b..1ca57bf20f3e 100644 --- a/shared/localization/locales/hi.json +++ b/shared/localization/locales/hi.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "प्रिंट के बारे में खास जानकारी" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gist के रूप में सेव करें" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "एचटीएमएल के रूप में सेव करें" }, diff --git a/shared/localization/locales/hr.json b/shared/localization/locales/hr.json index 0d936c096655..a1cde73b585f 100644 --- a/shared/localization/locales/hr.json +++ b/shared/localization/locales/hr.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Ispis sažetka" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Spremanje kao Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Spremanje kao HTML" }, diff --git a/shared/localization/locales/hu.json b/shared/localization/locales/hu.json index 015a20281785..8a996e3143ac 100644 --- a/shared/localization/locales/hu.json +++ b/shared/localization/locales/hu.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Összefoglalás nyomtatása" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Mentés Gistként" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Mentés HTML-ként" }, diff --git a/shared/localization/locales/id.json b/shared/localization/locales/id.json index 570787d19cc9..ed413eab7cfe 100644 --- a/shared/localization/locales/id.json +++ b/shared/localization/locales/id.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Cetak Ringkasan" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Simpan sebagai Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Simpan sebagai HTML" }, diff --git a/shared/localization/locales/it.json b/shared/localization/locales/it.json index c125543ba6cb..98f4348a8771 100644 --- a/shared/localization/locales/it.json +++ b/shared/localization/locales/it.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Stampa riepilogo" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Salva come Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Salva come HTML" }, diff --git a/shared/localization/locales/ja.json b/shared/localization/locales/ja.json index 29ae5ca5dbb8..9d9d149e4ade 100644 --- a/shared/localization/locales/ja.json +++ b/shared/localization/locales/ja.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "概要を印刷" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gist 形式で保存" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "HTML 形式で保存" }, diff --git a/shared/localization/locales/ko.json b/shared/localization/locales/ko.json index 82e882f54d6a..18f73fb84628 100644 --- a/shared/localization/locales/ko.json +++ b/shared/localization/locales/ko.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "인쇄 요약" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gist로 저장" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "HTML로 저장" }, diff --git a/shared/localization/locales/lt.json b/shared/localization/locales/lt.json index 1ff246668a2f..4fb9d6ac9c08 100644 --- a/shared/localization/locales/lt.json +++ b/shared/localization/locales/lt.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Spausdintinė suvestinė" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Išsaugoti kaip „Gist“" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Išsaugoti kaip HTML" }, diff --git a/shared/localization/locales/lv.json b/shared/localization/locales/lv.json index d8875b33a8db..8f7a59684b57 100644 --- a/shared/localization/locales/lv.json +++ b/shared/localization/locales/lv.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Drukāt kopsavilkumu" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Saglabāt kā Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Saglabāt kā HTML" }, diff --git a/shared/localization/locales/nl.json b/shared/localization/locales/nl.json index 9271b219c364..a36d5d4afa14 100644 --- a/shared/localization/locales/nl.json +++ b/shared/localization/locales/nl.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Afdrukoverzicht" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Opslaan als gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Opslaan als HTML" }, diff --git a/shared/localization/locales/no.json b/shared/localization/locales/no.json index 102bad52cad8..c29c4108a300 100644 --- a/shared/localization/locales/no.json +++ b/shared/localization/locales/no.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Skriv ut sammendrag" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Lagre som Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Lagre som HTML" }, diff --git a/shared/localization/locales/pl.json b/shared/localization/locales/pl.json index 880e73369c27..184bb92d58fd 100644 --- a/shared/localization/locales/pl.json +++ b/shared/localization/locales/pl.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Drukuj podsumowanie" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Zapisz jako Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Zapisz jako HTML" }, diff --git a/shared/localization/locales/pt-PT.json b/shared/localization/locales/pt-PT.json index fe52c23c36c2..b8ec60d58bfd 100644 --- a/shared/localization/locales/pt-PT.json +++ b/shared/localization/locales/pt-PT.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Imprimir resumo" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Guardar como Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Guardar como HTML" }, diff --git a/shared/localization/locales/pt.json b/shared/localization/locales/pt.json index 97396386dd08..0fbe690b092e 100644 --- a/shared/localization/locales/pt.json +++ b/shared/localization/locales/pt.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Imprimir resumo" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Salvar como Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Salvar como HTML" }, diff --git a/shared/localization/locales/ro.json b/shared/localization/locales/ro.json index 6549704c97be..2654e2778e5e 100644 --- a/shared/localization/locales/ro.json +++ b/shared/localization/locales/ro.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Rezumatul printării" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Salvează ca Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Salvează ca HTML" }, diff --git a/shared/localization/locales/ru.json b/shared/localization/locales/ru.json index 66ee4f525ed6..6dd626ff4b4f 100644 --- a/shared/localization/locales/ru.json +++ b/shared/localization/locales/ru.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Печать сводных данных" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Сохранить как Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Сохранить как HTML-файл" }, diff --git a/shared/localization/locales/sk.json b/shared/localization/locales/sk.json index 67c90199317b..d6d1130efd55 100644 --- a/shared/localization/locales/sk.json +++ b/shared/localization/locales/sk.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Súhrn tlače" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Uložiť ako Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Uložiť ako HTML" }, diff --git a/shared/localization/locales/sl.json b/shared/localization/locales/sl.json index a9f3c2e1cad6..59d724ce1af7 100644 --- a/shared/localization/locales/sl.json +++ b/shared/localization/locales/sl.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Tiskanje povzetka" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Shrani kot Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Shrani kot HTML" }, diff --git a/shared/localization/locales/sr-Latn.json b/shared/localization/locales/sr-Latn.json index d6db448da715..2f864b7b7242 100644 --- a/shared/localization/locales/sr-Latn.json +++ b/shared/localization/locales/sr-Latn.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Štampaj rezime" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Sačuvaj kao Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Sačuvaj kao HTML" }, diff --git a/shared/localization/locales/sr.json b/shared/localization/locales/sr.json index 5e1fc4b3e94f..8e368ab4421e 100644 --- a/shared/localization/locales/sr.json +++ b/shared/localization/locales/sr.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Штампај резиме" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Сачувај као Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Сачувај као HTML" }, diff --git a/shared/localization/locales/sv.json b/shared/localization/locales/sv.json index 0f819e442434..ae6e0e82973c 100644 --- a/shared/localization/locales/sv.json +++ b/shared/localization/locales/sv.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Skriv ut sammanfattning" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Spara som Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Spara som HTML" }, diff --git a/shared/localization/locales/ta.json b/shared/localization/locales/ta.json index 04507f55ca02..3025bbff9659 100644 --- a/shared/localization/locales/ta.json +++ b/shared/localization/locales/ta.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "பிரிண்ட் சுருக்கம்" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gistடாக சேமி" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "HTMLலாக சேமி" }, diff --git a/shared/localization/locales/te.json b/shared/localization/locales/te.json index e7578570ae98..566e7a5f6840 100644 --- a/shared/localization/locales/te.json +++ b/shared/localization/locales/te.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "ప్రింట్ సారాంశం" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gist లాగా సేవ్ చేయండి" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "HTML లాగా సేవ్ చేయండి" }, diff --git a/shared/localization/locales/th.json b/shared/localization/locales/th.json index 3f964720544c..713d78bdf600 100644 --- a/shared/localization/locales/th.json +++ b/shared/localization/locales/th.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "สรุปการพิมพ์" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "บันทึกเป็น Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "บันทึกเป็น HTML" }, diff --git a/shared/localization/locales/tr.json b/shared/localization/locales/tr.json index 2448ea742ad0..2ecc91f03243 100644 --- a/shared/localization/locales/tr.json +++ b/shared/localization/locales/tr.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Yazdırma Özeti" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Gist olarak kaydet" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "HTML olarak kaydet" }, diff --git a/shared/localization/locales/uk.json b/shared/localization/locales/uk.json index ed2a5e8dc335..d75c02d6b0a5 100644 --- a/shared/localization/locales/uk.json +++ b/shared/localization/locales/uk.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Друкувати підсумок" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Зберегти як Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Зберегти як HTML" }, diff --git a/shared/localization/locales/vi.json b/shared/localization/locales/vi.json index 02e57fd10dac..3b51170aa95d 100644 --- a/shared/localization/locales/vi.json +++ b/shared/localization/locales/vi.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "Báo cáo tóm tắt trong hộp thoại in" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "Lưu dưới dạng Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "Lưu dưới dạng HTML" }, diff --git a/shared/localization/locales/zh-HK.json b/shared/localization/locales/zh-HK.json index e67b75a7fca5..7acaa7b7d0b7 100644 --- a/shared/localization/locales/zh-HK.json +++ b/shared/localization/locales/zh-HK.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "列印摘要" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "另存為 Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "另存為 HTML" }, diff --git a/shared/localization/locales/zh-TW.json b/shared/localization/locales/zh-TW.json index 9bd968f4a0b5..37719c7f4d83 100644 --- a/shared/localization/locales/zh-TW.json +++ b/shared/localization/locales/zh-TW.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "列印摘要" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "另存為 Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "另存為 HTML" }, diff --git a/shared/localization/locales/zh.json b/shared/localization/locales/zh.json index 51cc8fcdf89e..2ea2d760fdf9 100644 --- a/shared/localization/locales/zh.json +++ b/shared/localization/locales/zh.json @@ -3299,9 +3299,6 @@ "report/renderer/report-utils.js | dropdownPrintSummary": { "message": "打印摘要" }, - "report/renderer/report-utils.js | dropdownSaveGist": { - "message": "另存为 Gist" - }, "report/renderer/report-utils.js | dropdownSaveHTML": { "message": "另存为 HTML" }, diff --git a/viewer/app/src/github-api.js b/viewer/app/src/github-api.js index 8690bf14f348..519f4c138934 100644 --- a/viewer/app/src/github-api.js +++ b/viewer/app/src/github-api.js @@ -11,9 +11,6 @@ import idbKeyval from 'idb-keyval'; import {FirebaseAuth} from './firebase-auth.js'; -// eslint-disable-next-line max-len -import {getLhrFilenamePrefix, getFlowResultFilenamePrefix} from '../../../report/generator/file-namer.js'; -import {Util} from '../../../shared/util.js'; /** * Wrapper around the GitHub API for reading/writing gists. @@ -32,58 +29,6 @@ export class GithubApi { return this._auth; } - /** - * Creates a gist under the users account. - * @param {LH.Result|LH.FlowResult} jsonFile The gist file body. - * @return {Promise} id of the created gist. - */ - async createGist(jsonFile) { - if (this._saving) { - throw new Error('Save already in progress'); - } - - logger.log('Saving report to GitHub...', false); - this._saving = true; - - try { - const accessToken = await this._auth.getAccessToken(); - let filename; - if ('steps' in jsonFile) { - filename = getFlowResultFilenamePrefix(jsonFile); - } else { - filename = getLhrFilenamePrefix({ - finalDisplayedUrl: Util.getFinalDisplayedUrl(jsonFile), - fetchTime: jsonFile.fetchTime, - }); - } - const body = { - description: 'Lighthouse json report', - public: false, - files: { - [`${filename}${GithubApi.LH_JSON_EXT}`]: { - content: JSON.stringify(jsonFile), - }, - }, - }; - const request = new Request('https://api.github.com/gists', { - method: 'POST', - headers: new Headers({Authorization: `token ${accessToken}`}), - // Stringify twice so quotes are escaped for POST request to succeed. - body: JSON.stringify(body), - }); - const response = await fetch(request); - const json = await response.json(); - if (json.id) { - logger.log('Saved!'); - return json.id; - } else { - throw new Error('Error: ' + JSON.stringify(json)); - } - } finally { - this._saving = false; - } - } - /** * Fetches a Lighthouse report from a gist. * @param {string} id The id of a gist. diff --git a/viewer/app/src/lighthouse-report-viewer.js b/viewer/app/src/lighthouse-report-viewer.js index 470f069ae290..f3be8dcfea00 100644 --- a/viewer/app/src/lighthouse-report-viewer.js +++ b/viewer/app/src/lighthouse-report-viewer.js @@ -14,6 +14,10 @@ import {DOM} from '../../../report/renderer/dom.js'; import {ReportRenderer} from '../../../report/renderer/report-renderer.js'; import {TextEncoding} from '../../../report/renderer/text-encoding.js'; import {renderFlowReport} from '../../../flow-report/api'; +import {uploadLhrToTraceCafe} from './tracecafe-storage.js'; +// eslint-disable-next-line max-len +import {getLhrFilenamePrefix, getFlowResultFilenamePrefix} from '../../../report/generator/file-namer.js'; +import {Util} from '../../../shared/util.js'; /* global logger ReportGenerator */ @@ -40,7 +44,7 @@ function find(query, context) { export class LighthouseReportViewer { constructor() { this._onPaste = this._onPaste.bind(this); - this._onSaveJson = this._onSaveJson.bind(this); + this._doUploadForPermalink = this._doUploadForPermalink.bind(this); this._onFileLoad = this._onFileLoad.bind(this); this._onUrlInputChange = this._onUrlInputChange.bind(this); @@ -53,6 +57,7 @@ export class LighthouseReportViewer { * @type {boolean} */ this._reportIsFromGist = false; + this._reportIsFromTraceCafe = false; this._reportIsFromPSI = false; this._reportIsFromJSON = false; @@ -108,6 +113,7 @@ export class LighthouseReportViewer { const gistId = params.get('gist'); const psiurl = params.get('psiurl'); const jsonurl = params.get('jsonurl'); + const cafeid = params.get('id'); const gzip = params.get('gzip') === '1'; const hash = window.__hash ?? location.hash; @@ -125,9 +131,10 @@ export class LighthouseReportViewer { } } - if (!gistId && !psiurl && !jsonurl) return Promise.resolve(); + if (!gistId && !psiurl && !jsonurl && !cafeid) return Promise.resolve(); this._toggleLoadingBlur(true); + let loadPromise = Promise.resolve(); if (psiurl) { loadPromise = this._fetchFromPSI({ @@ -142,18 +149,18 @@ export class LighthouseReportViewer { this._reportIsFromGist = true; this._replaceReportHtml(reportJson); }).catch(err => logger.error(err.message)); - } else if (jsonurl) { - const firebaseAuth = this._github.getFirebaseAuth(); - loadPromise = firebaseAuth.getAccessTokenIfLoggedIn() - .then(token => { - return token - ? Promise.reject(new Error('Can only use jsonurl when not logged in')) - : null; - }) - .then(() => fetch(jsonurl)) + } else if (jsonurl ?? cafeid) { + const fetchableUrl = jsonurl ?? + `https://firebasestorage.googleapis.com/v0/b/tum-lhrs/o/lhrs%2F${cafeid}?alt=media`; + + fetch(fetchableUrl) .then(resp => resp.json()) .then(json => { - this._reportIsFromJSON = true; + if (jsonurl) { + this._reportIsFromJSON = true; + } else { + this._reportIsFromTraceCafe = true; + } this._replaceReportHtml(json); }) .catch(err => logger.error(err.message)); @@ -200,9 +207,9 @@ export class LighthouseReportViewer { /** * @param {LH.Result} json * @param {HTMLElement} rootEl - * @param {(json: LH.Result|LH.FlowResult) => void} [saveGistCallback] + * @param {(json: LH.Result|LH.FlowResult) => void} [uploadForPermalinkHandler] */ - _renderLhr(json, rootEl, saveGistCallback) { + _renderLhr(json, rootEl, uploadForPermalinkHandler) { // Allow users to view the runnerResult if ('lhr' in json) { const runnerResult = /** @type {{lhr: LH.Result}} */ (/** @type {unknown} */ (json)); @@ -235,7 +242,7 @@ export class LighthouseReportViewer { renderer.renderReport(json, rootEl); const features = new ViewerUIFeatures(dom, { - saveGist: saveGistCallback, + uploadForPermalinkHandler, /** @param {LH.Result} newLhr */ refresh: newLhr => { this._replaceReportHtml(newLhr); @@ -250,12 +257,12 @@ export class LighthouseReportViewer { /** * @param {LH.FlowResult} json * @param {HTMLElement} rootEl - * @param {(json: LH.Result|LH.FlowResult) => void} [saveGistCallback] + * @param {(json: LH.Result|LH.FlowResult) => void} [uploadForPermalinkHandler] */ - _renderFlowResult(json, rootEl, saveGistCallback) { + _renderFlowResult(json, rootEl, uploadForPermalinkHandler) { // TODO: Add save HTML functionality with ReportGenerator loaded async. renderFlowReport(json, rootEl, { - saveAsGist: saveGistCallback, + uploadForPermalink: uploadForPermalinkHandler, }); // Install as global for easier debugging. window.__LIGHTHOUSE_FLOW_JSON__ = json; @@ -277,23 +284,22 @@ export class LighthouseReportViewer { const rootEl = document.createElement('div'); container.append(rootEl); - // Only give gist-saving callback if current report isn't from a gist. - let saveGistCallback; - if (!this._reportIsFromGist) { - saveGistCallback = this._onSaveJson; - } + // Don't allow uploading if the report is already uploaded. + const uploadForPermalinkHandler = this._reportIsFromTraceCafe ? + undefined : this._doUploadForPermalink; try { if (this._isFlowReport(json)) { - this._renderFlowResult(json, rootEl, saveGistCallback); + this._renderFlowResult(json, rootEl, uploadForPermalinkHandler); window.ga('send', 'event', 'report', 'flow-report'); } else { - this._renderLhr(json, rootEl, saveGistCallback); + this._renderLhr(json, rootEl, uploadForPermalinkHandler); window.ga('send', 'event', 'report', 'report'); } // Only clear query string if current report isn't from a gist or PSI. - if (!this._reportIsFromGist && !this._reportIsFromPSI && !this._reportIsFromJSON) { + if (!this._reportIsFromGist && !this._reportIsFromPSI && + !this._reportIsFromJSON && !this._reportIsFromTraceCafe) { history.pushState({}, '', LighthouseReportViewer.APP_URL); } } catch (e) { @@ -301,7 +307,8 @@ export class LighthouseReportViewer { container.innerHTML = ''; throw e; } finally { - this._reportIsFromGist = this._reportIsFromPSI = this._reportIsFromJSON = false; + this._reportIsFromGist = this._reportIsFromPSI = + this._reportIsFromJSON = this._reportIsFromTraceCafe = false; } // Remove the placeholder UI once the user has loaded a report. @@ -362,19 +369,31 @@ export class LighthouseReportViewer { * @return {Promise} id of the created gist. * @private */ - async _onSaveJson(reportJson) { + async _doUploadForPermalink(reportJson) { if (window.ga) { window.ga('send', 'event', 'report', 'share'); } - // TODO: find and reuse existing json gist if one exists. try { - const id = await this._github.createGist(reportJson); + let filename; + if ('steps' in reportJson) { + filename = getFlowResultFilenamePrefix(reportJson); + } else { + filename = getLhrFilenamePrefix({ + finalDisplayedUrl: Util.getFinalDisplayedUrl(reportJson), + fetchTime: reportJson.fetchTime, + }); + } + + const id = await uploadLhrToTraceCafe(reportJson, filename); + if (window.ga) { window.ga('send', 'event', 'report', 'created'); } - history.pushState({}, '', `${LighthouseReportViewer.APP_URL}?gist=${id}`); - return id; + const updatedUrl = new URL(LighthouseReportViewer.APP_URL); + updatedUrl.searchParams.append('id', id); + history.pushState({}, '', updatedUrl.href); + return filename; } catch (err) { logger.log(err.message); } diff --git a/viewer/app/src/tracecafe-storage.js b/viewer/app/src/tracecafe-storage.js new file mode 100644 index 000000000000..767be2151bdf --- /dev/null +++ b/viewer/app/src/tracecafe-storage.js @@ -0,0 +1,87 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/* global CompressionStream TransformStream */ + +/** + * @param {string} str + * @returns {Promise} + */ +async function gzipStringToBlob(str) { + const encodedBuffer = new TextEncoder().encode(str); + + const codecStream = new CompressionStream('gzip'); + const {readable, writable} = new TransformStream(); + const codecReadable = readable.pipeThrough(codecStream); + + const writer = writable.getWriter(); + void writer.write(encodedBuffer); + void writer.close(); + + const response = new Response(codecReadable); + return response.blob(); +} + +/** + * Thx https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string + * @param {string} str + */ +async function generateHash(str) { + const msgUint8 = new TextEncoder().encode(str); + const hashBuffer = await crypto.subtle.digest('SHA-1', msgUint8); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + // Reduce to a base-36 alpha-numeric hash + // FWIW: `hashArray.map(b => String.fromCharCode(b)).join('')` creates a shorter id, but NOT after uri encoding + const hash = hashArray.map(b => b.toString(36)).join(''); + return hash; +} +/** + * @param {LH.Result|LH.FlowResult} reportObject + * @param {string} filename + * @returns {Promise} + */ +async function uploadLhrToTraceCafe(reportObject, filename) { + const lhrJsonStr = JSON.stringify(reportObject); + const lhrBlob = await gzipStringToBlob(lhrJsonStr); + + const hash = await generateHash(lhrJsonStr); + // Remove the time string, for a cleaner look + const shortname = filename.split('_').slice(0, 2).join('_').replaceAll('-', '_'); + const cafeid = `${shortname}-${hash}`; + + // This REST technique is completely undocumented, but.. it works. + const formData = new FormData(); + formData.append( + 'metadata', + JSON.stringify({ + name: `lhrs/${cafeid}`, + cacheControl: 'max-age=31536000', + contentEncoding: 'gzip', + contentType: 'application/json', + metadata: {oName: `${filename}`}, + }) + ); + formData.append('file', lhrBlob, 'filename'); + + const resp = await fetch( + `https://firebasestorage.googleapis.com/v0/b/tum-lhrs/o?name=lhrs%2F${cafeid}`, + { + method: 'POST', + body: formData, + headers: {'X-Goog-Upload-Protocol': 'multipart'}, + } + ); + const payload = await resp.json(); + if (!resp.ok) { + console.error(payload); + throw new Error(`Upload failed. ${payload?.error?.message}`); + } + return cafeid; +} + +export { + uploadLhrToTraceCafe, +}; diff --git a/viewer/app/src/viewer-ui-features.js b/viewer/app/src/viewer-ui-features.js index 7731064bb69a..bd10ec654a10 100644 --- a/viewer/app/src/viewer-ui-features.js +++ b/viewer/app/src/viewer-ui-features.js @@ -17,14 +17,14 @@ import {SwapLocaleFeature} from '../../../report/renderer/swap-locale-feature.js export class ViewerUIFeatures extends ReportUIFeatures { /** * @param {DOM} dom - * @param {{saveGist?: function(LH.Result): void, refresh: function(LH.Result): void, getStandaloneReportHTML: function(): string}} callbacks + * @param {{uploadForPermalinkHandler?: function(LH.Result): void, refresh: function(LH.Result): void, getStandaloneReportHTML: function(): string}} callbacks */ constructor(dom, callbacks) { super(dom, { getStandaloneReportHTML: callbacks.getStandaloneReportHTML, }); - this._saveGistCallback = callbacks.saveGist; + this._uploadForPermalinkHandler = callbacks.uploadForPermalinkHandler; this._refreshCallback = callbacks.refresh; this._swapLocales = new SwapLocaleFeature(this, this._dom, { onLocaleSelected: this._swapLocale.bind(this), @@ -38,11 +38,12 @@ export class ViewerUIFeatures extends ReportUIFeatures { initFeatures(report) { super.initFeatures(report); - // Disable option to save as gist if no callback for saving. - if (!this._saveGistCallback) { - const saveGistItem = - this._dom.find('.lh-tools__dropdown a[data-action="save-gist"]', this._dom.rootEl); - saveGistItem.setAttribute('disabled', 'true'); + // Disable option to Upload for Shareable URL if no handler for saving. + if (!this._uploadForPermalinkHandler) { + const permalinkItem = + this._dom.find('.lh-tools__dropdown a[data-action="upload-for-permalink"]', + this._dom.rootEl); + permalinkItem.setAttribute('disabled', 'true'); } this._getI18nModule().then(i18nModule => { @@ -54,18 +55,18 @@ export class ViewerUIFeatures extends ReportUIFeatures { /** * @override */ - saveAsGist() { - if (this._saveGistCallback) { - this._saveGistCallback(this.json); + uploadForPermalink() { + if (this._uploadForPermalinkHandler) { + this._uploadForPermalinkHandler(this.json); } else { - // UI should prevent this from being called with no callback, but throw to be sure. - throw new Error('Cannot save this report as a gist'); + // UI should prevent this from being called with no handler, but throw to be sure. + throw new Error('Cannot upload this report for sharing'); } - // Disable save-gist option after saving. - const saveGistItem = - this._dom.find('.lh-tools__dropdown a[data-action="save-gist"]', this._dom.rootEl); - saveGistItem.setAttribute('disabled', 'true'); + // Disable upload-for-permalink option after saving. + const permalinkItem = + this._dom.find('.lh-tools__dropdown a[data-action="upload-for-permalink"]', this._dom.rootEl); + permalinkItem.setAttribute('disabled', 'true'); } /** diff --git a/viewer/app/styles/viewer.css b/viewer/app/styles/viewer.css index 49b4d8f95870..861dbb19069f 100644 --- a/viewer/app/styles/viewer.css +++ b/viewer/app/styles/viewer.css @@ -151,7 +151,7 @@ body { display: none; } -/* save-gist option visible in Viewer */ -.lh-tools__dropdown a[data-action="save-gist"] { +/* upload-for-permalink option visible in Viewer */ +.lh-tools__dropdown a[data-action="upload-for-permalink"] { display: flex !important; } diff --git a/viewer/tsconfig.json b/viewer/tsconfig.json index e171ed0d3866..86a08e10ff35 100644 --- a/viewer/tsconfig.json +++ b/viewer/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../tsconfig-base.json", "compilerOptions": { // Limit to base JS and DOM defs. - "lib": ["es2020", "dom", "dom.iterable"], + "lib": ["es2021", "dom", "dom.iterable"], // Don't include any types from node_modules/. "types": [], },