merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: CsjtXJM2vcs
This commit is contained in:
Sebastian Hengst 2017-10-05 10:55:31 +02:00
Родитель de4a55d914 9338d6959a
Коммит cade0f0bf3
40 изменённых файлов: 302 добавлений и 710 удалений

Просмотреть файл

@ -1,7 +1,7 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path fill-opacity=".05" d="M15,2H1v12c0,0.6,0.5,1,1,1h12c0.6,0,1-0.4,1-1V2L15,2z"/>
<path d="M3,5v1h2V5H3z M3,9h2V8H3V9z M3,12h2v-1H3V12z"/>
<path fill-opacity=".9" d="M6,5v1h7V5H6z M12,8H6v1h6V8z M6,12h7v-1H6V12z"/>

До

Ширина:  |  Высота:  |  Размер: 687 B

После

Ширина:  |  Высота:  |  Размер: 723 B

Просмотреть файл

@ -1,7 +1,7 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path fill-opacity=".15" d="M15,14H1c-0.6,0-1-0.4-1-1V3c0-0.5,0.4-1,1-1h14c0.6,0,1,0.5,1,1v10C16,13.6,15.6,14,15,14z"/>
<path d="M8.4,4.2l1,2.1l2.3,0.3c0.3,0,0.5,0.4,0.2,0.7l-1.7,1.7l0.4,2.4c0.1,0.3-0.3,0.6-0.6,0.4L8,10.8L6,12 c-0.3,0.1-0.6-0.1-0.6-0.4l0.4-2.4L4.1,7.4C3.9,7.2,4,6.8,4.3,6.7l2.3-0.3l1-2.1C7.8,3.9,8.2,3.9,8.4,4.2z"/>
<path d="M15,2H1C0.5,2,0,2.5,0,3v10c0,0.5,0.5,1,1,1h14c0.5,0,1-0.5,1-1V3C16,2.5,15.5,2,15,2z M15,12.5 c0,0.3-0.2,0.5-0.5,0.5h-13C1.2,13,1,12.8,1,12.5v-9C1,3.2,1.2,3,1.5,3h13C14.8,3,15,3.2,15,3.5V12.5z"/>

До

Ширина:  |  Высота:  |  Размер: 866 B

После

Ширина:  |  Высота:  |  Размер: 902 B

Просмотреть файл

@ -1,6 +1,6 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path fill="context-fill" d="M3.5,10A2.5,2.5,0,1,0,6,12.5,2.5,2.5,0,0,0,3.5,10ZM2,1A1,1,0,0,0,2,3,10.883,10.883,0,0,1,13,14a1,1,0,0,0,2,0A12.862,12.862,0,0,0,2,1ZM2,5A1,1,0,0,0,2,7a6.926,6.926,0,0,1,7,7,1,1,0,0,0,2,0A8.9,8.9,0,0,0,2,5Z"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path d="M3.5,10A2.5,2.5,0,1,0,6,12.5,2.5,2.5,0,0,0,3.5,10ZM2,1A1,1,0,0,0,2,3,10.883,10.883,0,0,1,13,14a1,1,0,0,0,2,0A12.862,12.862,0,0,0,2,1ZM2,5A1,1,0,0,0,2,7a6.926,6.926,0,0,1,7,7,1,1,0,0,0,2,0A8.9,8.9,0,0,0,2,5Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 544 B

После

Ширина:  |  Высота:  |  Размер: 580 B

Просмотреть файл

@ -1,6 +1,6 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path fill="context-fill" d="M14,7H12.9a4.967,4.967,0,0,0-.732-1.753l.782-.783A1,1,0,1,0,11.535,3.05l-.782.783A4.968,4.968,0,0,0,9,3.1V2A1,1,0,0,0,7,2V3.1a4.968,4.968,0,0,0-1.753.732L4.464,3.05A1,1,0,0,0,3.05,4.464l.783.783A4.968,4.968,0,0,0,3.1,7H2A1,1,0,0,0,2,9H3.1a4.968,4.968,0,0,0,.732,1.753l-.783.782a1,1,0,1,0,1.414,1.414l.783-.782A4.967,4.967,0,0,0,7,12.9V14a1,1,0,0,0,2,0V12.9a4.968,4.968,0,0,0,1.753-.732l.782.782a1,1,0,0,0,1.414-1.414l-.782-.782A4.968,4.968,0,0,0,12.9,9H14a1,1,0,0,0,0-2ZM8,11a3,3,0,1,1,3-3A3,3,0,0,1,8,11Z"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path d="M14,7H12.9a4.967,4.967,0,0,0-.732-1.753l.782-.783A1,1,0,1,0,11.535,3.05l-.782.783A4.968,4.968,0,0,0,9,3.1V2A1,1,0,0,0,7,2V3.1a4.968,4.968,0,0,0-1.753.732L4.464,3.05A1,1,0,0,0,3.05,4.464l.783.783A4.968,4.968,0,0,0,3.1,7H2A1,1,0,0,0,2,9H3.1a4.968,4.968,0,0,0,.732,1.753l-.783.782a1,1,0,1,0,1.414,1.414l.783-.782A4.967,4.967,0,0,0,7,12.9V14a1,1,0,0,0,2,0V12.9a4.968,4.968,0,0,0,1.753-.732l.782.782a1,1,0,0,0,1.414-1.414l-.782-.782A4.968,4.968,0,0,0,12.9,9H14a1,1,0,0,0,0-2ZM8,11a3,3,0,1,1,3-3A3,3,0,0,1,8,11Z"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 843 B

После

Ширина:  |  Высота:  |  Размер: 880 B

Просмотреть файл

@ -1,7 +1,7 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path fill-opacity=".15" d="M5,1H1C0.4,1,0,1.4,0,2v12.1C0,14.6,0.4,15,0.9,15h14.2c0.5,0,0.9-0.4,0.9-0.9V3.9C16,3.4,15.6,3,15.1,3H7 L6.2,1.9C6.2,1.9,5.6,1,5,1L5,1z"/>
<path d="M4.9,2C5,2.1,5.2,2.3,5.4,2.5l0.8,1.1L6.5,4H7h7.5C14.8,4,15,4.2,15,4.5v9c0,0.3-0.2,0.5-0.5,0.5h-13 C1.2,14,1,13.8,1,13.5v-11C1,2.2,1.2,2,1.5,2H4.9 M5,1H1C0.4,1,0,1.4,0,2v12.1C0,14.6,0.4,15,0.9,15h14.2c0.5,0,0.9-0.4,0.9-0.9V3.9 C16,3.4,15.6,3,15.1,3H7L6.2,1.9C6.2,1.9,5.6,1,5,1L5,1z"/>
<path fill-opacity=".15" d="M14,5H2C0.9,5,0,5.9,0,7v7c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1V7C16,5.9,15.1,5,14,5L14,5z"/>

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Просмотреть файл

