зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b-i
This commit is contained in:
Коммит
8dcd118bc0
2
CLOBBER
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 924839 - Touching ICU's configure scripts in this bug doesn't work without a clobber. This is filed as bug 966038.
|
||||
Bug 964200 - Touching webidl files in this bug doesn't work without a clobber. Tried landing already and had to back out.
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
:root {
|
||||
-moz-control-character-visibility: visible;
|
||||
}
|
||||
|
||||
/* Force height and width (possibly overflowing) from inline elements.
|
||||
* This allows long overflows of text or input fields to still be styled with
|
||||
* the container, rather than the background disappearing when scrolling */
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from mach.decorators import (
|
||||
|
@ -42,7 +43,6 @@ class MachCommands(MachCommandBase):
|
|||
'files.')
|
||||
def valgrind_test(self, suppressions):
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
@ -53,6 +53,7 @@ class MachCommands(MachCommandBase):
|
|||
from mozprofile.permissions import ServerLocations
|
||||
from mozrunner import FirefoxRunner
|
||||
from mozrunner.utils import findInPath
|
||||
from valgrind.output_handler import OutputHandler
|
||||
|
||||
build_dir = os.path.join(self.topsrcdir, 'build')
|
||||
|
||||
|
@ -92,16 +93,6 @@ class MachCommands(MachCommandBase):
|
|||
env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
|
||||
env['XPCOM_DEBUG_BREAK'] = 'warn'
|
||||
|
||||
class OutputHandler(object):
|
||||
def __init__(self):
|
||||
self.found_errors = False
|
||||
|
||||
def __call__(self, line):
|
||||
print(line)
|
||||
m = re.match(r'.*ERROR SUMMARY: [1-9]\d* errors from \d+ contexts', line)
|
||||
if m:
|
||||
self.found_errors = True
|
||||
|
||||
outputHandler = OutputHandler()
|
||||
kp_kwargs = {'processOutputLine': [outputHandler]}
|
||||
|
||||
|
@ -145,12 +136,18 @@ class MachCommands(MachCommandBase):
|
|||
exitcode = runner.wait()
|
||||
|
||||
finally:
|
||||
if not outputHandler.found_errors:
|
||||
errs = outputHandler.error_count
|
||||
supps = outputHandler.suppression_count
|
||||
if errs != supps:
|
||||
status = 1 # turns the TBPL job orange
|
||||
print('TEST-UNEXPECTED-FAILURE | valgrind-test | error parsing:', errs, "errors seen, but", supps, "generated suppressions seen")
|
||||
|
||||
elif errs == 0:
|
||||
status = 0
|
||||
print('TEST-PASS | valgrind-test | valgrind found no errors')
|
||||
else:
|
||||
status = 1 # turns the TBPL job orange
|
||||
print('TEST-UNEXPECTED-FAIL | valgrind-test | valgrind found errors')
|
||||
# We've already printed details of the errors.
|
||||
|
||||
if exitcode != 0:
|
||||
status = 2 # turns the TBPL job red
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
class OutputHandler(object):
|
||||
'''
|
||||
A class for handling Valgrind output.
|
||||
|
||||
Valgrind errors look like this:
|
||||
|
||||
==60741== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 2,746 of 5,235
|
||||
==60741== at 0x4C26B43: calloc (vg_replace_malloc.c:593)
|
||||
==60741== by 0x63AEF65: PR_Calloc (prmem.c:443)
|
||||
==60741== by 0x69F236E: PORT_ZAlloc_Util (secport.c:117)
|
||||
==60741== by 0x69F1336: SECITEM_AllocItem_Util (secitem.c:28)
|
||||
==60741== by 0xA04280B: ffi_call_unix64 (in /builds/slave/m-in-l64-valgrind-000000000000/objdir/toolkit/library/libxul.so)
|
||||
==60741== by 0xA042443: ffi_call (ffi64.c:485)
|
||||
|
||||
For each such error, this class extracts most or all of the first (error
|
||||
kind) line, plus the function name in each of the first few stack entries.
|
||||
With this data it constructs and prints a TEST-UNEXPECTED-FAIL message that
|
||||
TBPL will highlight.
|
||||
|
||||
It buffers these lines from which text is extracted so that the
|
||||
TEST-UNEXPECTED-FAIL message can be printed before the full error.
|
||||
|
||||
Parsing the Valgrind output isn't ideal, and it may break in the future if
|
||||
Valgrind changes the format of the messages, or introduces new error kinds.
|
||||
To protect against this, we also count how many lines containing
|
||||
"<insert_a_suppression_name_here>" are seen. Thanks to the use of
|
||||
--gen-suppressions=yes, exactly one of these lines is present per error. If
|
||||
the count of these lines doesn't match the error count found during
|
||||
parsing, then the parsing has missed one or more errors and we can fail
|
||||
appropriately.
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
# The regexps in this list match all of Valgrind's errors. Note that
|
||||
# Valgrind is English-only, so we don't have to worry about
|
||||
# localization.
|
||||
self.re_error = \
|
||||
r'==\d+== (' + \
|
||||
r'(Use of uninitialised value of size \d+)|' + \
|
||||
r'(Conditional jump or move depends on uninitialised value\(s\))|' + \
|
||||
r'(Syscall param .* contains uninitialised byte\(s\))|' + \
|
||||
r'(Syscall param .* points to (unaddressable|uninitialised) byte\(s\))|' + \
|
||||
r'((Unaddressable|Uninitialised) byte\(s\) found during client check request)|' + \
|
||||
r'(Invalid free\(\) / delete / delete\[\] / realloc\(\))|' + \
|
||||
r'(Mismatched free\(\) / delete / delete \[\])|' + \
|
||||
r'(Invalid (read|write) of size \d+)|' + \
|
||||
r'(Jump to the invalid address stated on the next line)|' + \
|
||||
r'(Source and destination overlap in .*)|' + \
|
||||
r'(.* bytes in .* blocks are .* lost)' + \
|
||||
r')'
|
||||
# Match identifer chars, plus ':' for namespaces, and '\?' in order to
|
||||
# match "???" which Valgrind sometimes produces.
|
||||
self.re_stack_entry = r'^==\d+==.*0x[A-Z0-9]+: ([A-Za-z0_9_:\?]+)'
|
||||
self.re_suppression = r' *<insert_a_suppression_name_here>'
|
||||
self.error_count = 0
|
||||
self.suppression_count = 0
|
||||
self.number_of_stack_entries_to_get = 0
|
||||
self.curr_failure_msg = None
|
||||
self.buffered_lines = None
|
||||
|
||||
def __call__(self, line):
|
||||
if self.number_of_stack_entries_to_get == 0:
|
||||
# Look for the start of a Valgrind error.
|
||||
m = re.search(self.re_error, line)
|
||||
if m:
|
||||
self.error_count += 1
|
||||
self.number_of_stack_entries_to_get = 4
|
||||
self.curr_failure_msg = 'TEST-UNEXPECTED-FAIL | valgrind-test | ' + m.group(1) + " at "
|
||||
self.buffered_lines = [line]
|
||||
else:
|
||||
print(line)
|
||||
|
||||
else:
|
||||
# We've recently found a Valgrind error, and are now extracting
|
||||
# details from the first few stack entries.
|
||||
self.buffered_lines.append(line)
|
||||
m = re.match(self.re_stack_entry, line)
|
||||
if m:
|
||||
self.curr_failure_msg += m.group(1)
|
||||
else:
|
||||
self.curr_failure_msg += '?!?'
|
||||
|
||||
self.number_of_stack_entries_to_get -= 1
|
||||
if self.number_of_stack_entries_to_get != 0:
|
||||
self.curr_failure_msg += ' / '
|
||||
else:
|
||||
# We've finished getting the first few stack entries. Print the
|
||||
# failure message and the buffered lines, and then reset state.
|
||||
print('\n' + self.curr_failure_msg + '\n')
|
||||
for b in self.buffered_lines:
|
||||
print(b)
|
||||
self.curr_failure_msg = None
|
||||
self.buffered_lines = None
|
||||
|
||||
if re.match(self.re_suppression, line):
|
||||
self.suppression_count += 1
|
||||
|
|
@ -45,6 +45,7 @@ SVG_TAG(feConvolveMatrix, FEConvolveMatrix)
|
|||
SVG_TAG(feDiffuseLighting, FEDiffuseLighting)
|
||||
SVG_TAG(feDisplacementMap, FEDisplacementMap)
|
||||
SVG_TAG(feDistantLight, FEDistantLight)
|
||||
SVG_TAG(feDropShadow, FEDropShadow)
|
||||
SVG_TAG(feFlood, FEFlood)
|
||||
SVG_TAG(feFuncA, FEFuncA)
|
||||
SVG_TAG(feFuncB, FEFuncB)
|
||||
|
|
|
@ -169,6 +169,7 @@ UNIFIED_SOURCES += [
|
|||
'SVGFEDiffuseLightingElement.cpp',
|
||||
'SVGFEDisplacementMapElement.cpp',
|
||||
'SVGFEDistantLightElement.cpp',
|
||||
'SVGFEDropShadowElement.cpp',
|
||||
'SVGFEFloodElement.cpp',
|
||||
'SVGFEGaussianBlurElement.cpp',
|
||||
'SVGFEImageElement.cpp',
|
||||
|
|
|
@ -54,6 +54,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=589640
|
|||
<feDiffuseLighting id="feDiffuseLighting" />
|
||||
<feDisplacementMap id="feDisplacementMap" />
|
||||
<feDistantLight id="feDistantLight" />
|
||||
<feDropShadow id="feDropShadow" />
|
||||
<feFlood id="feFlood" />
|
||||
<feFuncA id="feFuncA" />
|
||||
<feFuncB id="feFuncB" />
|
||||
|
|
|
@ -38,8 +38,7 @@ MobileConnectionArray::MobileConnectionArray(nsPIDOMWindow* aWindow)
|
|||
uint32_t numRil = mozilla::Preferences::GetUint("ril.numRadioInterfaces", 1);
|
||||
MOZ_ASSERT(numRil > 0);
|
||||
|
||||
bool ret = mMobileConnections.SetLength(numRil);
|
||||
MOZ_ASSERT(ret);
|
||||
mMobileConnections.SetLength(numRil);
|
||||
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
|
|
@ -462,6 +462,7 @@ exports.browser = {
|
|||
SVGFEDiffuseLightingElement: false,
|
||||
SVGFEDisplacementMapElement: false,
|
||||
SVGFEDistantLightElement: false,
|
||||
SVGFEDropShadowElement: false,
|
||||
SVGFEFloodElement : false,
|
||||
SVGFEFuncAElement : false,
|
||||
SVGFEFuncBElement : false,
|
||||
|
|
|
@ -880,6 +880,8 @@ var interfaceNamesInGlobalScope =
|
|||
"SVGFEDisplacementMapElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGFEDistantLightElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGFEDropShadowElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SVGFEFloodElement",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -326,6 +326,7 @@ WEBIDL_FILES = [
|
|||
'SVGFEDiffuseLightingElement.webidl',
|
||||
'SVGFEDisplacementMapElement.webidl',
|
||||
'SVGFEDistantLightElement.webidl',
|
||||
'SVGFEDropShadowElement.webidl',
|
||||
'SVGFEFloodElement.webidl',
|
||||
'SVGFEFuncAElement.webidl',
|
||||
'SVGFEFuncBElement.webidl',
|
||||
|
|
|
@ -310,7 +310,7 @@ gfxDWriteFontFamily::LocalizedName(nsAString &aLocalizedName)
|
|||
idx = 0;
|
||||
}
|
||||
}
|
||||
nsAutoTArray<WCHAR, 32> famName;
|
||||
AutoFallibleTArray<WCHAR, 32> famName;
|
||||
UINT32 length;
|
||||
|
||||
hr = names->GetStringLength(idx, &length);
|
||||
|
@ -991,7 +991,7 @@ gfxDWriteFontList::DelayedInitFontList()
|
|||
englishIdx = 0;
|
||||
}
|
||||
|
||||
nsAutoTArray<WCHAR, 32> enName;
|
||||
AutoFallibleTArray<WCHAR, 32> enName;
|
||||
UINT32 length;
|
||||
|
||||
hr = names->GetStringLength(englishIdx, &length);
|
||||
|
@ -1036,7 +1036,7 @@ gfxDWriteFontList::DelayedInitFontList()
|
|||
|
||||
for (nameIndex = 0; nameIndex < nameCount; nameIndex++) {
|
||||
UINT32 nameLen;
|
||||
nsAutoTArray<WCHAR, 32> localizedName;
|
||||
AutoFallibleTArray<WCHAR, 32> localizedName;
|
||||
|
||||
// only add other names
|
||||
if (nameIndex == englishIdx) {
|
||||
|
@ -1402,7 +1402,7 @@ static HRESULT GetFamilyName(IDWriteFont *aFont, nsString& aFamilyName)
|
|||
index = 0;
|
||||
}
|
||||
|
||||
nsAutoTArray<WCHAR, 32> name;
|
||||
AutoFallibleTArray<WCHAR, 32> name;
|
||||
UINT32 length;
|
||||
|
||||
hr = familyNames->GetStringLength(index, &length);
|
||||
|
|
|
@ -67,10 +67,10 @@ trymoreglyphs:
|
|||
}
|
||||
maxGlyphs += 3 * length / 2 + 16;
|
||||
|
||||
nsAutoTArray<UINT16, 400> clusters;
|
||||
nsAutoTArray<UINT16, 400> indices;
|
||||
nsAutoTArray<DWRITE_SHAPING_TEXT_PROPERTIES, 400> textProperties;
|
||||
nsAutoTArray<DWRITE_SHAPING_GLYPH_PROPERTIES, 400> glyphProperties;
|
||||
AutoFallibleTArray<UINT16, 400> clusters;
|
||||
AutoFallibleTArray<UINT16, 400> indices;
|
||||
AutoFallibleTArray<DWRITE_SHAPING_TEXT_PROPERTIES, 400> textProperties;
|
||||
AutoFallibleTArray<DWRITE_SHAPING_GLYPH_PROPERTIES, 400> glyphProperties;
|
||||
if (!clusters.SetLength(length) ||
|
||||
!indices.SetLength(maxGlyphs) ||
|
||||
!textProperties.SetLength(maxGlyphs) ||
|
||||
|
@ -98,8 +98,8 @@ trymoreglyphs:
|
|||
}
|
||||
|
||||
WORD gID = indices[0];
|
||||
nsAutoTArray<FLOAT, 400> advances;
|
||||
nsAutoTArray<DWRITE_GLYPH_OFFSET, 400> glyphOffsets;
|
||||
AutoFallibleTArray<FLOAT, 400> advances;
|
||||
AutoFallibleTArray<DWRITE_GLYPH_OFFSET, 400> glyphOffsets;
|
||||
if (!advances.SetLength(actualGlyphs) ||
|
||||
!glyphOffsets.SetLength(actualGlyphs)) {
|
||||
NS_WARNING("Shaper failed to allocate memory.");
|
||||
|
|
|
@ -3482,7 +3482,8 @@ gfxFont::ShapeTextWithoutWordCache(gfxContext *aContext,
|
|||
aTextRun->SetIsTab(aOffset + i);
|
||||
} else if (ch == '\n') {
|
||||
aTextRun->SetIsNewline(aOffset + i);
|
||||
} else if (IsInvalidControlChar(ch)) {
|
||||
} else if (IsInvalidControlChar(ch) &&
|
||||
!(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) {
|
||||
aTextRun->SetMissingGlyph(aOffset + i, ch, this);
|
||||
}
|
||||
fragStart = i + 1;
|
||||
|
@ -3652,7 +3653,8 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
|
|||
aTextRun->SetIsTab(aRunStart + i);
|
||||
} else if (ch == '\n') {
|
||||
aTextRun->SetIsNewline(aRunStart + i);
|
||||
} else if (IsInvalidControlChar(ch)) {
|
||||
} else if (IsInvalidControlChar(ch) &&
|
||||
!(aTextRun->GetFlags() & gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS)) {
|
||||
aTextRun->SetMissingGlyph(aRunStart + i, ch, this);
|
||||
}
|
||||
|
||||
|
|
|
@ -1137,6 +1137,11 @@ public:
|
|||
* textruns that have been seen so as to avoid multiple-accounting.
|
||||
*/
|
||||
TEXT_RUN_SIZE_ACCOUNTED = 0x0200,
|
||||
/**
|
||||
* When set, the textrun should discard control characters instead of
|
||||
* turning them into hexboxes.
|
||||
*/
|
||||
TEXT_HIDE_CONTROL_CHARACTERS = 0x0400,
|
||||
|
||||
/**
|
||||
* nsTextFrameThebes sets these, but they're defined here rather than
|
||||
|
|
|
@ -989,7 +989,7 @@ int CALLBACK GDIFontInfo::EnumerateFontsForFamily(
|
|||
uint32_t kNAME =
|
||||
NativeEndian::swapToBigEndian(TRUETYPE_TAG('n','a','m','e'));
|
||||
uint32_t nameSize;
|
||||
nsAutoTArray<uint8_t, 1024> nameData;
|
||||
AutoFallibleTArray<uint8_t, 1024> nameData;
|
||||
|
||||
nameSize = ::GetFontData(hdc, kNAME, 0, nullptr, 0);
|
||||
if (nameSize != GDI_ERROR &&
|
||||
|
@ -1032,7 +1032,7 @@ int CALLBACK GDIFontInfo::EnumerateFontsForFamily(
|
|||
uint32_t kCMAP =
|
||||
NativeEndian::swapToBigEndian(TRUETYPE_TAG('c','m','a','p'));
|
||||
uint32_t cmapSize;
|
||||
nsAutoTArray<uint8_t, 1024> cmapData;
|
||||
AutoFallibleTArray<uint8_t, 1024> cmapData;
|
||||
|
||||
cmapSize = ::GetFontData(hdc, kCMAP, 0, nullptr, 0);
|
||||
if (cmapSize != GDI_ERROR &&
|
||||
|
|
|
@ -25,7 +25,7 @@ gfxGDIShaper::ShapeText(gfxContext *aContext,
|
|||
AutoSelectFont selectFont(dc, static_cast<gfxGDIFont*>(mFont)->GetHFONT());
|
||||
|
||||
uint32_t length = aLength;
|
||||
nsAutoTArray<WORD,500> glyphArray;
|
||||
AutoFallibleTArray<WORD,500> glyphArray;
|
||||
if (!glyphArray.SetLength(length)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ gfxGDIShaper::ShapeText(gfxContext *aContext,
|
|||
}
|
||||
|
||||
SIZE size;
|
||||
nsAutoTArray<int,500> partialWidthArray;
|
||||
AutoFallibleTArray<int,500> partialWidthArray;
|
||||
if (!partialWidthArray.SetLength(length)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -349,12 +349,12 @@ private:
|
|||
|
||||
#define AVERAGE_ITEM_LENGTH 40
|
||||
|
||||
nsAutoTArray<WORD, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mGlyphs;
|
||||
nsAutoTArray<WORD, AVERAGE_ITEM_LENGTH + 1> mClusters;
|
||||
nsAutoTArray<SCRIPT_VISATTR, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mAttr;
|
||||
AutoFallibleTArray<WORD, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mGlyphs;
|
||||
AutoFallibleTArray<WORD, AVERAGE_ITEM_LENGTH + 1> mClusters;
|
||||
AutoFallibleTArray<SCRIPT_VISATTR, uint32_t(ESTIMATE_MAX_GLYPHS(AVERAGE_ITEM_LENGTH))> mAttr;
|
||||
|
||||
nsAutoTArray<GOFFSET, 2 * AVERAGE_ITEM_LENGTH> mOffsets;
|
||||
nsAutoTArray<int, 2 * AVERAGE_ITEM_LENGTH> mAdvances;
|
||||
AutoFallibleTArray<GOFFSET, 2 * AVERAGE_ITEM_LENGTH> mOffsets;
|
||||
AutoFallibleTArray<int, 2 * AVERAGE_ITEM_LENGTH> mAdvances;
|
||||
|
||||
#undef AVERAGE_ITEM_LENGTH
|
||||
|
||||
|
@ -424,7 +424,7 @@ private:
|
|||
|
||||
SCRIPT_CONTROL mControl;
|
||||
SCRIPT_STATE mState;
|
||||
nsTArray<SCRIPT_ITEM> mItems;
|
||||
FallibleTArray<SCRIPT_ITEM> mItems;
|
||||
int mNumItems;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Owning elements and attribute names are attached to scripts compiled
|
||||
// off-thread.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
var gDO = dbg.addDebuggee(g);
|
||||
|
||||
var elt = new g.Object;
|
||||
var eltDO = gDO.makeDebuggeeValue(elt);
|
||||
|
||||
var log = '';
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
log += 'd';
|
||||
var source = frame.script.source;
|
||||
assertEq(source.element, eltDO);
|
||||
assertEq(source.elementAttributeName, 'mass');
|
||||
};
|
||||
|
||||
g.offThreadCompileScript('debugger;',
|
||||
{ element: elt,
|
||||
elementAttributeName: 'mass' });
|
||||
log += 'o';
|
||||
g.runOffThreadScript();
|
||||
assertEq(log, 'od');
|
|
@ -4355,6 +4355,7 @@ JS::OwningCompileOptions::copy(JSContext *cx, const ReadOnlyCompileOptions &rhs)
|
|||
setPrincipals(rhs.principals());
|
||||
setOriginPrincipals(rhs.originPrincipals());
|
||||
setElement(rhs.element());
|
||||
setElementAttributeName(rhs.elementAttributeName());
|
||||
|
||||
return (setFileAndLine(cx, rhs.filename(), rhs.lineno) &&
|
||||
setSourceMapURL(cx, rhs.sourceMapURL()) &&
|
||||
|
|
|
@ -4989,6 +4989,7 @@ nsCSSFrameConstructor::FindSVGData(Element* aElement,
|
|||
SIMPLE_SVG_CREATE(feConvolveMatrix, NS_NewSVGFELeafFrame),
|
||||
SIMPLE_SVG_CREATE(feDiffuseLighting, NS_NewSVGFEContainerFrame),
|
||||
SIMPLE_SVG_CREATE(feDisplacementMap, NS_NewSVGFELeafFrame),
|
||||
SIMPLE_SVG_CREATE(feDropShadow, NS_NewSVGFELeafFrame),
|
||||
SIMPLE_SVG_CREATE(feFlood, NS_NewSVGFELeafFrame),
|
||||
SIMPLE_SVG_CREATE(feGaussianBlur, NS_NewSVGFELeafFrame),
|
||||
SIMPLE_SVG_CREATE(feImage, NS_NewSVGFEImageFrame),
|
||||
|
|
|
@ -4700,12 +4700,16 @@ nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame)
|
|||
/* static */ uint32_t
|
||||
nsLayoutUtils::GetTextRunFlagsForStyle(nsStyleContext* aStyleContext,
|
||||
const nsStyleFont* aStyleFont,
|
||||
const nsStyleText* aStyleText,
|
||||
nscoord aLetterSpacing)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
if (aLetterSpacing != 0) {
|
||||
result |= gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES;
|
||||
}
|
||||
if (aStyleText->mControlCharacterVisibility == NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN) {
|
||||
result |= gfxTextRunFactory::TEXT_HIDE_CONTROL_CHARACTERS;
|
||||
}
|
||||
switch (aStyleContext->StyleSVG()->mTextRendering) {
|
||||
case NS_STYLE_TEXT_RENDERING_OPTIMIZESPEED:
|
||||
result |= gfxTextRunFactory::TEXT_OPTIMIZE_SPEED;
|
||||
|
|
|
@ -1525,6 +1525,7 @@ public:
|
|||
*/
|
||||
static uint32_t GetTextRunFlagsForStyle(nsStyleContext* aStyleContext,
|
||||
const nsStyleFont* aStyleFont,
|
||||
const nsStyleText* aStyleText,
|
||||
nscoord aLetterSpacing);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1650,8 +1650,8 @@ BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFr
|
|||
return fontStyle1->mFont.BaseEquals(fontStyle2->mFont) &&
|
||||
sc1->StyleFont()->mLanguage == sc2->StyleFont()->mLanguage &&
|
||||
textStyle1->mTextTransform == textStyle2->mTextTransform &&
|
||||
nsLayoutUtils::GetTextRunFlagsForStyle(sc1, fontStyle1, letterSpacing1) ==
|
||||
nsLayoutUtils::GetTextRunFlagsForStyle(sc2, fontStyle2, letterSpacing2);
|
||||
nsLayoutUtils::GetTextRunFlagsForStyle(sc1, fontStyle1, textStyle1, letterSpacing1) ==
|
||||
nsLayoutUtils::GetTextRunFlagsForStyle(sc2, fontStyle2, textStyle2, letterSpacing2);
|
||||
}
|
||||
|
||||
void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame)
|
||||
|
@ -2066,7 +2066,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
|||
// frame's style is used, so we use a mixture of the first frame and
|
||||
// last frame's style
|
||||
textFlags |= nsLayoutUtils::GetTextRunFlagsForStyle(lastStyleContext,
|
||||
fontStyle, LetterSpacing(firstFrame, textStyle));
|
||||
fontStyle, textStyle, LetterSpacing(firstFrame, textStyle));
|
||||
// XXX this is a bit of a hack. For performance reasons, if we're favouring
|
||||
// performance over quality, don't try to get accurate glyph extents.
|
||||
if (!(textFlags & gfxTextRunFactory::TEXT_OPTIMIZE_SPEED)) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="-moz-appearance:none; width:300px; height:300px;">
|
||||
foobar
|
||||
</textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="-moz-appearance:none; width:300px; height:300px;">
|
||||
foobar
|
||||
</textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="-moz-appearance:none; width:300px; height:300px;">
|
||||
foobar
|
||||
</textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="-moz-appearance:none; width:300px; height:300px;">
|
||||
foobar
|
||||
</textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<textarea style="-moz-appearance:none; width:300px; height:300px;">
|
||||
foobar
|
||||
</textarea>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="-moz-control-character-visibility:visible">
|
||||
foobar
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="-moz-control-character-visibility:visible">
|
||||
foobar
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
foobar
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="-moz-control-character-visibility:hidden">
|
||||
foobar
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="-moz-control-character-visibility:visible">
|
||||
<span id="s">foobar</span>
|
||||
<script>
|
||||
var x = s.getBoundingClientRect().width;
|
||||
document.body.setAttribute("style", "-moz-control-character-visibility:hidden");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -292,3 +292,6 @@ pref(layout.css.text-align-true-value.enabled,true) == text-align-true.html text
|
|||
!= control-chars-01b.html control-chars-01-notref.html
|
||||
!= control-chars-01c.html control-chars-01-notref.html
|
||||
!= control-chars-01d.html control-chars-01-notref.html
|
||||
!= control-chars-02.html control-chars-02-notref.html
|
||||
== control-chars-03a.html control-chars-03-ref.html
|
||||
== control-chars-03b.html control-chars-03-ref.html
|
||||
|
|
|
@ -136,6 +136,7 @@ textarea::-moz-placeholder {
|
|||
display: inline-block;
|
||||
ime-mode: inherit;
|
||||
resize: inherit;
|
||||
-moz-control-character-visibility: visible;
|
||||
}
|
||||
|
||||
textarea > .anonymous-div.wrap,
|
||||
|
|
|
@ -1534,6 +1534,18 @@ CSS_PROP_CONTENT(
|
|||
kContentKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
|
||||
CSS_PROP_TEXT(
|
||||
-moz-control-character-visibility,
|
||||
_moz_control_character_visibility,
|
||||
CSS_PROP_DOMPROP_PREFIXED(ControlCharacterVisibility),
|
||||
CSS_PROPERTY_PARSE_VALUE,
|
||||
"",
|
||||
VARIANT_HK,
|
||||
kControlCharacterVisibilityKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
#endif
|
||||
CSS_PROP_CONTENT(
|
||||
counter-increment,
|
||||
counter_increment,
|
||||
|
|
|
@ -914,6 +914,12 @@ const KTableValue nsCSSProps::kContentKTable[] = {
|
|||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kControlCharacterVisibilityKTable[] = {
|
||||
eCSSKeyword_hidden, NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN,
|
||||
eCSSKeyword_visible, NS_STYLE_CONTROL_CHARACTER_VISIBILITY_VISIBLE,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kCursorKTable[] = {
|
||||
// CSS 2.0
|
||||
eCSSKeyword_auto, NS_STYLE_CURSOR_AUTO,
|
||||
|
|
|
@ -491,6 +491,7 @@ public:
|
|||
static const KTableValue kClearKTable[];
|
||||
static const KTableValue kColorKTable[];
|
||||
static const KTableValue kContentKTable[];
|
||||
static const KTableValue kControlCharacterVisibilityKTable[];
|
||||
static const KTableValue kCursorKTable[];
|
||||
static const KTableValue kDirectionKTable[];
|
||||
static const KTableValue kDisplayKTable[];
|
||||
|
|
|
@ -4219,6 +4219,14 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
|
|||
NS_STYLE_TEXT_SIZE_ADJUST_NONE, // none value
|
||||
0, 0);
|
||||
|
||||
// -moz-text-discard: enum, inherit, initial
|
||||
SetDiscrete(*aRuleData->ValueForControlCharacterVisibility(),
|
||||
text->mControlCharacterVisibility,
|
||||
canStoreInRuleTree,
|
||||
SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
|
||||
parentText->mControlCharacterVisibility,
|
||||
NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN, 0, 0, 0, 0);
|
||||
|
||||
// text-orientation: enum, inherit, initial
|
||||
SetDiscrete(*aRuleData->ValueForTextOrientation(), text->mTextOrientation,
|
||||
canStoreInRuleTree,
|
||||
|
|
|
@ -1025,6 +1025,10 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
|||
#define NS_STYLE_BLEND_COLOR 14
|
||||
#define NS_STYLE_BLEND_LUMINOSITY 15
|
||||
|
||||
// See nsStyleText::mControlCharacterVisibility
|
||||
#define NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN 0
|
||||
#define NS_STYLE_CONTROL_CHARACTER_VISIBILITY_VISIBLE 1
|
||||
|
||||
/*****************************************************************************
|
||||
* Constants for media features. *
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -2970,6 +2970,7 @@ nsStyleText::nsStyleText(void)
|
|||
mTextSizeAdjust = NS_STYLE_TEXT_SIZE_ADJUST_AUTO;
|
||||
mTextOrientation = NS_STYLE_TEXT_ORIENTATION_AUTO;
|
||||
mTextCombineHorizontal = NS_STYLE_TEXT_COMBINE_HORIZ_NONE;
|
||||
mControlCharacterVisibility = NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN;
|
||||
|
||||
mLetterSpacing.SetNormalValue();
|
||||
mLineHeight.SetNormalValue();
|
||||
|
@ -2993,6 +2994,7 @@ nsStyleText::nsStyleText(const nsStyleText& aSource)
|
|||
mTextSizeAdjust(aSource.mTextSizeAdjust),
|
||||
mTextOrientation(aSource.mTextOrientation),
|
||||
mTextCombineHorizontal(aSource.mTextCombineHorizontal),
|
||||
mControlCharacterVisibility(aSource.mControlCharacterVisibility),
|
||||
mTabSize(aSource.mTabSize),
|
||||
mWordSpacing(aSource.mWordSpacing),
|
||||
mLetterSpacing(aSource.mLetterSpacing),
|
||||
|
@ -3016,7 +3018,8 @@ nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aOther) const
|
|||
return NS_STYLE_HINT_FRAMECHANGE;
|
||||
}
|
||||
|
||||
if (mTextCombineHorizontal != aOther.mTextCombineHorizontal) {
|
||||
if (mTextCombineHorizontal != aOther.mTextCombineHorizontal ||
|
||||
mControlCharacterVisibility != aOther.mControlCharacterVisibility) {
|
||||
return nsChangeHint_ReconstructFrame;
|
||||
}
|
||||
|
||||
|
|
|
@ -1395,6 +1395,7 @@ struct nsStyleText {
|
|||
uint8_t mTextSizeAdjust; // [inherited] see nsStyleConsts.h
|
||||
uint8_t mTextOrientation; // [inherited] see nsStyleConsts.h
|
||||
uint8_t mTextCombineHorizontal; // [inherited] see nsStyleConsts.h
|
||||
uint8_t mControlCharacterVisibility; // [inherited] see nsStyleConsts.h
|
||||
int32_t mTabSize; // [inherited] see nsStyleConsts.h
|
||||
|
||||
nscoord mWordSpacing; // [inherited]
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
-moz-control-character-visibility: visible;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ const char *gInaccessibleProperties[] = {
|
|||
"padding-left-rtl-source",
|
||||
"padding-right-ltr-source",
|
||||
"padding-right-rtl-source",
|
||||
"-moz-control-character-visibility",
|
||||
"-moz-script-level", // parsed by UA sheets only
|
||||
"-moz-script-size-multiplier",
|
||||
"-moz-script-min-size",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
background-color: white;
|
||||
color: black;
|
||||
direction: ltr;
|
||||
-moz-control-character-visibility: visible;
|
||||
}
|
||||
#viewsource {
|
||||
font-family: -moz-fixed;
|
||||
|
|
|
@ -1835,11 +1835,15 @@ Init(const malloc_table_t* aMallocTable)
|
|||
|
||||
DMD_CREATE_TLS_INDEX(gTlsIndex);
|
||||
|
||||
gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
|
||||
gStackTraceTable->init(8192);
|
||||
{
|
||||
AutoLockState lock;
|
||||
|
||||
gBlockTable = InfallibleAllocPolicy::new_<BlockTable>();
|
||||
gBlockTable->init(8192);
|
||||
gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
|
||||
gStackTraceTable->init(8192);
|
||||
|
||||
gBlockTable = InfallibleAllocPolicy::new_<BlockTable>();
|
||||
gBlockTable->init(8192);
|
||||
}
|
||||
|
||||
if (gOptions->IsTestMode()) {
|
||||
// OpenOutputFile() can allocate. So do this before setting
|
||||
|
@ -2012,12 +2016,13 @@ PrintSortedTraceAndFrameRecords(const Writer& aWriter,
|
|||
}
|
||||
|
||||
// Note that, unlike most SizeOf* functions, this function does not take a
|
||||
// |mozilla::MallocSizeOf| argument. That's because those arguments are primarily
|
||||
// to aid DMD track heap blocks... but DMD deliberately doesn't track heap
|
||||
// blocks it allocated for itself!
|
||||
// |mozilla::MallocSizeOf| argument. That's because those arguments are
|
||||
// primarily to aid DMD track heap blocks... but DMD deliberately doesn't track
|
||||
// heap blocks it allocated for itself!
|
||||
//
|
||||
// SizeOfInternal should be called while you're holding the state lock and while
|
||||
// intercepts are blocked; SizeOf acquires the lock and blocks intercepts.
|
||||
// SizeOfInternal should be called while you're holding the state lock and
|
||||
// while intercepts are blocked; SizeOf acquires the lock and blocks
|
||||
// intercepts.
|
||||
|
||||
static void
|
||||
SizeOfInternal(Sizes* aSizes)
|
||||
|
@ -2066,12 +2071,10 @@ SizeOf(Sizes* aSizes)
|
|||
SizeOfInternal(aSizes);
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
ClearReports()
|
||||
void
|
||||
ClearReportsInternal()
|
||||
{
|
||||
if (!gIsDMDRunning) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(gStateLock->IsLocked());
|
||||
|
||||
// Unreport all blocks that were marked reported by a memory reporter. This
|
||||
// excludes those that were reported on allocation, because they need to keep
|
||||
|
@ -2081,6 +2084,17 @@ ClearReports()
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
ClearReports()
|
||||
{
|
||||
if (!gIsDMDRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoLockState lock;
|
||||
ClearReportsInternal();
|
||||
}
|
||||
|
||||
MOZ_EXPORT void
|
||||
Dump(Writer aWriter)
|
||||
{
|
||||
|
@ -2270,7 +2284,7 @@ Dump(Writer aWriter)
|
|||
|
||||
InfallibleAllocPolicy::delete_(locService);
|
||||
|
||||
ClearReports();
|
||||
ClearReportsInternal(); // Use internal version, we already have the lock.
|
||||
|
||||
StatusMsg("}\n");
|
||||
}
|
||||
|
|
|
@ -125,7 +125,9 @@ For objects that do have synthetic children defined for them, like nsTArray,
|
|||
the "expr -R -- EXPR" command can be used to show its actual member variables.
|
||||
|
||||
|
||||
* nsAString, nsACString
|
||||
* nsAString, nsACString,
|
||||
nsFixedString, nsFixedCString,
|
||||
nsAutoString, nsAutoCString
|
||||
|
||||
Strings have a type summary that shows the actual string.
|
||||
|
||||
|
|
|
@ -69,6 +69,10 @@ def prefcnt(debugger, command, result, dict):
|
|||
def init(debugger):
|
||||
debugger.HandleCommand("type summary add nsAString_internal -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type summary add nsACString_internal -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type summary add nsFixedString -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type summary add nsFixedCString -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type summary add nsAutoString -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type summary add nsAutoCString -F lldbutils.general.summarize_string")
|
||||
debugger.HandleCommand("type synthetic add -x \"nsTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
|
||||
debugger.HandleCommand("type synthetic add -x \"nsAutoTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
|
||||
debugger.HandleCommand("type synthetic add -x \"FallibleTArray<\" -l lldbutils.general.TArraySyntheticChildrenProvider")
|
||||
|
|
|
@ -77,9 +77,9 @@ import mozinfo
|
|||
# TODO: perhaps this should be in a more generally shared location?
|
||||
# This regex matches all of the C0 and C1 control characters
|
||||
# (U+0000 through U+001F; U+007F; U+0080 through U+009F),
|
||||
# except TAB (U+0009) and LF (U+000A); also, backslash (U+005C).
|
||||
# except TAB (U+0009), CR (U+000D), LF (U+000A) and backslash (U+005C).
|
||||
# A raw string is deliberately not used.
|
||||
_cleanup_encoding_re = re.compile(u'[\x00-\x08\x0b-\x1f\x7f-\x9f\\\\]')
|
||||
_cleanup_encoding_re = re.compile(u'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f\\\\]')
|
||||
def _cleanup_encoding_repl(m):
|
||||
c = m.group(0)
|
||||
return '\\\\' if c == '\\' else '\\x{:02X}'.format(ord(c))
|
||||
|
|
|
@ -30,15 +30,9 @@ XPCOMUtils.defineLazyGetter(this, "localFileCtor",
|
|||
|
||||
this.PlacesBackups = {
|
||||
get _filenamesRegex() {
|
||||
// Get the localized backup filename, will be used to clear out
|
||||
// old backups with a localized name (bug 445704).
|
||||
let localizedFilename =
|
||||
PlacesUtils.getFormattedString("bookmarksArchiveFilename", [new Date()]);
|
||||
let localizedFilenamePrefix =
|
||||
localizedFilename.substr(0, localizedFilename.indexOf("-"));
|
||||
delete this._filenamesRegex;
|
||||
return this._filenamesRegex =
|
||||
new RegExp("^(bookmarks|" + localizedFilenamePrefix + ")-([0-9-]+)(_[0-9]+)*\.(json|html)");
|
||||
new RegExp("^(bookmarks)-([0-9-]+)(_[0-9]+)*\.(json|html)");
|
||||
},
|
||||
|
||||
get folder() {
|
||||
|
@ -319,9 +313,7 @@ this.PlacesBackups = {
|
|||
if (aMaxBackups !== undefined && aMaxBackups > -1) {
|
||||
let backupFiles = yield this.getBackupFiles();
|
||||
numberOfBackupsToDelete = backupFiles.length - aMaxBackups;
|
||||
}
|
||||
|
||||
if (numberOfBackupsToDelete > 0) {
|
||||
// If we don't have today's backup, remove one more so that
|
||||
// the total backups after this operation does not exceed the
|
||||
// number specified in the pref.
|
||||
|
@ -329,15 +321,15 @@ this.PlacesBackups = {
|
|||
!this._isFilenameWithSameDate(OS.Path.basename(mostRecentBackupFile),
|
||||
newBackupFilename))
|
||||
numberOfBackupsToDelete++;
|
||||
}
|
||||
|
||||
while (numberOfBackupsToDelete--) {
|
||||
this._entries.pop();
|
||||
if (!this._backupFiles) {
|
||||
yield this.getBackupFiles();
|
||||
}
|
||||
let oldestBackup = this._backupFiles.pop();
|
||||
yield OS.File.remove(oldestBackup);
|
||||
while (numberOfBackupsToDelete--) {
|
||||
this._entries.pop();
|
||||
if (!this._backupFiles) {
|
||||
yield this.getBackupFiles();
|
||||
}
|
||||
let oldestBackup = this._backupFiles.pop();
|
||||
yield OS.File.remove(oldestBackup);
|
||||
}
|
||||
|
||||
// Do nothing if we already have this backup or we don't want backups.
|
||||
|
|
|
@ -9,17 +9,17 @@
|
|||
*/
|
||||
|
||||
const PREFIX = "bookmarks-";
|
||||
// The localized prefix must be "bigger" and associated to older backups.
|
||||
const LOCALIZED_PREFIX = "segnalibri-";
|
||||
const SUFFIX = ".json";
|
||||
const NUMBER_OF_BACKUPS = 10;
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
// Generate random dates.
|
||||
var dateObj = new Date();
|
||||
var dates = [];
|
||||
let dateObj = new Date();
|
||||
let dates = [];
|
||||
while (dates.length < NUMBER_OF_BACKUPS) {
|
||||
// Use last year to ensure today's backup is the newest.
|
||||
let randomDate = new Date(dateObj.getFullYear() - 1,
|
||||
|
@ -32,74 +32,63 @@ function run_test() {
|
|||
// Sort dates from oldest to newest.
|
||||
dates.sort();
|
||||
|
||||
Task.spawn(function() {
|
||||
// Get and cleanup the backups folder.
|
||||
let backupFolderPath = yield PlacesBackups.getBackupFolder();
|
||||
let bookmarksBackupDir = new FileUtils.File(backupFolderPath);
|
||||
// Get and cleanup the backups folder.
|
||||
let backupFolderPath = yield PlacesBackups.getBackupFolder();
|
||||
let bookmarksBackupDir = new FileUtils.File(backupFolderPath);
|
||||
|
||||
// Fake backups are created backwards to ensure we won't consider file
|
||||
// creation time.
|
||||
// Create fake backups for the newest dates.
|
||||
for (let i = dates.length - 1; i >= 0; i--) {
|
||||
let backupFilename;
|
||||
if (i > Math.floor(dates.length/2))
|
||||
backupFilename = PREFIX + dates[i] + SUFFIX;
|
||||
else
|
||||
backupFilename = LOCALIZED_PREFIX + dates[i] + SUFFIX;
|
||||
let backupFile = bookmarksBackupDir.clone();
|
||||
backupFile.append(backupFilename);
|
||||
backupFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
do_check_true(backupFile.exists());
|
||||
}
|
||||
// Fake backups are created backwards to ensure we won't consider file
|
||||
// creation time.
|
||||
// Create fake backups for the newest dates.
|
||||
for (let i = dates.length - 1; i >= 0; i--) {
|
||||
let backupFilename = PREFIX + dates[i] + SUFFIX;
|
||||
let backupFile = bookmarksBackupDir.clone();
|
||||
backupFile.append(backupFilename);
|
||||
backupFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("0666", 8));
|
||||
do_log_info("Creating fake backup " + backupFile.leafName);
|
||||
if (!backupFile.exists())
|
||||
do_throw("Unable to create fake backup " + backupFile.leafName);
|
||||
}
|
||||
|
||||
// Replace PlacesUtils getFormattedString so that it will return the localized
|
||||
// string we want.
|
||||
PlacesUtils.getFormattedString = function (aKey, aValue) {
|
||||
return LOCALIZED_PREFIX + aValue;
|
||||
}
|
||||
yield PlacesBackups.create(NUMBER_OF_BACKUPS);
|
||||
// Add today's backup.
|
||||
dates.push(dateObj.toLocaleFormat("%Y-%m-%d"));
|
||||
|
||||
yield PlacesBackups.create(Math.floor(dates.length/2));
|
||||
// Add today's backup.
|
||||
dates.push(dateObj.toLocaleFormat("%Y-%m-%d"));
|
||||
|
||||
// Check backups.
|
||||
for (var i = 0; i < dates.length; i++) {
|
||||
let backupFilename;
|
||||
let shouldExist;
|
||||
let backupFile;
|
||||
if (i > Math.floor(dates.length/2)) {
|
||||
let files = bookmarksBackupDir.directoryEntries;
|
||||
let rx = new RegExp("^" + PREFIX + dates[i] + "(_[0-9]+){0,1}" + SUFFIX + "$");
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
if (entry.leafName.match(rx)) {
|
||||
backupFilename = entry.leafName;
|
||||
backupFile = entry;
|
||||
break;
|
||||
}
|
||||
// Check backups. We have 11 dates but we the max number is 10 so the
|
||||
// oldest backup should have been removed.
|
||||
for (let i = 0; i < dates.length; i++) {
|
||||
let backupFilename;
|
||||
let shouldExist;
|
||||
let backupFile;
|
||||
if (i > 0) {
|
||||
let files = bookmarksBackupDir.directoryEntries;
|
||||
let rx = new RegExp("^" + PREFIX + dates[i] + "(_[0-9]+){0,1}" + SUFFIX + "$");
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
if (entry.leafName.match(rx)) {
|
||||
backupFilename = entry.leafName;
|
||||
backupFile = entry;
|
||||
break;
|
||||
}
|
||||
shouldExist = true;
|
||||
}
|
||||
else {
|
||||
backupFilename = LOCALIZED_PREFIX + dates[i] + SUFFIX;
|
||||
backupFile = bookmarksBackupDir.clone();
|
||||
backupFile.append(backupFilename);
|
||||
shouldExist = false;
|
||||
}
|
||||
if (backupFile.exists() != shouldExist)
|
||||
do_throw("Backup should " + (shouldExist ? "" : "not") + " exist: " + backupFilename);
|
||||
shouldExist = true;
|
||||
}
|
||||
|
||||
// Cleanup backups folder.
|
||||
// XXX: Can't use bookmarksBackupDir.remove(true) because file lock happens
|
||||
// on WIN XP.
|
||||
let files = bookmarksBackupDir.directoryEntries;
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
entry.remove(false);
|
||||
else {
|
||||
backupFilename = PREFIX + dates[i] + SUFFIX;
|
||||
backupFile = bookmarksBackupDir.clone();
|
||||
backupFile.append(backupFilename);
|
||||
shouldExist = false;
|
||||
}
|
||||
do_check_false(bookmarksBackupDir.directoryEntries.hasMoreElements());
|
||||
if (backupFile.exists() != shouldExist)
|
||||
do_throw("Backup should " + (shouldExist ? "" : "not") + " exist: " + backupFilename);
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
||||
// Cleanup backups folder.
|
||||
// XXX: Can't use bookmarksBackupDir.remove(true) because file lock happens
|
||||
// on WIN XP.
|
||||
let files = bookmarksBackupDir.directoryEntries;
|
||||
while (files.hasMoreElements()) {
|
||||
let entry = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
entry.remove(false);
|
||||
}
|
||||
do_check_false(bookmarksBackupDir.directoryEntries.hasMoreElements());
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
:root {
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-binding: url("chrome://global/content/bindings/general.xml#root-element");
|
||||
-moz-control-character-visibility: visible;
|
||||
}
|
||||
|
||||
:root:-moz-locale-dir(rtl) {
|
||||
|
|
|
@ -24,13 +24,6 @@ finduri-MonthYear=%1$S %2$S
|
|||
# This is used to generate local files container when history is grouped by site
|
||||
localhost=(local files)
|
||||
|
||||
# LOCALIZATION NOTE (bookmarksArchiveFilename):
|
||||
# Do not change this string! It's used only to
|
||||
# detect older localized bookmark archives from
|
||||
# before bug 445704 was fixed. It will be removed
|
||||
# in a subsequent release.
|
||||
bookmarksArchiveFilename=bookmarks-%S.json
|
||||
|
||||
# LOCALIZATION NOTE
|
||||
# The string is used for showing file size of each backup in the "fileRestorePopup" popup
|
||||
# %1$S is the file size
|
||||
|
|
Загрузка…
Ссылка в новой задаче