Merge TodoMVC-React with TodoMVC-React-Window
Reuse TodoMVC-React source and generate TodoMVC-React-Window files in resources/architecture-examples/react/dist. Change-Id: I67e37442f594cf17b13b350fc9fa5ec1bf4d6b68 TodoMVC-React windowed variation Add a variation of the TodoMVC-React workload that renders the app in a new Window but controls it through scripts loaded in the parent window. Change-Id: I8b84cf7d9f0e80672808b5bf28959a034e139e0c Add signpost support Change-Id: I199b12c21fa25c2daab806988b0b1812a492a3d4 Add suiteForceGC helper Force run a gc() (expose with `--js-flags=--expose-gc`) before and after preparing a suite to limit potential ripple-effects from previous tests. Change-Id: Ia397b9e0aa8f5dabfb1dc4a69cfad9a7cf63ce60 [speedometer][v3.1-custom] Add params.leakyIframes to main-custom DevTools can't handle sources from detached iframes. To simplify local development we add an an option that just hides the iframes away but never detaches them from the DOM. Change-Id: Icac6d69018e7151cc82b406973a9bdd6b7b67629 Merge with upstream/release/3.1b475f2dfPerf-Dashboard.Render sync phase sets location.hash, but the actual DOM (#488) (#496)b270564a(origin/3.1, 3.1) Release/3.1 428 - add id to input (NEW - with correct base to merge into) (#494)aba1d5e4(thor/release/3.1, flashd/release/3.1) Deconfuse Geomean Metric and geomean aggregate value (#408) (#480)ce03cfbbDon't display invalid results (#406) (#479)6f253451Update Version Text from 3.0 to 3.1 (#485)cc9ee085Release/3.1 - merge 400 (rename className -> class) (#483)e12e84c3Release/3.1 - merge 448 (news site article ids nuxt) (#482)8a4a5660Release/3.1 - merge 447 (news site article ids next) (#481) Change-Id: If0b19391128b82389eda1a61d33dc4e2be2cd180 Remove duplicated word. (#402) (#477) Co-authored-by: Zev Eisenberg <zev@zeveisenberg.com> Release/3.1 - merge 471 (news site remove useEffect) (#475) Change-Id: Ie25d06e297c9145b9af942fb4abd9d9d3b5ec7b7
This commit is contained in:
parent
8d67f28d02
commit
19b7ca9c64
51 changed files with 713 additions and 94 deletions
|
|
@ -23,6 +23,8 @@ package-lock.json
|
|||
!/resources/todomvc/architecture-examples/vue
|
||||
!/resources/todomvc/architecture-examples/vue-complex
|
||||
|
||||
/resources/todomvc/architecture-examples/react/public/window/*
|
||||
|
||||
/resources/todomvc/vanilla-examples/*
|
||||
!/resources/todomvc/vanilla-examples/javascript-es5
|
||||
!/resources/todomvc/vanilla-examples/javascript-es5-complex
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ package-lock.json
|
|||
!/resources/todomvc/architecture-examples/vue
|
||||
!/resources/todomvc/architecture-examples/vue-complex
|
||||
|
||||
/resources/todomvc/architecture-examples/react/public/window/*
|
||||
|
||||
/resources/todomvc/vanilla-examples/*
|
||||
!/resources/todomvc/vanilla-examples/javascript-es5
|
||||
!/resources/todomvc/vanilla-examples/javascript-es5-complex
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
<div class="version">3.0</div>
|
||||
</a>
|
||||
<div id="testContainer"></div>
|
||||
<div id="leakedIframes"></div>
|
||||
<div id="progress">
|
||||
<progress aria-label="Progress" id="progress-completed"></progress>
|
||||
</div>
|
||||
|
|
@ -80,6 +81,7 @@
|
|||
<div class="aggregated-metric-result">
|
||||
<h2>Geomean</h2>
|
||||
<div id="geomean-chart"></div>
|
||||
<div id="toplevel-chart"></div>
|
||||
<h2>Tests</h2>
|
||||
<div id="tests-chart"></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ function getParent(lookupStartNode, path) {
|
|||
class Page {
|
||||
constructor(frame) {
|
||||
this._frame = frame;
|
||||
// Downstream-only. this._lookupStartNode is used by the React-Window workload to run the
|
||||
// querySelector* methods on a child window.
|
||||
this._lookupStartNode = null;
|
||||
}
|
||||
|
||||
layout() {
|
||||
|
|
@ -58,7 +61,7 @@ class Page {
|
|||
* @returns PageElement | null
|
||||
*/
|
||||
querySelector(selector, path = []) {
|
||||
const lookupStartNode = this._frame.contentDocument;
|
||||
const lookupStartNode = this._lookupStartNode ?? this._frame.contentDocument;
|
||||
const element = getParent(lookupStartNode, path).querySelector(selector);
|
||||
|
||||
if (element === null)
|
||||
|
|
@ -82,7 +85,7 @@ class Page {
|
|||
* @returns array
|
||||
*/
|
||||
querySelectorAll(selector, path = []) {
|
||||
const lookupStartNode = this._frame.contentDocument;
|
||||
const lookupStartNode = this._lookupStartNode ?? this._frame.contentDocument;
|
||||
const elements = Array.from(getParent(lookupStartNode, path).querySelectorAll(selector));
|
||||
for (let i = 0; i < elements.length; i++)
|
||||
elements[i] = this._wrapElement(elements[i]);
|
||||
|
|
@ -114,6 +117,24 @@ class Page {
|
|||
_wrapElement(element) {
|
||||
return new PageElement(element);
|
||||
}
|
||||
|
||||
// Downstream only.
|
||||
async targetChildWindow() {
|
||||
return new Promise((resolve) => {
|
||||
const resolveIfReady = () => {
|
||||
// Expects the workload to set a global childWindow object.
|
||||
const maybeChildWindow = this._frame.contentWindow.globalThis.childWindow;
|
||||
let callback = resolveIfReady;
|
||||
if (maybeChildWindow) {
|
||||
this._lookupStartNode = maybeChildWindow.document;
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
window.requestAnimationFrame(callback);
|
||||
};
|
||||
resolveIfReady();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const NATIVE_OPTIONS = {
|
||||
|
|
@ -330,8 +351,40 @@ export class BenchmarkRunner {
|
|||
this._page = null;
|
||||
this._metrics = null;
|
||||
this._iterationCount = params.iterationCount;
|
||||
this._currentIteration = 0;
|
||||
if (params.shuffleSeed !== "off")
|
||||
this._suiteOrderRandomNumberGenerator = seededHashRandomNumberGenerator(params.shuffleSeed);
|
||||
this._maybeForceGC = this._initForceGC();
|
||||
this._useSignPost = !!globalThis.__signpostStart;
|
||||
}
|
||||
|
||||
markStart(groupLabel, startLabel) {
|
||||
performance.mark(startLabel);
|
||||
if (this._useSignPost)
|
||||
globalThis.__signpostStart(groupLabel);
|
||||
}
|
||||
|
||||
markEnd(groupLabel, startLabel, endLabel) {
|
||||
performance.mark(endLabel);
|
||||
if (this._useSignPost)
|
||||
globalThis.__signpostStop(groupLabel);
|
||||
performance.measure(groupLabel, startLabel, endLabel);
|
||||
}
|
||||
|
||||
_initForceGC() {
|
||||
if (!params.suiteForceGC)
|
||||
return () => {};
|
||||
try {
|
||||
let gc_extension = eval("gc");
|
||||
return () => gc_extension({ type: "major", execution: "async" });
|
||||
} catch (e) {
|
||||
console.error("suiteForceGC was enabled but --expose-gc was not set", e);
|
||||
}
|
||||
return () => {};
|
||||
}
|
||||
|
||||
get currentIteration() {
|
||||
return this._currentIteration;
|
||||
}
|
||||
|
||||
async runMultipleIterations(iterationCount) {
|
||||
|
|
@ -341,11 +394,11 @@ export class BenchmarkRunner {
|
|||
|
||||
const iterationStartLabel = "iteration-start";
|
||||
const iterationEndLabel = "iteration-end";
|
||||
for (let i = 0; i < iterationCount; i++) {
|
||||
performance.mark(iterationStartLabel);
|
||||
for (; this._currentIteration < this._iterationCount; this._currentIteration++) {
|
||||
const iterationLabel = `iteration-${this._currentIteration}`;
|
||||
this.markStart(iterationLabel, iterationStartLabel);
|
||||
await this._runAllSuites();
|
||||
performance.mark(iterationEndLabel);
|
||||
performance.measure(`iteration-${i}`, iterationStartLabel, iterationEndLabel);
|
||||
this.markEnd(iterationLabel, iterationStartLabel, iterationEndLabel);
|
||||
}
|
||||
|
||||
if (this._client?.didFinishLastIteration)
|
||||
|
|
@ -354,7 +407,14 @@ export class BenchmarkRunner {
|
|||
|
||||
_removeFrame() {
|
||||
if (this._frame) {
|
||||
this._frame.parentNode.removeChild(this._frame);
|
||||
if (params.leakyIframes) {
|
||||
document.getElementById("leakedIframes").append(this._frame);
|
||||
} else {
|
||||
// Downstream only. The React-Window workload sets a global childWindow object.
|
||||
if (this._frame.contentWindow?.globalThis?.childWindow)
|
||||
this._frame.contentWindow.globalThis.childWindow.close();
|
||||
this._frame.parentNode.removeChild(this._frame);
|
||||
}
|
||||
this._frame = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -383,10 +443,11 @@ export class BenchmarkRunner {
|
|||
async _runAllSuites() {
|
||||
this._measuredValues = { tests: {}, total: 0, mean: NaN, geomean: NaN, score: NaN };
|
||||
|
||||
const prepareLabel = "runner-prepare";
|
||||
const prepareStartLabel = "runner-prepare-start";
|
||||
const prepareEndLabel = "runner-prepare-end";
|
||||
|
||||
performance.mark(prepareStartLabel);
|
||||
this.markStart(prepareLabel, prepareStartLabel);
|
||||
this._removeFrame();
|
||||
await this._appendFrame();
|
||||
this._page = new Page(this._frame);
|
||||
|
|
@ -402,43 +463,59 @@ export class BenchmarkRunner {
|
|||
suites[j] = tmp;
|
||||
}
|
||||
}
|
||||
this.markEnd(prepareLabel, prepareStartLabel, prepareEndLabel);
|
||||
|
||||
performance.mark(prepareEndLabel);
|
||||
performance.measure("runner-prepare", prepareStartLabel, prepareEndLabel);
|
||||
|
||||
for (const suite of suites) {
|
||||
if (!suite.disabled)
|
||||
await this._runSuite(suite);
|
||||
try {
|
||||
for (const suite of suites) {
|
||||
if (!suite.disabled)
|
||||
await this._runSuite(suite);
|
||||
}
|
||||
} finally {
|
||||
await this._finishRunAllSuites();
|
||||
}
|
||||
}
|
||||
|
||||
async _finishRunAllSuites() {
|
||||
const finalizeLabel = "runner-finalize";
|
||||
const finalizeStartLabel = "runner-finalize-start";
|
||||
const finalizeEndLabel = "runner-finalize-end";
|
||||
|
||||
performance.mark(finalizeStartLabel);
|
||||
this.markStart(finalizeLabel, finalizeStartLabel);
|
||||
// Remove frame to clear the view for displaying the results.
|
||||
this._removeFrame();
|
||||
await this._finalize();
|
||||
performance.mark(finalizeEndLabel);
|
||||
performance.measure("runner-finalize", finalizeStartLabel, finalizeEndLabel);
|
||||
this.markEnd(finalizeLabel, finalizeStartLabel, finalizeEndLabel);
|
||||
}
|
||||
|
||||
async _runSuite(suite) {
|
||||
const suitePrepareStartLabel = `suite-${suite.name}-prepare-start`;
|
||||
const suitePrepareEndLabel = `suite-${suite.name}-prepare-end`;
|
||||
const suiteStartLabel = `suite-${suite.name}-start`;
|
||||
const suiteEndLabel = `suite-${suite.name}-end`;
|
||||
const suiteName = suite.name;
|
||||
const suitePrepareLabel = `suite-${suite.name}-prepare`;
|
||||
const suitePrepareStartLabel = `suite-${suiteName}-prepare-start`;
|
||||
const suitePrepareEndLabel = `suite-${suiteName}-prepare-end`;
|
||||
const suiteLabel = `suite-${suite.name}`;
|
||||
const suiteStartLabel = `suite-${suiteName}-start`;
|
||||
const suiteEndLabel = `suite-${suiteName}-end`;
|
||||
|
||||
performance.mark(suitePrepareStartLabel);
|
||||
this._prepareMetrics(suite);
|
||||
await this._maybeForceGC();
|
||||
|
||||
this.markStart(suitePrepareLabel, suitePrepareStartLabel);
|
||||
const prepareStartTime = performance.now();
|
||||
await this._prepareSuite(suite);
|
||||
performance.mark(suitePrepareEndLabel);
|
||||
const prepareEndTime = performance.now();
|
||||
this.markEnd(suitePrepareLabel, suitePrepareStartLabel, suitePrepareEndLabel);
|
||||
|
||||
performance.mark(suiteStartLabel);
|
||||
await this._maybeForceGC();
|
||||
|
||||
if (params.measurePrepare) {
|
||||
const prepareTime = prepareEndTime - prepareStartTime;
|
||||
this._recordPrepareMetric(suite, prepareTime);
|
||||
}
|
||||
|
||||
this.markStart(suiteLabel, suiteStartLabel);
|
||||
for (const test of suite.tests)
|
||||
await this._runTestAndRecordResults(suite, test);
|
||||
performance.mark(suiteEndLabel);
|
||||
|
||||
performance.measure(`suite-${suite.name}-prepare`, suitePrepareStartLabel, suitePrepareEndLabel);
|
||||
performance.measure(`suite-${suite.name}`, suiteStartLabel, suiteEndLabel);
|
||||
this.markEnd(suiteLabel, suiteStartLabel, suiteEndLabel);
|
||||
}
|
||||
|
||||
async _prepareSuite(suite) {
|
||||
|
|
@ -458,8 +535,10 @@ export class BenchmarkRunner {
|
|||
await this._client.willRunTest(suite, test);
|
||||
|
||||
// Prepare all mark labels outside the measuring loop.
|
||||
const startLabel = `${suite.name}.${test.name}-start`;
|
||||
const syncLabel = `${suite.name}.${test.name}`;
|
||||
const syncStartLabel = `${suite.name}.${test.name}-start`;
|
||||
const syncEndLabel = `${suite.name}.${test.name}-sync-end`;
|
||||
const asyncLabel = `${suite.name}.${test.name}-async`;
|
||||
const asyncStartLabel = `${suite.name}.${test.name}-async-start`;
|
||||
const asyncEndLabel = `${suite.name}.${test.name}-async-end`;
|
||||
|
||||
|
|
@ -468,22 +547,22 @@ export class BenchmarkRunner {
|
|||
let asyncTime;
|
||||
const runSync = () => {
|
||||
if (params.warmupBeforeSync) {
|
||||
performance.mark("warmup-start");
|
||||
this.markStart("warmup", "warmup-start");
|
||||
const startTime = performance.now();
|
||||
// Infinite loop for the specified ms.
|
||||
while (performance.now() - startTime < params.warmupBeforeSync)
|
||||
continue;
|
||||
performance.mark("warmup-end");
|
||||
this.markEnd("warmup", "warmup-start", "warmup-end");
|
||||
}
|
||||
performance.mark(startLabel);
|
||||
this.markStart(syncLabel, syncStartLabel);
|
||||
const syncStartTime = performance.now();
|
||||
test.run(this._page);
|
||||
const syncEndTime = performance.now();
|
||||
performance.mark(syncEndLabel);
|
||||
this.markEnd(syncLabel, syncStartLabel, syncEndLabel);
|
||||
|
||||
syncTime = syncEndTime - syncStartTime;
|
||||
|
||||
performance.mark(asyncStartLabel);
|
||||
this.markStart(asyncLabel, asyncStartLabel);
|
||||
asyncStartTime = performance.now();
|
||||
};
|
||||
const measureAsync = () => {
|
||||
|
|
@ -493,11 +572,7 @@ export class BenchmarkRunner {
|
|||
const asyncEndTime = performance.now();
|
||||
asyncTime = asyncEndTime - asyncStartTime;
|
||||
this._frame.contentWindow._unusedHeightValue = height; // Prevent dead code elimination.
|
||||
performance.mark(asyncEndLabel);
|
||||
if (params.warmupBeforeSync)
|
||||
performance.measure("warmup", "warmup-start", "warmup-end");
|
||||
performance.measure(`${suite.name}.${test.name}-sync`, startLabel, syncEndLabel);
|
||||
performance.measure(`${suite.name}.${test.name}-async`, asyncStartLabel, asyncEndLabel);
|
||||
this.markEnd(asyncLabel, asyncStartLabel, asyncEndLabel);
|
||||
};
|
||||
const report = () => this._recordTestResults(suite, test, syncTime, asyncTime);
|
||||
const invokerClass = params.measurementMethod === "raf" ? RAFTestInvoker : TimerTestInvoker;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@ export function createDeveloperModeContainer() {
|
|||
settings.append(createUIForWarmupSuite());
|
||||
settings.append(createUIForWarmupBeforeSync());
|
||||
settings.append(createUIForSyncStepDelay());
|
||||
settings.append(createUIForLeakyIframes());
|
||||
settings.append(createUIForMeasurePrepare());
|
||||
settings.append(createUIForDomainPerIteration());
|
||||
settings.append(createUIForForceGC());
|
||||
|
||||
content.append(document.createElement("hr"));
|
||||
content.append(settings);
|
||||
|
|
@ -57,6 +61,23 @@ function createUIForMeasurementMethod() {
|
|||
return label;
|
||||
}
|
||||
|
||||
function createUIForLeakyIframes() {
|
||||
let check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = "leaky-iframes-checkbox";
|
||||
check.checked = !!params.leakyIframes;
|
||||
|
||||
check.onchange = () => {
|
||||
params.leakyIframes = check.checked;
|
||||
updateURL();
|
||||
};
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.append(check, " ", span("Leak IFrames"));
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
function createUIForWarmupSuite() {
|
||||
let check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
|
|
@ -74,6 +95,57 @@ function createUIForWarmupSuite() {
|
|||
return label;
|
||||
}
|
||||
|
||||
function createUIForMeasurePrepare() {
|
||||
let check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = "measure-prepare";
|
||||
check.checked = params.measurePrepare;
|
||||
|
||||
check.onchange = () => {
|
||||
params.measurePrepare = check.checked;
|
||||
updateURL();
|
||||
};
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.append(check, " ", "Measure Prepare");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
function createUIForDomainPerIteration() {
|
||||
let check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = "domain-per-iteration";
|
||||
check.checked = params.domainPerIteration;
|
||||
|
||||
check.onchange = () => {
|
||||
params.domainPerIteration = check.checked;
|
||||
updateURL();
|
||||
};
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.append(check, " ", "Use Subdomain-Runner");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
function createUIForForceGC() {
|
||||
let check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = "suite-force-gc";
|
||||
check.checked = params.suiteForceGC;
|
||||
|
||||
check.onchange = () => {
|
||||
params.suiteForceGC = check.checked;
|
||||
updateURL();
|
||||
};
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.append(check, " ", "Force GC before every Suite");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
function createUIForIterationCount() {
|
||||
const { range, label } = createTimeRangeUI("Iterations: ", params.iterationCount, "#", 1, 200);
|
||||
range.onchange = () => {
|
||||
|
|
@ -273,7 +345,7 @@ function updateURL() {
|
|||
else
|
||||
url.searchParams.delete("measurementMethod");
|
||||
|
||||
const boolParamKeys = ["iterationCount", "useWarmupSuite", "warmupBeforeSync", "waitBeforeSync"];
|
||||
const boolParamKeys = ["iterationCount", "useWarmupSuite", "warmupBeforeSync", "waitBeforeSync", "domainPerIteration", "suiteForceGC", "leakyIframes"];
|
||||
for (const paramKey of boolParamKeys) {
|
||||
if (params[paramKey] !== defaultParams[paramKey])
|
||||
url.searchParams.set(paramKey, params[paramKey]);
|
||||
|
|
|
|||
|
|
@ -324,6 +324,10 @@ section > p {
|
|||
height: var(--viewport-height);
|
||||
}
|
||||
|
||||
#leakedIframes {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section#home p {
|
||||
margin: 0 auto;
|
||||
width: 70%;
|
||||
|
|
@ -423,6 +427,25 @@ section#summary > #confidence-number {
|
|||
color: var(--inactive-color);
|
||||
}
|
||||
|
||||
section#summary.invalid h1,
|
||||
section#summary.invalid .gauge,
|
||||
section#summary.invalid hr {
|
||||
opacity: 0.2;
|
||||
}
|
||||
section#summary.invalid #result-number {
|
||||
color: var(--highlight);
|
||||
}
|
||||
section#summary.invalid .buttons {
|
||||
display: none;
|
||||
}
|
||||
#invalid-score-text {
|
||||
display: none;
|
||||
text-align: center;
|
||||
}
|
||||
section#summary.invalid #invalid-score-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
section#details {
|
||||
--viewport-height: max(600px, 90vh);
|
||||
--viewport-width: max(800px, 80vw);
|
||||
|
|
|
|||
|
|
@ -107,19 +107,42 @@ class MainBenchmarkClient {
|
|||
this._metrics = metrics;
|
||||
|
||||
const scoreResults = this._computeResults(this._measuredValuesList, "score");
|
||||
this._updateGaugeNeedle(scoreResults.mean);
|
||||
document.getElementById("result-number").textContent = scoreResults.formattedMean;
|
||||
if (scoreResults.formattedDelta)
|
||||
document.getElementById("confidence-number").textContent = `\u00b1 ${scoreResults.formattedDelta}`;
|
||||
if (scoreResults.isValid)
|
||||
this._populateValidScore(scoreResults);
|
||||
else
|
||||
this._populateInvalidScore();
|
||||
|
||||
this._populateDetailedResults(metrics);
|
||||
|
||||
if (params.developerMode)
|
||||
this.showResultsDetails();
|
||||
else
|
||||
this.showResultsSummary();
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
console.assert(this._isRunning);
|
||||
this._isRunning = false;
|
||||
this._hasResults = true;
|
||||
this._metrics = Object.create(null);
|
||||
this._populateInvalidScore();
|
||||
this.showResultsSummary();
|
||||
}
|
||||
|
||||
_populateValidScore(scoreResults) {
|
||||
document.getElementById("summary").className = "valid";
|
||||
|
||||
this._updateGaugeNeedle(scoreResults.mean);
|
||||
document.getElementById("result-number").textContent = scoreResults.formattedMean;
|
||||
if (scoreResults.formattedDelta)
|
||||
document.getElementById("confidence-number").textContent = `\u00b1 ${scoreResults.formattedDelta}`;
|
||||
}
|
||||
|
||||
_populateInvalidScore() {
|
||||
document.getElementById("summary").className = "invalid";
|
||||
document.getElementById("result-number").textContent = "Error";
|
||||
document.getElementById("confidence-number").textContent = "";
|
||||
}
|
||||
|
||||
_computeResults(measuredValuesList, displayUnit) {
|
||||
function valueForUnit(measuredValues) {
|
||||
if (displayUnit === "ms")
|
||||
|
|
@ -137,9 +160,7 @@ class MainBenchmarkClient {
|
|||
}
|
||||
|
||||
const values = measuredValuesList.map(valueForUnit);
|
||||
const sum = values.reduce((a, b) => {
|
||||
return a + b;
|
||||
}, 0);
|
||||
const sum = values.reduce((a, b) => a + b, 0);
|
||||
const arithmeticMean = sum / values.length;
|
||||
let meanSigFig = 4;
|
||||
let formattedDelta;
|
||||
|
|
@ -162,6 +183,7 @@ class MainBenchmarkClient {
|
|||
formattedMean: formattedMean,
|
||||
formattedDelta: formattedDelta,
|
||||
formattedMeanAndDelta: formattedMean + (formattedDelta ? ` \xb1 ${formattedDelta} (${formattedPercentDelta})` : ""),
|
||||
isValid: values.length > 0 && isFinite(sum) && sum > 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,15 @@ export class Metric {
|
|||
throw new Error(`Invalid metric.name=${name}, expected string.`);
|
||||
this.name = name;
|
||||
this.unit = unit;
|
||||
this.description = "";
|
||||
|
||||
this.mean = 0.0;
|
||||
this.geomean = 0.0;
|
||||
// Make "geomean" non-enumerable so we don't serialize it with JSON.stringify
|
||||
// and avoid some confusion with the top-level Geomean metric.
|
||||
Object.defineProperty(this, "geomean", {
|
||||
writable: true,
|
||||
value: 0,
|
||||
});
|
||||
this.delta = 0.0;
|
||||
this.percentDelta = 0.0;
|
||||
|
||||
|
|
@ -21,7 +27,6 @@ export class Metric {
|
|||
this.max = 0.0;
|
||||
|
||||
this.values = [];
|
||||
this.children = [];
|
||||
|
||||
// Mark properties which refer to other Metric objects as
|
||||
// non-enumerable to avoid issue with JSON.stringify due to circular
|
||||
|
|
@ -31,6 +36,10 @@ export class Metric {
|
|||
writable: true,
|
||||
value: undefined,
|
||||
},
|
||||
children: {
|
||||
writable: true,
|
||||
value: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
2
resources/newssite/news-next/dist/404.html
vendored
2
resources/newssite/news-next/dist/404.html
vendored
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="./_next/static/css/a0dca1379a01e5cf.css" as="style"/><link rel="stylesheet" href="./_next/static/css/a0dca1379a01e5cf.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="./_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="./_next/static/chunks/webpack-e50e9853db18b759.js" defer=""></script><script src="./_next/static/chunks/framework-2c79e2a64abdb08b.js" defer=""></script><script src="./_next/static/chunks/main-2ba37e62325cc71b.js" defer=""></script><script src="./_next/static/chunks/pages/_app-77983e68be50f72a.js" defer=""></script><script src="./_next/static/chunks/pages/_error-54de1933a164a1ff.js" defer=""></script><script src="./_next/static/hVjtt3DRTxwTZ0w7LdK0j/_buildManifest.js" defer=""></script><script src="./_next/static/hVjtt3DRTxwTZ0w7LdK0j/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><div id="settings-container"></div><div id="notifications-container"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"hVjtt3DRTxwTZ0w7LdK0j","assetPrefix":".","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="./_next/static/css/a0dca1379a01e5cf.css" as="style"/><link rel="stylesheet" href="./_next/static/css/a0dca1379a01e5cf.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="./_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="./_next/static/chunks/webpack-e50e9853db18b759.js" defer=""></script><script src="./_next/static/chunks/framework-2c79e2a64abdb08b.js" defer=""></script><script src="./_next/static/chunks/main-2ba37e62325cc71b.js" defer=""></script><script src="./_next/static/chunks/pages/_app-77983e68be50f72a.js" defer=""></script><script src="./_next/static/chunks/pages/_error-54de1933a164a1ff.js" defer=""></script><script src="./_next/static/5v6xiLKzLrBzD4hPqXwOj/_buildManifest.js" defer=""></script><script src="./_next/static/5v6xiLKzLrBzD4hPqXwOj/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><div id="settings-container"></div><div id="notifications-container"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"5v6xiLKzLrBzD4hPqXwOj","assetPrefix":".","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
||||
|
|
@ -1 +1 @@
|
|||
self.__BUILD_MANIFEST={__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static/chunks/743-fd706aeabb7828e3.js","static/css/2cf5163b53bb0adb.css","static/chunks/pages/index-a6d76b1b73bbfbe0.js"],"/_error":["static/chunks/pages/_error-54de1933a164a1ff.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||
self.__BUILD_MANIFEST={__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":["static/chunks/743-fd706aeabb7828e3.js","static/css/2cf5163b53bb0adb.css","static/chunks/pages/index-61e648f02ae686f6.js"],"/_error":["static/chunks/pages/_error-54de1933a164a1ff.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
||||
File diff suppressed because one or more lines are too long
2
resources/newssite/news-next/dist/index.html
vendored
2
resources/newssite/news-next/dist/index.html
vendored
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="./_next/static/css/a0dca1379a01e5cf.css" as="style"/><link rel="stylesheet" href="./_next/static/css/a0dca1379a01e5cf.css" data-n-g=""/><link rel="preload" href="./_next/static/css/2cf5163b53bb0adb.css" as="style"/><link rel="stylesheet" href="./_next/static/css/2cf5163b53bb0adb.css" data-n-p=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="./_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="./_next/static/chunks/webpack-e50e9853db18b759.js" defer=""></script><script src="./_next/static/chunks/framework-2c79e2a64abdb08b.js" defer=""></script><script src="./_next/static/chunks/main-2ba37e62325cc71b.js" defer=""></script><script src="./_next/static/chunks/pages/_app-77983e68be50f72a.js" defer=""></script><script src="./_next/static/chunks/743-fd706aeabb7828e3.js" defer=""></script><script src="./_next/static/chunks/pages/index-a6d76b1b73bbfbe0.js" defer=""></script><script src="./_next/static/hVjtt3DRTxwTZ0w7LdK0j/_buildManifest.js" defer=""></script><script src="./_next/static/hVjtt3DRTxwTZ0w7LdK0j/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><div id="settings-container"></div><div id="notifications-container"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"hVjtt3DRTxwTZ0w7LdK0j","assetPrefix":".","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="./_next/static/css/a0dca1379a01e5cf.css" as="style"/><link rel="stylesheet" href="./_next/static/css/a0dca1379a01e5cf.css" data-n-g=""/><link rel="preload" href="./_next/static/css/2cf5163b53bb0adb.css" as="style"/><link rel="stylesheet" href="./_next/static/css/2cf5163b53bb0adb.css" data-n-p=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="./_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="./_next/static/chunks/webpack-e50e9853db18b759.js" defer=""></script><script src="./_next/static/chunks/framework-2c79e2a64abdb08b.js" defer=""></script><script src="./_next/static/chunks/main-2ba37e62325cc71b.js" defer=""></script><script src="./_next/static/chunks/pages/_app-77983e68be50f72a.js" defer=""></script><script src="./_next/static/chunks/743-fd706aeabb7828e3.js" defer=""></script><script src="./_next/static/chunks/pages/index-61e648f02ae686f6.js" defer=""></script><script src="./_next/static/5v6xiLKzLrBzD4hPqXwOj/_buildManifest.js" defer=""></script><script src="./_next/static/5v6xiLKzLrBzD4hPqXwOj/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><div id="settings-container"></div><div id="notifications-container"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"5v6xiLKzLrBzD4hPqXwOj","assetPrefix":".","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
import classNames from "classnames";
|
||||
|
||||
import ArticleImage from "./article-image";
|
||||
|
|
@ -21,7 +20,7 @@ export default function ArticleContent({ type, content, display }) {
|
|||
<div className={styles["article-content"]}>
|
||||
<ul className={classNames(styles["article-list"], styles.vertical, { [styles[display]]: display })}>
|
||||
{content.map((item) =>
|
||||
<li key={uuidv4()} className={styles["article-list-item"]}>
|
||||
<li key={item.id} className={styles["article-list-item"]}>
|
||||
{item.url && !item.title
|
||||
? <a href={item.url}>
|
||||
<ArticleText text={item.content} />
|
||||
|
|
@ -40,7 +39,7 @@ export default function ArticleContent({ type, content, display }) {
|
|||
<div className={styles["article-list-content"]}>
|
||||
<ul className={classNames(styles["article-list"], styles.vertical)}>
|
||||
{content.map((item) =>
|
||||
<li key={uuidv4()} className={styles["article-list-item"]}>
|
||||
<li key={item.id} className={styles["article-list-item"]}>
|
||||
<ArticleText textClass={classNames(styles["article-title"], "truncate-multiline", "truncate-multiline-3")} text={item.title} type="h3" />
|
||||
{item.url && !item.title
|
||||
? <a href={item.url}>
|
||||
|
|
@ -59,7 +58,7 @@ export default function ArticleContent({ type, content, display }) {
|
|||
return (
|
||||
<ul className={classNames(styles["article-list"], styles.horizontal)}>
|
||||
{content.map((item) =>
|
||||
<li key={uuidv4()} className={styles["article-list-item"]}>
|
||||
<li key={item.id} className={styles["article-list-item"]}>
|
||||
<ArticleImage imageClass={styles["article-hero"]} image={item.image} />
|
||||
<div className={styles["article-content"]}>
|
||||
<ArticleText textClass="truncate-multiline truncate-multiline-3" text={item.text} type="div" />
|
||||
|
|
@ -74,7 +73,7 @@ export default function ArticleContent({ type, content, display }) {
|
|||
return (
|
||||
<div className={classNames(layoutStyles["grid-container"], { [layoutStyles[display]]: display })}>
|
||||
{content.map((item) =>
|
||||
<div key={uuidv4()} className={layoutStyles["grid-item"]}>
|
||||
<div key={item.id} className={layoutStyles["grid-item"]}>
|
||||
<ArticleImage imageClass={styles["article-image-container"]} image={item.image} meta={item.meta} />
|
||||
|
||||
{item.url
|
||||
|
|
@ -93,7 +92,7 @@ export default function ArticleContent({ type, content, display }) {
|
|||
return (
|
||||
<ul className={classNames(styles["article-list"], styles.vertical)}>
|
||||
{content.map((item) =>
|
||||
<li key={uuidv4()} className={styles["article-list-item"]}>
|
||||
<li key={item.id} className={styles["article-list-item"]}>
|
||||
<ArticleImage imageClass={styles["article-image-container"]} image={item.image} />
|
||||
<ArticleText textClass={classNames(styles["article-title"], "truncate-multiline", "truncate-multiline-3")} text={item.title} type="h3" />
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { createContext, useContext } from "react";
|
||||
import { dataSource } from "../data";
|
||||
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
const RTL_LOCALES = ["ar", "he", "fa", "ps", "ur"];
|
||||
const DEFAULT_LANG = "en";
|
||||
const DEFAULT_DIR = "ltr";
|
||||
|
|
@ -16,10 +18,41 @@ export const DataContextProvider = ({ children }) => {
|
|||
document.documentElement.setAttribute("dir", dir);
|
||||
document.documentElement.setAttribute("lang", lang);
|
||||
|
||||
const { content } = dataSource[lang];
|
||||
|
||||
// Generate unique IDs for all articles, and their content items where appropriate.
|
||||
const contentWithIds = Object.create(null);
|
||||
Object.keys(content).forEach((key) => {
|
||||
const { sections } = content[key];
|
||||
|
||||
const currentSections = sections.map((section) => {
|
||||
const currentSection = { ...section };
|
||||
currentSection.articles = section.articles.map((article) => {
|
||||
const currentArticle = { ...article };
|
||||
currentArticle.id = uuidv4();
|
||||
if (Array.isArray(article.content)) {
|
||||
currentArticle.content = article.content.map((item) => {
|
||||
const currentItem = { ...item };
|
||||
currentItem.id = uuidv4();
|
||||
return currentItem;
|
||||
});
|
||||
}
|
||||
return currentArticle;
|
||||
});
|
||||
return currentSection;
|
||||
});
|
||||
|
||||
contentWithIds[key] = {
|
||||
...content[key],
|
||||
sections: currentSections,
|
||||
};
|
||||
});
|
||||
|
||||
const value = {
|
||||
lang,
|
||||
dir,
|
||||
...dataSource[lang],
|
||||
content: contentWithIds,
|
||||
};
|
||||
|
||||
return <DataContext.Provider value={value}>{children}</DataContext.Provider>;
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ export default function App() {
|
|||
<DataContextProvider>
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/business" element={<Page id="business" />} />
|
||||
<Route path="/health" element={<Page id="health" />} />
|
||||
<Route path="/opinion" element={<Page id="opinion" />} />
|
||||
<Route path="/politics" element={<Page id="politics" />} />
|
||||
<Route path="/us" element={<Page id="us" />} />
|
||||
<Route path="/world" element={<Page id="world" />} />
|
||||
<Route path="/home" element={<Page id="home" />} />
|
||||
<Route path="/" element={<Page id="home" />} />
|
||||
<Route path="/business" element={<Page id="business" key="business" />} />
|
||||
<Route path="/health" element={<Page id="health" key="health" />} />
|
||||
<Route path="/opinion" element={<Page id="opinion" key="opinion" />} />
|
||||
<Route path="/politics" element={<Page id="politics" key="politics" />} />
|
||||
<Route path="/us" element={<Page id="us" key="us" />} />
|
||||
<Route path="/world" element={<Page id="world" key="world" />} />
|
||||
<Route path="/home" element={<Page id="home" key="home" />} />
|
||||
<Route path="/" element={<Page id="home" key="home" />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</DataContextProvider>
|
||||
|
|
|
|||
|
|
@ -13,12 +13,8 @@ import { useDataContext } from "@/context/data-context";
|
|||
import styles from "news-site-css/dist/layout.module.css";
|
||||
|
||||
export default function Layout({ children, id }) {
|
||||
const [showMessage, setShowMessage] = useState(false);
|
||||
const { content, links } = useDataContext();
|
||||
|
||||
useEffect(() => {
|
||||
setShowMessage(content[id].message);
|
||||
}, [id]);
|
||||
const [showMessage, setShowMessage] = useState(Boolean(content[id].message));
|
||||
|
||||
const pageRef = useRef(null);
|
||||
const { pathname } = useLocation();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
import Layout from "@/partials/layout/layout";
|
||||
|
|
@ -8,12 +8,8 @@ import Toast from "@/components/toast/toast";
|
|||
import { useDataContext } from "@/context/data-context";
|
||||
|
||||
export default function Page({ id }) {
|
||||
const [showPortal, setShowPortal] = useState(false);
|
||||
const { content } = useDataContext();
|
||||
|
||||
useEffect(() => {
|
||||
setShowPortal(content[id].notification);
|
||||
}, [id]);
|
||||
const [showPortal, setShowPortal] = useState(Boolean(content[id].notification));
|
||||
|
||||
function closePortal() {
|
||||
setShowPortal(false);
|
||||
|
|
|
|||
119
resources/newssite/news-nuxt/dist/_nuxt/entry.30f4d106.js
vendored
Normal file
119
resources/newssite/news-nuxt/dist/_nuxt/entry.30f4d106.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
resources/newssite/news-nuxt/dist/_nuxt/error-404.f07efa12.js
vendored
Normal file
1
resources/newssite/news-nuxt/dist/_nuxt/error-404.f07efa12.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{a,b as n,o as r,e as d,f as e,t as s,h as l,w as c,i as p,j as f,p as h,k as x}from"./entry.30f4d106.js";const m=t=>(h("data-v-30d2164e"),t=t(),x(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=m(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),_={class:"max-w-520px text-center z-20"},b=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return n({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,v)=>{const i=f;return r(),d("div",u,[g,e("div",_,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,b),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[l(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:c(()=>[p(s(t.backHome),1)]),_:1})])])])}}},z=a(S,[["__scopeId","data-v-30d2164e"]]);export{z as default};
|
||||
1
resources/newssite/news-nuxt/dist/_nuxt/error-500.f207c42f.js
vendored
Normal file
1
resources/newssite/news-nuxt/dist/_nuxt/error-500.f207c42f.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{a as i,b as a,o as r,e as n,f as e,t as s,p as l,k as d}from"./entry.30f4d106.js";const c=t=>(l("data-v-32388612"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},h=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),f={class:"max-w-520px text-center"},g=["textContent"],m=["textContent"],x={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return a({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(b,u)=>(r(),n("div",p,[h,e("div",f,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,g),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,m)])]))}},w=i(x,[["__scopeId","data-v-32388612"]]);export{w as default};
|
||||
3
resources/newssite/news-nuxt/dist/_nuxt/error-component.1bc5c237.js
vendored
Normal file
3
resources/newssite/news-nuxt/dist/_nuxt/error-component.1bc5c237.js
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import{o as m,c as E,n as f,g,u as s,d as n,_ as a}from"./entry.30f4d106.js";const k={__name:"nuxt-error-page",props:{error:Object},setup(c){const u=c,{error:t}=u;(t.stack||"").split(`
|
||||
`).splice(1).map(e=>({text:e.replace("webpack:/","").replace(".vue",".js").trim(),internal:e.includes("node_modules")&&!e.includes(".cache")||e.includes("internal")||e.includes("new Promise")})).map(e=>`<span class="stack${e.internal?" internal":""}">${e.text}</span>`).join(`
|
||||
`);const r=Number(t.statusCode||500),o=r===404,i=t.statusMessage??(o?"Page Not Found":"Internal Server Error"),p=t.message||t.toString(),_=void 0,d=o?n(()=>a(()=>import("./error-404.f07efa12.js"),["./error-404.f07efa12.js","./entry.30f4d106.js","./entry.4163a698.css","./error-404.23f2309d.css"],import.meta.url).then(e=>e.default||e)):n(()=>a(()=>import("./error-500.f207c42f.js"),["./error-500.f207c42f.js","./entry.30f4d106.js","./entry.4163a698.css","./error-500.aa16ed4d.css"],import.meta.url).then(e=>e.default||e));return(e,l)=>(m(),E(s(d),f(g({statusCode:s(r),statusMessage:s(i),description:s(p),stack:s(_)})),null,16))}},h=k;export{h as default};
|
||||
|
|
@ -25,6 +25,16 @@ class Params {
|
|||
// "generate": generate a random seed
|
||||
// <integer>: use the provided integer as a seed
|
||||
shuffleSeed = "off";
|
||||
// Leak iframes to DevTools can display sources.
|
||||
leakyIframes = false;
|
||||
// Emit metrics for the prepare phase.
|
||||
measurePrepare = false;
|
||||
// Use a new subdomain for each iteration to avoid caching.
|
||||
domainPerIteration = false;
|
||||
// Force a gc before every suite (chrome specific)
|
||||
suiteForceGC = false;
|
||||
currentIteration = 0;
|
||||
embedded = false;
|
||||
|
||||
constructor(searchParams = undefined) {
|
||||
if (searchParams)
|
||||
|
|
@ -81,6 +91,18 @@ class Params {
|
|||
this.developerMode = searchParams.has("developerMode");
|
||||
searchParams.delete("developerMode");
|
||||
|
||||
this.measurePrepare = searchParams.has("measurePrepare");
|
||||
searchParams.delete("measurePrepare");
|
||||
|
||||
this.domainPerIteration = searchParams.has("domainPerIteration");
|
||||
searchParams.delete("domainPerIteration");
|
||||
|
||||
this.suiteForceGC = searchParams.has("suiteForceGC");
|
||||
searchParams.delete("suiteForceGC");
|
||||
|
||||
this.currentIteration = searchParams.get("currentIteration") | 0;
|
||||
searchParams.delete("currentIteration");
|
||||
|
||||
if (searchParams.has("useWarmupSuite")) {
|
||||
this.useWarmupSuite = true;
|
||||
searchParams.delete("useWarmupSuite");
|
||||
|
|
@ -122,6 +144,11 @@ class Params {
|
|||
searchParams.delete("shuffleSeed");
|
||||
}
|
||||
|
||||
if (searchParams.has("leakyIframes")) {
|
||||
this.leakyIframes = true;
|
||||
searchParams.delete("leakyIframes");
|
||||
}
|
||||
|
||||
const unused = Array.from(searchParams.keys());
|
||||
if (unused.length > 0)
|
||||
console.error("Got unused search params", unused);
|
||||
|
|
|
|||
|
|
@ -304,6 +304,39 @@ Suites.push({
|
|||
],
|
||||
});
|
||||
|
||||
// Downstream only.
|
||||
Suites.push({
|
||||
name: "TodoMVC-React-Window",
|
||||
url: "todomvc/architecture-examples/react/dist/index-window.html#/home",
|
||||
tags: ["todomvc"],
|
||||
disabled: true,
|
||||
async prepare(page) {
|
||||
await page.targetChildWindow();
|
||||
const element = await page.waitForElement(".new-todo");
|
||||
element.focus();
|
||||
},
|
||||
tests: [
|
||||
new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => {
|
||||
const newTodo = page.querySelector(".new-todo");
|
||||
for (let i = 0; i < numberOfItemsToAdd; i++) {
|
||||
newTodo.setValue(getTodoText(defaultLanguage, i));
|
||||
newTodo.dispatchEvent("input");
|
||||
newTodo.enter("keydown");
|
||||
}
|
||||
}),
|
||||
new BenchmarkTestStep("CompletingAllItems", (page) => {
|
||||
const checkboxes = page.querySelectorAll(".toggle");
|
||||
for (let i = 0; i < numberOfItemsToAdd; i++)
|
||||
checkboxes[i].click();
|
||||
}),
|
||||
new BenchmarkTestStep("DeletingAllItems", (page) => {
|
||||
const deleteButtons = page.querySelectorAll(".destroy");
|
||||
for (let i = numberOfItemsToAdd - 1; i >= 0; i--)
|
||||
deleteButtons[i].click();
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
Suites.push({
|
||||
name: "TodoMVC-React-Redux",
|
||||
url: "todomvc/architecture-examples/react-redux/dist/index.html",
|
||||
|
|
@ -1036,6 +1069,55 @@ Suites.push({
|
|||
],
|
||||
});
|
||||
|
||||
// The WarmupSuite is used to make sure all runner helper functions and
|
||||
// classes are compiled, to avoid unnecessary pauses due to delayed
|
||||
// compilation of runner methods in the middle of the measuring cycle.
|
||||
export const WarmupSuite = {
|
||||
name: "Warmup",
|
||||
url: "warmup/index.html",
|
||||
disabled: true,
|
||||
async prepare(page) {
|
||||
await page.waitForElement("#testItem");
|
||||
},
|
||||
tests: [
|
||||
// Make sure to run ever page.method once at least
|
||||
new BenchmarkTestStep("WarmingUpPageMethods", (page) => {
|
||||
let results = [];
|
||||
results.push(page.querySelector(".testItem"));
|
||||
results.push(page.querySelectorAll(".item"));
|
||||
results.push(page.getElementById("testItem"));
|
||||
}),
|
||||
new BenchmarkTestStep("WarmingUpPageElementMethods", (page) => {
|
||||
const item = page.getElementById("testItem");
|
||||
item.setValue("value");
|
||||
item.click();
|
||||
item.focus();
|
||||
item.dispatchEvent("change");
|
||||
item.enter("keypress");
|
||||
item.dispatchEvent("input");
|
||||
item.enter("keyup");
|
||||
}),
|
||||
new BenchmarkTestStep("WarmingUpPageElementMouseMethods", (page) => {
|
||||
const item = page.getElementById("testItem");
|
||||
const mouseEventOptions = { clientX: 100, clientY: 100, bubbles: true, cancelable: true };
|
||||
const wheelEventOptions = {
|
||||
clientX: 200,
|
||||
clientY: 200,
|
||||
deltaMode: 0,
|
||||
delta: -10,
|
||||
deltaY: -10,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
};
|
||||
item.dispatchEvent("mousedown", mouseEventOptions, MouseEvent);
|
||||
item.dispatchEvent("mousemove", mouseEventOptions, MouseEvent);
|
||||
item.dispatchEvent("mouseup", mouseEventOptions, MouseEvent);
|
||||
item.dispatchEvent("wheel", wheelEventOptions, WheelEvent);
|
||||
}),
|
||||
],
|
||||
};
|
||||
Suites.push(WarmupSuite);
|
||||
|
||||
Object.freeze(Suites);
|
||||
Suites.forEach((suite) => {
|
||||
if (!suite.tags)
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
ie=ce,function(){var e={}.hasOwnProperty;function t(){for(var n=[],_=0;_<arguments.length;_++){var o=arguments[_];if(o){var l=typeof o;if("string"===l||"number"===l)n.push(o);else if(Array.isArray(o)){if(o.length){var r=t.apply(null,o);r&&n.push(r)}}else if("object"===l){if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]")){n.push(o.toString());continue}for(var i in o)e.call(o,i)&&o[i]&&n.push(i)}}}return n.join(" ")}ie.exports?(t.default=t,ie.exports=t):window.classNames=t}();var se=ue;function ae(e){let{onSave:t,onRemove:n,onToggle:_,todo:o,index:l}=e;const[r,i]=G(!1),u=J(null);function c(e){const _=e.target.value.trim();_?(t(o,_),i(!1)):n(o)}return z((()=>{u.current&&(u.current.focus(),u.current.setSelectionRange(u.current.value.length,u.current.value.length))}),[r]),f("li",{class:se({completed:o.completed,editing:r}),"data-priority":4-l%5},f("div",{class:"view"},f("input",{class:"toggle",type:"checkbox",checked:o.completed,onChange:function(e){_(o),e.preventDefault()}}),f("label",{onDblClick:function(){i(!0)}},o.title),f("button",{class:"destroy",onClick:function(){n(o)}})),r?f("div",{class:"input-container"},f("input",{class:"edit",id:"edit-todo-input",ref:u,onBlur:c,onKeyDown:function(e){"Escape"===e.key?i(!1):"Enter"===e.key&&c(e)},defaultValue:o.title}),f("label",{class:"visually-hidden",htmlFor:"edit-todo-input"},"Edit Todo Input"," ")):null)}const fe={all:e=>!0,active:e=>!e.completed,completed:e=>e.completed};function pe(e){let{onChange:t,onToggle:n,onRemove:_,onSave:o,todos:l,route:r}=e;const i=l.filter(fe[r]);return f("main",{class:"main"},f("div",{class:"toggle-all-container"},f("input",{class:"toggle-all",type:"checkbox",checked:0===l.filter(fe.active).length,onChange:t}),f("label",{class:"toggle-all-label",htmlFor:"toggle-all"},"Toggle All Input")),f("ul",{class:"todo-list show-priority"},i.map(((e,t)=>f(ae,{key:e.id,todo:e,onToggle:n,onRemove:_,onSave:o,index:t})))))}function de(e){let{todos:t,route:n,onClearCompleted:_}=e;const o=t.filter((e=>!e.completed)).length,l=t.length-o;return f("footer",{class:"footer"},f("span",{class:"todo-count"},`${o} ${1===o?"item":"items"} left!`),f("ul",{class:"filters"},f("li",null,f("a",{href:"#/",class:se({selected:"all"===n})},"All"))," ",f("li",null,f("a",{href:"#/active",class:se({selected:"active"===n})},"Active"))," ",f("li",null,f("a",{href:"#/completed",class:se({selected:"completed"===n})},"Completed"))),l>0&&f("button",{class:"clear-completed",onClick:_},"Clear completed"))}const he=()=>{let e=String(location.hash||"").split("/").pop();return fe[e]||(e="all"),e};!function(n,_,o){var l,r,u;t.__&&t.__(n,_),r=(l="function"==typeof o)?null:o&&o.__k||_.__k,u=[],T(_,n=(!l&&o||_).__k=f(d,null,[n]),r||i,i,void 0!==_.ownerSVGElement,!l&&o?[o]:r?null:_.firstChild?e.call(_.childNodes):null,u,!l&&o?o:r?r.__e:_.firstChild,l),N(u,n)}(f((function(){const[,e]=G(Date.now()),[t,n]=G("all"),_=function(e){const t=[e];function n(){t.forEach((e=>e()))}return{addItem:function(e){le=le.concat({id:oe(),title:e,completed:!1}),n()},toggleAll:function(e){le=le.map((t=>({...t,completed:e}))),n()},toggleItem:function(e){le=le.map((t=>t!==e?t:{...t,completed:!t.completed})),n()},removeItem:function(e){le=le.filter((t=>t!==e)),n()},updateItem:function(e,t){le=le.map((n=>n!==e?n:{...n,title:t})),n()},clearCompleted:function(){le=le.filter((e=>!e.completed)),n()},getTodos:function(){return[...le]}}}((function(){e(Date.now())}));return z((()=>{function e(){n(he())}addEventListener("hashchange",e),e()}),[]),f(d,null,f(re,{onKeyDown:function(e){if("Enter"===e.key){const t=e.target.value.trim();t&&(_.addItem(t),e.target.value="")}}}),_.getTodos().length>0?f(d,null,f(pe,{todos:_.getTodos(),route:t,onChange:function(e){_.toggleAll(e.target.checked)},onToggle:_.toggleItem,onRemove:_.removeItem,onSave:_.updateItem}),f(de,{todos:_.getTodos(),route:t,onClearCompleted:_.clearCompleted})):null)}),null),document.querySelector(".todoapp"))}();
|
||||
ie=ce,function(){var e={}.hasOwnProperty;function t(){for(var n=[],_=0;_<arguments.length;_++){var o=arguments[_];if(o){var l=typeof o;if("string"===l||"number"===l)n.push(o);else if(Array.isArray(o)){if(o.length){var r=t.apply(null,o);r&&n.push(r)}}else if("object"===l){if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]")){n.push(o.toString());continue}for(var i in o)e.call(o,i)&&o[i]&&n.push(i)}}}return n.join(" ")}ie.exports?(t.default=t,ie.exports=t):window.classNames=t}();var se=ue;function ae(e){let{onSave:t,onRemove:n,onToggle:_,todo:o,index:l}=e;const[r,i]=G(!1),u=J(null);function c(e){const _=e.target.value.trim();_?(t(o,_),i(!1)):n(o)}return z((()=>{u.current&&(u.current.focus(),u.current.setSelectionRange(u.current.value.length,u.current.value.length))}),[r]),f("li",{class:se({completed:o.completed,editing:r}),"data-priority":4-l%5},f("div",{class:"view"},f("input",{class:"toggle",type:"checkbox",checked:o.completed,onChange:function(e){_(o),e.preventDefault()}}),f("label",{onDblClick:function(){i(!0)}},o.title),f("button",{class:"destroy",onClick:function(){n(o)}})),r?f("div",{class:"input-container"},f("input",{class:"edit",id:"edit-todo-input",ref:u,onBlur:c,onKeyDown:function(e){"Escape"===e.key?i(!1):"Enter"===e.key&&c(e)},defaultValue:o.title}),f("label",{class:"visually-hidden",htmlFor:"edit-todo-input"},"Edit Todo Input"," ")):null)}const fe={all:e=>!0,active:e=>!e.completed,completed:e=>e.completed};function pe(e){let{onChange:t,onToggle:n,onRemove:_,onSave:o,todos:l,route:r}=e;const i=l.filter(fe[r]);return f("main",{class:"main"},f("div",{class:"toggle-all-container"},f("input",{class:"toggle-all",type:"checkbox",id:"toggle-all",checked:0===l.filter(fe.active).length,onChange:t}),f("label",{class:"toggle-all-label",htmlFor:"toggle-all"},"Toggle All Input")),f("ul",{class:"todo-list show-priority"},i.map(((e,t)=>f(ae,{key:e.id,todo:e,onToggle:n,onRemove:_,onSave:o,index:t})))))}function de(e){let{todos:t,route:n,onClearCompleted:_}=e;const o=t.filter((e=>!e.completed)).length,l=t.length-o;return f("footer",{class:"footer"},f("span",{class:"todo-count"},`${o} ${1===o?"item":"items"} left!`),f("ul",{class:"filters"},f("li",null,f("a",{href:"#/",class:se({selected:"all"===n})},"All"))," ",f("li",null,f("a",{href:"#/active",class:se({selected:"active"===n})},"Active"))," ",f("li",null,f("a",{href:"#/completed",class:se({selected:"completed"===n})},"Completed"))),l>0&&f("button",{class:"clear-completed",onClick:_},"Clear completed"))}const he=()=>{let e=String(location.hash||"").split("/").pop();return fe[e]||(e="all"),e};!function(n,_,o){var l,r,u;t.__&&t.__(n,_),r=(l="function"==typeof o)?null:o&&o.__k||_.__k,u=[],T(_,n=(!l&&o||_).__k=f(d,null,[n]),r||i,i,void 0!==_.ownerSVGElement,!l&&o?[o]:r?null:_.firstChild?e.call(_.childNodes):null,u,!l&&o?o:r?r.__e:_.firstChild,l),N(u,n)}(f((function(){const[,e]=G(Date.now()),[t,n]=G("all"),_=function(e){const t=[e];function n(){t.forEach((e=>e()))}return{addItem:function(e){le=le.concat({id:oe(),title:e,completed:!1}),n()},toggleAll:function(e){le=le.map((t=>({...t,completed:e}))),n()},toggleItem:function(e){le=le.map((t=>t!==e?t:{...t,completed:!t.completed})),n()},removeItem:function(e){le=le.filter((t=>t!==e)),n()},updateItem:function(e,t){le=le.map((n=>n!==e?n:{...n,title:t})),n()},clearCompleted:function(){le=le.filter((e=>!e.completed)),n()},getTodos:function(){return[...le]}}}((function(){e(Date.now())}));return z((()=>{function e(){n(he())}addEventListener("hashchange",e),e()}),[]),f(d,null,f(re,{onKeyDown:function(e){if("Enter"===e.key){const t=e.target.value.trim();t&&(_.addItem(t),e.target.value="")}}}),_.getTodos().length>0?f(d,null,f(pe,{todos:_.getTodos(),route:t,onChange:function(e){_.toggleAll(e.target.checked)},onToggle:_.toggleItem,onRemove:_.removeItem,onSave:_.updateItem}),f(de,{todos:_.getTodos(),route:t,onClearCompleted:_.clearCompleted})):null)}),null),document.querySelector(".todoapp"))}();
|
||||
//# sourceMappingURL=app.js.map
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -4,5 +4,5 @@
|
|||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
ie=ce,function(){var e={}.hasOwnProperty;function t(){for(var n=[],_=0;_<arguments.length;_++){var o=arguments[_];if(o){var l=typeof o;if("string"===l||"number"===l)n.push(o);else if(Array.isArray(o)){if(o.length){var r=t.apply(null,o);r&&n.push(r)}}else if("object"===l){if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]")){n.push(o.toString());continue}for(var i in o)e.call(o,i)&&o[i]&&n.push(i)}}}return n.join(" ")}ie.exports?(t.default=t,ie.exports=t):window.classNames=t}();var se=ue;function ae(e){let{onSave:t,onRemove:n,onToggle:_,todo:o,index:l}=e;const[r,i]=G(!1),u=J(null);function c(e){const _=e.target.value.trim();_?(t(o,_),i(!1)):n(o)}return z((()=>{u.current&&(u.current.focus(),u.current.setSelectionRange(u.current.value.length,u.current.value.length))}),[r]),f("li",{class:se({completed:o.completed,editing:r}),"data-priority":4-l%5},f("div",{class:"view"},f("input",{class:"toggle",type:"checkbox",checked:o.completed,onChange:function(e){_(o),e.preventDefault()}}),f("label",{onDblClick:function(){i(!0)}},o.title),f("button",{class:"destroy",onClick:function(){n(o)}})),r?f("div",{class:"input-container"},f("input",{class:"edit",id:"edit-todo-input",ref:u,onBlur:c,onKeyDown:function(e){"Escape"===e.key?i(!1):"Enter"===e.key&&c(e)},defaultValue:o.title}),f("label",{class:"visually-hidden",htmlFor:"edit-todo-input"},"Edit Todo Input"," ")):null)}const fe={all:e=>!0,active:e=>!e.completed,completed:e=>e.completed};function pe(e){let{onChange:t,onToggle:n,onRemove:_,onSave:o,todos:l,route:r}=e;const i=l.filter(fe[r]);return f("main",{class:"main"},f("div",{class:"toggle-all-container"},f("input",{class:"toggle-all",type:"checkbox",checked:0===l.filter(fe.active).length,onChange:t}),f("label",{class:"toggle-all-label",htmlFor:"toggle-all"},"Toggle All Input")),f("ul",{class:"todo-list show-priority"},i.map(((e,t)=>f(ae,{key:e.id,todo:e,onToggle:n,onRemove:_,onSave:o,index:t})))))}function de(e){let{todos:t,route:n,onClearCompleted:_}=e;const o=t.filter((e=>!e.completed)).length,l=t.length-o;return f("footer",{class:"footer"},f("span",{class:"todo-count"},`${o} ${1===o?"item":"items"} left!`),f("ul",{class:"filters"},f("li",null,f("a",{href:"#/",class:se({selected:"all"===n})},"All"))," ",f("li",null,f("a",{href:"#/active",class:se({selected:"active"===n})},"Active"))," ",f("li",null,f("a",{href:"#/completed",class:se({selected:"completed"===n})},"Completed"))),l>0&&f("button",{class:"clear-completed",onClick:_},"Clear completed"))}const he=()=>{let e=String(location.hash||"").split("/").pop();return fe[e]||(e="all"),e};!function(n,_,o){var l,r,u;t.__&&t.__(n,_),r=(l="function"==typeof o)?null:o&&o.__k||_.__k,u=[],T(_,n=(!l&&o||_).__k=f(d,null,[n]),r||i,i,void 0!==_.ownerSVGElement,!l&&o?[o]:r?null:_.firstChild?e.call(_.childNodes):null,u,!l&&o?o:r?r.__e:_.firstChild,l),N(u,n)}(f((function(){const[,e]=G(Date.now()),[t,n]=G("all"),_=function(e){const t=[e];function n(){t.forEach((e=>e()))}return{addItem:function(e){le=le.concat({id:oe(),title:e,completed:!1}),n()},toggleAll:function(e){le=le.map((t=>({...t,completed:e}))),n()},toggleItem:function(e){le=le.map((t=>t!==e?t:{...t,completed:!t.completed})),n()},removeItem:function(e){le=le.filter((t=>t!==e)),n()},updateItem:function(e,t){le=le.map((n=>n!==e?n:{...n,title:t})),n()},clearCompleted:function(){le=le.filter((e=>!e.completed)),n()},getTodos:function(){return[...le]}}}((function(){e(Date.now())}));return z((()=>{function e(){n(he())}addEventListener("hashchange",e),e()}),[]),f(d,null,f(re,{onKeyDown:function(e){if("Enter"===e.key){const t=e.target.value.trim();t&&(_.addItem(t),e.target.value="")}}}),_.getTodos().length>0?f(d,null,f(pe,{todos:_.getTodos(),route:t,onChange:function(e){_.toggleAll(e.target.checked)},onToggle:_.toggleItem,onRemove:_.removeItem,onSave:_.updateItem}),f(de,{todos:_.getTodos(),route:t,onClearCompleted:_.clearCompleted})):null)}),null),document.querySelector(".todoapp"))}();
|
||||
ie=ce,function(){var e={}.hasOwnProperty;function t(){for(var n=[],_=0;_<arguments.length;_++){var o=arguments[_];if(o){var l=typeof o;if("string"===l||"number"===l)n.push(o);else if(Array.isArray(o)){if(o.length){var r=t.apply(null,o);r&&n.push(r)}}else if("object"===l){if(o.toString!==Object.prototype.toString&&!o.toString.toString().includes("[native code]")){n.push(o.toString());continue}for(var i in o)e.call(o,i)&&o[i]&&n.push(i)}}}return n.join(" ")}ie.exports?(t.default=t,ie.exports=t):window.classNames=t}();var se=ue;function ae(e){let{onSave:t,onRemove:n,onToggle:_,todo:o,index:l}=e;const[r,i]=G(!1),u=J(null);function c(e){const _=e.target.value.trim();_?(t(o,_),i(!1)):n(o)}return z((()=>{u.current&&(u.current.focus(),u.current.setSelectionRange(u.current.value.length,u.current.value.length))}),[r]),f("li",{class:se({completed:o.completed,editing:r}),"data-priority":4-l%5},f("div",{class:"view"},f("input",{class:"toggle",type:"checkbox",checked:o.completed,onChange:function(e){_(o),e.preventDefault()}}),f("label",{onDblClick:function(){i(!0)}},o.title),f("button",{class:"destroy",onClick:function(){n(o)}})),r?f("div",{class:"input-container"},f("input",{class:"edit",id:"edit-todo-input",ref:u,onBlur:c,onKeyDown:function(e){"Escape"===e.key?i(!1):"Enter"===e.key&&c(e)},defaultValue:o.title}),f("label",{class:"visually-hidden",htmlFor:"edit-todo-input"},"Edit Todo Input"," ")):null)}const fe={all:e=>!0,active:e=>!e.completed,completed:e=>e.completed};function pe(e){let{onChange:t,onToggle:n,onRemove:_,onSave:o,todos:l,route:r}=e;const i=l.filter(fe[r]);return f("main",{class:"main"},f("div",{class:"toggle-all-container"},f("input",{class:"toggle-all",type:"checkbox",id:"toggle-all",checked:0===l.filter(fe.active).length,onChange:t}),f("label",{class:"toggle-all-label",htmlFor:"toggle-all"},"Toggle All Input")),f("ul",{class:"todo-list show-priority"},i.map(((e,t)=>f(ae,{key:e.id,todo:e,onToggle:n,onRemove:_,onSave:o,index:t})))))}function de(e){let{todos:t,route:n,onClearCompleted:_}=e;const o=t.filter((e=>!e.completed)).length,l=t.length-o;return f("footer",{class:"footer"},f("span",{class:"todo-count"},`${o} ${1===o?"item":"items"} left!`),f("ul",{class:"filters"},f("li",null,f("a",{href:"#/",class:se({selected:"all"===n})},"All"))," ",f("li",null,f("a",{href:"#/active",class:se({selected:"active"===n})},"Active"))," ",f("li",null,f("a",{href:"#/completed",class:se({selected:"completed"===n})},"Completed"))),l>0&&f("button",{class:"clear-completed",onClick:_},"Clear completed"))}const he=()=>{let e=String(location.hash||"").split("/").pop();return fe[e]||(e="all"),e};!function(n,_,o){var l,r,u;t.__&&t.__(n,_),r=(l="function"==typeof o)?null:o&&o.__k||_.__k,u=[],T(_,n=(!l&&o||_).__k=f(d,null,[n]),r||i,i,void 0!==_.ownerSVGElement,!l&&o?[o]:r?null:_.firstChild?e.call(_.childNodes):null,u,!l&&o?o:r?r.__e:_.firstChild,l),N(u,n)}(f((function(){const[,e]=G(Date.now()),[t,n]=G("all"),_=function(e){const t=[e];function n(){t.forEach((e=>e()))}return{addItem:function(e){le=le.concat({id:oe(),title:e,completed:!1}),n()},toggleAll:function(e){le=le.map((t=>({...t,completed:e}))),n()},toggleItem:function(e){le=le.map((t=>t!==e?t:{...t,completed:!t.completed})),n()},removeItem:function(e){le=le.filter((t=>t!==e)),n()},updateItem:function(e,t){le=le.map((n=>n!==e?n:{...n,title:t})),n()},clearCompleted:function(){le=le.filter((e=>!e.completed)),n()},getTodos:function(){return[...le]}}}((function(){e(Date.now())}));return z((()=>{function e(){n(he())}addEventListener("hashchange",e),e()}),[]),f(d,null,f(re,{onKeyDown:function(e){if("Enter"===e.key){const t=e.target.value.trim();t&&(_.addItem(t),e.target.value="")}}}),_.getTodos().length>0?f(d,null,f(pe,{todos:_.getTodos(),route:t,onChange:function(e){_.toggleAll(e.target.checked)},onToggle:_.toggleItem,onRemove:_.removeItem,onSave:_.updateItem}),f(de,{todos:_.getTodos(),route:t,onClearCompleted:_.clearCompleted})):null)}),null),document.querySelector(".todoapp"))}();
|
||||
//# sourceMappingURL=app.js.map
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -10,7 +10,7 @@ export default function TodoMain({ onChange, onToggle, onRemove, onSave, todos,
|
|||
return (
|
||||
<main class="main">
|
||||
<div class="toggle-all-container">
|
||||
<input class="toggle-all" type="checkbox" checked={activeTodoCount === 0} onChange={onChange} />
|
||||
<input class="toggle-all" type="checkbox" id="toggle-all" checked={activeTodoCount === 0} onChange={onChange} />
|
||||
<label class="toggle-all-label" htmlFor="toggle-all">
|
||||
Toggle All Input
|
||||
</label>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -26,7 +26,7 @@ export default class Main extends Component {
|
|||
return (
|
||||
<main className="main" data-testid="main">
|
||||
<div className="toggle-all-container">
|
||||
<input className="toggle-all" type="checkbox" data-testid="toggle-all" checked={completedCount === todos.length} onChange={toggleAll} />
|
||||
<input className="toggle-all" type="checkbox" id="toggle-all" data-testid="toggle-all" checked={completedCount === todos.length} onChange={toggleAll} />
|
||||
<label className="toggle-all-label" htmlFor="toggle-all">
|
||||
Toggle All Input
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ This application uses React 17.0.2 to implement a todo application.
|
|||
|
||||
- [React](https://reactjs.org/) is a JavaScript library for creating user interfaces.
|
||||
|
||||
The downstream version also generates the TodoMVC-React-Window workload. A variation of TodoMVC-React that renders and controls the app in a new window using the scripts loaded in the parent window.
|
||||
|
||||
## Implementation details
|
||||
|
||||
React:\
|
||||
|
|
@ -22,6 +24,8 @@ Controller: serves as an interface between view & model components
|
|||
|
||||
To build the static files, this application utilizes webpack. It minifies and optimizes output files and copies all necessary files to a `dist` folder.
|
||||
|
||||
For TodoMVC-React-Window, the webpack scripts separate the JavaScript from the CSS. The JavaScript is loaded by index.html in the main window, while the css is loaded by todo.html in the child window.
|
||||
|
||||
## Requirements
|
||||
|
||||
The only requirement is an installation of Node, to be able to install dependencies and run scripts to serve a local server.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
resources/todomvc/architecture-examples/react/dist/index-window.html
vendored
Normal file
1
resources/todomvc/architecture-examples/react/dist/index-window.html
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<!doctype html><html lang="en" data-framework="react" data-version="17.0.2" data-features=""><head><meta charset="UTF-8"/><meta name="description" content="A TodoMVC workload app for Speedometer!"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta http-equiv="X-UA-Compatible" content="ie=edge"/><title>TodoMVC: React-Window</title><script defer="defer" src="windowed.bundle.js"></script></head></html>
|
||||
1
resources/todomvc/architecture-examples/react/dist/todo.html
vendored
Normal file
1
resources/todomvc/architecture-examples/react/dist/todo.html
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<!doctype html><html lang="en" data-framework="react" data-version="17.0.2" data-features=""><head><meta charset="UTF-8"/><meta name="description" content="A TodoMVC workload app for Speedometer!"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta http-equiv="X-UA-Compatible" content="ie=edge"/><link href="windowed.css" rel="stylesheet"><title>TodoMVC: React-Window inner window</title></head><body><section class="todoapp" id="root"></section><footer class="info"><p>Click on input field to write your todo.</p><p>At least two characters are needed to be a valid entry.</p><p>Press 'enter' to add the todo.</p><p>Double-click to edit a todo</p></footer></body></html>
|
||||
3
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js
vendored
Normal file
3
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js
vendored
Normal file
File diff suppressed because one or more lines are too long
69
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js.LICENSE.txt
vendored
Normal file
69
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js.LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/**
|
||||
* @remix-run/router v1.3.3
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* React Router v6.8.2
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE.md file in the root directory of this source tree.
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v0.20.2
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
1
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js.map
vendored
Normal file
1
resources/todomvc/architecture-examples/react/dist/windowed.bundle.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
resources/todomvc/architecture-examples/react/dist/windowed.css
vendored
Normal file
2
resources/todomvc/architecture-examples/react/dist/windowed.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
resources/todomvc/architecture-examples/react/dist/windowed.css.map
vendored
Normal file
1
resources/todomvc/architecture-examples/react/dist/windowed.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" data-framework="react" data-version="17.0.2" data-features="">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="A TodoMVC workload app for Speedometer!" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>TodoMVC: React-Window</title>
|
||||
<script defer="defer" src=<%= htmlWebpackPlugin.options.script %> ></script>
|
||||
</head>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" data-framework="react" data-version="17.0.2" data-features="">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="A TodoMVC workload app for Speedometer!" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<link href=<%= htmlWebpackPlugin.options.styles %> rel="stylesheet">
|
||||
<title>TodoMVC: React-Window inner window</title>
|
||||
</head>
|
||||
<body>
|
||||
<section class="todoapp" id="root"></section>
|
||||
<footer class="info">
|
||||
<p>Click on input field to write your todo.</p>
|
||||
<p>At least two characters are needed to be a valid entry.</p>
|
||||
<p>Press 'enter' to add the todo.</p>
|
||||
<p>Double-click to edit a todo</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react";
|
||||
import { render } from "react-dom";
|
||||
import { HashRouter, Route, Routes } from "react-router-dom";
|
||||
|
||||
import { App } from "./todo/app";
|
||||
import "todomvc-app-css/index.css";
|
||||
|
||||
let childWindow = window.open("todo.html", "_blank", "width=800,height=600");
|
||||
|
||||
let AsyncLoop = () => {
|
||||
if (childWindow.document.getElementById("root")) {
|
||||
render(
|
||||
<HashRouter>
|
||||
<Routes>
|
||||
<Route path="*" element={<App />} />
|
||||
</Routes>
|
||||
</HashRouter>,
|
||||
childWindow.document.getElementById("root")
|
||||
);
|
||||
globalThis.childWindow = childWindow;
|
||||
} else {
|
||||
setTimeout(AsyncLoop, 10);
|
||||
}
|
||||
};
|
||||
|
||||
AsyncLoop();
|
||||
|
|
@ -27,7 +27,7 @@ export function Main({ todos, dispatch }) {
|
|||
<main className="main" data-testid="main">
|
||||
{visibleTodos.length > 0 ? (
|
||||
<div className="toggle-all-container">
|
||||
<input className="toggle-all" type="checkbox" data-testid="toggle-all" checked={visibleTodos.every((todo) => todo.completed)} onChange={toggleAll} />
|
||||
<input className="toggle-all" type="checkbox" id="toggle-all" data-testid="toggle-all" checked={visibleTodos.every((todo) => todo.completed)} onChange={toggleAll} />
|
||||
<label className="toggle-all-label" htmlFor="toggle-all">
|
||||
Toggle All Input
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -4,12 +4,28 @@ const path = require("path");
|
|||
module.exports = {
|
||||
entry: {
|
||||
app: path.resolve(__dirname, "src", "index.js"),
|
||||
windowed: path.resolve(__dirname, "src", "index-window.js"),
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
title: "TodoMVC: React",
|
||||
chunks: ["app"],
|
||||
template: path.resolve(__dirname, "public", "index.html"),
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
title: "TodoMVC: React-Window",
|
||||
inject: false,
|
||||
template: path.resolve(__dirname, "public", "window", "index.html"),
|
||||
filename: "index-window.html",
|
||||
script: "windowed.bundle.js",
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
title: "TodoMVC: React-Window inner window",
|
||||
inject: false,
|
||||
template: path.resolve(__dirname, "public", "window", "todo.html"),
|
||||
filename: "todo.html",
|
||||
styles: "windowed.css",
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: "[name].bundle.js",
|
||||
|
|
|
|||
Loading…
Reference in a new issue