зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
c7183440fe
|
@ -78,7 +78,9 @@
|
|||
<link rel="localization" href="preview/firefoxSuggest.ftl"/>
|
||||
<link rel="localization" href="browser/toolbarContextMenu.ftl"/>
|
||||
<link rel="localization" href="browser/screenshots.ftl"/>
|
||||
#ifdef NIGHTLY_BUILD
|
||||
<link rel="localization" href="preview/firefoxView.ftl"/>
|
||||
#endif
|
||||
|
||||
<title data-l10n-id="browser-main-window-title"></title>
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ skip-if =
|
|||
[browser_navigator.js]
|
||||
https_first_disabled = true
|
||||
skip-if =
|
||||
os == "win" && debug && bits == 32 # fails on win10-32/debug
|
||||
os == "win" && bits == 32 # fails on win10-32
|
||||
[browser_netInfo.js]
|
||||
https_first_disabled = true
|
||||
[browser_performanceAPI.js]
|
||||
|
|
|
@ -8,7 +8,13 @@ class PictureInPictureVideoWrapper {
|
|||
constructor() {
|
||||
let netflixPlayerAPI = window.wrappedJSObject.netflix.appContext.state.playerApp.getAPI()
|
||||
.videoPlayer;
|
||||
let sessionId = netflixPlayerAPI.getAllPlayerSessionIds()[0];
|
||||
let sessionId = null;
|
||||
for (let id of netflixPlayerAPI.getAllPlayerSessionIds()) {
|
||||
if (id.startsWith("watch-")) {
|
||||
sessionId = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.player = netflixPlayerAPI.getVideoPlayerBySessionId(sessionId);
|
||||
}
|
||||
play() {
|
||||
|
|
|
@ -68,6 +68,8 @@
|
|||
"talos/tests/perf-reftest-singletons/style-attr-1.html",
|
||||
"talos/tests/perf-reftest-singletons/style-sharing-style-attr.html",
|
||||
"talos/tests/perf-reftest-singletons/style-sharing.html",
|
||||
"talos/tests/perf-reftest-singletons/svg-text-textLength-1.html",
|
||||
"talos/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html",
|
||||
"talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html",
|
||||
"talos/tests/perf-reftest-singletons/window-named-property-get.html",
|
||||
"webkit/PerformanceTests/Speedometer/index.html",
|
||||
|
|
|
@ -409,21 +409,26 @@ bool gfxTextRun::GetAdjustedSpacingArray(
|
|||
return true;
|
||||
}
|
||||
|
||||
void gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange) const {
|
||||
if (aRange->start >= aRange->end) return;
|
||||
bool gfxTextRun::ShrinkToLigatureBoundaries(Range* aRange) const {
|
||||
if (aRange->start >= aRange->end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const CompressedGlyph* charGlyphs = mCharacterGlyphs;
|
||||
|
||||
bool adjusted = false;
|
||||
while (aRange->start < aRange->end &&
|
||||
!charGlyphs[aRange->start].IsLigatureGroupStart()) {
|
||||
++aRange->start;
|
||||
adjusted = true;
|
||||
}
|
||||
if (aRange->end < GetLength()) {
|
||||
while (aRange->end > aRange->start &&
|
||||
!charGlyphs[aRange->end].IsLigatureGroupStart()) {
|
||||
--aRange->end;
|
||||
adjusted = true;
|
||||
}
|
||||
}
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
void gfxTextRun::DrawGlyphs(gfxFont* aFont, Range aRange, gfx::Point* aPt,
|
||||
|
@ -669,11 +674,12 @@ void gfxTextRun::Draw(const Range aRange, const gfx::Point aPt,
|
|||
}
|
||||
|
||||
Range ligatureRange(runRange);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
bool adjusted = ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
bool drawPartial =
|
||||
(aParams.drawMode & (DrawMode::GLYPH_FILL | DrawMode::GLYPH_STROKE)) ||
|
||||
(aParams.drawMode == DrawMode::GLYPH_PATH && aParams.callbacks);
|
||||
adjusted &&
|
||||
((aParams.drawMode & (DrawMode::GLYPH_FILL | DrawMode::GLYPH_STROKE)) ||
|
||||
(aParams.drawMode == DrawMode::GLYPH_PATH && aParams.callbacks));
|
||||
gfx::Point origPt = pt;
|
||||
|
||||
if (drawPartial) {
|
||||
|
@ -731,11 +737,13 @@ void gfxTextRun::DrawEmphasisMarks(gfxContext* aContext, gfxTextRun* aMark,
|
|||
uint32_t start = iter.GetStringStart();
|
||||
uint32_t end = iter.GetStringEnd();
|
||||
Range ligatureRange(start, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
bool adjusted = ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
inlineCoord +=
|
||||
direction * ComputePartialLigatureWidth(
|
||||
Range(start, ligatureRange.start), aProvider);
|
||||
if (adjusted) {
|
||||
inlineCoord +=
|
||||
direction * ComputePartialLigatureWidth(
|
||||
Range(start, ligatureRange.start), aProvider);
|
||||
}
|
||||
|
||||
AutoTArray<PropertyProvider::Spacing, 200> spacingBuffer;
|
||||
bool haveSpacing = GetAdjustedSpacingArray(ligatureRange, aProvider,
|
||||
|
@ -744,8 +752,10 @@ void gfxTextRun::DrawEmphasisMarks(gfxContext* aContext, gfxTextRun* aMark,
|
|||
font->DrawEmphasisMarks(this, &aPt, ligatureRange.start,
|
||||
ligatureRange.Length(), params);
|
||||
|
||||
inlineCoord += direction * ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, end), aProvider);
|
||||
if (adjusted) {
|
||||
inlineCoord += direction * ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, end), aProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,12 +820,14 @@ gfxTextRun::Metrics gfxTextRun::MeasureText(
|
|||
uint32_t start = iter.GetStringStart();
|
||||
uint32_t end = iter.GetStringEnd();
|
||||
Range ligatureRange(start, end);
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
bool adjusted = ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(start, ligatureRange.start), aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider, iter.GetGlyphRun()->mOrientation,
|
||||
&accumulatedMetrics);
|
||||
if (adjusted) {
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(start, ligatureRange.start), aBoundingBoxType,
|
||||
aRefDrawTarget, aProvider, iter.GetGlyphRun()->mOrientation,
|
||||
&accumulatedMetrics);
|
||||
}
|
||||
|
||||
// XXX This sucks. We have to get glyph extents just so we can detect
|
||||
// glyphs outside the font box, even when aBoundingBoxType is LOOSE,
|
||||
|
@ -826,14 +838,31 @@ gfxTextRun::Metrics gfxTextRun::MeasureText(
|
|||
font, ligatureRange, aBoundingBoxType, aRefDrawTarget, aProvider,
|
||||
ligatureRange, iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(ligatureRange.end, end), aBoundingBoxType, aRefDrawTarget,
|
||||
aProvider, iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
if (adjusted) {
|
||||
AccumulatePartialLigatureMetrics(
|
||||
font, Range(ligatureRange.end, end), aBoundingBoxType, aRefDrawTarget,
|
||||
aProvider, iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
return accumulatedMetrics;
|
||||
}
|
||||
|
||||
void gfxTextRun::GetLineHeightMetrics(Range aRange, gfxFloat& aAscent,
|
||||
gfxFloat& aDescent) const {
|
||||
Metrics accumulatedMetrics;
|
||||
GlyphRunIterator iter(this, aRange);
|
||||
while (iter.NextRun()) {
|
||||
gfxFont* font = iter.GetGlyphRun()->mFont;
|
||||
auto metrics =
|
||||
font->Measure(this, 0, 0, gfxFont::LOOSE_INK_EXTENTS, nullptr, nullptr,
|
||||
iter.GetGlyphRun()->mOrientation);
|
||||
accumulatedMetrics.CombineWith(metrics, false);
|
||||
}
|
||||
aAscent = accumulatedMetrics.mAscent;
|
||||
aDescent = accumulatedMetrics.mDescent;
|
||||
}
|
||||
|
||||
#define MEASUREMENT_BUFFER_SIZE 100
|
||||
|
||||
void gfxTextRun::ClassifyAutoHyphenations(uint32_t aStart, Range aRange,
|
||||
|
@ -1192,12 +1221,14 @@ gfxFloat gfxTextRun::GetAdvanceWidth(
|
|||
NS_ASSERTION(aRange.end <= GetLength(), "Substring out of range");
|
||||
|
||||
Range ligatureRange = aRange;
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
bool adjusted = ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
gfxFloat result = ComputePartialLigatureWidth(
|
||||
Range(aRange.start, ligatureRange.start), aProvider) +
|
||||
ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, aRange.end), aProvider);
|
||||
gfxFloat result =
|
||||
adjusted ? ComputePartialLigatureWidth(
|
||||
Range(aRange.start, ligatureRange.start), aProvider) +
|
||||
ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, aRange.end), aProvider)
|
||||
: 0.0;
|
||||
|
||||
if (aSpacing) {
|
||||
aSpacing->mBefore = aSpacing->mAfter = 0;
|
||||
|
@ -1229,13 +1260,15 @@ gfxFloat gfxTextRun::GetMinAdvanceWidth(Range aRange) {
|
|||
MOZ_ASSERT(aRange.end <= GetLength(), "Substring out of range");
|
||||
|
||||
Range ligatureRange = aRange;
|
||||
ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
bool adjusted = ShrinkToLigatureBoundaries(&ligatureRange);
|
||||
|
||||
gfxFloat result =
|
||||
std::max(ComputePartialLigatureWidth(
|
||||
Range(aRange.start, ligatureRange.start), nullptr),
|
||||
ComputePartialLigatureWidth(Range(ligatureRange.end, aRange.end),
|
||||
nullptr));
|
||||
adjusted
|
||||
? std::max(ComputePartialLigatureWidth(
|
||||
Range(aRange.start, ligatureRange.start), nullptr),
|
||||
ComputePartialLigatureWidth(
|
||||
Range(ligatureRange.end, aRange.end), nullptr))
|
||||
: 0.0;
|
||||
|
||||
// Compute min advance width by assuming each grapheme cluster takes its own
|
||||
// line.
|
||||
|
|
|
@ -312,6 +312,12 @@ class gfxTextRun : public gfxShapedText {
|
|||
aDrawTargetForTightBoundingBox, aProvider);
|
||||
}
|
||||
|
||||
void GetLineHeightMetrics(Range aRange, gfxFloat& aAscent,
|
||||
gfxFloat& aDescent) const;
|
||||
void GetLineHeightMetrics(gfxFloat& aAscent, gfxFloat& aDescent) const {
|
||||
GetLineHeightMetrics(Range(this), aAscent, aDescent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes just the advance width for a substring.
|
||||
* Uses GetSpacing from aBreakProvider.
|
||||
|
@ -828,7 +834,8 @@ class gfxTextRun : public gfxShapedText {
|
|||
// Advance aRange.start to the start of the nearest ligature, back
|
||||
// up aRange.end to the nearest ligature end; may result in
|
||||
// aRange->start == aRange->end.
|
||||
void ShrinkToLigatureBoundaries(Range* aRange) const;
|
||||
// Returns whether any adjustment was made.
|
||||
bool ShrinkToLigatureBoundaries(Range* aRange) const;
|
||||
// result in appunits
|
||||
gfxFloat GetPartialLigatureWidth(Range aRange,
|
||||
PropertyProvider* aProvider) const;
|
||||
|
|
|
@ -477,7 +477,10 @@ void Decoder::PostFrameStop(Opacity aFrameOpacity) {
|
|||
mInFrame = false;
|
||||
mFinishedNewFrame = true;
|
||||
|
||||
mCurrentFrame->Finish(aFrameOpacity, mFinalizeFrames);
|
||||
mCurrentFrame->Finish(
|
||||
aFrameOpacity, mFinalizeFrames,
|
||||
/* aOrientationSwapsWidthAndHeight = */ mImageMetadata.HasOrientation() &&
|
||||
mImageMetadata.GetOrientation().SwapsWidthAndHeight());
|
||||
|
||||
mProgress |= FLAG_FRAME_COMPLETE;
|
||||
|
||||
|
|
|
@ -522,23 +522,39 @@ nsresult imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect) {
|
|||
}
|
||||
|
||||
void imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */,
|
||||
bool aFinalize /* = true */) {
|
||||
bool aFinalize /* = true */,
|
||||
bool aOrientationSwapsWidthAndHeight /* = false */) {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
IntRect frameRect(GetRect());
|
||||
if (!mDecoded.IsEqualEdges(frameRect)) {
|
||||
// The decoder should have produced rows starting from either the bottom or
|
||||
// the top of the image. We need to calculate the region for which we have
|
||||
// not yet invalidated.
|
||||
// not yet invalidated. And if the orientation swaps width and height then
|
||||
// its from the left or right.
|
||||
IntRect delta(0, 0, frameRect.width, 0);
|
||||
if (mDecoded.y == 0) {
|
||||
delta.y = mDecoded.height;
|
||||
delta.height = frameRect.height - mDecoded.height;
|
||||
} else if (mDecoded.y + mDecoded.height == frameRect.height) {
|
||||
delta.height = frameRect.height - mDecoded.y;
|
||||
if (!aOrientationSwapsWidthAndHeight) {
|
||||
delta.width = frameRect.width;
|
||||
if (mDecoded.y == 0) {
|
||||
delta.y = mDecoded.height;
|
||||
delta.height = frameRect.height - mDecoded.height;
|
||||
} else if (mDecoded.y + mDecoded.height == frameRect.height) {
|
||||
delta.height = frameRect.height - mDecoded.y;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
|
||||
delta = frameRect;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
|
||||
delta = frameRect;
|
||||
delta.height = frameRect.height;
|
||||
if (mDecoded.x == 0) {
|
||||
delta.x = mDecoded.width;
|
||||
delta.width = frameRect.width - mDecoded.width;
|
||||
} else if (mDecoded.x + mDecoded.width == frameRect.width) {
|
||||
delta.width = frameRect.width - mDecoded.x;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Decoder only updated middle of image!");
|
||||
delta = frameRect;
|
||||
}
|
||||
}
|
||||
|
||||
ImageUpdatedInternal(delta);
|
||||
|
|
|
@ -109,7 +109,8 @@ class imgFrame {
|
|||
* may be marked as read only if possible).
|
||||
*/
|
||||
void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY,
|
||||
bool aFinalize = true);
|
||||
bool aFinalize = true,
|
||||
bool aOrientationSwapsWidthAndHeight = false);
|
||||
|
||||
/**
|
||||
* Mark this imgFrame as aborted. This informs the imgFrame that if it isn't
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 6.7 KiB |
|
@ -68,3 +68,4 @@ HTTP load 1634839-1.html
|
|||
HTTP load 1634839-2.html
|
||||
pref(image.animated.decode-on-demand.batch-size,1) pref(image.animated.decode-on-demand.threshold-kb,0) HTTP load 1676172-1.html
|
||||
pref(browser.soft_reload.only_force_validate_top_level_document,false) HTTP load 1763581-1.html
|
||||
load 1765871-1.jpg
|
||||
|
|
|
@ -126,13 +126,7 @@ static void GetAscentAndDescentInAppUnits(nsTextFrame* aFrame,
|
|||
gfxTextRun::Range range = ConvertOriginalToSkipped(
|
||||
it, aFrame->GetContentOffset(), aFrame->GetContentLength());
|
||||
|
||||
// We pass in null for the PropertyProvider since letter-spacing and
|
||||
// word-spacing should not affect the ascent and descent values we get.
|
||||
gfxTextRun::Metrics metrics =
|
||||
textRun->MeasureText(range, gfxFont::LOOSE_INK_EXTENTS, nullptr, nullptr);
|
||||
|
||||
aAscent = metrics.mAscent;
|
||||
aDescent = metrics.mDescent;
|
||||
textRun->GetLineHeightMetrics(range, aAscent, aDescent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,26 +273,23 @@ static nscoord GetBaselinePosition(nsTextFrame* aFrame, gfxTextRun* aTextRun,
|
|||
StyleDominantBaseline aDominantBaseline,
|
||||
float aFontSizeScaleFactor) {
|
||||
WritingMode writingMode = aFrame->GetWritingMode();
|
||||
// We pass in null for the PropertyProvider since letter-spacing and
|
||||
// word-spacing should not affect the ascent and descent values we get.
|
||||
gfxTextRun::Metrics metrics =
|
||||
aTextRun->MeasureText(gfxFont::LOOSE_INK_EXTENTS, nullptr);
|
||||
gfxFloat ascent, descent;
|
||||
aTextRun->GetLineHeightMetrics(ascent, descent);
|
||||
|
||||
auto convertIfVerticalRL = [&](gfxFloat dominantBaseline) {
|
||||
return writingMode.IsVerticalRL()
|
||||
? metrics.mAscent + metrics.mDescent - dominantBaseline
|
||||
: dominantBaseline;
|
||||
return writingMode.IsVerticalRL() ? ascent + descent - dominantBaseline
|
||||
: dominantBaseline;
|
||||
};
|
||||
|
||||
switch (aDominantBaseline) {
|
||||
case StyleDominantBaseline::Hanging:
|
||||
return convertIfVerticalRL(metrics.mAscent * 0.2);
|
||||
return convertIfVerticalRL(ascent * 0.2);
|
||||
case StyleDominantBaseline::TextBeforeEdge:
|
||||
return convertIfVerticalRL(0);
|
||||
|
||||
case StyleDominantBaseline::Alphabetic:
|
||||
return writingMode.IsVerticalRL()
|
||||
? metrics.mAscent * 0.5
|
||||
? ascent * 0.5
|
||||
: aFrame->GetLogicalBaseline(writingMode);
|
||||
|
||||
case StyleDominantBaseline::Auto:
|
||||
|
@ -312,13 +303,12 @@ static nscoord GetBaselinePosition(nsTextFrame* aFrame, gfxTextRun* aTextRun,
|
|||
|
||||
case StyleDominantBaseline::TextAfterEdge:
|
||||
case StyleDominantBaseline::Ideographic:
|
||||
return writingMode.IsVerticalLR() ? 0
|
||||
: metrics.mAscent + metrics.mDescent;
|
||||
return writingMode.IsVerticalLR() ? 0 : ascent + descent;
|
||||
|
||||
case StyleDominantBaseline::Central:
|
||||
return (metrics.mAscent + metrics.mDescent) / 2.0;
|
||||
return (ascent + descent) / 2.0;
|
||||
case StyleDominantBaseline::Mathematical:
|
||||
return convertIfVerticalRL(metrics.mAscent / 2.0);
|
||||
return convertIfVerticalRL(ascent / 2.0);
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected dominant-baseline value");
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
% http://localhost/tests/perf-reftest-singletons/style-attr-1.html
|
||||
% http://localhost/tests/perf-reftest-singletons/style-sharing-style-attr.html
|
||||
% http://localhost/tests/perf-reftest-singletons/style-sharing.html
|
||||
% http://localhost/tests/perf-reftest-singletons/svg-text-textLength-1.html
|
||||
% http://localhost/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html
|
||||
% http://localhost/tests/perf-reftest-singletons/tiny-traversal-singleton.html
|
||||
% http://localhost/tests/perf-reftest-singletons/window-named-property-get.html
|
||||
# When modifying this list, please also update build/pgo/index.html.
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="util.js"></script>
|
||||
<body>
|
||||
<svg width="144130" height="20" style="visibility:hidden">
|
||||
<rect width="144130" height="20" fill="#555"/>
|
||||
<g fill="#fff" font-family="sans-serif" font-size="110">
|
||||
<!-- The use of textLength here forces adjusted positioning of all the glyphs,
|
||||
which may put the SVG layout engine under some strain -->
|
||||
<text id="test" x="500" y="140" transform="scale(.1)" textLength="2440730"></text>
|
||||
</g>
|
||||
</svg>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// "word0 word1 word2 ... word99 " -> 690 chars
|
||||
text = "";
|
||||
for (i = 0; i < 100; i++) {
|
||||
text = text + "word" + i + " ";
|
||||
}
|
||||
// 6 doublings -> approx 44k chars
|
||||
for (i = 0; i < 6; i++) {
|
||||
text = text + text;
|
||||
}
|
||||
// set the text and force a reflow
|
||||
testElem = document.getElementById("test");
|
||||
testElem.textContent = text;
|
||||
flush_layout();
|
||||
// try calling getExtentOfChar for some of the characters
|
||||
len = text.length / 2;
|
||||
perf_start();
|
||||
for (i = 0; i < len; i++) {
|
||||
testElem.getExtentOfChar(i);
|
||||
}
|
||||
perf_finish();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="util.js"></script>
|
||||
<body>
|
||||
<svg width="144130" height="20" style="visibility:hidden">
|
||||
<rect width="144130" height="20" fill="#555"/>
|
||||
<g fill="#fff" font-family="sans-serif" font-size="110">
|
||||
<!-- The use of textLength here forces adjusted positioning of all the glyphs,
|
||||
which may put the SVG layout engine under some strain -->
|
||||
<text id="test" x="500" y="140" transform="scale(.1)" textLength="2440730"></text>
|
||||
</g>
|
||||
</svg>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// "word0 word1 word2 ... word99 " -> 690 chars
|
||||
text = "";
|
||||
for (i = 0; i < 100; i++) {
|
||||
text = text + "word" + i + " ";
|
||||
}
|
||||
// 6 doublings -> approx 44k chars
|
||||
for (i = 0; i < 6; i++) {
|
||||
text = text + text;
|
||||
}
|
||||
// set the text and time how long a reflow takes
|
||||
testElem = document.getElementById("test");
|
||||
testElem.textContent = text;
|
||||
perf_start();
|
||||
flush_layout();
|
||||
perf_finish();
|
||||
}
|
||||
</script>
|
|
@ -1261,6 +1261,8 @@ this.LoginManagerChild = class LoginManagerChild extends JSWindowActorChild {
|
|||
* Records the number of possible username event received for this document.
|
||||
*/
|
||||
numFormHasPossibleUsernameEvent: 0,
|
||||
|
||||
captureLoginTimeStamp: 0,
|
||||
};
|
||||
this._loginFormStateByDocument.set(document, loginFormState);
|
||||
}
|
||||
|
@ -2202,6 +2204,9 @@ this.LoginManagerChild = class LoginManagerChild extends JSWindowActorChild {
|
|||
messageSent: true,
|
||||
};
|
||||
|
||||
if (messageName == "PasswordManager:ShowDoorhanger") {
|
||||
docState.captureLoginTimeStamp = doc.lastUserGestureTimeStamp;
|
||||
}
|
||||
this.sendAsyncMessage(messageName, detail);
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
|
@ -2929,22 +2934,25 @@ this.LoginManagerChild = class LoginManagerChild extends JSWindowActorChild {
|
|||
|
||||
_formHasModifiedFields(form) {
|
||||
let doc = form.rootElement.ownerDocument;
|
||||
let state = this.stateForDocument(doc);
|
||||
let userHasInteracted;
|
||||
let testOnlyUserHasInteracted =
|
||||
LoginHelper.testOnlyUserHasInteractedWithDocument;
|
||||
if (Cu.isInAutomation && testOnlyUserHasInteracted !== null) {
|
||||
userHasInteracted = testOnlyUserHasInteracted;
|
||||
} else {
|
||||
userHasInteracted = doc.userHasInteracted;
|
||||
userHasInteracted =
|
||||
!LoginHelper.userInputRequiredToCapture ||
|
||||
state.captureLoginTimeStamp != doc.lastUserGestureTimeStamp;
|
||||
}
|
||||
|
||||
log("_formHasModifiedFields, userHasInteracted:", userHasInteracted);
|
||||
|
||||
// If the user hasn't interacted at all with the page, we don't need to check futher
|
||||
// Skip if user didn't interact with the page since last call or ever
|
||||
if (!userHasInteracted) {
|
||||
return false;
|
||||
}
|
||||
let state = this.stateForDocument(doc);
|
||||
|
||||
// check for user inputs to the form fields
|
||||
let fieldsModified = state.fieldModificationsByRootElement.get(
|
||||
form.rootElement
|
||||
|
|
Загрузка…
Ссылка в новой задаче