@ -1,7 +1,7 @@
<!-- 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/. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" xmlns="http://www.w3.org/2000/svg">
<svg width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity" xmlns="http://www.w3.org/2000/svg">
<path fill-opacity=".05" d="M12.7,1H3.3l-.2.6L.1,9,0,9.2V13a2.006,2.006,0,0,0,2,2H14a2.006,2.006,0,0,0,2-2V9.2L15.9,9l-3-7.4L12.7,1Z"/>
<path d="M12,2l3,7.4V13a.945.945,0,0,1-1,1H2a.945.945,0,0,1-1-1V9.4L4,2h8m.7-1H3.3L.1,9.1,0,9.2V13a2.006,2.006,0,0,0,2,2H14a2.006,2.006,0,0,0,2-2V9.2L15.9,9,12.7,1Z"/>
<path fill-opacity=".05" d="M14.988,9,12,2H4L.851,9H5.023A2.931,2.931,0,0,0,8,11.6,2.889,2.889,0,0,0,11.012,9Z"/>

До

Ширина:  |  Высота:  |  Размер: 823 B

После

Ширина:  |  Высота:  |  Размер: 859 B

Просмотреть файл

@ -526,8 +526,9 @@ toolbar[brighttext] {
.bookmark-item {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
-moz-context-properties: fill;
-moz-context-properties: fill, fill-opacity;
fill: currentColor;
fill-opacity: var(--toolbarbutton-icon-fill-opacity);
}
.bookmark-item[container] {

Просмотреть файл

@ -258,6 +258,7 @@ def get_tool(config, key):
# clang/
# bin/
# clang-tidy
# clang-apply-replacements
# include/
# * (nothing will be deleted here)
# lib/
@ -278,8 +279,10 @@ def prune_final_dir_for_clang_tidy(final_dir):
if not os.path.isdir(f):
raise Exception("Expected %s to be a directory" %f)
# In bin/, only keep clang-tidy.
re_clang_tidy = re.compile(r"^clang-tidy(\.exe)?$", re.I)
# In bin/, only keep clang-tidy and clang-apply-replacements. The last one
# is used to auto-fix some of the issues detected by clang-tidy.
re_clang_tidy = re.compile(
r"^clang-(tidy|apply-replacements)(\.exe)?$", re.I)
for f in glob.glob("%s/bin/*" % final_dir):
if re_clang_tidy.search(os.path.basename(f)) is None:
delete(f)

Просмотреть файл

@ -59,7 +59,7 @@ pref("devtools.inspector.showAllAnonymousContent", false);
// Enable the new color widget
pref("devtools.inspector.colorWidget.enabled", false);
// Enable the CSS shapes highlighter
pref("devtools.inspector.shapesHighlighter.enabled", false);
pref("devtools.inspector.shapesHighlighter.enabled", true);
// Enable the Font Inspector
pref("devtools.fontinspector.enabled", true);

Просмотреть файл

@ -29,6 +29,7 @@ const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
const HTML_NS = "http://www.w3.org/1999/xhtml";
const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled";
const CSS_SHAPES_ENABLED_PREF = "devtools.inspector.shapesHighlighter.enabled";
const CSS_SHAPE_OUTSIDE_ENABLED_PREF = "layout.css.shape-outside.enabled";
/**
* This module is used to process text for output by developer tools. This means
@ -88,7 +89,9 @@ OutputParser.prototype = {
options.expectCubicBezier = this.supportsType(name, CSS_TYPES.TIMING_FUNCTION);
options.expectDisplay = name === "display";
options.expectFilter = name === "filter";
options.expectShape = name === "clip-path" || name === "shape-outside";
options.expectShape = name === "clip-path" ||
(name === "shape-outside"
&& Services.prefs.getBoolPref(CSS_SHAPE_OUTSIDE_ENABLED_PREF));
options.supportsColor = this.supportsType(name, CSS_TYPES.COLOR) ||
this.supportsType(name, CSS_TYPES.GRADIENT);

Просмотреть файл

@ -2087,12 +2087,12 @@ protected:
mozilla::ErrorResult& aRv);
/**
* Parse the given selector string into a SelectorList.
* Parse the given selector string a SelectorList, depending on whether we're
* in a Servo or Gecko-backed document, and execute either aServoFunctor or
* aGeckoFunctor on it.
*
* A null return value with a non-failing aRv means the string only
* contained pseudo-element selectors.
*
* A failing aRv means the string was not a valid selector.
* Note that the selector list is owned by the owner doc's selector cache
* which can get expired, so you shouldn't keep it around for long.
*/
template<typename Ret, typename ServoFunctor, typename GeckoFunctor>
Ret WithSelectorList(

4
dom/cache/FileUtils.cpp поставляемый
Просмотреть файл

@ -875,10 +875,10 @@ LockedDirectoryPaddingRestore(nsIFile* aBaseDir, mozIStorageConnection* aConn)
// The content of padding file is untrusted, so remove it here.
nsresult rv = LockedDirectoryPaddingDeleteFile(aBaseDir,
DirPaddingFile::TMP_FILE);
DirPaddingFile::FILE);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
rv = LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
int64_t paddingSize = 0;

21
dom/cache/Manager.cpp поставляемый
Просмотреть файл

@ -495,6 +495,13 @@ public:
virtual void
CompleteOnInitiatingThread(nsresult aRv) override
{
// If the transaction fails, we shouldn't delete the body files and decrease
// their padding size.
if (NS_FAILED(aRv)) {
mDeletedBodyIdList.Clear();
mDeletedPaddingSize = 0;
}
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {
@ -867,6 +874,13 @@ private:
mList[i].mResponseStream = nullptr;
}
// If the transaction fails, we shouldn't delete the body files and decrease
// their padding size.
if (NS_FAILED(aRv)) {
mDeletedBodyIdList.Clear();
mDeletedPaddingSize = 0;
}
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {
@ -1107,6 +1121,13 @@ public:
virtual void
Complete(Listener* aListener, ErrorResult&& aRv) override
{
// If the transaction fails, we shouldn't delete the body files and decrease
// their padding size.
if (aRv.Failed()) {
mDeletedBodyIdList.Clear();
mDeletedPaddingSize = 0;
}
mManager->NoteOrphanedBodyIdList(mDeletedBodyIdList);
if (mDeletedPaddingSize > 0) {

23
dom/cache/QuotaClient.cpp поставляемый
Просмотреть файл

@ -329,23 +329,34 @@ public:
aDecreaseSize,
temporaryPaddingFileExist);
if (NS_WARN_IF(NS_FAILED(rv))) {
mozilla::dom::cache::
LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
// Don't delete the temporary padding file here to force the next action
// recalculate the padding size.
return rv;
}
rv = aCommitHook();
if (NS_WARN_IF(NS_FAILED(rv))) {
mozilla::dom::cache::
LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::TMP_FILE);
// Don't delete the temporary padding file here to force the next action
// recalculate the padding size.
return rv;
}
rv = mozilla::dom::cache::LockedDirectoryPaddingFinalizeWrite(aBaseDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
// Force restore file next time.
mozilla::dom::cache::
LockedDirectoryPaddingDeleteFile(aBaseDir, DirPaddingFile::FILE);
Unused << mozilla::dom::cache::
LockedDirectoryPaddingDeleteFile(aBaseDir,
DirPaddingFile::FILE);
// Ensure that we are able to force the padding file to be restored.
MOZ_ASSERT(
mozilla::dom::cache::
DirectoryPaddingFileExists(aBaseDir, DirPaddingFile::TMP_FILE));
// Since both the body file and header have been stored in the
// file-system, just make the action be resolve and let the padding file
// be restored in the next action.
rv = NS_OK;
}
}

Просмотреть файл

@ -115,7 +115,8 @@ WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
}
void
WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
wr::BuiltDisplayList& aDL,
wr::IpcResourceUpdateQueue& aResources,
const gfx::IntSize& aSize,
bool aIsSync,
@ -126,10 +127,7 @@ WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mIsInTransaction);
wr::BuiltDisplayList dl;
wr::LayoutSize contentSize;
aBuilder.Finalize(contentSize, dl);
ByteBuffer dlData(Move(dl.dl));
ByteBuffer dlData(Move(aDL.dl));
TimeStamp fwdTime;
#if defined(ENABLE_FRAME_LATENCY_LOG)
@ -144,13 +142,13 @@ WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
if (aIsSync) {
this->SendSetDisplayListSync(aSize, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId,
contentSize, dlData, dl.dl_desc, aScrollData,
aContentSize, dlData, aDL.dl_desc, aScrollData,
Move(resourceUpdates), Move(smallShmems), Move(largeShmems),
mIdNamespace, aTxnStartTime, fwdTime);
} else {
this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId,
contentSize, dlData, dl.dl_desc, aScrollData,
aContentSize, dlData, aDL.dl_desc, aScrollData,
Move(resourceUpdates), Move(smallShmems), Move(largeShmems),
mIdNamespace, aTxnStartTime, fwdTime);
}

