Merge mozilla-central to mozilla-inbound
This commit is contained in:
@@ -67,3 +67,41 @@ add_task(async function test_discarded() {
|
|||||||
BrowserTestUtils.removeTab(tab2);
|
BrowserTestUtils.removeTab(tab2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// If discard is called immediately after creating a new tab, the new tab may not have loaded,
|
||||||
|
// and the sessionstore for that tab is not ready for discarding. The result was a corrupted
|
||||||
|
// sessionstore for the tab, which when the tab was activated, resulted in a tab with partial
|
||||||
|
// state.
|
||||||
|
add_task(async function test_create_then_discard() {
|
||||||
|
let extension = ExtensionTestUtils.loadExtension({
|
||||||
|
manifest: {
|
||||||
|
"permissions": ["tabs", "webNavigation"],
|
||||||
|
},
|
||||||
|
|
||||||
|
background: async function() {
|
||||||
|
let createdTab;
|
||||||
|
|
||||||
|
browser.tabs.onUpdated.addListener((tabId, updatedInfo) => {
|
||||||
|
if (!updatedInfo.discarded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.webNavigation.onCompleted.addListener(async (details) => {
|
||||||
|
browser.test.assertEq(createdTab.id, details.tabId, "created tab navigation is completed");
|
||||||
|
let activeTab = await browser.tabs.get(details.tabId);
|
||||||
|
browser.test.assertEq("http://example.com/", details.url, "created tab url is correct");
|
||||||
|
browser.test.assertEq("http://example.com/", activeTab.url, "created tab url is correct");
|
||||||
|
browser.tabs.remove(details.tabId);
|
||||||
|
browser.test.notifyPass("test-finished");
|
||||||
|
}, {url: [{hostContains: "example.com"}]});
|
||||||
|
|
||||||
|
browser.tabs.update(tabId, {active: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
createdTab = await browser.tabs.create({url: "http://example.com/", active: false});
|
||||||
|
browser.tabs.discard(createdTab.id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await extension.startup();
|
||||||
|
await extension.awaitFinish("test-finished");
|
||||||
|
await extension.unload();
|
||||||
|
});
|
||||||
|
|||||||
@@ -2030,11 +2030,25 @@ var SessionStoreInternal = {
|
|||||||
this._crashedBrowsers.delete(browser.permanentKey);
|
this._crashedBrowsers.delete(browser.permanentKey);
|
||||||
aTab.removeAttribute("crashed");
|
aTab.removeAttribute("crashed");
|
||||||
|
|
||||||
|
let {userTypedValue = "", userTypedClear = 0} = browser;
|
||||||
|
|
||||||
|
let cacheState = TabStateCache.get(browser);
|
||||||
|
if (cacheState === undefined && userTypedValue) {
|
||||||
|
// Discard was likely called before state can be cached. Update
|
||||||
|
// the persistent tab state cache with browser information so a
|
||||||
|
// restore will be successful. This information is necessary for
|
||||||
|
// restoreTabContent in ContentRestore.jsm to work properly.
|
||||||
|
TabStateCache.update(browser, {
|
||||||
|
userTypedValue,
|
||||||
|
userTypedClear: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
TAB_LAZY_STATES.set(aTab, {
|
TAB_LAZY_STATES.set(aTab, {
|
||||||
url: browser.currentURI.spec,
|
url: browser.currentURI.spec,
|
||||||
title: aTab.label,
|
title: aTab.label,
|
||||||
userTypedValue: browser.userTypedValue || "",
|
userTypedValue,
|
||||||
userTypedClear: browser.userTypedClear || 0
|
userTypedClear,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -36,18 +36,6 @@ const ThemeVariableMap = [
|
|||||||
["--toolbar-color", {
|
["--toolbar-color", {
|
||||||
lwtProperty: "toolbar_text"
|
lwtProperty: "toolbar_text"
|
||||||
}],
|
}],
|
||||||
["--lwt-toolbar-field-border-color", {
|
|
||||||
lwtProperty: "toolbar_field_border"
|
|
||||||
}],
|
|
||||||
["--lwt-toolbar-field-focus", {
|
|
||||||
lwtProperty: "toolbar_field_focus"
|
|
||||||
}],
|
|
||||||
["--lwt-toolbar-field-focus-color", {
|
|
||||||
lwtProperty: "toolbar_field_text_focus"
|
|
||||||
}],
|
|
||||||
["--toolbar-field-focus-border-color", {
|
|
||||||
lwtProperty: "toolbar_field_border_focus"
|
|
||||||
}],
|
|
||||||
["--urlbar-separator-color", {
|
["--urlbar-separator-color", {
|
||||||
lwtProperty: "toolbar_field_separator"
|
lwtProperty: "toolbar_field_separator"
|
||||||
}],
|
}],
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ SHARED_LIBRARY_TARGET = target
|
|||||||
INSTALL_TARGETS += SHARED_LIBRARY
|
INSTALL_TARGETS += SHARED_LIBRARY
|
||||||
endif # SHARED_LIBRARY
|
endif # SHARED_LIBRARY
|
||||||
|
|
||||||
ifneq (,$(strip $(HOST_SIMPLE_PROGRAMS)$(HOST_PROGRAM)))
|
ifneq (,$(strip $(HOST_SIMPLE_PROGRAMS)))
|
||||||
HOST_PROGRAMS_EXECUTABLES = $(HOST_SIMPLE_PROGRAMS) $(HOST_PROGRAM) $(HOST_RUST_PROGRAMS)
|
HOST_PROGRAMS_EXECUTABLES = $(HOST_SIMPLE_PROGRAMS) $(HOST_RUST_PROGRAMS)
|
||||||
HOST_PROGRAMS_DEST ?= $(DIST)/host/bin
|
HOST_PROGRAMS_DEST ?= $(DIST)/host/bin
|
||||||
HOST_PROGRAMS_TARGET = host
|
HOST_PROGRAMS_TARGET = host
|
||||||
INSTALL_TARGETS += HOST_PROGRAMS
|
INSTALL_TARGETS += HOST_PROGRAMS
|
||||||
|
|||||||
@@ -575,22 +575,22 @@ ifdef MOZ_POST_PROGRAM_COMMAND
|
|||||||
$(MOZ_POST_PROGRAM_COMMAND) $@
|
$(MOZ_POST_PROGRAM_COMMAND) $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
|
$(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS) $(call mkdir_deps,$(DEPTH)/dist/host/bin)
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
|
ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
|
||||||
$(LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
$(LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||||
ifdef MSMANIFEST_TOOL
|
ifdef MSMANIFEST_TOOL
|
||||||
@if test -f $@.manifest; then \
|
@if test -f $@.manifest; then \
|
||||||
if test -f '$(srcdir)/$@.manifest'; then \
|
if test -f '$(srcdir)/$(notdir $@).manifest'; then \
|
||||||
echo 'Embedding manifest from $(srcdir)/$@.manifest and $@.manifest'; \
|
echo 'Embedding manifest from $(srcdir)/$(notdir $@).manifest and $@.manifest'; \
|
||||||
$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$@.manifest' $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$(notdir $@).manifest' $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
||||||
else \
|
else \
|
||||||
echo 'Embedding manifest from $@.manifest'; \
|
echo 'Embedding manifest from $@.manifest'; \
|
||||||
$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
$(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
|
||||||
fi; \
|
fi; \
|
||||||
elif test -f '$(srcdir)/$@.manifest'; then \
|
elif test -f '$(srcdir)/$(notdir $@).manifest'; then \
|
||||||
echo 'Embedding manifest from $(srcdir)/$@.manifest'; \
|
echo 'Embedding manifest from $(srcdir)/$(notdir $@).manifest'; \
|
||||||
$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$@.manifest' -OUTPUTRESOURCE:$@\;1; \
|
$(MT) -NOLOGO -MANIFEST '$(win_srcdir)/$(notdir $@).manifest' -OUTPUTRESOURCE:$@\;1; \
|
||||||
fi
|
fi
|
||||||
endif # MSVC with manifest tool
|
endif # MSVC with manifest tool
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -13,15 +13,6 @@ module.exports = {
|
|||||||
"require": true,
|
"require": true,
|
||||||
},
|
},
|
||||||
"overrides": [{
|
"overrides": [{
|
||||||
// XXX Bug 1230193. We're still working on enabling no-undef for these test
|
|
||||||
// directories.
|
|
||||||
"files": [
|
|
||||||
"server/tests/mochitest/**",
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"no-undef": "off",
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"files": [
|
"files": [
|
||||||
"client/framework/**",
|
"client/framework/**",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ const { gDevTools } = require("devtools/client/framework/devtools");
|
|||||||
const { getColor } = require("devtools/client/shared/theme");
|
const { getColor } = require("devtools/client/shared/theme");
|
||||||
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
|
const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
|
||||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||||
const { throttle } = require("devtools/shared/throttle");
|
|
||||||
const { debounce } = require("devtools/shared/debounce");
|
const { debounce } = require("devtools/shared/debounce");
|
||||||
const { ELEMENT_STYLE } = require("devtools/shared/specs/styles");
|
const { ELEMENT_STYLE } = require("devtools/shared/specs/styles");
|
||||||
|
|
||||||
@@ -63,8 +62,6 @@ class FontInspector {
|
|||||||
this.ruleView = this.inspector.getPanel("ruleview").view;
|
this.ruleView = this.inspector.getPanel("ruleview").view;
|
||||||
this.selectedRule = null;
|
this.selectedRule = null;
|
||||||
this.store = this.inspector.store;
|
this.store = this.inspector.store;
|
||||||
// Map CSS property names to corresponding TextProperty instances from the Rule view.
|
|
||||||
this.textProperties = new Map();
|
|
||||||
// Map CSS property names and variable font axis names to methods that write their
|
// Map CSS property names and variable font axis names to methods that write their
|
||||||
// corresponding values to the appropriate TextProperty from the Rule view.
|
// corresponding values to the appropriate TextProperty from the Rule view.
|
||||||
// Values of variable font registered axes may be written to CSS font properties under
|
// Values of variable font registered axes may be written to CSS font properties under
|
||||||
@@ -72,7 +69,7 @@ class FontInspector {
|
|||||||
this.writers = new Map();
|
this.writers = new Map();
|
||||||
|
|
||||||
this.snapshotChanges = debounce(this.snapshotChanges, 100, this);
|
this.snapshotChanges = debounce(this.snapshotChanges, 100, this);
|
||||||
this.syncChanges = throttle(this.syncChanges, 100, this);
|
this.syncChanges = debounce(this.syncChanges, 100, this);
|
||||||
this.onInstanceChange = this.onInstanceChange.bind(this);
|
this.onInstanceChange = this.onInstanceChange.bind(this);
|
||||||
this.onNewNode = this.onNewNode.bind(this);
|
this.onNewNode = this.onNewNode.bind(this);
|
||||||
this.onPreviewFonts = this.onPreviewFonts.bind(this);
|
this.onPreviewFonts = this.onPreviewFonts.bind(this);
|
||||||
@@ -151,8 +148,6 @@ class FontInspector {
|
|||||||
this.ruleView = null;
|
this.ruleView = null;
|
||||||
this.selectedRule = null;
|
this.selectedRule = null;
|
||||||
this.store = null;
|
this.store = null;
|
||||||
this.textProperties.clear();
|
|
||||||
this.textProperties = null;
|
|
||||||
this.writers.clear();
|
this.writers.clear();
|
||||||
this.writers = null;
|
this.writers = null;
|
||||||
}
|
}
|
||||||
@@ -229,17 +224,13 @@ class FontInspector {
|
|||||||
* @return {TextProperty}
|
* @return {TextProperty}
|
||||||
*/
|
*/
|
||||||
getTextProperty(name, value) {
|
getTextProperty(name, value) {
|
||||||
if (!this.textProperties.has(name)) {
|
|
||||||
let textProperty =
|
let textProperty =
|
||||||
this.selectedRule.textProps.find(prop => prop.name === name);
|
this.selectedRule.textProps.find(prop => prop.name === name);
|
||||||
if (!textProperty) {
|
if (!textProperty) {
|
||||||
textProperty = this.selectedRule.editor.addProperty(name, value, "", true);
|
textProperty = this.selectedRule.editor.addProperty(name, value, "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.textProperties.set(name, textProperty);
|
return textProperty;
|
||||||
}
|
|
||||||
|
|
||||||
return this.textProperties.get(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,18 +363,22 @@ class FontInspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync the Rule view with the styles from the page. Called in a throttled way
|
* Sync the Rule view with the latest styles from the page. Called in a debounced way
|
||||||
* (see constructor) after property changes are applied directly to the CSS style rule
|
* (see constructor) after property changes are applied directly to the CSS style rule
|
||||||
* on the page circumventing TextProperty.setValue() which triggers expensive DOM
|
* on the page circumventing direct TextProperty.setValue() which triggers expensive DOM
|
||||||
* operations in TextPropertyEditor.update().
|
* operations in TextPropertyEditor.update().
|
||||||
*
|
*
|
||||||
* @param {TextProperty} textProperty
|
* @param {String} name
|
||||||
* Model of CSS declaration for a property in used in the rule view.
|
* CSS property name
|
||||||
* @param {String} value
|
* @param {String} value
|
||||||
* Value of the CSS property that should be reflected in the rule view.
|
* CSS property value
|
||||||
*/
|
*/
|
||||||
syncChanges(textProperty, value) {
|
syncChanges(name, value) {
|
||||||
textProperty.updateValue(value);
|
const textProperty = this.getTextProperty(name, value);
|
||||||
|
if (textProperty) {
|
||||||
|
textProperty.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
this.ruleView.on("property-value-updated", this.onRuleUpdated);
|
this.ruleView.on("property-value-updated", this.onRuleUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,10 +577,9 @@ class FontInspector {
|
|||||||
this.nodeComputedStyle = await this.pageStyle.getComputed(node, {
|
this.nodeComputedStyle = await this.pageStyle.getComputed(node, {
|
||||||
filterProperties: FONT_PROPERTIES
|
filterProperties: FONT_PROPERTIES
|
||||||
});
|
});
|
||||||
// Clear any references to writer methods and CSS declarations because the node's
|
// Clear any references to writer methods because the node's
|
||||||
// styles may have changed since the last font editor refresh.
|
// styles may have changed since the last font editor refresh.
|
||||||
this.writers.clear();
|
this.writers.clear();
|
||||||
this.textProperties.clear();
|
|
||||||
// Select the node's inline style as the rule where to write property value changes.
|
// Select the node's inline style as the rule where to write property value changes.
|
||||||
this.selectedRule =
|
this.selectedRule =
|
||||||
this.ruleView.rules.find(rule => rule.domRule.type === ELEMENT_STYLE);
|
this.ruleView.rules.find(rule => rule.domRule.type === ELEMENT_STYLE);
|
||||||
@@ -696,7 +690,15 @@ class FontInspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preview a property value (live) then sync the changes (throttled) to the Rule view.
|
* Preview a property value (live) then sync the changes (debounced) to the Rule view.
|
||||||
|
*
|
||||||
|
* NOTE: Until Bug 1462591 is addressed, all changes are written to the element's inline
|
||||||
|
* style attribute. In this current scenario, Rule.previewPropertyValue()
|
||||||
|
* causes the whole inline style representation in the Rule view to update instead of
|
||||||
|
* just previewing the change on the element.
|
||||||
|
* We keep the debounced call to syncChanges() because it explicitly calls
|
||||||
|
* TextProperty.setValue() which performs other actions, including marking the property
|
||||||
|
* as "changed" in the Rule view with a green indicator.
|
||||||
*
|
*
|
||||||
* @param {String} name
|
* @param {String} name
|
||||||
* CSS property name
|
* CSS property name
|
||||||
@@ -713,8 +715,8 @@ class FontInspector {
|
|||||||
this.ruleView.off("property-value-updated", this.onRuleUpdated);
|
this.ruleView.off("property-value-updated", this.onRuleUpdated);
|
||||||
// Live preview font property changes on the page.
|
// Live preview font property changes on the page.
|
||||||
textProperty.rule.previewPropertyValue(textProperty, value, "");
|
textProperty.rule.previewPropertyValue(textProperty, value, "");
|
||||||
// Sync Rule view with changes reflected on the page (throttled).
|
// Sync Rule view with changes reflected on the page (debounced).
|
||||||
this.syncChanges(textProperty, value);
|
this.syncChanges(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// Extend from the common devtools mochitest eslintrc config.
|
// Extend from the common devtools mochitest eslintrc config.
|
||||||
"extends": "../../../.eslintrc.xpcshell.js"
|
"extends": "../../../.eslintrc.mochitests.js"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/* exported heinrichFun */
|
/* exported heinrichFun */
|
||||||
|
/* global franz */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function heinrichFun() {
|
function heinrichFun() {
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ Bug 966991 - Test DebuggerServer.connectToFrame
|
|||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// Part of this is a frame script.
|
||||||
|
/* eslint-env mozilla/frame-script */
|
||||||
|
|
||||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||||
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||||
const { DebuggerServer } = require("devtools/server/main");
|
const { DebuggerServer } = require("devtools/server/main");
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ Test that css-logic handles media-queries correctly
|
|||||||
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||||
const Services = require("Services");
|
const Services = require("Services");
|
||||||
const {CssLogic} = require("devtools/server/actors/inspector/css-logic");
|
const {CssLogic} = require("devtools/server/actors/inspector/css-logic");
|
||||||
|
const InspectorUtils = require("InspectorUtils");
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ Bug 1060093 - Test DebuggerServer.getProcess
|
|||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// Part of this is a frame script.
|
||||||
|
/* eslint-env mozilla/frame-script */
|
||||||
|
|
||||||
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||||
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
const {DebuggerClient} = require("devtools/shared/client/debugger-client");
|
||||||
const {DebuggerServer} = require("devtools/server/main");
|
const {DebuggerServer} = require("devtools/server/main");
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ window.onload = function() {
|
|||||||
runNextTest();
|
runNextTest();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const InspectorUtils = require("InspectorUtils");
|
||||||
|
|
||||||
let gInspectee = null;
|
let gInspectee = null;
|
||||||
let gWalker = null;
|
let gWalker = null;
|
||||||
let gCleanupConnection = null;
|
let gCleanupConnection = null;
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ async function test_connect_addon(oopMode) {
|
|||||||
const extension = ExtensionTestUtils.loadExtension({
|
const extension = ExtensionTestUtils.loadExtension({
|
||||||
useAddonManager: "temporary",
|
useAddonManager: "temporary",
|
||||||
background: function() {
|
background: function() {
|
||||||
|
/* eslint-disable no-undef */
|
||||||
browser.test.log("background script executed");
|
browser.test.log("background script executed");
|
||||||
browser.test.sendMessage("background page ready");
|
browser.test.sendMessage("background page ready");
|
||||||
|
/* eslint-enable no-undef */
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await extension.startup();
|
await extension.startup();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "mozilla/TextServicesDocument.h" // for TextServicesDocument
|
#include "mozilla/TextServicesDocument.h" // for TextServicesDocument
|
||||||
#include "nsAString.h" // for nsAString::IsEmpty, etc
|
#include "nsAString.h" // for nsAString::IsEmpty, etc
|
||||||
#include "nsComponentManagerUtils.h" // for do_CreateInstance
|
#include "nsComponentManagerUtils.h" // for do_CreateInstance
|
||||||
|
#include "nsComposeTxtSrvFilter.h"
|
||||||
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
||||||
#include "nsDependentSubstring.h" // for Substring
|
#include "nsDependentSubstring.h" // for Substring
|
||||||
#include "nsError.h" // for NS_ERROR_NOT_INITIALIZED, etc
|
#include "nsError.h" // for NS_ERROR_NOT_INITIALIZED, etc
|
||||||
@@ -694,7 +695,7 @@ EditorSpellCheck::UninitSpellChecker()
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
EditorSpellCheck::SetFilter(nsITextServicesFilter *aFilter)
|
EditorSpellCheck::SetFilter(nsITextServicesFilter *aFilter)
|
||||||
{
|
{
|
||||||
mTxtSrvFilter = aFilter;
|
mTxtSrvFilter = reinterpret_cast<nsComposeTxtSrvFilter*>(aFilter);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "nscore.h" // for nsresult
|
#include "nscore.h" // for nsresult
|
||||||
|
|
||||||
class mozSpellChecker;
|
class mozSpellChecker;
|
||||||
|
class nsComposeTxtSrvFilter;
|
||||||
class nsIEditor;
|
class nsIEditor;
|
||||||
class nsISpellChecker;
|
class nsISpellChecker;
|
||||||
class nsITextServicesFilter;
|
class nsITextServicesFilter;
|
||||||
@@ -57,7 +58,7 @@ protected:
|
|||||||
virtual ~EditorSpellCheck();
|
virtual ~EditorSpellCheck();
|
||||||
|
|
||||||
RefPtr<mozSpellChecker> mSpellChecker;
|
RefPtr<mozSpellChecker> mSpellChecker;
|
||||||
nsCOMPtr<nsITextServicesFilter> mTxtSrvFilter;
|
RefPtr<nsComposeTxtSrvFilter> mTxtSrvFilter;
|
||||||
RefPtr<EditorBase> mEditor;
|
RefPtr<EditorBase> mEditor;
|
||||||
|
|
||||||
nsTArray<nsString> mSuggestedWordList;
|
nsTArray<nsString> mSuggestedWordList;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "mozilla/TextEditor.h" // for TextEditor
|
#include "mozilla/TextEditor.h" // for TextEditor
|
||||||
#include "nsAString.h" // for nsAString::Length, etc
|
#include "nsAString.h" // for nsAString::Length, etc
|
||||||
#include "nsContentUtils.h" // for nsContentUtils
|
#include "nsContentUtils.h" // for nsContentUtils
|
||||||
|
#include "nsComposeTxtSrvFilter.h"
|
||||||
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
|
||||||
#include "nsDependentSubstring.h" // for Substring
|
#include "nsDependentSubstring.h" // for Substring
|
||||||
#include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
|
#include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
|
||||||
@@ -26,7 +27,6 @@
|
|||||||
#include "nsISelectionController.h" // for nsISelectionController, etc
|
#include "nsISelectionController.h" // for nsISelectionController, etc
|
||||||
#include "nsISupportsBase.h" // for nsISupports
|
#include "nsISupportsBase.h" // for nsISupports
|
||||||
#include "nsISupportsUtils.h" // for NS_IF_ADDREF, NS_ADDREF, etc
|
#include "nsISupportsUtils.h" // for NS_IF_ADDREF, NS_ADDREF, etc
|
||||||
#include "nsITextServicesFilter.h" // for nsITextServicesFilter
|
|
||||||
#include "mozilla/intl/WordBreaker.h" // for WordRange, WordBreaker
|
#include "mozilla/intl/WordBreaker.h" // for WordRange, WordBreaker
|
||||||
#include "nsRange.h" // for nsRange
|
#include "nsRange.h" // for nsRange
|
||||||
#include "nsString.h" // for nsString, nsAutoString
|
#include "nsString.h" // for nsString, nsAutoString
|
||||||
@@ -359,7 +359,7 @@ TextServicesDocument::ExpandRangeToWordBoundaries(nsRange* aRange)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
TextServicesDocument::SetFilter(nsITextServicesFilter* aFilter)
|
TextServicesDocument::SetFilter(nsComposeTxtSrvFilter* aFilter)
|
||||||
{
|
{
|
||||||
// Hang on to the filter so we can set it into the filtered iterator.
|
// Hang on to the filter so we can set it into the filtered iterator.
|
||||||
mTxtSvcFilter = aFilter;
|
mTxtSvcFilter = aFilter;
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
|
||||||
|
class nsComposeTxtSrvFilter;
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIContentIterator;
|
class nsIContentIterator;
|
||||||
class nsIEditor;
|
class nsIEditor;
|
||||||
class nsINode;
|
class nsINode;
|
||||||
class nsISelectionController;
|
class nsISelectionController;
|
||||||
class nsITextServicesFilter;
|
|
||||||
class nsRange;
|
class nsRange;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@@ -58,7 +58,7 @@ private:
|
|||||||
nsCOMPtr<nsIContent> mNextTextBlock;
|
nsCOMPtr<nsIContent> mNextTextBlock;
|
||||||
nsTArray<OffsetEntry*> mOffsetTable;
|
nsTArray<OffsetEntry*> mOffsetTable;
|
||||||
RefPtr<nsRange> mExtent;
|
RefPtr<nsRange> mExtent;
|
||||||
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
|
RefPtr<nsComposeTxtSrvFilter> mTxtSvcFilter;
|
||||||
|
|
||||||
int32_t mSelStartIndex;
|
int32_t mSelStartIndex;
|
||||||
int32_t mSelStartOffset;
|
int32_t mSelStartOffset;
|
||||||
@@ -110,7 +110,7 @@ public:
|
|||||||
* @param aFilter The filter to be used while iterating over
|
* @param aFilter The filter to be used while iterating over
|
||||||
* content.
|
* content.
|
||||||
*/
|
*/
|
||||||
nsresult SetFilter(nsITextServicesFilter* aFilter);
|
nsresult SetFilter(nsComposeTxtSrvFilter* aFilter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the text in the current text block.
|
* Returns the text in the current text block.
|
||||||
|
|||||||
@@ -18,51 +18,57 @@ nsComposeTxtSrvFilter::nsComposeTxtSrvFilter() :
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsComposeTxtSrvFilter, nsITextServicesFilter)
|
NS_IMPL_ISUPPORTS(nsComposeTxtSrvFilter, nsITextServicesFilter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
bool
|
||||||
nsComposeTxtSrvFilter::Skip(nsINode* aNode, bool *_retval)
|
nsComposeTxtSrvFilter::Skip(nsINode* aNode) const
|
||||||
{
|
{
|
||||||
*_retval = false;
|
if (NS_WARN_IF(!aNode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check to see if we can skip this node
|
// Check to see if we can skip this node
|
||||||
// For nodes that are blockquotes, we must make sure
|
|
||||||
// their type is "cite"
|
if (aNode->IsAnyOfHTMLElements(nsGkAtoms::script,
|
||||||
if (aNode) {
|
|
||||||
if (aNode->IsHTMLElement(nsGkAtoms::blockquote)) {
|
|
||||||
if (mIsForMail) {
|
|
||||||
*_retval = aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
|
||||||
nsGkAtoms::type,
|
|
||||||
nsGkAtoms::cite,
|
|
||||||
eIgnoreCase);
|
|
||||||
}
|
|
||||||
} else if (aNode->IsHTMLElement(nsGkAtoms::span)) {
|
|
||||||
if (mIsForMail) {
|
|
||||||
*_retval = aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
|
||||||
nsGkAtoms::mozquote,
|
|
||||||
nsGkAtoms::_true,
|
|
||||||
eIgnoreCase);
|
|
||||||
if (!*_retval) {
|
|
||||||
*_retval = aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
|
||||||
nsGkAtoms::_class,
|
|
||||||
nsGkAtoms::mozsignature,
|
|
||||||
eCaseMatters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (aNode->IsAnyOfHTMLElements(nsGkAtoms::script,
|
|
||||||
nsGkAtoms::textarea,
|
nsGkAtoms::textarea,
|
||||||
nsGkAtoms::select,
|
nsGkAtoms::select,
|
||||||
nsGkAtoms::style,
|
nsGkAtoms::style,
|
||||||
nsGkAtoms::map)) {
|
nsGkAtoms::map)) {
|
||||||
*_retval = true;
|
return true;
|
||||||
} else if (aNode->IsHTMLElement(nsGkAtoms::table)) {
|
}
|
||||||
if (mIsForMail) {
|
|
||||||
*_retval =
|
if (!mIsForMail) {
|
||||||
aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For nodes that are blockquotes, we must make sure
|
||||||
|
// their type is "cite"
|
||||||
|
if (aNode->IsHTMLElement(nsGkAtoms::blockquote)) {
|
||||||
|
return aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||||
|
nsGkAtoms::type,
|
||||||
|
nsGkAtoms::cite,
|
||||||
|
eIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNode->IsHTMLElement(nsGkAtoms::span)) {
|
||||||
|
if (aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||||
|
nsGkAtoms::mozquote,
|
||||||
|
nsGkAtoms::_true,
|
||||||
|
eIgnoreCase)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aNode->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||||
|
nsGkAtoms::_class,
|
||||||
|
nsGkAtoms::mozsignature,
|
||||||
|
eCaseMatters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNode->IsHTMLElement(nsGkAtoms::table)) {
|
||||||
|
return aNode->AsElement()->AttrValueIs(
|
||||||
|
kNameSpaceID_None,
|
||||||
nsGkAtoms::_class,
|
nsGkAtoms::_class,
|
||||||
NS_LITERAL_STRING("moz-email-headers-table"),
|
NS_LITERAL_STRING("moz-email-headers-table"),
|
||||||
eCaseMatters);
|
eCaseMatters);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ public:
|
|||||||
// Helper - Intializer
|
// Helper - Intializer
|
||||||
void Init(bool aIsForMail) { mIsForMail = aIsForMail; }
|
void Init(bool aIsForMail) { mIsForMail = aIsForMail; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the content node should be skipped by the iterator
|
||||||
|
* @param aNode - node to skip
|
||||||
|
*/
|
||||||
|
bool Skip(nsINode* aNode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~nsComposeTxtSrvFilter() {}
|
~nsComposeTxtSrvFilter() {}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "mozilla/mozalloc.h"
|
#include "mozilla/mozalloc.h"
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
|
#include "nsComposeTxtSrvFilter.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
@@ -16,13 +17,12 @@
|
|||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsISupportsBase.h"
|
#include "nsISupportsBase.h"
|
||||||
#include "nsISupportsUtils.h"
|
#include "nsISupportsUtils.h"
|
||||||
#include "nsITextServicesFilter.h"
|
|
||||||
#include "nsRange.h"
|
#include "nsRange.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
nsFilteredContentIterator::nsFilteredContentIterator(nsITextServicesFilter* aFilter) :
|
nsFilteredContentIterator::nsFilteredContentIterator(nsComposeTxtSrvFilter* aFilter) :
|
||||||
mFilter(aFilter),
|
mFilter(aFilter),
|
||||||
mDidSkip(false),
|
mDidSkip(false),
|
||||||
mIsOutOfRange(false),
|
mIsOutOfRange(false),
|
||||||
@@ -347,15 +347,13 @@ nsFilteredContentIterator::CheckAdvNode(nsINode* aNode, bool& aDidSkip, eDirecti
|
|||||||
|
|
||||||
if (aNode && mFilter) {
|
if (aNode && mFilter) {
|
||||||
nsCOMPtr<nsINode> currentNode = aNode;
|
nsCOMPtr<nsINode> currentNode = aNode;
|
||||||
bool skipIt;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
nsresult rv = mFilter->Skip(aNode, &skipIt);
|
if (mFilter->Skip(aNode)) {
|
||||||
if (NS_SUCCEEDED(rv) && skipIt) {
|
|
||||||
aDidSkip = true;
|
aDidSkip = true;
|
||||||
// Get the next/prev node and then
|
// Get the next/prev node and then
|
||||||
// see if we should skip that
|
// see if we should skip that
|
||||||
nsCOMPtr<nsINode> advNode;
|
nsCOMPtr<nsINode> advNode;
|
||||||
rv = AdvanceNode(aNode, *getter_AddRefs(advNode), aDir);
|
nsresult rv = AdvanceNode(aNode, *getter_AddRefs(advNode), aDir);
|
||||||
if (NS_SUCCEEDED(rv) && advNode) {
|
if (NS_SUCCEEDED(rv) && advNode) {
|
||||||
aNode = advNode;
|
aNode = advNode;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
|
||||||
class nsAtom;
|
class nsAtom;
|
||||||
|
class nsComposeTxtSrvFilter;
|
||||||
class nsINode;
|
class nsINode;
|
||||||
class nsITextServicesFilter;
|
|
||||||
class nsRange;
|
class nsRange;
|
||||||
|
|
||||||
class nsFilteredContentIterator final : public nsIContentIterator
|
class nsFilteredContentIterator final : public nsIContentIterator
|
||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsFilteredContentIterator)
|
NS_DECL_CYCLE_COLLECTION_CLASS(nsFilteredContentIterator)
|
||||||
|
|
||||||
explicit nsFilteredContentIterator(nsITextServicesFilter* aFilter);
|
explicit nsFilteredContentIterator(nsComposeTxtSrvFilter* aFilter);
|
||||||
|
|
||||||
/* nsIContentIterator */
|
/* nsIContentIterator */
|
||||||
virtual nsresult Init(nsINode* aRoot) override;
|
virtual nsresult Init(nsINode* aRoot) override;
|
||||||
@@ -77,7 +77,7 @@ protected:
|
|||||||
RefPtr<nsAtom> mSelectAreaAtom;
|
RefPtr<nsAtom> mSelectAreaAtom;
|
||||||
RefPtr<nsAtom> mMapAtom;
|
RefPtr<nsAtom> mMapAtom;
|
||||||
|
|
||||||
nsCOMPtr<nsITextServicesFilter> mFilter;
|
RefPtr<nsComposeTxtSrvFilter> mFilter;
|
||||||
RefPtr<nsRange> mRange;
|
RefPtr<nsRange> mRange;
|
||||||
bool mDidSkip;
|
bool mDidSkip;
|
||||||
bool mIsOutOfRange;
|
bool mIsOutOfRange;
|
||||||
|
|||||||
@@ -5,17 +5,8 @@
|
|||||||
|
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
webidl Node;
|
[scriptable, builtinclass, uuid(5BEC321F-59AC-413a-A4AD-8A8D7C50A0D0)]
|
||||||
|
|
||||||
[scriptable, uuid(5BEC321F-59AC-413a-A4AD-8A8D7C50A0D0)]
|
|
||||||
interface nsITextServicesFilter : nsISupports
|
interface nsITextServicesFilter : nsISupports
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the content node should be skipped by the iterator
|
|
||||||
* @param aNode - node to skip
|
|
||||||
*/
|
|
||||||
boolean skip(in Node aNode);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -535,8 +535,13 @@ function getHitTestConfig() {
|
|||||||
return window.hitTestConfig;
|
return window.hitTestConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the coordinates of the center of the given element.
|
// Compute the coordinates of the center of the given element. The argument
|
||||||
|
// can either be a string (the id of the element desired) or the element
|
||||||
|
// itself.
|
||||||
function centerOf(element) {
|
function centerOf(element) {
|
||||||
|
if (typeof element === "string") {
|
||||||
|
element = document.getElementById(element);
|
||||||
|
}
|
||||||
var bounds = element.getBoundingClientRect();
|
var bounds = element.getBoundingClientRect();
|
||||||
return { x: bounds.x + (bounds.width / 2), y: bounds.y + (bounds.height / 2) };
|
return { x: bounds.x + (bounds.width / 2), y: bounds.y + (bounds.height / 2) };
|
||||||
}
|
}
|
||||||
|
|||||||
311
gfx/layers/apz/test/mochitest/helper_hittest_touchaction.html
Normal file
311
gfx/layers/apz/test/mochitest/helper_hittest_touchaction.html
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Testing APZ hit-test with touch-action boxes</title>
|
||||||
|
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||||
|
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width"/>
|
||||||
|
<style>
|
||||||
|
.taBox {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: green;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.taBox > div {
|
||||||
|
/* make sure this doesn't obscure the center of the enclosing taBox */
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.taBigBox {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
background-color: green;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.taBigBox > div {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.taBigBox > div > div {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Create a bunch of divs for hit-testing. Some of the divs also
|
||||||
|
contain nested divs to test inheritance/combination of touch-action
|
||||||
|
properties. This is not an exhaustive list of all the possible
|
||||||
|
combinations but it's assorted enough to provide good coverage. -->
|
||||||
|
<div id="taNone" class="taBox" style="touch-action: none">
|
||||||
|
<div id="taInnerNonePanX" style="touch-action: pan-x"></div>
|
||||||
|
<div id="taInnerNoneManip" style="touch-action: manipulation"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taPanX" class="taBox" style="touch-action: pan-x">
|
||||||
|
<div id="taInnerPanXY" style="touch-action: pan-y"></div>
|
||||||
|
<div id="taInnerPanXManip" style="touch-action: manipulation"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taPanY" class="taBox" style="touch-action: pan-y">
|
||||||
|
<div id="taInnerPanYX" style="touch-action: pan-x"></div>
|
||||||
|
<div id="taInnerPanYY" style="touch-action: pan-y"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taPanXY" class="taBox" style="touch-action: pan-x pan-y">
|
||||||
|
<div id="taInnerPanXYNone" style="touch-action: none"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taManip" class="taBox" style="touch-action: manipulation">
|
||||||
|
<div id="taInnerManipPanX" style="touch-action: pan-x"></div>
|
||||||
|
<div id="taInnerManipNone" style="touch-action: none"></div>
|
||||||
|
<div id="taInnerManipListener" ontouchstart="return false;"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taListener" class="taBox" ontouchstart="return false;">
|
||||||
|
<div id="taInnerListenerPanX" style="touch-action: pan-x"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<!-- More divs for hit-testing. These comprise one big outer div with
|
||||||
|
a touch-action property, then inside is a scrollable div, possibly with
|
||||||
|
a touch-action of its own, and inside that is another div to make the
|
||||||
|
scrollable div scrollable. Note that the touch-action for an element
|
||||||
|
includes the restrictions from all ancestor elements up to and including
|
||||||
|
the element that has the default action for that touch-action property.
|
||||||
|
Panning actions therefore get inherited from the nearest scrollframe
|
||||||
|
downwards, while zooming actions get inherited from the root content
|
||||||
|
element (because that's the only one that has zooming as the default action)
|
||||||
|
downwards. In effect, any pan restrictions on the outer div should not
|
||||||
|
apply to the inner div, but zooming restrictions should. Also, the
|
||||||
|
touch-action on the scrollable div itself should apply to user interaction
|
||||||
|
inside the scrollable div. -->
|
||||||
|
<div id="taOuterPanX" class="taBigBox" style="touch-action: pan-x">
|
||||||
|
<div id="taScrollerPanY" style="touch-action: pan-y">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<div id="taScroller">
|
||||||
|
<div style="touch-action: pan-y"></div>
|
||||||
|
</div>
|
||||||
|
<div id="taScroller2">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="taOuterManipulation" class="taBigBox" style="touch-action: manipulation">
|
||||||
|
<div id="taScrollerPanX" style="touch-action: pan-x">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<div id="taScroller3">
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
var config = getHitTestConfig();
|
||||||
|
|
||||||
|
function* test(testDriver) {
|
||||||
|
for (var scroller of document.querySelectorAll('.taBigBox > div')) {
|
||||||
|
// layerize all the scrollable divs
|
||||||
|
config.utils.setDisplayPortForElement(0, 0, 100, 100, scroller, 1);
|
||||||
|
}
|
||||||
|
yield waitForApzFlushedRepaints(testDriver);
|
||||||
|
|
||||||
|
var scrollId = config.utils.getViewId(document.scrollingElement);
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taNone')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: none");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerNonePanX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x inside touch-action: none");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerNoneManip')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: manipulation inside touch-action: none");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taPanX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerPanXY')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-y inside touch-action: pan-x");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerPanXManip')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: manipulation inside touch-action: pan-x");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taPanY')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-y");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerPanYX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x inside touch-action: pan-y");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerPanYY')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-y inside touch-action: pan-y");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taPanXY')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x pan-y");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerPanXYNone')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: none inside touch-action: pan-x pan-y");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taManip')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: manipulation");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerManipPanX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x inside touch-action: manipulation");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerManipNone')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: none inside touch-action: manipulation");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerManipListener')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.DISPATCH_TO_CONTENT |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"div with touch listener inside touch-action: manipulation");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taListener')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.DISPATCH_TO_CONTENT,
|
||||||
|
scrollId,
|
||||||
|
"div with touch listener");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taInnerListenerPanX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.DISPATCH_TO_CONTENT |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
scrollId,
|
||||||
|
"touch-action: pan-x inside div with touch listener");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taScrollerPanY')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
config.utils.getViewId(document.getElementById('taScrollerPanY')),
|
||||||
|
"touch-action: pan-y on scroller");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taScroller')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_X_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
config.utils.getViewId(document.getElementById('taScroller')),
|
||||||
|
"touch-action: pan-y on div inside scroller");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taScroller2')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
config.utils.getViewId(document.getElementById('taScroller2')),
|
||||||
|
"zooming restrictions from pan-x outside scroller get inherited in");
|
||||||
|
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taScrollerPanX')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.PAN_Y_DISABLED |
|
||||||
|
APZHitResultFlags.PINCH_ZOOM_DISABLED |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
config.utils.getViewId(document.getElementById('taScrollerPanX')),
|
||||||
|
"touch-action: pan-x on scroller inside manipulation");
|
||||||
|
checkHitResult(
|
||||||
|
hitTest(centerOf('taScroller3')),
|
||||||
|
APZHitResultFlags.VISIBLE |
|
||||||
|
APZHitResultFlags.DOUBLE_TAP_ZOOM_DISABLED,
|
||||||
|
config.utils.getViewId(document.getElementById('taScroller3')),
|
||||||
|
"touch-action: manipulation outside scroller gets inherited in");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.isWebRender) {
|
||||||
|
ok(true, "This test is WebRender-only because we get a bunch of dispatch-to-content regions without it and the test isn't very interesting.");
|
||||||
|
subtestDone();
|
||||||
|
} else {
|
||||||
|
waitUntilApzStable()
|
||||||
|
.then(runContinuation(test))
|
||||||
|
.then(subtestDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -32,7 +32,8 @@ var subtests = [
|
|||||||
{'file': 'helper_hittest_float_bug1434846.html', 'prefs': prefs},
|
{'file': 'helper_hittest_float_bug1434846.html', 'prefs': prefs},
|
||||||
{'file': 'helper_hittest_float_bug1443518.html', 'prefs': prefs},
|
{'file': 'helper_hittest_float_bug1443518.html', 'prefs': prefs},
|
||||||
{'file': 'helper_hittest_checkerboard.html', 'prefs': prefs},
|
{'file': 'helper_hittest_checkerboard.html', 'prefs': prefs},
|
||||||
{'file': 'helper_hittest_backface_hidden.html', 'prefs': prefs}
|
{'file': 'helper_hittest_backface_hidden.html', 'prefs': prefs},
|
||||||
|
{'file': 'helper_hittest_touchaction.html', 'prefs': prefs}
|
||||||
];
|
];
|
||||||
|
|
||||||
if (isApzEnabled()) {
|
if (isApzEnabled()) {
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ load 1229972.html
|
|||||||
load 1242811.html
|
load 1242811.html
|
||||||
load 1242822.html
|
load 1242822.html
|
||||||
load 1248222.html
|
load 1248222.html
|
||||||
skip-if(webrender) load 1278305.html # skip because of bug 1435896
|
load 1278305.html
|
||||||
load 1308394.html
|
load 1308394.html
|
||||||
load 1317403-1.html # bug 1331533
|
load 1317403-1.html # bug 1331533
|
||||||
load 1325159-1.html
|
load 1325159-1.html
|
||||||
|
|||||||
@@ -670,29 +670,14 @@ GetFirstDisplayItemWithChildren(nsIFrame* aFrame)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsIFrame*
|
static bool
|
||||||
HandlePreserve3D(nsIFrame* aFrame, nsRect& aOverflow)
|
IsInPreserve3DContext(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
// Preserve-3d frames don't have valid overflow areas, and they might
|
return aFrame->Extend3DContext() ||
|
||||||
// have singular transforms (despite still being visible when combined
|
aFrame->Combines3DTransformWithAncestors();
|
||||||
// with their ancestors). If we're at one, jump up to the root of the
|
|
||||||
// preserve-3d context and use the whole overflow area.
|
|
||||||
nsIFrame* last = aFrame;
|
|
||||||
while (aFrame->Extend3DContext() ||
|
|
||||||
aFrame->Combines3DTransformWithAncestors()) {
|
|
||||||
last = aFrame;
|
|
||||||
aFrame = aFrame->GetParent();
|
|
||||||
}
|
|
||||||
if (last != aFrame) {
|
|
||||||
aOverflow = last->GetVisualOverflowRectRelativeToParent();
|
|
||||||
CRR_LOG("HandlePreserve3D() Updated overflow rect to: %d %d %d %d\n",
|
|
||||||
aOverflow.x, aOverflow.y, aOverflow.width, aOverflow.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
return aFrame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
||||||
AnimatedGeometryRoot** aAGR, nsRect& aOverflow,
|
AnimatedGeometryRoot** aAGR, nsRect& aOverflow,
|
||||||
nsIFrame* aStopAtFrame, nsTArray<nsIFrame*>& aOutFramesWithProps,
|
nsIFrame* aStopAtFrame, nsTArray<nsIFrame*>& aOutFramesWithProps,
|
||||||
@@ -705,8 +690,6 @@ ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
currentFrame, !aStopAtStackingContext,
|
currentFrame, !aStopAtStackingContext,
|
||||||
aOverflow.x, aOverflow.y, aOverflow.width, aOverflow.height);
|
aOverflow.x, aOverflow.y, aOverflow.width, aOverflow.height);
|
||||||
|
|
||||||
currentFrame = HandlePreserve3D(currentFrame, aOverflow);
|
|
||||||
|
|
||||||
// If the current frame is an OOF frame, DisplayListBuildingData needs to be
|
// If the current frame is an OOF frame, DisplayListBuildingData needs to be
|
||||||
// set on all the ancestor stacking contexts of the placeholder frame, up
|
// set on all the ancestor stacking contexts of the placeholder frame, up
|
||||||
// to the containing block of the OOF frame. This is done to ensure that the
|
// to the containing block of the OOF frame. This is done to ensure that the
|
||||||
@@ -739,8 +722,11 @@ ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
nsLayoutUtils::FindNearestCommonAncestorFrame(currentFrame->GetParent(),
|
nsLayoutUtils::FindNearestCommonAncestorFrame(currentFrame->GetParent(),
|
||||||
placeholder->GetParent());
|
placeholder->GetParent());
|
||||||
|
|
||||||
ProcessFrameInternal(placeholder, aBuilder, &dummyAGR, placeholderOverflow,
|
if (!ProcessFrameInternal(placeholder, aBuilder, &dummyAGR,
|
||||||
ancestor, aOutFramesWithProps, false);
|
placeholderOverflow, ancestor,
|
||||||
|
aOutFramesWithProps, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert 'aOverflow' into the coordinate space of the nearest stacking context
|
// Convert 'aOverflow' into the coordinate space of the nearest stacking context
|
||||||
@@ -749,6 +735,10 @@ ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
nullptr, nullptr,
|
nullptr, nullptr,
|
||||||
/* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
|
/* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
|
||||||
¤tFrame);
|
¤tFrame);
|
||||||
|
if (IsInPreserve3DContext(currentFrame)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(currentFrame);
|
MOZ_ASSERT(currentFrame);
|
||||||
|
|
||||||
if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
|
if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
|
||||||
@@ -856,6 +846,7 @@ ProcessFrameInternal(nsIFrame* aFrame, nsDisplayListBuilder& aBuilder,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -896,8 +887,10 @@ RetainedDisplayListBuilder::ProcessFrame(nsIFrame* aFrame, nsDisplayListBuilder&
|
|||||||
overflow.UnionRect(overflow, aBuilder.GetCaretRect());
|
overflow.UnionRect(overflow, aBuilder.GetCaretRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessFrameInternal(aFrame, aBuilder, &agr, overflow, aStopAtFrame,
|
if (!ProcessFrameInternal(aFrame, aBuilder, &agr, overflow, aStopAtFrame,
|
||||||
aOutFramesWithProps, aStopAtStackingContext);
|
aOutFramesWithProps, aStopAtStackingContext)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!overflow.IsEmpty()) {
|
if (!overflow.IsEmpty()) {
|
||||||
aOutDirty->UnionRect(*aOutDirty, overflow);
|
aOutDirty->UnionRect(*aOutDirty, overflow);
|
||||||
|
|||||||
27
layout/painting/crashtests/1468124-1.html
Normal file
27
layout/painting/crashtests/1468124-1.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<html class="reftest-wait">
|
||||||
|
<style>
|
||||||
|
:not(feFuncB) {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
a:last-child {
|
||||||
|
-webkit-transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
window.requestIdleCallback(function() {
|
||||||
|
document.documentElement.getBoundingClientRect();
|
||||||
|
});
|
||||||
|
function go() {
|
||||||
|
var c = document.createElement("a")
|
||||||
|
c.text = "-";
|
||||||
|
try { c.replaceChild(b, c.childNodes[0]); } catch(e) { }
|
||||||
|
try { document.body.appendChild(c); } catch(e) { }
|
||||||
|
document.documentElement.className = "";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<body onload=go()>
|
||||||
|
<d id="b">|
|
||||||
|
<audio controls="">
|
||||||
|
</html>
|
||||||
@@ -12,4 +12,4 @@ skip-if(webrender) load 1430589-1.html # bug 1421825 for webrender
|
|||||||
load 1454105-1.html
|
load 1454105-1.html
|
||||||
load 1455944-1.html
|
load 1455944-1.html
|
||||||
load 1465305-1.html
|
load 1465305-1.html
|
||||||
|
load 1468124-1.html
|
||||||
|
|||||||
@@ -1043,21 +1043,24 @@ nsHostResolver::ConditionallyCreateThread(nsHostRecord *rec)
|
|||||||
}
|
}
|
||||||
else if ((mThreadCount < HighThreadThreshold) ||
|
else if ((mThreadCount < HighThreadThreshold) ||
|
||||||
(IsHighPriority(rec->flags) && mThreadCount < MAX_RESOLVER_THREADS)) {
|
(IsHighPriority(rec->flags) && mThreadCount < MAX_RESOLVER_THREADS)) {
|
||||||
// dispatch new worker thread
|
static nsThreadPoolNaming naming;
|
||||||
NS_ADDREF_THIS(); // owning reference passed to thread
|
nsCString name = naming.GetNextThreadName("DNS Resolver");
|
||||||
|
|
||||||
mThreadCount++;
|
// dispatch new worker thread
|
||||||
PRThread *thr = PR_CreateThread(PR_SYSTEM_THREAD,
|
nsCOMPtr<nsIThread> thread;
|
||||||
ThreadFunc,
|
nsresult rv = NS_NewNamedThread(name, getter_AddRefs(thread), nullptr);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv)) || !thread) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRunnable> event =
|
||||||
|
mozilla::NewRunnableMethod("nsHostResolver::ThreadFunc",
|
||||||
this,
|
this,
|
||||||
PR_PRIORITY_NORMAL,
|
&nsHostResolver::ThreadFunc);
|
||||||
PR_GLOBAL_THREAD,
|
mThreadCount++;
|
||||||
PR_UNJOINABLE_THREAD,
|
rv = thread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
|
||||||
0);
|
if (NS_FAILED(rv)) {
|
||||||
if (!thr) {
|
|
||||||
mThreadCount--;
|
mThreadCount--;
|
||||||
NS_RELEASE_THIS();
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1770,27 +1773,20 @@ nsHostResolver::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHostResolver::ThreadFunc(void *arg)
|
nsHostResolver::ThreadFunc()
|
||||||
{
|
{
|
||||||
LOG(("DNS lookup thread - starting execution.\n"));
|
LOG(("DNS lookup thread - starting execution.\n"));
|
||||||
|
|
||||||
static nsThreadPoolNaming naming;
|
|
||||||
nsCString name = naming.GetNextThreadName("DNS Resolver");
|
|
||||||
|
|
||||||
AUTO_PROFILER_REGISTER_THREAD(name.BeginReading());
|
|
||||||
NS_SetCurrentThreadName(name.BeginReading());
|
|
||||||
|
|
||||||
#if defined(RES_RETRY_ON_FAILURE)
|
#if defined(RES_RETRY_ON_FAILURE)
|
||||||
nsResState rs;
|
nsResState rs;
|
||||||
#endif
|
#endif
|
||||||
RefPtr<nsHostResolver> resolver = dont_AddRef((nsHostResolver *)arg);
|
|
||||||
RefPtr<nsHostRecord> rec;
|
RefPtr<nsHostRecord> rec;
|
||||||
AddrInfo *ai = nullptr;
|
AddrInfo *ai = nullptr;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!rec) {
|
if (!rec) {
|
||||||
RefPtr<nsHostRecord> tmpRec;
|
RefPtr<nsHostRecord> tmpRec;
|
||||||
if (!resolver->GetHostToLookup(getter_AddRefs(tmpRec))) {
|
if (!GetHostToLookup(getter_AddRefs(tmpRec))) {
|
||||||
break; // thread shutdown signal
|
break; // thread shutdown signal
|
||||||
}
|
}
|
||||||
// GetHostToLookup() returns an owning reference
|
// GetHostToLookup() returns an owning reference
|
||||||
@@ -1814,9 +1810,9 @@ nsHostResolver::ThreadFunc(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ // obtain lock to check shutdown and manage inter-module telemetry
|
{ // obtain lock to check shutdown and manage inter-module telemetry
|
||||||
MutexAutoLock lock(resolver->mLock);
|
MutexAutoLock lock(mLock);
|
||||||
|
|
||||||
if (!resolver->mShutdown) {
|
if (!mShutdown) {
|
||||||
TimeDuration elapsed = TimeStamp::Now() - startTime;
|
TimeDuration elapsed = TimeStamp::Now() - startTime;
|
||||||
uint32_t millis = static_cast<uint32_t>(elapsed.ToMilliseconds());
|
uint32_t millis = static_cast<uint32_t>(elapsed.ToMilliseconds());
|
||||||
|
|
||||||
@@ -1843,7 +1839,7 @@ nsHostResolver::ThreadFunc(void *arg)
|
|||||||
rec->host.get(),
|
rec->host.get(),
|
||||||
ai ? "success" : "failure: unknown host"));
|
ai ? "success" : "failure: unknown host"));
|
||||||
|
|
||||||
if (LOOKUP_RESOLVEAGAIN == resolver->CompleteLookup(rec, status, ai, rec->pb)) {
|
if (LOOKUP_RESOLVEAGAIN == CompleteLookup(rec, status, ai, rec->pb)) {
|
||||||
// leave 'rec' assigned and loop to make a renewed host resolve
|
// leave 'rec' assigned and loop to make a renewed host resolve
|
||||||
LOG(("DNS lookup thread - Re-resolving host [%s].\n", rec->host.get()));
|
LOG(("DNS lookup thread - Re-resolving host [%s].\n", rec->host.get()));
|
||||||
} else {
|
} else {
|
||||||
@@ -1851,8 +1847,7 @@ nsHostResolver::ThreadFunc(void *arg)
|
|||||||
}
|
}
|
||||||
} while(true);
|
} while(true);
|
||||||
|
|
||||||
resolver->mThreadCount--;
|
mThreadCount--;
|
||||||
resolver = nullptr;
|
|
||||||
LOG(("DNS lookup thread - queue empty, thread finished.\n"));
|
LOG(("DNS lookup thread - queue empty, thread finished.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const nsACString &host);
|
nsresult ConditionallyRefreshRecord(nsHostRecord *rec, const nsACString &host);
|
||||||
|
|
||||||
static void ThreadFunc(void *);
|
void ThreadFunc();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
METHOD_HIT = 1,
|
METHOD_HIT = 1,
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||||||
self._no_skip['syms'].add(backend_file.relobjdir)
|
self._no_skip['syms'].add(backend_file.relobjdir)
|
||||||
|
|
||||||
elif isinstance(obj, HostProgram):
|
elif isinstance(obj, HostProgram):
|
||||||
self._process_host_program(obj.program, backend_file)
|
self._process_host_program(obj, backend_file)
|
||||||
self._process_linked_libraries(obj, backend_file)
|
self._process_linked_libraries(obj, backend_file)
|
||||||
|
|
||||||
elif isinstance(obj, SimpleProgram):
|
elif isinstance(obj, SimpleProgram):
|
||||||
@@ -1106,7 +1106,8 @@ class RecursiveMakeBackend(CommonBackend):
|
|||||||
backend_file.write('PROG_IS_C_ONLY_%s := 1\n' % obj.program)
|
backend_file.write('PROG_IS_C_ONLY_%s := 1\n' % obj.program)
|
||||||
|
|
||||||
def _process_host_program(self, program, backend_file):
|
def _process_host_program(self, program, backend_file):
|
||||||
backend_file.write('HOST_PROGRAM = %s\n' % program)
|
backend_file.write('HOST_PROGRAM = %s\n' %
|
||||||
|
self._pretty_path(program.output_path, backend_file))
|
||||||
|
|
||||||
def _process_rust_program_base(self, obj, backend_file,
|
def _process_rust_program_base(self, obj, backend_file,
|
||||||
target_variable,
|
target_variable,
|
||||||
|
|||||||
@@ -463,7 +463,12 @@ class TupBackend(CommonBackend):
|
|||||||
def _gen_host_program(self, backend_file, prog):
|
def _gen_host_program(self, backend_file, prog):
|
||||||
_, _, _, extra_libs, _ = self._expand_libs(prog)
|
_, _, _, extra_libs, _ = self._expand_libs(prog)
|
||||||
objs = prog.objs
|
objs = prog.objs
|
||||||
outputs = [prog.program]
|
|
||||||
|
if isinstance(prog, HostSimpleProgram):
|
||||||
|
outputs = [prog.name]
|
||||||
|
else:
|
||||||
|
outputs = [mozpath.relpath(prog.output_path.full_path,
|
||||||
|
backend_file.objdir)]
|
||||||
host_libs = []
|
host_libs = []
|
||||||
for lib in prog.linked_libraries:
|
for lib in prog.linked_libraries:
|
||||||
if isinstance(lib, HostLibrary):
|
if isinstance(lib, HostLibrary):
|
||||||
|
|||||||
@@ -512,6 +512,10 @@ class HostProgram(HostMixin, BaseProgram):
|
|||||||
SUFFIX_VAR = 'HOST_BIN_SUFFIX'
|
SUFFIX_VAR = 'HOST_BIN_SUFFIX'
|
||||||
KIND = 'host'
|
KIND = 'host'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def install_target(self):
|
||||||
|
return 'dist/host/bin'
|
||||||
|
|
||||||
|
|
||||||
class SimpleProgram(BaseProgram):
|
class SimpleProgram(BaseProgram):
|
||||||
"""Context derived container object for each program in SIMPLE_PROGRAMS"""
|
"""Context derived container object for each program in SIMPLE_PROGRAMS"""
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
FINAL_TARGET = 'final/target'
|
||||||
|
HostProgram('final-target')
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
HostProgram('dist-host-bin')
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
@template
|
||||||
|
def HostProgram(name):
|
||||||
|
HOST_PROGRAM = name
|
||||||
|
|
||||||
|
DIRS += [
|
||||||
|
'final-target',
|
||||||
|
'installed',
|
||||||
|
'not-installed',
|
||||||
|
]
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Any copyright is dedicated to the Public Domain.
|
||||||
|
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
DIST_INSTALL = False
|
||||||
|
HostProgram('not-installed')
|
||||||
@@ -24,6 +24,7 @@ from mozbuild.frontend.data import (
|
|||||||
GeneratedFile,
|
GeneratedFile,
|
||||||
GeneratedSources,
|
GeneratedSources,
|
||||||
HostDefines,
|
HostDefines,
|
||||||
|
HostProgram,
|
||||||
HostRustLibrary,
|
HostRustLibrary,
|
||||||
HostRustProgram,
|
HostRustProgram,
|
||||||
HostSources,
|
HostSources,
|
||||||
@@ -75,6 +76,7 @@ class TestEmitterBasic(unittest.TestCase):
|
|||||||
substs = dict(
|
substs = dict(
|
||||||
ENABLE_TESTS='1' if enable_tests else '',
|
ENABLE_TESTS='1' if enable_tests else '',
|
||||||
BIN_SUFFIX='.prog',
|
BIN_SUFFIX='.prog',
|
||||||
|
HOST_BIN_SUFFIX='.hostprog',
|
||||||
OS_TARGET='WINNT',
|
OS_TARGET='WINNT',
|
||||||
COMPILE_ENVIRONMENT='1',
|
COMPILE_ENVIRONMENT='1',
|
||||||
STL_FLAGS=['-I/path/to/topobjdir/dist/stl_wrappers'],
|
STL_FLAGS=['-I/path/to/topobjdir/dist/stl_wrappers'],
|
||||||
@@ -699,6 +701,18 @@ class TestEmitterBasic(unittest.TestCase):
|
|||||||
'!not-installed.prog',
|
'!not-installed.prog',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_host_program_paths(self):
|
||||||
|
"""The destination of a HOST_PROGRAM (almost always dist/host/bin)
|
||||||
|
should be accurately reflected in Program.output_path."""
|
||||||
|
reader = self.reader('host-program-paths')
|
||||||
|
objs = self.read_topsrcdir(reader)
|
||||||
|
prog_paths = [o.output_path for o in objs if isinstance(o, HostProgram)]
|
||||||
|
self.assertEqual(prog_paths, [
|
||||||
|
'!/dist/host/bin/final-target.hostprog',
|
||||||
|
'!/dist/host/bin/dist-host-bin.hostprog',
|
||||||
|
'!not-installed.hostprog',
|
||||||
|
])
|
||||||
|
|
||||||
def test_test_manifest_missing_manifest(self):
|
def test_test_manifest_missing_manifest(self):
|
||||||
"""A missing manifest file should result in an error."""
|
"""A missing manifest file should result in an error."""
|
||||||
reader = self.reader('test-manifest-missing-manifest')
|
reader = self.reader('test-manifest-missing-manifest')
|
||||||
|
|||||||
@@ -80,4 +80,4 @@ END
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
/home/worker/scripts/periodic_file_updates.sh -p "${PRODUCT}" -b "${BRANCH}" ${PARAMS}
|
/home/worker/scripts/periodic_file_updates.sh -p "${PRODUCT}" -b "${BRANCH}" -a ${PARAMS}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ UNPACK_CMD="tar jxf"
|
|||||||
CLOSED_TREE=false
|
CLOSED_TREE=false
|
||||||
DONTBUILD=false
|
DONTBUILD=false
|
||||||
APPROVAL=false
|
APPROVAL=false
|
||||||
HG_SSH_USER='ffxbld'
|
COMMIT_AUTHOR='ffxbld@mozilla.com'
|
||||||
REPODIR=''
|
REPODIR=''
|
||||||
APP_DIR=''
|
APP_DIR=''
|
||||||
APP_ID=''
|
APP_ID=''
|
||||||
@@ -401,7 +401,7 @@ function push_repo {
|
|||||||
# Clean up older review requests
|
# Clean up older review requests
|
||||||
# Turn Needs Review D624: No bug, Automated HSTS ...
|
# Turn Needs Review D624: No bug, Automated HSTS ...
|
||||||
# into D624
|
# into D624
|
||||||
for diff in $($ARC list | grep "Needs Review" | grep -E "Automated HSTS|Automated HPKP|Automated blocklist" | awk 'match($0, /D[0-9]+[^: ]/) { print substr($0, RSTART, RLENGTH) }')
|
for diff in $($ARC list | grep "Needs Review" | grep -E "${BRANCH} repo-update" | awk 'match($0, /D[0-9]+[^: ]/) { print substr($0, RSTART, RLENGTH) }')
|
||||||
do
|
do
|
||||||
echo "Removing old request $diff"
|
echo "Removing old request $diff"
|
||||||
# There is no 'arc abandon', see bug 1452082
|
# There is no 'arc abandon', see bug 1452082
|
||||||
@@ -597,7 +597,7 @@ if [ ${APPROVAL} == true ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if ${HG} -R "${REPODIR}" commit -u "${HG_SSH_USER}" -m "${COMMIT_MESSAGE}"
|
if ${HG} -R "${REPODIR}" commit -u "${COMMIT_AUTHOR}" -m "${COMMIT_MESSAGE}"
|
||||||
then
|
then
|
||||||
push_repo
|
push_repo
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ class MobileSingleLocale(LocalesMixin, TooltoolMixin, AutomationMixin,
|
|||||||
return self.repack_env
|
return self.repack_env
|
||||||
c = self.config
|
c = self.config
|
||||||
repack_env = self.query_env(partial_env=c.get("repack_env"))
|
repack_env = self.query_env(partial_env=c.get("repack_env"))
|
||||||
if self.query_is_nightly() or self.query_is_nightly_promotion():
|
|
||||||
if self.query_is_nightly():
|
if self.query_is_nightly():
|
||||||
# Nightly promotion needs to set update_channel but not do all
|
# Nightly promotion needs to set update_channel but not do all
|
||||||
# the 'IS_NIGHTLY' automation parts, like uploading symbols
|
# the 'IS_NIGHTLY' automation parts, like uploading symbols
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ def env_options():
|
|||||||
|
|
||||||
def run_info_extras(**kwargs):
|
def run_info_extras(**kwargs):
|
||||||
return {"e10s": kwargs["gecko_e10s"],
|
return {"e10s": kwargs["gecko_e10s"],
|
||||||
|
"verify": kwargs["verify"],
|
||||||
"headless": "MOZ_HEADLESS" in os.environ}
|
"headless": "MOZ_HEADLESS" in os.environ}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2493,7 +2493,12 @@ PlacesUtils.keywords = {
|
|||||||
FROM moz_places h
|
FROM moz_places h
|
||||||
JOIN moz_keywords k ON k.place_id = h.id
|
JOIN moz_keywords k ON k.place_id = h.id
|
||||||
GROUP BY h.id
|
GROUP BY h.id
|
||||||
HAVING h.foreign_count = COUNT(*)`);
|
HAVING h.foreign_count = count(*) +
|
||||||
|
(SELECT count(*)
|
||||||
|
FROM moz_bookmarks b
|
||||||
|
JOIN moz_bookmarks p ON b.parent = p.id
|
||||||
|
WHERE p.parent = :tags_root AND b.fk = h.id)
|
||||||
|
`, { tags_root: PlacesUtils.tagsFolderId });
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
placeInfosToRemove.push({
|
placeInfosToRemove.push({
|
||||||
placeId: row.getResultByName("id"),
|
placeId: row.getResultByName("id"),
|
||||||
|
|||||||
@@ -491,3 +491,33 @@ add_task(async function test_bookmarkURLChange() {
|
|||||||
Assert.equal((await foreign_count("http://example1.com/")), fc1); // -1 bookmark -1 keyword
|
Assert.equal((await foreign_count("http://example1.com/")), fc1); // -1 bookmark -1 keyword
|
||||||
Assert.equal((await foreign_count("http://example2.com/")), fc2 + 2); // +1 bookmark +1 keyword
|
Assert.equal((await foreign_count("http://example2.com/")), fc2 + 2); // +1 bookmark +1 keyword
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function test_tagDoesntPreventKeywordRemoval() {
|
||||||
|
await check_keyword(false, "http://example.com/", "example");
|
||||||
|
let fc = await foreign_count("http://example.com/");
|
||||||
|
|
||||||
|
let httpBookmark = await PlacesUtils.bookmarks.insert({
|
||||||
|
url: "http://example.com/",
|
||||||
|
parentGuid: PlacesUtils.bookmarks.unfiledGuid
|
||||||
|
});
|
||||||
|
Assert.equal((await foreign_count("http://example.com/")), fc + 1); // +1 bookmark
|
||||||
|
|
||||||
|
PlacesUtils.tagging.tagURI(uri("http://example.com/"), ["example_tag"]);
|
||||||
|
Assert.equal((await foreign_count("http://example.com/")), fc + 2); // +1 bookmark +1 tag
|
||||||
|
|
||||||
|
await PlacesUtils.keywords.insert({ keyword: "example", url: "http://example.com/" });
|
||||||
|
Assert.equal((await foreign_count("http://example.com/")), fc + 3); // +1 bookmark +1 tag +1 keyword
|
||||||
|
|
||||||
|
await check_keyword(true, "http://example.com/", "example");
|
||||||
|
|
||||||
|
await PlacesUtils.bookmarks.remove(httpBookmark);
|
||||||
|
|
||||||
|
await TestUtils.waitForCondition(
|
||||||
|
async () => !(await PlacesUtils.bookmarks.fetch({ url: "http://example.com/"})),
|
||||||
|
"Wait for bookmark to be removed");
|
||||||
|
|
||||||
|
await check_keyword(false, "http://example.com/", "example");
|
||||||
|
Assert.equal((await foreign_count("http://example.com/")), fc); // bookmark, keyword, and tag should all have been removed
|
||||||
|
|
||||||
|
await check_no_orphans();
|
||||||
|
});
|
||||||
|
|||||||
@@ -83,6 +83,18 @@ const toolkitVariableMap = [
|
|||||||
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
["--lwt-toolbar-field-border-color", {
|
||||||
|
lwtProperty: "toolbar_field_border"
|
||||||
|
}],
|
||||||
|
["--lwt-toolbar-field-focus", {
|
||||||
|
lwtProperty: "toolbar_field_focus"
|
||||||
|
}],
|
||||||
|
["--lwt-toolbar-field-focus-color", {
|
||||||
|
lwtProperty: "toolbar_field_text_focus"
|
||||||
|
}],
|
||||||
|
["--toolbar-field-focus-border-color", {
|
||||||
|
lwtProperty: "toolbar_field_border_focus"
|
||||||
|
}],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Get the theme variables from the app resource directory.
|
// Get the theme variables from the app resource directory.
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ label.findbar-find-fast:-moz-lwtheme,
|
|||||||
}
|
}
|
||||||
|
|
||||||
.findbar-textbox[focused="true"] {
|
.findbar-textbox[focused="true"] {
|
||||||
box-shadow: var(--focus-ring-box-shadow);
|
box-shadow: 0 0 0 1px var(--toolbar-field-focus-border-color) inset,
|
||||||
|
0 0 0 1px var(--toolbar-field-focus-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.findbar-textbox:-moz-locale-dir(rtl) {
|
.findbar-textbox:-moz-locale-dir(rtl) {
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ findbar[noanim] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.findbar-textbox[focused="true"] {
|
.findbar-textbox[focused="true"] {
|
||||||
border-color: Highlight;
|
background-color: var(--lwt-toolbar-field-focus, var(--lwt-toolbar-field-background-color, -moz-Field));
|
||||||
|
color: var(--lwt-toolbar-field-focus-color, var(--lwt-toolbar-field-color, -moz-FieldText));
|
||||||
|
border-color: var(--toolbar-field-focus-border-color, Highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
.findbar-textbox[status="notfound"] {
|
.findbar-textbox[status="notfound"] {
|
||||||
@@ -91,8 +93,7 @@ findbar[noanim] {
|
|||||||
.findbar-find-next {
|
.findbar-find-next {
|
||||||
margin-inline-start: 0;
|
margin-inline-start: 0;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
background: linear-gradient(rgba(255,255,255,.3), rgba(255,255,255,.1));
|
background: rgba(255,255,255,.2);
|
||||||
background-clip: padding-box;
|
|
||||||
border: 1px solid ThreeDShadow;
|
border: 1px solid ThreeDShadow;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
@@ -101,6 +102,11 @@ findbar[noanim] {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.findbar-find-previous:not([disabled]):hover,
|
||||||
|
.findbar-find-next:not([disabled]):hover {
|
||||||
|
background: rgba(190,190,190,.2);
|
||||||
|
}
|
||||||
|
|
||||||
.findbar-find-previous:not([disabled]):hover:active,
|
.findbar-find-previous:not([disabled]):hover:active,
|
||||||
.findbar-find-next:not([disabled]):hover:active {
|
.findbar-find-next:not([disabled]):hover:active {
|
||||||
background: rgba(23,50,76,.2);
|
background: rgba(23,50,76,.2);
|
||||||
|
|||||||
Reference in New Issue
Block a user