Просмотреть файл

@ -68,7 +68,8 @@ public:
void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
bool BeginTransaction(const gfx::IntSize& aSize);
void EndTransaction(wr::DisplayListBuilder &aBuilder,
void EndTransaction(const wr::LayoutSize& aContentSize,
wr::BuiltDisplayList& dl,
wr::IpcResourceUpdateQueue& aResources,
const gfx::IntSize& aSize,
bool aIsSync, uint64_t aTransactionId,

Просмотреть файл

@ -49,8 +49,6 @@ WebRenderCommandBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder
CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc,
aBuilder, aResourceUpdates);
aBuilder.Finalize(aContentSize, mBuiltDisplayList);
// Make a "root" layer data that has everything else as descendants
mLayerScrollData.emplace_back();
mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
@ -81,7 +79,6 @@ WebRenderCommandBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder
RemoveUnusedAndResetWebRenderUserData();
}
aBuilder.PushBuiltDisplayList(mBuiltDisplayList);
mManager->WrBridge()->AddWebRenderParentCommands(mParentCommands);
}

Просмотреть файл

@ -158,7 +158,6 @@ private:
// These fields are used to save a copy of the display list for
// empty transactions in layers-free mode.
wr::BuiltDisplayList mBuiltDisplayList;
nsTArray<WebRenderParentCommand> mParentCommands;
// We use this as a temporary data structure while building the mScrollData

Просмотреть файл

@ -34,6 +34,7 @@ WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
, mTarget(nullptr)
, mPaintSequenceNumber(0)
, mWebRenderCommandBuilder(this)
, mLastDisplayListSize(0)
{
MOZ_COUNT_CTOR(WebRenderLayerManager);
}
@ -244,7 +245,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
DiscardCompositorAnimations();
wr::LayoutSize contentSize { (float)size.width, (float)size.height };
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize, mLastDisplayListSize);
wr::IpcResourceUpdateQueue resourceUpdates(WrBridge()->GetShmemAllocator());
mWebRenderCommandBuilder.BuildWebRenderCommands(builder,
@ -295,10 +296,15 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
WrBridge()->GetSyncObject()->Synchronize();
}
}
wr::BuiltDisplayList dl;
builder.Finalize(contentSize, dl);
mLastDisplayListSize = dl.dl.inner.capacity;
{
AutoProfilerTracing
tracing("Paint", sync ? "ForwardDPTransactionSync":"ForwardDPTransaction");
WrBridge()->EndTransaction(builder, resourceUpdates, size.ToUnknownSize(), sync,
WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(), sync,
mLatestTransactionId, mScrollData, transactionStart);
}

Просмотреть файл

@ -212,6 +212,8 @@ private:
APZTestData mApzTestData;
WebRenderCommandBuilder mWebRenderCommandBuilder;
size_t mLastDisplayListSize;
};
} // namespace layers

Просмотреть файл

@ -538,7 +538,7 @@ private:
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram", FPSPrintHistogram, bool, false);
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
DECL_GFX_PREF(Once, "layers.acceleration.force-enabled", LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.background-color", LayersAllowBackgroundColorLayers, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.background-color", LayersAllowBackgroundColorLayers, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.background-image", LayersAllowBackgroundImage, gfxPrefs::OverrideBase_WebRender());
DECL_GFX_PREF(Live, "layers.advanced.basic-layer.enabled", LayersAdvancedBasicLayerEnabled, bool, false);
DECL_OVERRIDE_PREF(Live, "layers.advanced.border-layers", LayersAllowBorderLayers, gfxPrefs::OverrideBase_WebRender());

Просмотреть файл

@ -623,11 +623,12 @@ WebRenderAPI::RunOnRenderThread(UniquePtr<RendererEvent> aEvent)
}
DisplayListBuilder::DisplayListBuilder(PipelineId aId,
const wr::LayoutSize& aContentSize)
const wr::LayoutSize& aContentSize,
size_t aCapacity)
: mMaskClipCount(0)
{
MOZ_COUNT_CTOR(DisplayListBuilder);
mWrState = wr_state_new(aId, aContentSize);
mWrState = wr_state_new(aId, aContentSize, aCapacity);
}
DisplayListBuilder::~DisplayListBuilder()

Просмотреть файл

@ -202,7 +202,8 @@ protected:
class DisplayListBuilder {
public:
explicit DisplayListBuilder(wr::PipelineId aId,
const wr::LayoutSize& aContentSize);
const wr::LayoutSize& aContentSize,
size_t aCapacity = 0);
DisplayListBuilder(DisplayListBuilder&&) = default;
~DisplayListBuilder();

Просмотреть файл

@ -1062,6 +1062,15 @@ impl WebRenderFrameBuilder {
dl_builder: webrender_api::DisplayListBuilder::new(root_pipeline_id, content_size),
}
}
pub fn with_capacity(root_pipeline_id: WrPipelineId,
content_size: LayoutSize,
capacity: usize) -> WebRenderFrameBuilder {
WebRenderFrameBuilder {
root_pipeline_id: root_pipeline_id,
dl_builder: webrender_api::DisplayListBuilder::with_capacity(root_pipeline_id, content_size, capacity),
}
}
}
pub struct WrState {
@ -1071,13 +1080,15 @@ pub struct WrState {
#[no_mangle]
pub extern "C" fn wr_state_new(pipeline_id: WrPipelineId,
content_size: LayoutSize) -> *mut WrState {
content_size: LayoutSize,
capacity: usize) -> *mut WrState {
assert!(unsafe { !is_in_render_thread() });
let state = Box::new(WrState {
pipeline_id: pipeline_id,
frame_builder: WebRenderFrameBuilder::new(pipeline_id,
content_size),
frame_builder: WebRenderFrameBuilder::with_capacity(pipeline_id,
content_size,
capacity),
});
Box::into_raw(state)

Просмотреть файл

@ -1307,7 +1307,8 @@ WR_DESTRUCTOR_SAFE_FUNC;
WR_INLINE
WrState *wr_state_new(WrPipelineId aPipelineId,
LayoutSize aContentSize)
LayoutSize aContentSize,
size_t aCapacity)
WR_FUNC;
WR_INLINE

Просмотреть файл

@ -4262,15 +4262,15 @@ nsDisplayBackgroundColor::CreateWebRenderCommands(mozilla::wr::DisplayListBuilde
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
ContainerLayerParameters parameter;
if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
return false;
}
if (mColor == Color()) {
return true;
}
StyleGeometryBox clip = mBackgroundStyle->mImage.mLayers[0].mClip;
if (clip == StyleGeometryBox::Text) {
return false;
}
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
mBackgroundRect, mFrame->PresContext()->AppUnitsPerDevPixel());
wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(bounds);

Просмотреть файл

@ -5888,7 +5888,7 @@ pref("layers.mlgpu.enable-on-windows7", true);
// it to a boolean as appropriate. In particular, do NOT add ifdefs here to
// turn these on and off, instead use the conditional-pref code in gfxPrefs.h
// to do that.
pref("layers.advanced.background-color", 2);
pref("layers.advanced.background-color", false);
pref("layers.advanced.background-image", 2);
pref("layers.advanced.border-layers", 2);
pref("layers.advanced.boxshadow-inset-layers", 2);

Просмотреть файл

@ -3320,7 +3320,7 @@ nsCookieService::GetCookiesForURI(nsIURI *aHostURI,
}
// Note: The following permissions logic is mirrored in
// toolkit/modules/addons/MatchPattern.jsm:MatchPattern.matchesCookie().
// extensions::MatchPattern::MatchesCookie.
// If it changes, please update that function, or file a bug for someone
// else to do so.

Просмотреть файл

@ -8,7 +8,7 @@
/* global tabTracker */
XPCOMUtils.defineLazyModuleGetter(this, "MatchURLFilters",
"resource://gre/modules/MatchPattern.jsm");
"resource://gre/modules/MatchURLFilters.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebNavigation",
"resource://gre/modules/WebNavigation.jsm");

Просмотреть файл

@ -34,6 +34,7 @@ skip-if = os == 'android' # Bug 1350559
[test_chrome_ext_webrequest_errors.html]
[test_chrome_ext_webrequest_host_permissions.html]
[test_chrome_ext_webrequest_mozextension.html]
skip-if = true # Bug 1404172
[test_chrome_native_messaging_paths.html]
skip-if = os != "mac" && os != "linux"
[test_ext_cookies_expiry.html]

Просмотреть файл

@ -1,424 +0,0 @@
/* 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/. */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["MatchPattern", "MatchGlobs", "MatchURLFilters"];
/* globals MatchPattern, MatchGlobs */
const PERMITTED_SCHEMES = ["http", "https", "ws", "wss", "file", "ftp", "data"];
const PERMITTED_SCHEMES_REGEXP = [...PERMITTED_SCHEMES, "moz-extension"].join("|");
// The basic RE for matching patterns
const PATTERN_REGEXP = new RegExp(`^(${PERMITTED_SCHEMES_REGEXP}|\\*)://(\\*|\\*\\.[^*/]+|[^*/]+|)(/.*)$`);
// The schemes/protocols implied by a pattern that starts with *://
const WILDCARD_SCHEMES = ["http", "https"];
// This function converts a glob pattern (containing * and possibly ?
// as wildcards) to a regular expression.
function globToRegexp(pat, allowQuestion) {
// Escape everything except ? and *.
pat = pat.replace(/[.+^${}()|[\]\\]/g, "\\$&");
if (allowQuestion) {
pat = pat.replace(/\?/g, ".");
} else {
pat = pat.replace(/\?/g, "\\?");
}
pat = pat.replace(/\*/g, ".*");
return new RegExp("^" + pat + "$");
}
// These patterns follow the syntax in
// https://developer.chrome.com/extensions/match_patterns
function SingleMatchPattern(pat) {
this.pat = pat;
if (pat == "<all_urls>") {
this.schemes = PERMITTED_SCHEMES;
this.hostMatch = () => true;
this.pathMatch = () => true;
} else if (!pat) {
this.schemes = [];
} else {
let match = PATTERN_REGEXP.exec(pat);
if (!match) {
Cu.reportError(`Invalid match pattern: '${pat}'`);
this.schemes = [];
return;
}
if (match[1] == "*") {
this.schemes = WILDCARD_SCHEMES;
} else {
this.schemes = [match[1]];
}
// We allow the host to be empty for file URLs.
if (match[2] == "" && this.schemes[0] != "file") {
Cu.reportError(`Invalid match pattern: '${pat}'`);
this.schemes = [];
return;
}
// We disallow the host to be * for moz-extension URLs.
if (match[2] == "*" && this.schemes[0] == "moz-extension") {
Cu.reportError(`Invalid match pattern: '${pat}'`);
this.schemes = [];
return;
}
this.host = match[2];
this.hostMatch = this.getHostMatcher(match[2]);
let pathMatch = globToRegexp(match[3], false);
this.pathMatch = pathMatch.test.bind(pathMatch);
}
}
SingleMatchPattern.prototype = {
getHostMatcher(host) {
// This code ignores the port, as Chrome does.
if (host == "*") {
return () => true;
}
if (host.startsWith("*.")) {
let suffix = host.substr(2);
let dotSuffix = "." + suffix;
return ({host}) => host === suffix || host.endsWith(dotSuffix);
}
return uri => uri.host === host;
},
matches(uri, ignorePath = false) {
return (
this.schemes.includes(uri.scheme) &&
this.hostMatch(uri) &&
(ignorePath || (
this.pathMatch(uri.cloneIgnoringRef().pathQueryRef)
))
);
},
// Tests if this can possibly overlap with the |other| SingleMatchPattern.
overlapsIgnoringPath(other) {
return this.schemes.some(scheme => other.schemes.includes(scheme)) &&
(this.hostMatch(other) || other.hostMatch(this));
},
get pattern() { return this.pat; },
};
this.MatchPattern = function(pat) {
this.pat = pat;
if (!pat) {
this.matchers = [];
} else if (pat instanceof String || typeof(pat) == "string") {
this.matchers = [new SingleMatchPattern(pat)];
} else {
this.matchers = pat.map(p => new SingleMatchPattern(p));
}
XPCOMUtils.defineLazyGetter(this, "explicitMatchers", () => {
return this.matchers.filter(matcher => matcher.pat != "<all_urls>" &&
matcher.host &&
!matcher.host.startsWith("*"));
});
};
MatchPattern.prototype = {
// |uri| should be an nsIURI.
matches(uri) {
return this.matchers.some(matcher => matcher.matches(uri));
},
get patterns() { return this.matchers; },
matchesIgnoringPath(uri, explicit = false) {
if (explicit) {
return this.explicitMatchers.some(matcher => matcher.matches(uri, true));
}
return this.matchers.some(matcher => matcher.matches(uri, true));
},
// Checks that this match pattern grants access to read the given
// cookie. |cookie| should be an |nsICookie2| instance.
matchesCookie(cookie) {
// First check for simple matches.
let secureURI = NetUtil.newURI(`https://${cookie.rawHost}/`);
if (this.matchesIgnoringPath(secureURI)) {
return true;
}
let plainURI = NetUtil.newURI(`http://${cookie.rawHost}/`);
if (!cookie.isSecure && this.matchesIgnoringPath(plainURI)) {
return true;
}
if (!cookie.isDomain) {
return false;
}
// Things get tricker for domain cookies. The extension needs to be able
// to read any cookies that could be read any host it has permissions
// for. This means that our normal host matching checks won't work,
// since the pattern "*://*.foo.example.com/" doesn't match ".example.com",
// but it does match "bar.foo.example.com", which can read cookies
// with the domain ".example.com".
//
// So, instead, we need to manually check our filters, and accept any
// with hosts that end with our cookie's host.
let {host, isSecure} = cookie;
for (let matcher of this.matchers) {
let schemes = matcher.schemes;
if (schemes.includes("https") || (!isSecure && schemes.includes("http"))) {
if (matcher.host.endsWith(host)) {
return true;
}
}
}
return false;
},
// Checks if every part of this filter overlaps with
// some of the |hosts| or |optional| permissions MatchPatterns.
overlapsPermissions(hosts, optional) {
const perms = hosts.matchers.concat(optional.matchers);
return this.matchers.length &&
this.matchers.every(m => perms.some(p => p.overlapsIgnoringPath(m)));
},
// Test if this MatchPattern subsumes the given pattern (i.e., whether
// this pattern matches everything the given pattern does).
// Note, this method considers only to protocols and hosts/domains,
// paths are ignored.
subsumes(pattern) {
let match = PATTERN_REGEXP.exec(pattern);
if (!match) {
throw new Error("Invalid match pattern");
}
if (match[1] == "*") {
return WILDCARD_SCHEMES.every(scheme => this.matchesIgnoringPath({scheme, host: match[2]}));
}
return this.matchesIgnoringPath({scheme: match[1], host: match[2]});
},
serialize() {
return this.pat;
},
removeOne(pattern) {
if (!Array.isArray(this.pat)) {
return;
}
let index = this.pat.indexOf(pattern);
if (index >= 0) {
if (this.matchers[index].pat != pattern) {
throw new Error("pat/matcher mismatch in removeOne()");
}
this.pat.splice(index, 1);
this.matchers.splice(index, 1);
}
},
};
// Globs can match everything. Be careful, this DOES NOT filter by allowed schemes!
this.MatchGlobs = function(globs) {
this.original = globs;
if (globs) {
this.regexps = Array.from(globs, (glob) => globToRegexp(glob, true));
} else {
this.regexps = [];
}
};
MatchGlobs.prototype = {
matches(str) {
return this.regexps.some(regexp => regexp.test(str));
},
serialize() {
return this.original;
},
};
// Match WebNavigation URL Filters.
this.MatchURLFilters = function(filters) {
if (!Array.isArray(filters)) {
throw new TypeError("filters should be an array");
}
if (filters.length == 0) {
throw new Error("filters array should not be empty");
}
this.filters = filters;
};
MatchURLFilters.prototype = {
matches(url) {
let uri = NetUtil.newURI(url);
// Set uriURL to an empty object (needed because some schemes, e.g. about doesn't support nsIURL).
let uriURL = {};
if (uri instanceof Ci.nsIURL) {
uriURL = uri;
}
// Set host to a empty string by default (needed so that schemes without an host,
// e.g. about, can pass an empty string for host based event filtering as expected).
let host = "";
try {
host = uri.host;
} catch (e) {
// 'uri.host' throws an exception with some uri schemes (e.g. about).
}
let port;
try {
port = uri.port;
} catch (e) {
// 'uri.port' throws an exception with some uri schemes (e.g. about),
// in which case it will be |undefined|.
}
let data = {
// NOTE: This properties are named after the name of their related
// filters (e.g. `pathContains/pathEquals/...` will be tested against the
// `data.path` property, and the same is done for the `host`, `query` and `url`
// components as well).
path: uriURL.filePath,
query: uriURL.query,
host,
port,
url,
};
// If any of the filters matches, matches returns true.
return this.filters.some(filter => this.matchURLFilter({filter, data, uri, uriURL}));
},
matchURLFilter({filter, data, uri, uriURL}) {
// Test for scheme based filtering.
if (filter.schemes) {
// Return false if none of the schemes matches.
if (!filter.schemes.some((scheme) => uri.schemeIs(scheme))) {
return false;
}
}
// Test for exact port matching or included in a range of ports.
if (filter.ports) {
let port = data.port;
if (port === -1) {
// NOTE: currently defaultPort for "resource" and "chrome" schemes defaults to -1,
// for "about", "data" and "javascript" schemes defaults to undefined.
if (["resource", "chrome"].includes(uri.scheme)) {
port = undefined;
} else {
port = Services.io.getProtocolHandler(uri.scheme).defaultPort;
}
}
// Return false if none of the ports (or port ranges) is verified
return filter.ports.some((filterPort) => {
if (Array.isArray(filterPort)) {
let [lower, upper] = filterPort;
return port >= lower && port <= upper;
}
return port === filterPort;
});
}
// Filters on host, url, path, query:
// hostContains, hostEquals, hostSuffix, hostPrefix,
// urlContains, urlEquals, ...
for (let urlComponent of ["host", "path", "query", "url"]) {
if (!this.testMatchOnURLComponent({urlComponent, data, filter})) {
return false;
}
}
// urlMatches is a regular expression string and it is tested for matches
// on the "url without the ref".
if (filter.urlMatches) {
let urlWithoutRef = uri.specIgnoringRef;
if (!urlWithoutRef.match(filter.urlMatches)) {
return false;
}
}
// originAndPathMatches is a regular expression string and it is tested for matches
// on the "url without the query and the ref".
if (filter.originAndPathMatches) {
let urlWithoutQueryAndRef = uri.resolve(uriURL.filePath);
// The above 'uri.resolve(...)' will be null for some URI schemes
// (e.g. about).
// TODO: handle schemes which will not be able to resolve the filePath
// (e.g. for "about:blank", 'urlWithoutQueryAndRef' should be "about:blank" instead
// of null)
if (!urlWithoutQueryAndRef ||
!urlWithoutQueryAndRef.match(filter.originAndPathMatches)) {
return false;
}
}
return true;
},
testMatchOnURLComponent({urlComponent: key, data, filter}) {
// Test for equals.
// NOTE: an empty string should not be considered a filter to skip.
if (filter[`${key}Equals`] != null) {
if (data[key] !== filter[`${key}Equals`]) {
return false;
}
}
// Test for contains.
if (filter[`${key}Contains`]) {
let value = (key == "host" ? "." : "") + data[key];
if (!data[key] || !value.includes(filter[`${key}Contains`])) {
return false;
}
}
// Test for prefix.
if (filter[`${key}Prefix`]) {
if (!data[key] || !data[key].startsWith(filter[`${key}Prefix`])) {
return false;
}
}
// Test for suffix.
if (filter[`${key}Suffix`]) {
if (!data[key] || !data[key].endsWith(filter[`${key}Suffix`])) {
return false;
}
}
return true;
},
serialize() {
return this.filters;
},
};

Просмотреть файл

@ -0,0 +1,180 @@
/* 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/. */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
/* exported MatchURLFilters */
this.EXPORTED_SYMBOLS = ["MatchURLFilters"];
// Match WebNavigation URL Filters.
class MatchURLFilters {
constructor(filters) {
if (!Array.isArray(filters)) {
throw new TypeError("filters should be an array");
}
if (filters.length == 0) {
throw new Error("filters array should not be empty");
}
this.filters = filters;
}
matches(url) {
let uri = Services.io.newURI(url);
// Set uriURL to an empty object (needed because some schemes, e.g. about doesn't support nsIURL).
let uriURL = {};
if (uri instanceof Ci.nsIURL) {
uriURL = uri;
}
// Set host to a empty string by default (needed so that schemes without an host,
// e.g. about, can pass an empty string for host based event filtering as expected).
let host = "";
try {
host = uri.host;
} catch (e) {
// 'uri.host' throws an exception with some uri schemes (e.g. about).
}
let port;
try {
port = uri.port;
} catch (e) {
// 'uri.port' throws an exception with some uri schemes (e.g. about),
// in which case it will be |undefined|.
}
let data = {
// NOTE: This properties are named after the name of their related
// filters (e.g. `pathContains/pathEquals/...` will be tested against the
// `data.path` property, and the same is done for the `host`, `query` and `url`
// components as well).
path: uriURL.filePath,
query: uriURL.query,
host,
port,
url,
};
// If any of the filters matches, matches returns true.
return this.filters.some(filter => this.matchURLFilter({filter, data, uri, uriURL}));
}
matchURLFilter({filter, data, uri, uriURL}) {
// Test for scheme based filtering.
if (filter.schemes) {
// Return false if none of the schemes matches.
if (!filter.schemes.some((scheme) => uri.schemeIs(scheme))) {
return false;
}
}
// Test for exact port matching or included in a range of ports.
if (filter.ports) {
let port = data.port;
if (port === -1) {
// NOTE: currently defaultPort for "resource" and "chrome" schemes defaults to -1,
// for "about", "data" and "javascript" schemes defaults to undefined.
if (["resource", "chrome"].includes(uri.scheme)) {
port = undefined;
} else {
port = Services.io.getProtocolHandler(uri.scheme).defaultPort;
}
}
// Return false if none of the ports (or port ranges) is verified
return filter.ports.some((filterPort) => {
if (Array.isArray(filterPort)) {
let [lower, upper] = filterPort;
return port >= lower && port <= upper;
}
return port === filterPort;
});
}
// Filters on host, url, path, query:
// hostContains, hostEquals, hostSuffix, hostPrefix,
// urlContains, urlEquals, ...
for (let urlComponent of ["host", "path", "query", "url"]) {
if (!this.testMatchOnURLComponent({urlComponent, data, filter})) {
return false;
}
}
// urlMatches is a regular expression string and it is tested for matches
// on the "url without the ref".
if (filter.urlMatches) {
let urlWithoutRef = uri.specIgnoringRef;
if (!urlWithoutRef.match(filter.urlMatches)) {
return false;
}
}
// originAndPathMatches is a regular expression string and it is tested for matches
// on the "url without the query and the ref".
if (filter.originAndPathMatches) {
let urlWithoutQueryAndRef = uri.resolve(uriURL.filePath);
// The above 'uri.resolve(...)' will be null for some URI schemes
// (e.g. about).
// TODO: handle schemes which will not be able to resolve the filePath
// (e.g. for "about:blank", 'urlWithoutQueryAndRef' should be "about:blank" instead
// of null)
if (!urlWithoutQueryAndRef ||
!urlWithoutQueryAndRef.match(filter.originAndPathMatches)) {
return false;
}
}
return true;
}
testMatchOnURLComponent({urlComponent: key, data, filter}) {
// Test for equals.
// NOTE: an empty string should not be considered a filter to skip.
if (filter[`${key}Equals`] != null) {
if (data[key] !== filter[`${key}Equals`]) {
return false;
}
}
// Test for contains.
if (filter[`${key}Contains`]) {
let value = (key == "host" ? "." : "") + data[key];
if (!data[key] || !value.includes(filter[`${key}Contains`])) {
return false;
}
}
// Test for prefix.
if (filter[`${key}Prefix`]) {
if (!data[key] || !data[key].startsWith(filter[`${key}Prefix`])) {
return false;
}
}
// Test for suffix.
if (filter[`${key}Suffix`]) {
if (!data[key] || !data[key].endsWith(filter[`${key}Suffix`])) {
return false;
}
}
return true;
}
serialize() {
return this.filters;
}
}

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Managed via the message managers.
/* global initialProcessData */
/* globals MatchPatternSet, initialProcessData */
"use strict";
@ -15,8 +15,6 @@ var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "MatchPattern",
"resource://gre/modules/MatchPattern.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "WebRequestCommon",
"resource://gre/modules/WebRequestCommon.jsm");
@ -53,7 +51,7 @@ var ContentPolicy = {
this.register();
}
if (filter.urls) {
filter.urls = new MatchPattern(filter.urls);
filter.urls = new MatchPatternSet(filter.urls);
}
this.contentPolicies.set(id, {blocking, filter});
},

Просмотреть файл

@ -163,7 +163,7 @@ TESTING_JS_MODULES += [
SPHINX_TREES['toolkit_modules'] = 'docs'
EXTRA_JS_MODULES += [
'addons/MatchPattern.jsm',
'addons/MatchURLFilters.jsm',
'addons/WebNavigation.jsm',
'addons/WebNavigationContent.js',
'addons/WebNavigationFrames.jsm',

Просмотреть файл

@ -1,58 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Components.utils.import("resource://gre/modules/MatchPattern.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function test(url, pattern) {
let uri = Services.io.newURI(url);
let m = new MatchGlobs(pattern);
return m.matches(uri.spec);
}
function pass({url, pattern}) {
ok(test(url, pattern), `Expected match: ${JSON.stringify(pattern)}, ${url}`);
}
function fail({url, pattern}) {
ok(!test(url, pattern), `Expected no match: ${JSON.stringify(pattern)}, ${url}`);
}
function run_test() {
let moz = "http://mozilla.org";
pass({url: moz, pattern: ["*"]});
pass({url: moz, pattern: ["http://*"]}),
pass({url: moz, pattern: ["*mozilla*"]});
pass({url: moz, pattern: ["*example*", "*mozilla*"]});
pass({url: moz, pattern: ["*://*"]});
pass({url: "https://mozilla.org", pattern: ["*://*"]});
// Documentation example
pass({url: "http://www.example.com/foo/bar", pattern: ["http://???.example.com/foo/*"]});
pass({url: "http://the.example.com/foo/", pattern: ["http://???.example.com/foo/*"]});
fail({url: "http://my.example.com/foo/bar", pattern: ["http://???.example.com/foo/*"]});
fail({url: "http://example.com/foo/", pattern: ["http://???.example.com/foo/*"]});
fail({url: "http://www.example.com/foo", pattern: ["http://???.example.com/foo/*"]});
// Matches path
let path = moz + "/abc/def";
pass({url: path, pattern: ["*def"]});
pass({url: path, pattern: ["*c/d*"]});
pass({url: path, pattern: ["*org/abc*"]});
fail({url: path + "/", pattern: ["*def"]});
// Trailing slash
pass({url: moz, pattern: ["*.org/"]});
fail({url: moz, pattern: ["*.org"]});
// Wrong TLD
fail({url: moz, pattern: ["www*.m*.com/"]});
// Case sensitive
fail({url: moz, pattern: ["*.ORG/"]});
fail({url: moz, pattern: []});
}

Просмотреть файл

@ -1,158 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
Components.utils.import("resource://gre/modules/MatchPattern.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function test_matches() {
function test(url, pattern) {
let uri = Services.io.newURI(url);
let m = new MatchPattern(pattern);
return m.matches(uri);
}
function pass({url, pattern}) {
do_check_true(test(url, pattern), `Expected match: ${JSON.stringify(pattern)}, ${url}`);
}
function fail({url, pattern}) {
do_check_false(test(url, pattern), `Expected no match: ${JSON.stringify(pattern)}, ${url}`);
}
// Invalid pattern.
fail({url: "http://mozilla.org", pattern: ""});
// Pattern must include trailing slash.
fail({url: "http://mozilla.org", pattern: "http://mozilla.org"});
// Protocol not allowed.
fail({url: "http://mozilla.org", pattern: "gopher://wuarchive.wustl.edu/"});
pass({url: "http://mozilla.org", pattern: "http://mozilla.org/"});
pass({url: "http://mozilla.org/", pattern: "http://mozilla.org/"});
pass({url: "http://mozilla.org/", pattern: "*://mozilla.org/"});
pass({url: "https://mozilla.org/", pattern: "*://mozilla.org/"});
fail({url: "file://mozilla.org/", pattern: "*://mozilla.org/"});
fail({url: "ftp://mozilla.org/", pattern: "*://mozilla.org/"});
fail({url: "http://mozilla.com", pattern: "http://*mozilla.com*/"});
fail({url: "http://mozilla.com", pattern: "http://mozilla.*/"});
fail({url: "http://mozilla.com", pattern: "http:/mozilla.com/"});
pass({url: "http://google.com", pattern: "http://*.google.com/"});
pass({url: "http://docs.google.com", pattern: "http://*.google.com/"});
pass({url: "http://mozilla.org:8080", pattern: "http://mozilla.org/"});
pass({url: "http://mozilla.org:8080", pattern: "*://mozilla.org/"});
fail({url: "http://mozilla.org:8080", pattern: "http://mozilla.org:8080/"});
// Now try with * in the path.
pass({url: "http://mozilla.org", pattern: "http://mozilla.org/*"});
pass({url: "http://mozilla.org/", pattern: "http://mozilla.org/*"});
pass({url: "http://mozilla.org/", pattern: "*://mozilla.org/*"});
pass({url: "https://mozilla.org/", pattern: "*://mozilla.org/*"});
fail({url: "file://mozilla.org/", pattern: "*://mozilla.org/*"});
fail({url: "http://mozilla.com", pattern: "http://mozilla.*/*"});
pass({url: "http://google.com", pattern: "http://*.google.com/*"});
pass({url: "http://docs.google.com", pattern: "http://*.google.com/*"});
// Check path stuff.
fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/"});
pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*"});
pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/a*f"});
pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/a*"});
pass({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*f"});
fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*e"});
fail({url: "http://mozilla.com/abc/def", pattern: "http://mozilla.com/*c"});
fail({url: "http:///a.html", pattern: "http:///a.html"});
pass({url: "file:///foo", pattern: "file:///foo*"});
pass({url: "file:///foo/bar.html", pattern: "file:///foo*"});
pass({url: "http://mozilla.org/a", pattern: "<all_urls>"});
pass({url: "https://mozilla.org/a", pattern: "<all_urls>"});
pass({url: "ftp://mozilla.org/a", pattern: "<all_urls>"});
pass({url: "file:///a", pattern: "<all_urls>"});
fail({url: "gopher://wuarchive.wustl.edu/a", pattern: "<all_urls>"});
// Multiple patterns.
pass({url: "http://mozilla.org", pattern: ["http://mozilla.org/"]});
pass({url: "http://mozilla.org", pattern: ["http://mozilla.org/", "http://mozilla.com/"]});
pass({url: "http://mozilla.com", pattern: ["http://mozilla.org/", "http://mozilla.com/"]});
fail({url: "http://mozilla.biz", pattern: ["http://mozilla.org/", "http://mozilla.com/"]});
// Match url with fragments.
pass({url: "http://mozilla.org/base#some-fragment", pattern: "http://mozilla.org/base"});
}
function test_overlaps() {
function test(filter, hosts, optional) {
const f = new MatchPattern(filter);
return f.overlapsPermissions(new MatchPattern(hosts), new MatchPattern(optional));
}
function pass({filter = [], hosts = [], optional = []}) {
ok(test(filter, hosts, optional), `Expected overlap: ${filter}, ${hosts} (${optional})`);
}
function fail({filter = [], hosts = [], optional = []}) {
ok(!test(filter, hosts, optional), `Expected no overlap: ${filter}, ${hosts} (${optional})`);
}
// Direct comparison.
pass({hosts: "http://ab.cd/", filter: "http://ab.cd/"});
fail({hosts: "http://ab.cd/", filter: "ftp://ab.cd/"});
// Wildcard protocol.
pass({hosts: "*://ab.cd/", filter: "https://ab.cd/"});
fail({hosts: "*://ab.cd/", filter: "ftp://ab.cd/"});
// Wildcard subdomain.
pass({hosts: "http://*.ab.cd/", filter: "http://ab.cd/"});
pass({hosts: "http://*.ab.cd/", filter: "http://www.ab.cd/"});
fail({hosts: "http://*.ab.cd/", filter: "http://ab.cd.ef/"});
fail({hosts: "http://*.ab.cd/", filter: "http://www.cd/"});
// Wildcard subsumed.
pass({hosts: "http://*.ab.cd/", filter: "http://*.cd/"});
fail({hosts: "http://*.cd/", filter: "http://*.xy/"});
// Subdomain vs substring.
fail({hosts: "http://*.ab.cd/", filter: "http://fake-ab.cd/"});
fail({hosts: "http://*.ab.cd/", filter: "http://*.fake-ab.cd/"});
// Wildcard domain.
pass({hosts: "http://*/", filter: "http://ab.cd/"});
fail({hosts: "http://*/", filter: "https://ab.cd/"});
// Wildcard wildcards.
pass({hosts: "<all_urls>", filter: "ftp://ab.cd/"});
fail({hosts: "<all_urls>", filter: ""});
fail({hosts: "<all_urls>"});
// Multiple hosts.
pass({hosts: ["http://ab.cd/"], filter: ["http://ab.cd/"]});
pass({hosts: ["http://ab.cd/", "http://ab.xy/"], filter: "http://ab.cd/"});
pass({hosts: ["http://ab.cd/", "http://ab.xy/"], filter: "http://ab.xy/"});
fail({hosts: ["http://ab.cd/", "http://ab.xy/"], filter: "http://ab.zz/"});
// Multiple Multiples.
pass({hosts: ["http://*.ab.cd/"], filter: ["http://ab.cd/", "http://www.ab.cd/"]});
pass({hosts: ["http://ab.cd/", "http://ab.xy/"], filter: ["http://ab.cd/", "http://ab.xy/"]});
fail({hosts: ["http://ab.cd/", "http://ab.xy/"], filter: ["http://ab.cd/", "http://ab.zz/"]});
// Optional.
pass({hosts: [], optional: "http://ab.cd/", filter: "http://ab.cd/"});
pass({hosts: "http://ab.cd/", optional: "http://ab.xy/", filter: ["http://ab.cd/", "http://ab.xy/"]});
fail({hosts: "http://ab.cd/", optional: "https://ab.xy/", filter: "http://ab.xy/"});
}
function run_test() {
test_matches();
test_overlaps();
}

Просмотреть файл

@ -3,7 +3,7 @@
"use strict";
Components.utils.import("resource://gre/modules/MatchPattern.jsm");
Components.utils.import("resource://gre/modules/MatchURLFilters.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
function createTestFilter({url, filters}) {

Просмотреть файл

@ -28,10 +28,6 @@ skip-if = toolkit == 'android'
skip-if = toolkit == 'android'
[test_Log.js]
skip-if = toolkit == 'android'
[test_MatchPattern.js]
skip-if = toolkit == 'android'
[test_MatchGlobs.js]
skip-if = toolkit == 'android'
[test_MatchURLFilters.js]
skip-if = toolkit == 'android'
[test_NewTabUtils.js]

Просмотреть файл

@ -131,7 +131,7 @@
"lz4.js": ["Lz4"],
"lz4_internal.js": ["Primitives"],
"main.js": ["Weave"],
"MatchPattern.jsm": ["MatchPattern", "MatchGlobs", "MatchURLFilters"],
"MatchURLFilters.jsm": ["MatchURLFilters"],
"mcc_iso3166_table.jsm": ["MCC_ISO3166_TABLE"],
"message.js": ["Command", "Message", "MessageOrigin", "Response"],
"MessageContext.jsm": ["MessageContext"],

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsIContent.h"
#include "nsISelection.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/TextComposition.h"
#include "mozilla/TextEventDispatcherListener.h"
@ -1153,9 +1154,11 @@ GeckoEditableSupport::SetInputContext(const InputContext& aContext,
aAction.mCause, aAction.mFocusChange);
mInputContext = aContext;
const bool isUserAction = EventStateManager::IsHandlingUserInput();
if (mInputContext.mIMEState.mEnabled == IMEState::ENABLED &&
aAction.UserMightRequestOpenVKB()) {
isUserAction &&
aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
// Don't reset keyboard when we should simply open the vkb
mEditable->NotifyIME(GeckoEditableListener::NOTIFY_IME_OPEN_VKB);
return;
@ -1167,8 +1170,6 @@ GeckoEditableSupport::SetInputContext(const InputContext& aContext,
mIMEUpdatingContext = true;
RefPtr<GeckoEditableSupport> self(this);
bool isUserAction = aAction.IsUserAction();
nsAppShell::PostEvent([this, self, isUserAction] {
nsCOMPtr<nsIWidget> widget = GetWidget();