mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- some pref. cleanup (21e17660e7) - add some font names and aliases (cb38962246) - remove unused dom.max_child_script_run_time (d214b353d4) - align strange layout.css.scroll-snap.enabled overwrite (f2562a5cc1) - reshuffle some preferences, remove unused (41f586186b) - more reshuffle and cleanup of preferences (0208aa32a3) - Bug 1168891 Part 1 - Refine two functions related to caret positioning. r=mats (86d718d60e) - Bug 1168891 Part 2 - Allow one caret to be dragged across the other caret. r=mats (9276eb7728) - part of Bug 1252802 - Web page scrolls when dragging caret in editable, r=snorp (31dade8b77) - Bug 1235508 - Re-implement fast Phone number selection on long-press, r=TYLin (59b6371d17) - Bug 1249201 Part 1 - Add "scroll" reason to CaretStateChangedEvent. r=smaug (b92ff6cbfc) - Bug 1249201 Part 2 - Show carets continuously when panning or zooming. r=mats,sebastian (ca5c51c479) - Bug 1245246: Add null check for mDocViewerPrint in nsPrintEngine::FirePrintingErrorEvent. r=roc (e9d5b49a3f) - Bug 1025267 - Make some -moz- prefixed pseudo-classes chrome-only. r=bz (238f7a85d4) - Bug 1259889 Part 1 - Add @supports -moz-bool-pref for internal-only style sheets. r=heycam (d716a7b884) - Bug 1237633 - Part 1: Percentages are not allowed in a <source-size-value>. r=jdm (52ccffbf86) - Bug 1081362 - Change nsStyleBasicShape pointer to an nsRefPtr, to avoid leak in unexpected case. r=dholbert (2a5cb8ffdd) - Bug 1264317 - Make the basic shape clip-path clipping use nsCSSValue::Array instead of nsCSSValueList. r=dholbert (7aaf39f2d7) - Bug 1247150 - Consistently use StyleSheetHandle::RefPtr* for outparams in nsLayoutStylesheetCache. r=dholbert (ddc85f29f8) - Bug 1251848: Check StyleSheetHandles for being null-flavored before derefing them, in assertions within nsLayoutStylesheetCache::InvalidateSheet. r=bholley (edb3924075) - Bug 1245260 - Add crashtest; r=hiro (6347e37750) - Bug 460209 - Add crashtest. (97b4786de2) - Bug 474377 - Add crashtest. (516b4e8164) - Bug 1264396 - Don't allow animation of 'display' property; r=heycam (6e94bcb26a) - missing bit of 759568 - Part 1 (fc954f075b) - part of Bug 1037483 replace microdata with microformats (4ff01e11d6) - Bug 1245334 - Make PromiseMessage.jsm ids more meaningful. r=baku (913ac1b9a5) - Bug 1094201 - Implement an Integration.jsm module for low-overhead registration of overrides. r=mak (9982624b90) - Bug 1167663 - Mark nsCSSKeyframeStyleDeclaration/nsCSSPageStyleDeclaration::mRule as MOZ_NON_OWNING_REF. r=dbaron (6d4e9751a1) - Bug 1244992 - Avoid double-counting in various refcounted types related to nsCSSValue. r=heycam. (c830949dd9) - Bug 1262646 - Change the outparams passed to nsStyleUtil::AppendEscapedCSSString from nsString to nsAutoString. r=dholbert (2b0caadf9d) - Bug 1247336 - De-dupe changes in ActiveLayerTracker before treating property as animated. r=roc (c44ed5aee6) - space fix (5e79d245ea) - Bug 1266288 - Track changes to all margin properties for scroll-linked effects. r=mstange (fed6994e4d) - Bug 1259641 - Do not force reflow for all tabs when size mode changed. r=smaug (70847cc6d2) - Bug 1261265 - Fix nsStyleContext::MoveTo flag assertions to allow mismatch on parents if bit is set on child. r=dholbert (3e6b08372e) - Bug 1264837 Part 43 - Remove SVGFEUnstyledLeafFrameBase. r=dholbert (bb55feda77) - Remove mention of old SVG text pref in comment; no bug. (DONTBUILD) (3a618aca18) - Bug 752638, part 1 - Move SVGTextFrame::SetupContextPaint to nsSVGUtils. r=heycam (c125c2903f) - Bug 1258843 - Don't build SVG display items if their visibility is hidden. r=dholbert (150c3b0059) - Bug 1258650. Properly use aExtraMasksTransform when combining masks. r=Bas,a=kwierso (ba5ea1928b) - Bug 1263789 - Stop nsSVGMaskFrameNEON.h from polluting the global namespace. r=dholbert (e2c8544d35) - Bug 1162418 - Try to find a suitable non-zero dimension to use when containing block's inline-size depends on an SVG element which is specified as a percentage of its container. r=jwatt (3eab79c8a4) - Bug 1250143. Account for border/padding on outer <svg> elements in GeometryUtils. r=mats (f307820b75) - Bug 1243623. Don't skip unregistering a table part if we have a split table. r=mats (35bb0821c1) - Bug 1203417. Propagate error result from PaintTableFrame. r=seth (866e47b3e4) - Bug 1209780. Propagate the use of MOZ_MUST_USE DrawResult in nsTablePainter. r=seth (851618d06c) - var-const (29d5e9f859) - Bug 1209780. Propagate the use of MOZ_MUST_USE DrawResult in nsTreeBodyFrame::PaintText. r=seth (1ce563ea18) - Bug 1203626 - remove the unused argument from nsTreeBodyFrame::GetTwistyRect. r=mattwoodrow (03293f52b5) - Bug 1218041, part 1: Give nsTreeBodyFrame::PaintImage a fallback codepath for painting SVG images with no explicit height or width. r=seth (b6fd3a39f7) - Bug 1218041, part 2: add reftests for <treecell> SVG-image rendering. (no review) (90231e0bfa) - Bug 1224736: When image size lookup fails in nsTreeBodyFrame::PaintImage, only fall back to use the full destRect if we've got a VectorImage. r=tn (dd7d7667ca) - Bug 1156108 - Make nsTreeColumns::mFirstColumn an nsRefPtr; r=roc (f6888480bc) - Bug 1255069 - use UniquePtr for storage in nsTreeContentView; r=dholbert (598256735f) - Bug 1181560 - ensure previous menus get closed when opening new ones, r=Enn (2c88f3452a) - Bug 1192655 - Make menubar not react to events when it is not visible. r=enn (2bbcbc81a2) - Bug 1197913 - Keep the last hovered item highlighted after moving the cursor outside the <select> drop-down list on Windows. r=neil (abd3240473) - Bug 1228029 - Fix the usage of gtest assertion macros in TestJobScheduler.cpp. r=kats (0fcc9aa6fe) - Bug 1244234 - Simplify joining jobs with the gfx job scheduler. r=jrmuizel (f4b6bbf418) - Bug 1239288 - Add a shutdown test to the gfx job scheduler. r=jrmuizel (fd2432d108) - Bug 1239288 - Fix a race in the win32 job scheduler's shutdown. r=jrmuizel (4e509b4bf3) - Bug 1241161 - make Matrix4x4::ProjectTo2D normalize out perpective where possible. r=mattwoodrow (5a68e396a3) - bits of Bug 1135138 - Remove UNICODE from DEFINES (1eb51a0a79) - Bug 1249640: Part 4 Android to use new blocking. r=snorp (855e5c0dda) - Bug 1234875 - Remove alwaysAcceptSessionCookies pref. r=mak (8bed323449) - Bug 1247912 - convert left side expression to int64_t when assigning to mCookiesLifetimeSec in order to avoid overflow. r=jdm (0cedb68c83) - code and comment style (9215d74a8f) - code and comment style (1d4cda31af) - Bug 1219928 - Skip misspelled words in style blocks. r=enndeakin. (91dd0bcedf) - Bug 1236968 - autodial telemetry r=mayhemer (3844b9c19e) - Bug 1254310 - Add a hidden pref to temporarily disable Safe Browsing on given hostnames. r=gcp (4955fc88f8) - Bug 772528 - Remove nsFileInputStream::Seek() from nsPartialFileInputStream::Init(). r=baku (15db900fb5) - Bug 1150921 - Add telemetry for response codes to SafeBrowsing requests. r=francois f=bsmedberg (215d50e4ad) - Bug 1164518 - Better logging of completions. r=gcp (95b4fe3731) - Bug 1172688 - Add telemetry for when gethash calls timeout. r=francois, r=bsmedberg (b94a2b38a7) - Bug 1266184 - Implement nsIMIMEInputStream.data getter. r=mcmanus (8c9159c030) - Bug 1239955 - Let DNSService rely on IOService::Offline, r=bagder (336f161d21) - Bug 1260407 - added logging for proxy/pac to aid debugging, r=mcmanus (a179275ca6) - Bug 1259089 - Set TCP socket to non-blocking in sts again, just to be sure. r=mcmanus (bf0656bf07) - Bug 1256473 - Cast values to avoid C4838 on VS2015; r=mayhemer (d4b138dba8) - Bug 1260764 - Creation of PollableEvent needs a lock r=dragana a=kwierso (01c9d5e477) - Bug 652186 - Implement URL Standard's backslash replacement r=mcmanus (6485fa7e8c) - Bug 1042347 - %2e entered in URL bar not normalized leading to denormalized request r=mcmanus (3fc1ff92cd) - Bug 377052 - nsBaseURLParser::ParseURL doesn't handle spaces embedded in the scheme properly r=mcmanus (1f54055b9d) - fix editor format (444d6a62c4) - Bug 1154124 - Prevent recursion when calling HTTP cache entry's callbacks. r=michal (7bdfbf603d) - Bug 1247644 - Don't do any I/O on doomed and unused HTTP cache entries, r=michal (7668d29a36)
This commit is contained in:
+6
-1
@@ -224,7 +224,6 @@ pref("dom.use_watchdog", false);
|
||||
// ensure that those calls don't accidentally trigger the dialog.
|
||||
pref("dom.max_script_run_time", 0);
|
||||
pref("dom.max_chrome_script_run_time", 0);
|
||||
pref("dom.max_child_script_run_time", 0);
|
||||
|
||||
// plugins
|
||||
pref("plugin.disable", true);
|
||||
@@ -1046,6 +1045,12 @@ pref("touchcaret.enabled", true);
|
||||
// Enable selection caret by default
|
||||
pref("selectioncaret.enabled", true);
|
||||
|
||||
// The active caret is disallow to be dragged across the other (inactive) caret.
|
||||
pref("layout.accessiblecaret.allow_dragging_across_other_caret", false);
|
||||
|
||||
// Hide carets and text selection dialog during scrolling.
|
||||
pref("layout.accessiblecaret.always_show_when_scrolling", false);
|
||||
|
||||
// Enable sync and mozId with Firefox Accounts.
|
||||
pref("services.sync.fxaccounts.enabled", true);
|
||||
pref("identity.fxaccounts.enabled", true);
|
||||
|
||||
@@ -1675,13 +1675,15 @@ bool
|
||||
TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
|
||||
{
|
||||
mPuppetWidget->SetSizeMode(aSizeMode);
|
||||
if (!mPuppetWidget->IsVisible()) {
|
||||
return true;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> document(GetDocument());
|
||||
nsCOMPtr<nsIPresShell> presShell = document->GetShell();
|
||||
if (presShell) {
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
if (presContext) {
|
||||
presContext->MediaFeatureValuesChangedAllDocuments(eRestyle_Subtree,
|
||||
NS_STYLE_HINT_REFLOW);
|
||||
presContext->SizeModeChanged(aSizeMode);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -10,7 +10,8 @@ enum CaretChangedReason {
|
||||
"longpressonemptycontent",
|
||||
"taponcaret",
|
||||
"presscaret",
|
||||
"releasecaret"
|
||||
"releasecaret",
|
||||
"scroll"
|
||||
};
|
||||
|
||||
dictionary CaretStateChangedEventInit : EventInit {
|
||||
|
||||
@@ -45,6 +45,7 @@ nsComposeTxtSrvFilter::Skip(nsIDOMNode* aNode, bool *_retval)
|
||||
} else if (content->IsAnyOfHTMLElements(nsGkAtoms::script,
|
||||
nsGkAtoms::textarea,
|
||||
nsGkAtoms::select,
|
||||
nsGkAtoms::style,
|
||||
nsGkAtoms::map)) {
|
||||
*_retval = true;
|
||||
} else if (content->IsHTMLElement(nsGkAtoms::table)) {
|
||||
|
||||
@@ -6,3 +6,4 @@ skip-if = buildapp == 'b2g'
|
||||
[test_bug434998.xul]
|
||||
[test_bug678842.html]
|
||||
[test_bug717433.html]
|
||||
[test_bug1219928.html]
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1219928
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1219928</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1219928">Mozilla Bug 1219928</a>
|
||||
<p id="display"></p>
|
||||
|
||||
<div contenteditable id="en-US" lang="en-US">
|
||||
<p>And here a missspelled word</p>
|
||||
<style>
|
||||
<!-- and here another onnee in a style comment -->
|
||||
</style>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 1219928 **/
|
||||
/* Very simple test to check that <style> blocks are skipped in the spell check */
|
||||
|
||||
var spellchecker;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
Components.utils.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm");
|
||||
|
||||
var elem = document.getElementById('en-US');
|
||||
elem.focus();
|
||||
|
||||
onSpellCheck(elem, function () {
|
||||
var Ci = Components.interfaces;
|
||||
var editingSession = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIEditingSession);
|
||||
var editor = editingSession.getEditorForWindow(window);
|
||||
var selcon = editor.selectionController;
|
||||
var sel = selcon.getSelection(selcon.SELECTION_SPELLCHECK);
|
||||
|
||||
is(sel.toString(), "missspelled", "one misspelled word expected: missspelled");
|
||||
|
||||
spellchecker = Components.classes['@mozilla.org/editor/editorspellchecker;1'].createInstance(Components.interfaces.nsIEditorSpellCheck);
|
||||
var filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
|
||||
spellchecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
|
||||
spellchecker.InitSpellChecker(editor, false, spellCheckStarted);
|
||||
});
|
||||
});
|
||||
|
||||
function spellCheckStarted() {
|
||||
var misspelledWord = spellchecker.GetNextMisspelledWord();
|
||||
is(misspelledWord, "missspelled", "first misspelled word expected: missspelled");
|
||||
|
||||
// Without the fix, the next misspelled word was 'onnee', so we check that we don't get it.
|
||||
misspelledWord = spellchecker.GetNextMisspelledWord();
|
||||
isnot(misspelledWord, "onnee", "second misspelled word should not be: onnee");
|
||||
|
||||
spellchecker = "";
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -31,8 +31,8 @@ interface nsIWebBrowserChrome : nsISupports
|
||||
/**
|
||||
* The currently loaded WebBrowser. The browser chrome may be
|
||||
* told to set the WebBrowser object to a new object by setting this
|
||||
* attribute. In this case the implementer is responsible for taking the
|
||||
* new WebBrowser object and doing any necessary initialization or setup
|
||||
* attribute. In this case the implementer is responsible for taking the
|
||||
* new WebBrowser object and doing any necessary initialization or setup
|
||||
* as if it had created the WebBrowser itself. This includes positioning
|
||||
* setting up listeners etc.
|
||||
*/
|
||||
@@ -53,7 +53,7 @@ interface nsIWebBrowserChrome : nsISupports
|
||||
const unsigned long CHROME_SCROLLBARS = 0x00000200;
|
||||
const unsigned long CHROME_TITLEBAR = 0x00000400;
|
||||
const unsigned long CHROME_EXTRA = 0x00000800;
|
||||
|
||||
|
||||
// createBrowserWindow specific flags
|
||||
const unsigned long CHROME_WITH_SIZE = 0x00001000;
|
||||
const unsigned long CHROME_WITH_POSITION = 0x00002000;
|
||||
@@ -98,12 +98,12 @@ interface nsIWebBrowserChrome : nsISupports
|
||||
|
||||
// Note: The modal style bit just affects the way the window looks and does
|
||||
// mean it's actually modal.
|
||||
const unsigned long CHROME_MODAL = 0x20000000;
|
||||
const unsigned long CHROME_MODAL = 0x20000000;
|
||||
const unsigned long CHROME_OPENAS_DIALOG = 0x40000000;
|
||||
const unsigned long CHROME_OPENAS_CHROME = 0x80000000;
|
||||
|
||||
|
||||
const unsigned long CHROME_ALL = 0x00000ffe;
|
||||
|
||||
|
||||
/**
|
||||
* The chrome flags for this browser chrome. The implementation should
|
||||
* reflect the value of this attribute by hiding or showing its chrome
|
||||
@@ -118,20 +118,20 @@ interface nsIWebBrowserChrome : nsISupports
|
||||
void destroyBrowserWindow();
|
||||
|
||||
/**
|
||||
* Tells the chrome to size itself such that the browser will be the
|
||||
* Tells the chrome to size itself such that the browser will be the
|
||||
* specified size.
|
||||
* @param aCX new width of the browser
|
||||
* @param aCY new height of the browser
|
||||
*/
|
||||
void sizeBrowserTo(in long aCX, in long aCY);
|
||||
|
||||
|
||||
/**
|
||||
* Shows the window as a modal window.
|
||||
* @return (the function error code) the status value specified by
|
||||
* in exitModalEventLoop.
|
||||
*/
|
||||
void showAsModal();
|
||||
|
||||
|
||||
/**
|
||||
* Is the window modal (that is, currently executing a modal loop)?
|
||||
* @return true if it's a modal window
|
||||
@@ -145,4 +145,3 @@ interface nsIWebBrowserChrome : nsISupports
|
||||
*/
|
||||
void exitModalEventLoop(in nsresult aStatus);
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ static const uint32_t ACCEPT_FOR_N_DAYS = 3;
|
||||
static const bool kDefaultPolicy = true;
|
||||
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
|
||||
static const char kCookiesLifetimeDays[] = "network.cookie.lifetime.days";
|
||||
static const char kCookiesAlwaysAcceptSession[] = "network.cookie.alwaysAcceptSessionCookies";
|
||||
|
||||
static const char kCookiesPrefsMigrated[] = "network.cookie.prefsMigrated";
|
||||
// obsolete pref names for migration
|
||||
@@ -76,7 +75,6 @@ nsCookiePermission::Init()
|
||||
if (prefBranch) {
|
||||
prefBranch->AddObserver(kCookiesLifetimePolicy, this, false);
|
||||
prefBranch->AddObserver(kCookiesLifetimeDays, this, false);
|
||||
prefBranch->AddObserver(kCookiesAlwaysAcceptSession, this, false);
|
||||
PrefChanged(prefBranch, nullptr);
|
||||
|
||||
// migration code for original cookie prefs
|
||||
@@ -112,8 +110,7 @@ nsCookiePermission::PrefChanged(nsIPrefBranch *aPrefBranch,
|
||||
|
||||
if (PREF_CHANGED(kCookiesLifetimePolicy) &&
|
||||
NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimePolicy, &val))) {
|
||||
if (val != static_cast<int32_t>(ACCEPT_SESSION) &&
|
||||
val != static_cast<int32_t>(ACCEPT_FOR_N_DAYS)) {
|
||||
if (val != static_cast<int32_t>(ACCEPT_SESSION) && val != static_cast<int32_t>(ACCEPT_FOR_N_DAYS)) {
|
||||
val = ACCEPT_NORMALLY;
|
||||
}
|
||||
mCookiesLifetimePolicy = val;
|
||||
@@ -122,12 +119,7 @@ nsCookiePermission::PrefChanged(nsIPrefBranch *aPrefBranch,
|
||||
if (PREF_CHANGED(kCookiesLifetimeDays) &&
|
||||
NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimeDays, &val)))
|
||||
// save cookie lifetime in seconds instead of days
|
||||
mCookiesLifetimeSec = val * 24 * 60 * 60;
|
||||
|
||||
bool bval;
|
||||
if (PREF_CHANGED(kCookiesAlwaysAcceptSession) &&
|
||||
NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesAlwaysAcceptSession, &bval)))
|
||||
mCookiesAlwaysAcceptSession = bval;
|
||||
mCookiesLifetimeSec = (int64_t)val * 24 * 60 * 60;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -234,23 +226,23 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI,
|
||||
break;
|
||||
|
||||
default:
|
||||
// The permission manager has nothing to say about this cookie
|
||||
// so we apply the default prefs to it.
|
||||
// the permission manager has nothing to say about this cookie -
|
||||
// so, we apply the default prefs to it.
|
||||
NS_ASSERTION(perm == nsIPermissionManager::UNKNOWN_ACTION, "unknown permission");
|
||||
|
||||
// Now we need to figure out what type of accept policy we're dealing with.
|
||||
// If we accept cookies normally, just bail and return.
|
||||
// now we need to figure out what type of accept policy we're dealing with
|
||||
// if we accept cookies normally, just bail and return
|
||||
if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Declare this here since it'll be used in all of the remaining cases.
|
||||
// declare this here since it'll be used in all of the remaining cases
|
||||
int64_t currentTime = PR_Now() / PR_USEC_PER_SEC;
|
||||
int64_t delta = *aExpiry - currentTime;
|
||||
|
||||
// We are accepting the cookie, but if it's not a session cookie,
|
||||
// we may have to limit its lifetime.
|
||||
// We are accepting the cookie, but,
|
||||
// if it's not a session cookie, we may have to limit its lifetime.
|
||||
if (!*aIsSession && delta > 0) {
|
||||
if (mCookiesLifetimePolicy == ACCEPT_SESSION) {
|
||||
// limit lifetime to session
|
||||
|
||||
@@ -24,7 +24,6 @@ public:
|
||||
nsCookiePermission()
|
||||
: mCookiesLifetimeSec(INT64_MAX)
|
||||
, mCookiesLifetimePolicy(0) // ACCEPT_NORMALLY
|
||||
, mCookiesAlwaysAcceptSession(false)
|
||||
{}
|
||||
|
||||
bool Init();
|
||||
@@ -40,7 +39,6 @@ private:
|
||||
|
||||
int64_t mCookiesLifetimeSec; // lifetime limit specified in seconds
|
||||
uint8_t mCookiesLifetimePolicy; // pref for how long cookies are stored
|
||||
bool mCookiesAlwaysAcceptSession; // don't prompt for session cookies
|
||||
};
|
||||
|
||||
// {EF565D0A-AB9A-4A13-9160-0644CDFD859A}
|
||||
|
||||
@@ -77,6 +77,14 @@ JobScheduler::SubmitJob(Job* aJob)
|
||||
GetQueueForJob(aJob)->SubmitJob(aJob);
|
||||
}
|
||||
|
||||
void
|
||||
JobScheduler::Join(SyncObject* aCompletion)
|
||||
{
|
||||
RefPtr<EventObject> waitForCompletion = new EventObject();
|
||||
JobScheduler::SubmitJob(new SetEventJob(waitForCompletion, aCompletion));
|
||||
waitForCompletion->Wait();
|
||||
}
|
||||
|
||||
MultiThreadedJobQueue*
|
||||
JobScheduler::GetQueueForJob(Job* aJob)
|
||||
{
|
||||
|
||||
@@ -71,6 +71,12 @@ public:
|
||||
/// The caller looses ownership of the task buffer.
|
||||
static void SubmitJob(Job* aJobs);
|
||||
|
||||
/// Convenience function to block the current thread until a given SyncObject
|
||||
/// is in the signaled state.
|
||||
///
|
||||
/// The current thread will first try to steal jobs before blocking.
|
||||
static void Join(SyncObject* aCompletionSync);
|
||||
|
||||
/// Process commands until the command buffer needs to block on a sync object,
|
||||
/// completes, yields, or encounters an error.
|
||||
///
|
||||
|
||||
@@ -132,9 +132,14 @@ MultiThreadedJobQueue::RegisterThread()
|
||||
void
|
||||
MultiThreadedJobQueue::UnregisterThread()
|
||||
{
|
||||
CriticalSectionAutoEnter lock(&mSection);
|
||||
mSection.Enter();
|
||||
mThreadsCount -= 1;
|
||||
if (mThreadsCount == 0) {
|
||||
bool finishShutdown = mThreadsCount == 0;
|
||||
mSection.Leave();
|
||||
|
||||
if (finishShutdown) {
|
||||
// Can't touch mSection or any other member from now on because this object
|
||||
// may get deleted on the main thread after mShutdownEvent is set.
|
||||
::SetEvent(mShutdownEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -548,6 +548,24 @@ public:
|
||||
_33 = 1.0f;
|
||||
_43 = 0.0f;
|
||||
_34 = 0.0f;
|
||||
// Some matrices, such as those derived from perspective transforms,
|
||||
// can modify _44 from 1, while leaving the rest of the fourth column
|
||||
// (_14, _24) at 0. In this case, after resetting the third row and
|
||||
// third column above, the value of _44 functions only to scale the
|
||||
// coordinate transform divide by W. The matrix can be converted to
|
||||
// a true 2D matrix by normalizing out the scaling effect of _44 on
|
||||
// the remaining components ahead of time.
|
||||
if (_14 == 0.0f && _24 == 0.0f &&
|
||||
_44 != 1.0f && _44 != 0.0f) {
|
||||
Float scale = 1.0f / _44;
|
||||
_11 *= scale;
|
||||
_12 *= scale;
|
||||
_21 *= scale;
|
||||
_22 *= scale;
|
||||
_41 *= scale;
|
||||
_42 *= scale;
|
||||
_44 = 1.0f;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ struct SanityChecker {
|
||||
{
|
||||
MaybeYieldThread();
|
||||
CriticalSectionAutoEnter lock(&mSection);
|
||||
ASSERT_EQ(mAdvancements[aJobId], aCmdId-1);
|
||||
MOZ_RELEASE_ASSERT(mAdvancements[aJobId] == aCmdId-1);
|
||||
mAdvancements[aJobId] = aCmdId;
|
||||
}
|
||||
};
|
||||
@@ -66,12 +66,12 @@ struct JoinTestSanityCheck : public SanityChecker {
|
||||
{
|
||||
// Job 0 is the special task executed when everything is joined after task 1
|
||||
if (aCmdId == 0) {
|
||||
ASSERT_FALSE(mSpecialJobHasRun);
|
||||
MOZ_RELEASE_ASSERT(!mSpecialJobHasRun);
|
||||
mSpecialJobHasRun = true;
|
||||
for (auto advancement : mAdvancements) {
|
||||
// Because of the synchronization point (beforeFilter), all
|
||||
// task buffers should have run task 1 when task 0 is run.
|
||||
ASSERT_EQ(advancement, (uint32_t)1);
|
||||
MOZ_RELEASE_ASSERT(advancement == 1);
|
||||
}
|
||||
} else {
|
||||
// This check does not apply to task 0.
|
||||
@@ -79,7 +79,7 @@ struct JoinTestSanityCheck : public SanityChecker {
|
||||
}
|
||||
|
||||
if (aCmdId == 2) {
|
||||
ASSERT_TRUE(mSpecialJobHasRun);
|
||||
MOZ_RELEASE_ASSERT(mSpecialJobHasRun);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -145,18 +145,12 @@ void TestSchedulerJoin(uint32_t aNumThreads, uint32_t aNumCmdBuffers)
|
||||
}
|
||||
completion->FreezePrerequisites();
|
||||
|
||||
RefPtr<EventObject> waitForCompletion = new EventObject();
|
||||
auto evtJob = new SetEventJob(waitForCompletion, completion);
|
||||
JobScheduler::SubmitJob(evtJob);
|
||||
|
||||
MaybeYieldThread();
|
||||
|
||||
waitForCompletion->Wait();
|
||||
JobScheduler::Join(completion);
|
||||
|
||||
MaybeYieldThread();
|
||||
|
||||
for (auto advancement : check.mAdvancements) {
|
||||
ASSERT_TRUE(advancement == 2);
|
||||
EXPECT_TRUE(advancement == 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,21 +199,25 @@ void TestSchedulerChain(uint32_t aNumThreads, uint32_t aNumCmdBuffers)
|
||||
}
|
||||
completion->FreezePrerequisites();
|
||||
|
||||
RefPtr<EventObject> waitForCompletion = new EventObject();
|
||||
auto evtJob = new SetEventJob(waitForCompletion, completion);
|
||||
JobScheduler::SubmitJob(evtJob);
|
||||
|
||||
MaybeYieldThread();
|
||||
|
||||
waitForCompletion->Wait();
|
||||
JobScheduler::Join(completion);
|
||||
|
||||
for (auto advancement : check.mAdvancements) {
|
||||
ASSERT_TRUE(advancement == numJobs);
|
||||
EXPECT_TRUE(advancement == numJobs);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test_scheduler
|
||||
|
||||
TEST(Moz2D, JobScheduler_Shutdown) {
|
||||
srand(time(nullptr));
|
||||
for (uint32_t threads = 1; threads < 16; ++threads) {
|
||||
for (uint32_t i = 1; i < 1000; ++i) {
|
||||
mozilla::gfx::JobScheduler::Init(threads, threads);
|
||||
mozilla::gfx::JobScheduler::ShutDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Moz2D, JobScheduler_Join) {
|
||||
srand(time(nullptr));
|
||||
for (uint32_t threads = 1; threads < 8; ++threads) {
|
||||
|
||||
@@ -361,23 +361,6 @@ gfxAndroidPlatform::RequiresLinearZoom()
|
||||
return gfxPlatform::RequiresLinearZoom();
|
||||
}
|
||||
|
||||
bool
|
||||
gfxAndroidPlatform::UseAcceleratedSkiaCanvas()
|
||||
{
|
||||
return HaveChoiceOfHWAndSWCanvas() && gfxPlatform::UseAcceleratedSkiaCanvas();
|
||||
}
|
||||
|
||||
bool gfxAndroidPlatform::HaveChoiceOfHWAndSWCanvas()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (!AndroidBridge::Bridge() || AndroidBridge::Bridge()->GetAPIVersion() < 11) {
|
||||
// It's slower than software due to not having a compositing fast path
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return gfxPlatform::HaveChoiceOfHWAndSWCanvas();
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
class GonkVsyncSource final : public VsyncSource
|
||||
{
|
||||
|
||||
@@ -66,8 +66,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool HaveChoiceOfHWAndSWCanvas() override;
|
||||
virtual bool UseAcceleratedSkiaCanvas() override;
|
||||
virtual already_AddRefed<mozilla::gfx::VsyncSource> CreateHardwareVsyncSource() override;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIHapticFeedback.h"
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "nsWindow.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -69,13 +72,17 @@ AccessibleCaretManager::sSelectionBarEnabled = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretsExtendedVisibility = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretsAlwaysTilt = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = true;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretsScriptUpdates = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sCaretsAllowDraggingAcrossOtherCaret = true;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sHapticFeedback = false;
|
||||
/*static*/ bool
|
||||
AccessibleCaretManager::sExtendSelectionForPhoneNumber = false;
|
||||
|
||||
AccessibleCaretManager::AccessibleCaretManager(nsIPresShell* aPresShell)
|
||||
: mPresShell(aPresShell)
|
||||
@@ -95,14 +102,18 @@ AccessibleCaretManager::AccessibleCaretManager(nsIPresShell* aPresShell)
|
||||
"layout.accessiblecaret.bar.enabled");
|
||||
Preferences::AddBoolVarCache(&sCaretShownWhenLongTappingOnEmptyContent,
|
||||
"layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content");
|
||||
Preferences::AddBoolVarCache(&sCaretsExtendedVisibility,
|
||||
"layout.accessiblecaret.extendedvisibility");
|
||||
Preferences::AddBoolVarCache(&sCaretsAlwaysTilt,
|
||||
"layout.accessiblecaret.always_tilt");
|
||||
Preferences::AddBoolVarCache(&sCaretsAlwaysShowWhenScrolling,
|
||||
"layout.accessiblecaret.always_show_when_scrolling", true);
|
||||
Preferences::AddBoolVarCache(&sCaretsScriptUpdates,
|
||||
"layout.accessiblecaret.allow_script_change_updates");
|
||||
Preferences::AddBoolVarCache(&sCaretsAllowDraggingAcrossOtherCaret,
|
||||
"layout.accessiblecaret.allow_dragging_across_other_caret", true);
|
||||
Preferences::AddBoolVarCache(&sHapticFeedback,
|
||||
"layout.accessiblecaret.hapticfeedback");
|
||||
Preferences::AddBoolVarCache(&sExtendSelectionForPhoneNumber,
|
||||
"layout.accessiblecaret.extend_selection_for_phone_number");
|
||||
addedPrefs = true;
|
||||
}
|
||||
}
|
||||
@@ -197,18 +208,6 @@ AccessibleCaretManager::HideCarets()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::DoNotShowCarets()
|
||||
{
|
||||
if (mFirstCaret->IsLogicallyVisible() || mSecondCaret->IsLogicallyVisible()) {
|
||||
AC_LOG("%s", __FUNCTION__);
|
||||
mFirstCaret->SetAppearance(Appearance::NormalNotShown);
|
||||
mSecondCaret->SetAppearance(Appearance::NormalNotShown);
|
||||
DispatchCaretStateChangedEvent(CaretChangedReason::Visibilitychange);
|
||||
CancelCaretTimeoutTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::UpdateCarets(UpdateCaretsHint aHint)
|
||||
{
|
||||
@@ -345,10 +344,12 @@ AccessibleCaretManager::UpdateCaretsForSelectionMode(UpdateCaretsHint aHint)
|
||||
AC_LOG("%s: selection: %p", __FUNCTION__, GetSelection());
|
||||
|
||||
int32_t startOffset = 0;
|
||||
nsIFrame* startFrame = FindFirstNodeWithFrame(false, &startOffset);
|
||||
nsIFrame* startFrame =
|
||||
GetFrameForFirstRangeStartOrLastRangeEnd(eDirNext, &startOffset);
|
||||
|
||||
int32_t endOffset = 0;
|
||||
nsIFrame* endFrame = FindFirstNodeWithFrame(true, &endOffset);
|
||||
nsIFrame* endFrame =
|
||||
GetFrameForFirstRangeStartOrLastRangeEnd(eDirPrevious, &endOffset);
|
||||
|
||||
if (!CompareTreePosition(startFrame, endFrame)) {
|
||||
// XXX: Do we really have to hide carets if this condition isn't satisfied?
|
||||
@@ -620,14 +621,19 @@ AccessibleCaretManager::OnScrollStart()
|
||||
{
|
||||
AC_LOG("%s", __FUNCTION__);
|
||||
|
||||
mFirstCaretAppearanceOnScrollStart = mFirstCaret->GetAppearance();
|
||||
mSecondCaretAppearanceOnScrollStart = mSecondCaret->GetAppearance();
|
||||
|
||||
// Hide the carets. (Extended visibility makes them "NormalNotShown").
|
||||
if (sCaretsExtendedVisibility) {
|
||||
DoNotShowCarets();
|
||||
} else {
|
||||
if (!sCaretsAlwaysShowWhenScrolling) {
|
||||
// Backup the appearance so that we can restore them after the scrolling
|
||||
// ends.
|
||||
mFirstCaretAppearanceOnScrollStart = mFirstCaret->GetAppearance();
|
||||
mSecondCaretAppearanceOnScrollStart = mSecondCaret->GetAppearance();
|
||||
HideCarets();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFirstCaret->IsLogicallyVisible() || mSecondCaret->IsLogicallyVisible()) {
|
||||
// Dispatch the event only if one of the carets is logically visible like in
|
||||
// HideCarets().
|
||||
DispatchCaretStateChangedEvent(CaretChangedReason::Scroll);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -638,8 +644,11 @@ AccessibleCaretManager::OnScrollEnd()
|
||||
return;
|
||||
}
|
||||
|
||||
mFirstCaret->SetAppearance(mFirstCaretAppearanceOnScrollStart);
|
||||
mSecondCaret->SetAppearance(mSecondCaretAppearanceOnScrollStart);
|
||||
if (!sCaretsAlwaysShowWhenScrolling) {
|
||||
// Restore the appearance which is saved before the scrolling is started.
|
||||
mFirstCaret->SetAppearance(mFirstCaretAppearanceOnScrollStart);
|
||||
mSecondCaret->SetAppearance(mSecondCaretAppearanceOnScrollStart);
|
||||
}
|
||||
|
||||
if (GetCaretMode() == CaretMode::Cursor) {
|
||||
if (!mFirstCaret->IsLogicallyVisible()) {
|
||||
@@ -818,6 +827,11 @@ AccessibleCaretManager::SelectWord(nsIFrame* aFrame, const nsPoint& aPoint) cons
|
||||
SetSelectionDragState(false);
|
||||
ClearMaintainedSelection();
|
||||
|
||||
// Smart-select phone numbers if possible.
|
||||
if (sExtendSelectionForPhoneNumber) {
|
||||
SelectMoreIfPhoneNumber();
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
@@ -828,6 +842,62 @@ AccessibleCaretManager::SetSelectionDragState(bool aState) const
|
||||
if (fs) {
|
||||
fs->SetDragState(aState);
|
||||
}
|
||||
|
||||
// Pin Fennecs DynamicToolbarAnimator in place before/after dragging,
|
||||
// to avoid co-incident screen scrolling.
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
nsIDocument* doc = mPresShell->GetDocument();
|
||||
MOZ_ASSERT(doc);
|
||||
nsIWidget* widget = nsContentUtils::WidgetForDocument(doc);
|
||||
static_cast<nsWindow*>(widget)->SetSelectionDragState(aState);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::SelectMoreIfPhoneNumber() const
|
||||
{
|
||||
SetSelectionDirection(eDirNext);
|
||||
ExtendPhoneNumberSelection(NS_LITERAL_STRING("forward"));
|
||||
|
||||
SetSelectionDirection(eDirPrevious);
|
||||
ExtendPhoneNumberSelection(NS_LITERAL_STRING("backward"));
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::ExtendPhoneNumberSelection(const nsAString& aDirection) const
|
||||
{
|
||||
nsIDocument* doc = mPresShell->GetDocument();
|
||||
|
||||
// Extend the phone number selection until we find a boundary.
|
||||
Selection* selection = GetSelection();
|
||||
|
||||
while (selection) {
|
||||
// Save current Focus position, and extend the selection one char.
|
||||
nsINode* focusNode = selection->GetFocusNode();
|
||||
uint32_t focusOffset = selection->FocusOffset();
|
||||
selection->Modify(NS_LITERAL_STRING("extend"),
|
||||
aDirection,
|
||||
NS_LITERAL_STRING("character"));
|
||||
|
||||
// If the selection didn't change, (can't extend further), we're done.
|
||||
if (selection->GetFocusNode() == focusNode &&
|
||||
selection->FocusOffset() == focusOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the changed selection isn't a valid phone number, we're done.
|
||||
nsAutoString selectedText;
|
||||
selection->Stringify(selectedText);
|
||||
nsAutoString phoneRegex(NS_LITERAL_STRING("(^\\+)?[0-9\\s,\\-.()*#pw]{1,30}$"));
|
||||
|
||||
if (!nsContentUtils::IsPatternMatching(selectedText, phoneRegex, doc)) {
|
||||
// Backout the undesired selection extend, (collapse to original
|
||||
// Anchor, extend to original Focus), before exit.
|
||||
selection->Collapse(selection->GetAnchorNode(), selection->AnchorOffset());
|
||||
selection->Extend(focusNode, focusOffset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -859,41 +929,51 @@ AccessibleCaretManager::FlushLayout() const
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
AccessibleCaretManager::FindFirstNodeWithFrame(bool aBackward,
|
||||
int32_t* aOutOffset) const
|
||||
AccessibleCaretManager::GetFrameForFirstRangeStartOrLastRangeEnd(
|
||||
nsDirection aDirection, int32_t* aOutOffset, nsINode** aOutNode,
|
||||
int32_t* aOutNodeOffset) const
|
||||
{
|
||||
if (!mPresShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetCaretMode() == CaretMode::Selection);
|
||||
|
||||
nsRange* range = nullptr;
|
||||
RefPtr<nsINode> startNode;
|
||||
RefPtr<nsINode> endNode;
|
||||
int32_t nodeOffset = 0;
|
||||
CaretAssociationHint hint;
|
||||
|
||||
RefPtr<Selection> selection = GetSelection();
|
||||
if (!selection) {
|
||||
return nullptr;
|
||||
bool findInFirstRangeStart = aDirection == eDirNext;
|
||||
|
||||
if (findInFirstRangeStart) {
|
||||
range = selection->GetRangeAt(0);
|
||||
startNode = range->GetStartParent();
|
||||
endNode = range->GetEndParent();
|
||||
nodeOffset = range->StartOffset();
|
||||
hint = CARET_ASSOCIATE_AFTER;
|
||||
} else {
|
||||
range = selection->GetRangeAt(selection->RangeCount() - 1);
|
||||
startNode = range->GetEndParent();
|
||||
endNode = range->GetStartParent();
|
||||
nodeOffset = range->EndOffset();
|
||||
hint = CARET_ASSOCIATE_BEFORE;
|
||||
}
|
||||
|
||||
RefPtr<nsFrameSelection> fs = GetFrameSelection();
|
||||
if (!fs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
if (rangeCount <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRange* range = selection->GetRangeAt(aBackward ? rangeCount - 1 : 0);
|
||||
RefPtr<nsINode> startNode =
|
||||
aBackward ? range->GetEndParent() : range->GetStartParent();
|
||||
RefPtr<nsINode> endNode =
|
||||
aBackward ? range->GetStartParent() : range->GetEndParent();
|
||||
int32_t offset = aBackward ? range->EndOffset() : range->StartOffset();
|
||||
nsCOMPtr<nsIContent> startContent = do_QueryInterface(startNode);
|
||||
CaretAssociationHint hintStart =
|
||||
aBackward ? CARET_ASSOCIATE_BEFORE : CARET_ASSOCIATE_AFTER;
|
||||
RefPtr<nsFrameSelection> fs = GetFrameSelection();
|
||||
nsIFrame* startFrame =
|
||||
fs->GetFrameForNodeOffset(startContent, offset, hintStart, aOutOffset);
|
||||
fs->GetFrameForNodeOffset(startContent, nodeOffset, hint, aOutOffset);
|
||||
|
||||
if (startFrame) {
|
||||
if (aOutNode) {
|
||||
*aOutNode = startNode.get();
|
||||
}
|
||||
if (aOutNodeOffset) {
|
||||
*aOutNodeOffset = nodeOffset;
|
||||
}
|
||||
return startFrame;
|
||||
}
|
||||
|
||||
@@ -907,7 +987,8 @@ AccessibleCaretManager::FindFirstNodeWithFrame(bool aBackward,
|
||||
|
||||
startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr;
|
||||
while (!startFrame && startNode != endNode) {
|
||||
startNode = aBackward ? walker->PreviousNode(err) : walker->NextNode(err);
|
||||
startNode = findInFirstRangeStart ? walker->NextNode(err)
|
||||
: walker->PreviousNode(err);
|
||||
|
||||
if (!startNode) {
|
||||
break;
|
||||
@@ -920,78 +1001,86 @@ AccessibleCaretManager::FindFirstNodeWithFrame(bool aBackward,
|
||||
}
|
||||
|
||||
bool
|
||||
AccessibleCaretManager::CompareRangeWithContentOffset(nsIFrame::ContentOffsets& aOffsets)
|
||||
AccessibleCaretManager::RestrictCaretDraggingOffsets(
|
||||
nsIFrame::ContentOffsets& aOffsets)
|
||||
{
|
||||
Selection* selection = GetSelection();
|
||||
if (!selection) {
|
||||
if (!mPresShell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
MOZ_ASSERT(rangeCount > 0);
|
||||
|
||||
int32_t rangeIndex = (mActiveCaret == mFirstCaret.get() ? rangeCount - 1 : 0);
|
||||
RefPtr<nsRange> range = selection->GetRangeAt(rangeIndex);
|
||||
MOZ_ASSERT(GetCaretMode() == CaretMode::Selection);
|
||||
|
||||
nsDirection dir = mActiveCaret == mFirstCaret.get() ? eDirPrevious : eDirNext;
|
||||
int32_t offset = 0;
|
||||
nsINode* node = nullptr;
|
||||
int32_t nodeOffset = 0;
|
||||
CaretAssociationHint hint;
|
||||
nsDirection dir;
|
||||
int32_t contentOffset = 0;
|
||||
nsIFrame* frame =
|
||||
GetFrameForFirstRangeStartOrLastRangeEnd(dir, &offset, &node, &contentOffset);
|
||||
|
||||
if (mActiveCaret == mFirstCaret.get()) {
|
||||
// Check previous character of end node offset
|
||||
node = range->GetEndParent();
|
||||
nodeOffset = range->EndOffset();
|
||||
hint = CARET_ASSOCIATE_BEFORE;
|
||||
dir = eDirPrevious;
|
||||
} else {
|
||||
// Check next character of start node offset
|
||||
node = range->GetStartParent();
|
||||
nodeOffset = range->StartOffset();
|
||||
hint = CARET_ASSOCIATE_AFTER;
|
||||
dir = eDirNext;
|
||||
if (!frame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
|
||||
RefPtr<nsFrameSelection> fs = GetFrameSelection();
|
||||
if (!fs) {
|
||||
return false;
|
||||
}
|
||||
// Compare the active caret's new position (aOffsets) to the inactive caret's
|
||||
// position.
|
||||
int32_t cmpToInactiveCaretPos =
|
||||
nsContentUtils::ComparePoints(aOffsets.content, aOffsets.StartOffset(),
|
||||
content, contentOffset);
|
||||
|
||||
int32_t offset = 0;
|
||||
nsIFrame* theFrame =
|
||||
fs->GetFrameForNodeOffset(content, nodeOffset, hint, &offset);
|
||||
|
||||
if (!theFrame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move one character forward/backward from point and get offset
|
||||
nsPeekOffsetStruct pos(eSelectCluster,
|
||||
dir,
|
||||
offset,
|
||||
nsPoint(0, 0),
|
||||
true,
|
||||
true, //limit on scrolled views
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
nsresult rv = theFrame->PeekOffset(&pos);
|
||||
// Move one character (in the direction of dir) from the inactive caret's
|
||||
// position. This is the limit for the active caret's new position.
|
||||
nsPeekOffsetStruct limit(eSelectCluster, dir, offset, nsPoint(0, 0), true, true,
|
||||
false, false, false);
|
||||
nsresult rv = frame->PeekOffset(&limit);
|
||||
if (NS_FAILED(rv)) {
|
||||
pos.mResultContent = content;
|
||||
pos.mContentOffset = nodeOffset;
|
||||
limit.mResultContent = content;
|
||||
limit.mContentOffset = contentOffset;
|
||||
}
|
||||
|
||||
// Compare with current point
|
||||
int32_t result = nsContentUtils::ComparePoints(aOffsets.content,
|
||||
aOffsets.StartOffset(),
|
||||
pos.mResultContent,
|
||||
pos.mContentOffset);
|
||||
if ((mActiveCaret == mFirstCaret.get() && result == 1) ||
|
||||
(mActiveCaret == mSecondCaret.get() && result == -1)) {
|
||||
aOffsets.content = pos.mResultContent;
|
||||
aOffsets.offset = pos.mContentOffset;
|
||||
aOffsets.secondaryOffset = pos.mContentOffset;
|
||||
// Compare the active caret's new position (aOffsets) to the limit.
|
||||
int32_t cmpToLimit =
|
||||
nsContentUtils::ComparePoints(aOffsets.content, aOffsets.StartOffset(),
|
||||
limit.mResultContent, limit.mContentOffset);
|
||||
|
||||
auto SetOffsetsToLimit = [&aOffsets, &limit] () {
|
||||
aOffsets.content = limit.mResultContent;
|
||||
aOffsets.offset = limit.mContentOffset;
|
||||
aOffsets.secondaryOffset = limit.mContentOffset;
|
||||
};
|
||||
|
||||
if (!sCaretsAllowDraggingAcrossOtherCaret) {
|
||||
if ((mActiveCaret == mFirstCaret.get() && cmpToLimit == 1) ||
|
||||
(mActiveCaret == mSecondCaret.get() && cmpToLimit == -1)) {
|
||||
// The active caret's position is past the limit, which we don't allow
|
||||
// here. So set it to the limit, resulting in one character being
|
||||
// selected.
|
||||
SetOffsetsToLimit();
|
||||
}
|
||||
} else {
|
||||
switch (cmpToInactiveCaretPos) {
|
||||
case 0:
|
||||
// The active caret's position is the same as the position of the
|
||||
// inactive caret. So set it to the limit to prevent the selection from
|
||||
// being collapsed, resulting in one character being selected.
|
||||
SetOffsetsToLimit();
|
||||
break;
|
||||
case 1:
|
||||
if (mActiveCaret == mFirstCaret.get()) {
|
||||
// First caret was moved across the second caret. After making change
|
||||
// to the selection, the user will drag the second caret.
|
||||
mActiveCaret = mSecondCaret.get();
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
if (mActiveCaret == mSecondCaret.get()) {
|
||||
// Second caret was moved across the first caret. After making change
|
||||
// to the selection, the user will drag the first caret.
|
||||
mActiveCaret = mFirstCaret.get();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1051,7 +1140,7 @@ AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint)
|
||||
|
||||
nsIFrame::ContentOffsets offsets =
|
||||
newFrame->GetContentOffsetsFromPoint(newPoint);
|
||||
if (!offsets.content) {
|
||||
if (offsets.IsNull()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1061,7 +1150,7 @@ AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint)
|
||||
}
|
||||
|
||||
if (GetCaretMode() == CaretMode::Selection &&
|
||||
!CompareRangeWithContentOffset(offsets)) {
|
||||
!RestrictCaretDraggingOffsets(offsets)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1154,7 +1243,8 @@ AccessibleCaretManager::AdjustDragBoundary(const nsPoint& aPoint) const
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCaretMode() == CaretMode::Selection) {
|
||||
if (GetCaretMode() == CaretMode::Selection &&
|
||||
!sCaretsAllowDraggingAcrossOtherCaret) {
|
||||
// Bug 1068474: Adjust the Y-coordinate so that the carets won't be in tilt
|
||||
// mode when a caret is being dragged surpass the other caret.
|
||||
//
|
||||
|
||||
@@ -135,10 +135,6 @@ protected:
|
||||
// Force hiding all carets regardless of the current selection status.
|
||||
void HideCarets();
|
||||
|
||||
// Force carets to be "present" logically, but not visible. Allows ActionBar
|
||||
// to stay open when carets visibility is supressed during scroll.
|
||||
void DoNotShowCarets();
|
||||
|
||||
void UpdateCaretsForCursorMode(UpdateCaretsHint aHint);
|
||||
void UpdateCaretsForSelectionMode(UpdateCaretsHint aHint);
|
||||
|
||||
@@ -155,12 +151,21 @@ protected:
|
||||
|
||||
nsresult SelectWord(nsIFrame* aFrame, const nsPoint& aPoint) const;
|
||||
void SetSelectionDragState(bool aState) const;
|
||||
|
||||
// Called to extend a selection if possible that it's a phone number.
|
||||
void SelectMoreIfPhoneNumber() const;
|
||||
// Extend the current phone number selection in the requested direction.
|
||||
void ExtendPhoneNumberSelection(const nsAString& aDirection) const;
|
||||
|
||||
void SetSelectionDirection(nsDirection aDir) const;
|
||||
|
||||
// If aBackward is false, find the first node from the first range in current
|
||||
// selection, and return the frame and the offset into that frame. If aBackward
|
||||
// is true, find the last node from the last range instead.
|
||||
nsIFrame* FindFirstNodeWithFrame(bool aBackward, int32_t* aOutOffset) const;
|
||||
// If aDirection is eDirNext, get the frame for the range start in the first
|
||||
// range from the current selection, and return the offset into that frame as
|
||||
// well as the range start node and the node offset. Otherwise, get the frame
|
||||
// and offset for the range end in the last range instead.
|
||||
nsIFrame* GetFrameForFirstRangeStartOrLastRangeEnd(
|
||||
nsDirection aDirection, int32_t* aOutOffset, nsINode** aOutNode = nullptr,
|
||||
int32_t* aOutNodeOffset = nullptr) const;
|
||||
|
||||
nsresult DragCaretInternal(const nsPoint& aPoint);
|
||||
nsPoint AdjustDragBoundary(const nsPoint& aPoint) const;
|
||||
@@ -179,11 +184,18 @@ protected:
|
||||
// be dragged. Returns the rect relative to aFrame.
|
||||
nsRect GetAllChildFrameRectsUnion(nsIFrame* aFrame) const;
|
||||
|
||||
// If we're dragging the first caret, we do not want to drag it over the
|
||||
// previous character of the second caret. Same as the second caret. So we
|
||||
// check if content offset exceeds the previous/next character of second/first
|
||||
// caret base the active caret.
|
||||
bool CompareRangeWithContentOffset(nsIFrame::ContentOffsets& aOffsets);
|
||||
// Restrict the active caret's dragging position based on
|
||||
// sCaretsAllowDraggingAcrossOtherCaret. If the active caret is the first
|
||||
// caret, the `limit` will be the previous character of the second caret.
|
||||
// Otherwise, the `limit` will be the next character of the first caret.
|
||||
//
|
||||
// @param aOffsets is the new position of the active caret, and it will be set
|
||||
// to the `limit` when 1) sCaretsAllowDraggingAcrossOtherCaret is false and
|
||||
// it's being dragged past the limit. 2) sCaretsAllowDraggingAcrossOtherCaret
|
||||
// is true and the active caret's position is the same as the inactive's
|
||||
// position.
|
||||
// @return true if the aOffsets is suitable for changing the selection.
|
||||
bool RestrictCaretDraggingOffsets(nsIFrame::ContentOffsets& aOffsets);
|
||||
|
||||
// Timeout in milliseconds to hide the AccessibleCaret under cursor mode while
|
||||
// no one touches it.
|
||||
@@ -272,25 +284,35 @@ protected:
|
||||
// selection bar is always disabled in cursor mode.
|
||||
static bool sSelectionBarEnabled;
|
||||
|
||||
// Preference to allow smarter selection of phone numbers,
|
||||
// when user long presses text to start.
|
||||
static bool sExtendSelectionForPhoneNumber;
|
||||
|
||||
// Preference to show caret in cursor mode when long tapping on an empty
|
||||
// content. This also changes the default update behavior in cursor mode,
|
||||
// which is based on the emptiness of the content, into something more
|
||||
// heuristic. See UpdateCaretsForCursorMode() for the details.
|
||||
static bool sCaretShownWhenLongTappingOnEmptyContent;
|
||||
|
||||
// Android specific visibility extensions correct compatibility issues
|
||||
// with ActionBar visibility during page scroll.
|
||||
static bool sCaretsExtendedVisibility;
|
||||
|
||||
// Preference to make carets always tilt in selection mode. By default, the
|
||||
// carets become tilt only when they are overlapping.
|
||||
static bool sCaretsAlwaysTilt;
|
||||
|
||||
// Preference to allow carets always show when scrolling (either panning or
|
||||
// zooming) the page. When set to false, carets will hide during scrolling,
|
||||
// and show again after the user lifts the finger off the screen.
|
||||
static bool sCaretsAlwaysShowWhenScrolling;
|
||||
|
||||
// By default, javascript content selection changes closes AccessibleCarets and
|
||||
// UI interactions. Optionally, we can try to maintain the active UI, keeping
|
||||
// carets and ActionBar available.
|
||||
static bool sCaretsScriptUpdates;
|
||||
|
||||
// Preference to allow one caret to be dragged across the other caret without
|
||||
// any limitation. When set to false, one caret cannot be dragged across the
|
||||
// other one.
|
||||
static bool sCaretsAllowDraggingAcrossOtherCaret;
|
||||
|
||||
// AccessibleCaret pref for haptic feedback behaviour on longPress.
|
||||
static bool sHapticFeedback;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "nsStyleTransformMatrix.h"
|
||||
#include "nsTransitionManager.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsDOMCSSDeclaration.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -311,12 +312,21 @@ ActiveLayerTracker::NotifyOffsetRestyle(nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ActiveLayerTracker::NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty)
|
||||
ActiveLayerTracker::NotifyAnimated(nsIFrame* aFrame,
|
||||
nsCSSProperty aProperty,
|
||||
const nsAString& aNewValue,
|
||||
nsDOMCSSDeclaration* aDOMCSSDecl)
|
||||
{
|
||||
LayerActivity* layerActivity = GetLayerActivityForUpdate(aFrame);
|
||||
uint8_t& mutationCount = layerActivity->RestyleCountForProperty(aProperty);
|
||||
// We know this is animated, so just hack the mutation count.
|
||||
mutationCount = 0xFF;
|
||||
if (mutationCount != 0xFF) {
|
||||
nsAutoString oldValue;
|
||||
aDOMCSSDecl->GetPropertyValue(aProperty, oldValue);
|
||||
if (aNewValue != oldValue) {
|
||||
// We know this is animated, so just hack the mutation count.
|
||||
mutationCount = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@@ -354,10 +364,12 @@ IsPresContextInScriptAnimationCallback(nsPresContext* aPresContext)
|
||||
|
||||
/* static */ void
|
||||
ActiveLayerTracker::NotifyInlineStyleRuleModified(nsIFrame* aFrame,
|
||||
nsCSSProperty aProperty)
|
||||
nsCSSProperty aProperty,
|
||||
const nsAString& aNewValue,
|
||||
nsDOMCSSDeclaration* aDOMCSSDecl)
|
||||
{
|
||||
if (IsPresContextInScriptAnimationCallback(aFrame->PresContext())) {
|
||||
NotifyAnimated(aFrame, aProperty);
|
||||
NotifyAnimated(aFrame, aProperty, aNewValue, aDOMCSSDecl);
|
||||
}
|
||||
if (gLayerActivityTracker &&
|
||||
gLayerActivityTracker->mCurrentScrollHandlerFrame.IsAlive()) {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
class nsIFrame;
|
||||
class nsIContent;
|
||||
class nsDisplayListBuilder;
|
||||
class nsDOMCSSDeclaration;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -47,8 +48,12 @@ public:
|
||||
/**
|
||||
* Mark aFrame as being known to have an animation of aProperty.
|
||||
* Any such marking will time out after a short period.
|
||||
* aNewValue and aDOMCSSDecl are used to determine whether the property's
|
||||
* value has changed.
|
||||
*/
|
||||
static void NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty);
|
||||
static void NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty,
|
||||
const nsAString& aNewValue,
|
||||
nsDOMCSSDeclaration* aDOMCSSDecl);
|
||||
/**
|
||||
* Notify aFrame as being known to have an animation of aProperty through an
|
||||
* inline style modification during aScrollFrame's scroll event handler.
|
||||
@@ -60,8 +65,12 @@ public:
|
||||
* has been modified.
|
||||
* This notification is incomplete --- not all modifications to inline
|
||||
* style will trigger this.
|
||||
* aNewValue and aDOMCSSDecl are used to determine whether the property's
|
||||
* value has changed.
|
||||
*/
|
||||
static void NotifyInlineStyleRuleModified(nsIFrame* aFrame, nsCSSProperty aProperty);
|
||||
static void NotifyInlineStyleRuleModified(nsIFrame* aFrame, nsCSSProperty aProperty,
|
||||
const nsAString& aNewValue,
|
||||
nsDOMCSSDeclaration* aDOMCSSDecl);
|
||||
/**
|
||||
* Return true if aFrame's aProperty style should be considered as being animated
|
||||
* for pre-rendering.
|
||||
|
||||
@@ -140,8 +140,8 @@ GetBoxRectForFrame(nsIFrame** aFrame, CSSBoxType aType)
|
||||
{
|
||||
nsRect r;
|
||||
nsIFrame* f = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(*aFrame, &r);
|
||||
if (f) {
|
||||
// For SVG, the BoxType is ignored.
|
||||
if (f && f != *aFrame) {
|
||||
// For non-outer SVG frames, the BoxType is ignored.
|
||||
*aFrame = f;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ public:
|
||||
using AccessibleCaretManager::UpdateCarets;
|
||||
using AccessibleCaretManager::HideCarets;
|
||||
using AccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent;
|
||||
using AccessibleCaretManager::sCaretsExtendedVisibility;
|
||||
using AccessibleCaretManager::sCaretsAlwaysTilt;
|
||||
using AccessibleCaretManager::sCaretsAlwaysShowWhenScrolling;
|
||||
|
||||
MockAccessibleCaretManager()
|
||||
: AccessibleCaretManager(nullptr)
|
||||
@@ -350,6 +350,11 @@ TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput)
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode)
|
||||
{
|
||||
// Simulate B2G preference.
|
||||
AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Selection));
|
||||
|
||||
@@ -422,9 +427,13 @@ TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode)
|
||||
check.Call("scrollend2");
|
||||
}
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester,
|
||||
TestScrollInSelectionModeWithExtendedVisibilityAndAlwaysTilt)
|
||||
TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionModeWithAlwaysTiltPref)
|
||||
{
|
||||
// Simulate Firefox Android preference.
|
||||
AutoRestore<bool> saveCaretsAlwaysTilt(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysTilt);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysTilt = true;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Selection));
|
||||
|
||||
@@ -441,7 +450,7 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("updatecarets"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
CaretChangedReason::Visibilitychange));
|
||||
CaretChangedReason::Scroll));
|
||||
EXPECT_CALL(check, Call("scrollstart1"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
@@ -458,7 +467,7 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("scrollend1"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
CaretChangedReason::Visibilitychange));
|
||||
CaretChangedReason::Scroll));
|
||||
EXPECT_CALL(check, Call("scrollstart2"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
@@ -471,14 +480,6 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("scrollend2"));
|
||||
}
|
||||
|
||||
// Simulate Firefox Android preferences.
|
||||
AutoRestore<bool> saveCaretsExtendedVisibility(
|
||||
MockAccessibleCaretManager::sCaretsExtendedVisibility);
|
||||
MockAccessibleCaretManager::sCaretsExtendedVisibility = true;
|
||||
AutoRestore<bool> saveCaretsAlwaysTilt(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysTilt);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysTilt = true;
|
||||
|
||||
mManager.UpdateCarets();
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
|
||||
@@ -486,12 +487,12 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
|
||||
mManager.OnScrollStart();
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
|
||||
check.Call("scrollstart1");
|
||||
|
||||
mManager.OnReflow();
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
|
||||
check.Call("reflow1");
|
||||
|
||||
mManager.OnScrollEnd();
|
||||
@@ -500,12 +501,12 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
check.Call("scrollend1");
|
||||
|
||||
mManager.OnScrollStart();
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
|
||||
check.Call("scrollstart2");
|
||||
|
||||
mManager.OnReflow();
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
|
||||
EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
|
||||
EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
|
||||
check.Call("reflow2");
|
||||
|
||||
@@ -517,6 +518,11 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible)
|
||||
{
|
||||
// Simulate B2G preference.
|
||||
AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Cursor));
|
||||
|
||||
@@ -577,6 +583,11 @@ TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible)
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden)
|
||||
{
|
||||
// Simulate B2G preference.
|
||||
AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Cursor));
|
||||
|
||||
@@ -631,6 +642,11 @@ TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden)
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent)
|
||||
{
|
||||
// Simulate B2G preference.
|
||||
AutoRestore<bool> savesCaretsAlwaysShowWhenScrolling(
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling);
|
||||
MockAccessibleCaretManager::sCaretsAlwaysShowWhenScrolling = false;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Cursor));
|
||||
|
||||
@@ -700,8 +716,13 @@ TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent)
|
||||
}
|
||||
|
||||
TEST_F(AccessibleCaretManagerTester,
|
||||
TestScrollInCursorModeOnEmptyContentWithSpecialPreference)
|
||||
TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref)
|
||||
{
|
||||
// Simulate Firefox Android preference.
|
||||
AutoRestore<bool> savesCaretShownWhenLongTappingOnEmptyContent(
|
||||
MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent);
|
||||
MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent = true;
|
||||
|
||||
EXPECT_CALL(mManager, GetCaretMode())
|
||||
.WillRepeatedly(Return(CaretMode::Cursor));
|
||||
|
||||
@@ -721,7 +742,7 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("longtap updatecarets"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
CaretChangedReason::Visibilitychange));
|
||||
CaretChangedReason::Scroll));
|
||||
EXPECT_CALL(check, Call("longtap scrollstart1"));
|
||||
|
||||
EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
|
||||
@@ -731,7 +752,7 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("longtap scrollend1"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
CaretChangedReason::Visibilitychange));
|
||||
CaretChangedReason::Scroll));
|
||||
EXPECT_CALL(check, Call("longtap scrollstart2"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
@@ -739,7 +760,7 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("longtap scrollend2"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
CaretChangedReason::Visibilitychange));
|
||||
CaretChangedReason::Scroll));
|
||||
EXPECT_CALL(check, Call("longtap scrollstart3"));
|
||||
|
||||
EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
|
||||
@@ -747,10 +768,6 @@ TEST_F(AccessibleCaretManagerTester,
|
||||
EXPECT_CALL(check, Call("longtap scrollend3"));
|
||||
}
|
||||
|
||||
AutoRestore<bool> savePref(
|
||||
MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent);
|
||||
MockAccessibleCaretManager::sCaretShownWhenLongTappingOnEmptyContent = true;
|
||||
|
||||
// Simulate a single tap on an empty input.
|
||||
mManager.FirstCaret().SetAppearance(Appearance::None);
|
||||
mManager.UpdateCarets();
|
||||
|
||||
@@ -190,6 +190,11 @@ LOCAL_INCLUDES += [
|
||||
'/view',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
LOCAL_INCLUDES += [
|
||||
'/widget/android',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||
|
||||
@@ -208,6 +208,42 @@ class AccessibleCaretSelectionModeTestCase(MarionetteTestCase):
|
||||
|
||||
self.assertEqual(target_content, sel.selected_content)
|
||||
|
||||
@parameterized(_input_id, el_id=_input_id)
|
||||
@parameterized(_textarea_id, el_id=_textarea_id)
|
||||
@parameterized(_textarea_rtl_id, el_id=_textarea_rtl_id)
|
||||
@parameterized(_contenteditable_id, el_id=_contenteditable_id)
|
||||
@parameterized(_content_id, el_id=_content_id)
|
||||
def test_drag_swappable_carets(self, el_id):
|
||||
self.open_test_html(self._selection_html)
|
||||
el = self.marionette.find_element(By.ID, el_id)
|
||||
sel = SelectionManager(el)
|
||||
original_content = sel.content
|
||||
words = original_content.split()
|
||||
self.assertTrue(len(words) >= 1, 'Expect at least one word in the content.')
|
||||
|
||||
target_content1 = words[0]
|
||||
target_content2 = original_content[len(words[0]):]
|
||||
|
||||
# Get the location of the carets at the end of the content for later
|
||||
# use.
|
||||
el.tap()
|
||||
sel.select_all()
|
||||
end_caret_x, end_caret_y = sel.second_caret_location()
|
||||
|
||||
self.long_press_on_word(el, 0)
|
||||
|
||||
# Drag the first caret to the end and back to where it was
|
||||
# immediately. The selection range should not be collapsed.
|
||||
caret1_x, caret1_y = sel.first_caret_location()
|
||||
self.actions.flick(el, caret1_x, caret1_y, end_caret_x, end_caret_y)\
|
||||
.flick(el, end_caret_x, end_caret_y, caret1_x, caret1_y).perform()
|
||||
self.assertEqual(target_content1, sel.selected_content)
|
||||
|
||||
# Drag the first caret to the end.
|
||||
caret1_x, caret1_y = sel.first_caret_location()
|
||||
self.actions.flick(el, caret1_x, caret1_y, end_caret_x, end_caret_y).perform()
|
||||
self.assertEqual(target_content2, sel.selected_content)
|
||||
|
||||
@parameterized(_input_id, el_id=_input_id)
|
||||
@parameterized(_textarea_id, el_id=_textarea_id)
|
||||
@parameterized(_textarea_rtl_id, el_id=_textarea_rtl_id)
|
||||
@@ -414,6 +450,29 @@ class AccessibleCaretSelectionModeTestCase(MarionetteTestCase):
|
||||
self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
|
||||
'4\nuser can select this 5\nuser')
|
||||
|
||||
def test_drag_swappable_caret_over_non_selectable_field(self):
|
||||
self.open_test_html(self._multiplerange_html)
|
||||
body = self.marionette.find_element(By.ID, 'bd')
|
||||
sel3 = self.marionette.find_element(By.ID, 'sel3')
|
||||
sel4 = self.marionette.find_element(By.ID, 'sel4')
|
||||
sel = SelectionManager(body)
|
||||
|
||||
self.long_press_on_word(sel4, 3)
|
||||
(end_caret1_x, end_caret1_y), (end_caret2_x, end_caret2_y) = sel.carets_location()
|
||||
|
||||
self.long_press_on_word(sel3, 3)
|
||||
(caret1_x, caret1_y), (caret2_x, caret2_y) = sel.carets_location()
|
||||
|
||||
# Drag the first caret down, which will across the second caret.
|
||||
self.actions.flick(body, caret1_x, caret1_y, end_caret1_x, end_caret1_y).perform()
|
||||
self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
|
||||
'3\nuser can select')
|
||||
|
||||
# The old second caret becomes the first caret. Drag it down again.
|
||||
self.actions.flick(body, caret2_x, caret2_y, end_caret2_x, end_caret2_y).perform()
|
||||
self.assertEqual(self.to_unix_line_ending(sel.selected_content.strip()),
|
||||
'this')
|
||||
|
||||
def test_drag_caret_to_beginning_of_a_line(self):
|
||||
'''Bug 1094056
|
||||
Test caret visibility when caret is dragged to beginning of a line
|
||||
|
||||
@@ -336,7 +336,7 @@ TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText
|
||||
</div>
|
||||
|
||||
<div id="svgContainer">
|
||||
<svg id="svg" style="width:200px; height:200px; background:lightgray;">
|
||||
<svg id="svg" style="width:200px; height:200px; background:lightgray; border:7px solid blue; padding:4px">
|
||||
<circle id="circle" cx="50" cy="50" r="20" fill="red" style="margin:20px; padding:10px; border:15px solid black"></circle>
|
||||
<g transform="scale(2)">
|
||||
<foreignObject x="50" y="20">
|
||||
@@ -660,19 +660,26 @@ function runTest() {
|
||||
var svgContainerX = svgContainer.getBoundingClientRect().left;
|
||||
var svgContainerY = svgContainer.getBoundingClientRect().top;
|
||||
checkQuadIsRect("circle", {},
|
||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
||||
svgContainerX + 41, svgContainerY + 41, 40, 40);
|
||||
// Box types are ignored for SVG elements.
|
||||
checkQuadIsRect("circle", {box:"content"},
|
||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
||||
svgContainerX + 41, svgContainerY + 41, 40, 40);
|
||||
checkQuadIsRect("circle", {box:"padding"},
|
||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
||||
svgContainerX + 41, svgContainerY + 41, 40, 40);
|
||||
checkQuadIsRect("circle", {box:"margin"},
|
||||
svgContainerX + 30, svgContainerY + 30, 40, 40);
|
||||
svgContainerX + 41, svgContainerY + 41, 40, 40);
|
||||
checkQuadIsRect("d", {toStr:"circle"},
|
||||
dX - (svgContainerX + 30), dY - (svgContainerY + 30), dW, dH);
|
||||
dX - (svgContainerX + 41), dY - (svgContainerY + 41), dW, dH);
|
||||
// Test foreignObject inside an SVG transform.
|
||||
checkQuadIsRect("foreign", {},
|
||||
svgContainerX + 100, svgContainerY + 40, 200, 120);
|
||||
svgContainerX + 111, svgContainerY + 51, 200, 120);
|
||||
// Outer <svg> elements support padding and content boxes
|
||||
checkQuadIsRect("svg", {box:"border"},
|
||||
svgContainerX, svgContainerY, 222, 222);
|
||||
checkQuadIsRect("svg", {box:"padding"},
|
||||
svgContainerX + 7, svgContainerY + 7, 208, 208);
|
||||
checkQuadIsRect("svg", {box:"content"},
|
||||
svgContainerX + 11, svgContainerY + 11, 200, 200);
|
||||
|
||||
// XXX Test SVG text (probably broken; unclear what the best way is to handle it)
|
||||
|
||||
|
||||
@@ -1509,6 +1509,10 @@ void
|
||||
nsPrintEngine::FirePrintingErrorEvent(nsresult aPrintError)
|
||||
{
|
||||
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
|
||||
if (NS_WARN_IF(!cv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = cv->GetDocument();
|
||||
RefPtr<CustomEvent> event =
|
||||
NS_NewDOMCustomEvent(doc, nullptr, nullptr);
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
== at-rule-error-handling-media-1.html at-rule-error-handling-ref.html
|
||||
== invalid-font-face-descriptor-1.html invalid-font-face-descriptor-1-ref.html
|
||||
== two-dash-identifiers.html two-dash-identifiers-ref.html
|
||||
== supports-moz-bool-pref.html supports-moz-bool-pref-ref.html
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<html>
|
||||
<body>
|
||||
<p>This text should not have background color.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<html>
|
||||
<style>
|
||||
/* This is not a user agent style sheet, so the style will be ignored.
|
||||
"testing.supports.moz-bool-pref" is set to true in
|
||||
layout/tools/reftest/reftest-preferences.js. */
|
||||
@supports -moz-bool-pref("testing.supports.moz-bool-pref") {
|
||||
p {
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<p>This text should not have background color.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
</head>
|
||||
<body>
|
||||
<svg height="100%" preserveAspectRatio="none meet" viewBox="0 0 1070 462" width="100%">
|
||||
<g height="462" width="1070">
|
||||
<g mask="url(#mask-1)" transform="translate(0,10)">
|
||||
<g>
|
||||
<path class="data-line" d="M30,260L61,266.5L900,266.5" fill="none" stroke="#cc0000" stroke-width="20" visibility="visible">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<mask id="mask-1">
|
||||
<rect fill="#000" height="100%" width="100%" x="0" y="0">
|
||||
</rect>
|
||||
<rect fill="#fff" height="462" width="400" x="40" y="-10">
|
||||
</rect>
|
||||
<rect fill="#fff" height="460" width="100" x="800" y="-10">
|
||||
</rect>
|
||||
<rect fill="#000" height="447" offset="164" width="60" x="164" y="0">
|
||||
</rect>
|
||||
<rect fill="#000" height="447" offset="376" width="56" x="376" y="0">
|
||||
</rect>
|
||||
</mask>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
</head>
|
||||
<body>
|
||||
<svg height="100%" preserveAspectRatio="none meet" viewBox="0 0 1070 462" width="100%">
|
||||
<g height="462" width="1070">
|
||||
<g clip-path="url(#clip-1)" mask="url(#mask-1)" transform="translate(0,10)">
|
||||
<g>
|
||||
<path class="data-line" d="M30,260L61,266.5L900,266.5" fill="none" stroke="#cc0000" stroke-width="20" visibility="visible">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<clipPath id="clip-1">
|
||||
<rect height="462" width="400" x="40" y="-10">
|
||||
</rect>
|
||||
<rect height="460" width="100" x="800" y="-10">
|
||||
</rect>
|
||||
</clipPath>
|
||||
<g>
|
||||
<mask id="mask-1">
|
||||
<rect fill="#fff" height="100%" width="100%" x="0" y="0">
|
||||
</rect>
|
||||
<rect fill="#000" height="447" offset="164" width="60" x="164" y="0">
|
||||
</rect>
|
||||
<rect fill="#000" height="447" offset="376" width="56" x="376" y="0">
|
||||
</rect>
|
||||
</mask>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,7 @@ random-if(Android||B2G) fails-if(winWidget) skip-if((B2G&&browserIsRemote)||Mule
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == textbox-overflow-1.xul textbox-overflow-1-ref.xul # for bug 749658 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# accesskeys are not normally displayed on Mac, so skip this test
|
||||
skip-if(cocoaWidget) skip-if((B2G&&browserIsRemote)||Mulet) == accesskey.xul accesskey-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fails-if(cocoaWidget) skip-if((B2G&&browserIsRemote)||Mulet) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fails-if(cocoaWidget) fails-if(browserIsRemote&&d2d) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,11) skip-if((B2G&&browserIsRemote)||Mulet) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop, win8: bug 1254832
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) != tree-row-outline-1.xul tree-row-outline-1-notref.xul # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == text-small-caps-1.xul text-small-caps-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
@@ -42,8 +42,8 @@ skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-001.xul object-fit
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-002.xul object-fit-fill-svg-002-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-003.xul object-fit-fill-svg-003-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-004.xul object-fit-fill-svg-004-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) fails == object-fit-fill-svg-005.xul object-fit-fill-svg-005-ref.html # bug 1092436
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) fails == object-fit-fill-svg-006.xul object-fit-fill-svg-006-ref.html # bug 1092436
|
||||
fails skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-005.xul object-fit-fill-svg-005-ref.html # bug 1092436
|
||||
fails skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-fill-svg-006.xul object-fit-fill-svg-006-ref.html # bug 1092436
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-none-png-001.xul object-fit-none-png-001-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-none-png-002.xul object-fit-none-png-002-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-none-svg-001.xul object-fit-none-svg-001-ref.html
|
||||
@@ -63,4 +63,10 @@ skip-if((B2G&&browserIsRemote)||Mulet) == object-fit-scale-down-svg-006.xul obje
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-position-png-001.xul object-position-png-001-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == object-position-png-002.xul object-position-png-002-ref.html
|
||||
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == inactive-fixed-bg-bug1205630.xul inactive-fixed-bg-bug1205630-ref.html
|
||||
# Tests for rendering SVG images in a XUL <treecell>:
|
||||
# XXXdholbert: These are marked as "random" right now, since they might not
|
||||
# render the images they trying to test in time for the reftest snapshot, per
|
||||
# bug 1218954. Once that bug is fixed, we should replace the "random"
|
||||
# annotation with "skip-if((B2G&&browserIsRemote)||Mulet)", like above tests.
|
||||
skip == treecell-image-svg-1a.xul treecell-image-svg-1-ref.xul # bug 1218954
|
||||
skip == treecell-image-svg-1b.xul treecell-image-svg-1-ref.xul # bug 1218954
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<tree seltype="single" flex="1">
|
||||
<treecols>
|
||||
<treecol flex="1"/>
|
||||
</treecols>
|
||||
<treechildren>
|
||||
<treeitem>
|
||||
<treerow>
|
||||
<treecell src="colors-16x8.png"/>
|
||||
</treerow>
|
||||
</treeitem>
|
||||
</treechildren>
|
||||
</tree>
|
||||
</window>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<tree seltype="single" flex="1">
|
||||
<treecols>
|
||||
<treecol flex="1"/>
|
||||
</treecols>
|
||||
<treechildren>
|
||||
<treeitem>
|
||||
<treerow>
|
||||
<treecell src="colors-16x8.svg"/>
|
||||
</treerow>
|
||||
</treeitem>
|
||||
</treechildren>
|
||||
</tree>
|
||||
</window>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<tree seltype="single" flex="1">
|
||||
<treecols>
|
||||
<treecol flex="1"/>
|
||||
</treecols>
|
||||
<treechildren>
|
||||
<treeitem>
|
||||
<treerow>
|
||||
<treecell src="colors-16x8-noSize.svg"/>
|
||||
</treerow>
|
||||
</treeitem>
|
||||
</treechildren>
|
||||
</tree>
|
||||
</window>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Bug 1245260</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
body {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
div {
|
||||
transition: text-emphasis-color 0.1s;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: red;
|
||||
transition: text-emphasis-color 0.1s;
|
||||
}
|
||||
|
||||
span {
|
||||
transition: text-emphasis-color 0.1s;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "icon-fonts";
|
||||
src: url(x);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<span><a>Shows</a></span>
|
||||
<span><a>Video</a></span>
|
||||
<span><a>Schedule</a></span>
|
||||
<span><a>Topics</a></span>
|
||||
<span><a>Games</a></span>
|
||||
<span><a>Shop</a></span>
|
||||
<span><a>This Day In History</a></span>
|
||||
<span><a>Ask History</a></span>
|
||||
<span><a>History Lists</a></span>
|
||||
<span><a>Hungry History</a></span>
|
||||
<span><a>Speeches & Audio</a></span>
|
||||
<span class="hide"><a>Sign In</a></span>
|
||||
<span><a class="hide">Sign Out</a></span>
|
||||
</div>
|
||||
<script/>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
@keyframes bug {
|
||||
from {display:none}
|
||||
to {display:inline-block}
|
||||
}
|
||||
body {
|
||||
animation-name: bug;
|
||||
animation-duration: 1s;
|
||||
}
|
||||
</style>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@import "404.css" s x
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
|
||||
#q:after {
|
||||
content: 'A';
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<mrow xmlns="http://www.w3.org/1998/Math/MathML"></mrow>
|
||||
<span id="q"><span><div></div></span></span>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -35,6 +35,7 @@ load 448161-1.html
|
||||
load 448161-2.html
|
||||
load 452150-1.xhtml
|
||||
load 456196.html
|
||||
load 460209-1.html
|
||||
load 460217-1.html
|
||||
load 460323-1.html
|
||||
load 466845-1.html
|
||||
@@ -45,6 +46,7 @@ HTTP(..) load 472237-1.html
|
||||
load 473720-1.html
|
||||
load 473892-1.html
|
||||
load 473914-1.html
|
||||
load 474377-1.xhtml
|
||||
load 478321-1.xhtml
|
||||
load 495269-1.html
|
||||
load 495269-2.html
|
||||
@@ -52,10 +54,10 @@ load 498036-1.html
|
||||
load 509155-1.html
|
||||
load 509156-1.html
|
||||
load 509569-1.html
|
||||
load 512851-1.xhtml
|
||||
load 524252-1.html
|
||||
load font-face-truncated-src.html
|
||||
load 536789-1.html
|
||||
load 565248-1.html
|
||||
load 539613-1.xhtml
|
||||
load 558943-1.xhtml
|
||||
load 559491.html
|
||||
load 565248-1.html
|
||||
@@ -132,7 +134,9 @@ load 1230408-1.html
|
||||
load 1233135-1.html
|
||||
load 1233135-2.html
|
||||
load 1238660-1.html
|
||||
load 1245260-1.html
|
||||
load 1247865-1.html
|
||||
load 1264396-1.html
|
||||
load border-image-visited-link.html
|
||||
load font-face-truncated-src.html
|
||||
load large_border_image_width.html
|
||||
|
||||
@@ -348,6 +348,9 @@ public:
|
||||
bool AgentRulesEnabled() const {
|
||||
return mParsingMode == css::eAgentSheetFeatures;
|
||||
}
|
||||
bool ChromeRulesEnabled() const {
|
||||
return mIsChrome;
|
||||
}
|
||||
bool UserRulesEnabled() const {
|
||||
return mParsingMode == css::eAgentSheetFeatures ||
|
||||
mParsingMode == css::eUserSheetFeatures;
|
||||
@@ -692,6 +695,7 @@ protected:
|
||||
bool ParseSupportsCondition(bool& aConditionMet);
|
||||
bool ParseSupportsConditionNegation(bool& aConditionMet);
|
||||
bool ParseSupportsConditionInParens(bool& aConditionMet);
|
||||
bool ParseSupportsMozBoolPrefName(bool& aConditionMet);
|
||||
bool ParseSupportsConditionInParensInsideParens(bool& aConditionMet);
|
||||
bool ParseSupportsConditionTerms(bool& aConditionMet);
|
||||
enum SupportsConditionTermOperator { eAnd, eOr };
|
||||
@@ -2134,7 +2138,10 @@ CSSParserImpl::ParseSourceSizeList(const nsAString& aBuffer,
|
||||
query->SetNegated();
|
||||
}
|
||||
|
||||
if (ParseNonNegativeVariant(value, VARIANT_LPCALC, nullptr) !=
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#source-size-value
|
||||
// Percentages are not allowed in a <source-size-value>, to avoid
|
||||
// confusion about what it would be relative to.
|
||||
if (ParseNonNegativeVariant(value, VARIANT_LCALC, nullptr) !=
|
||||
CSSParseResult::Ok) {
|
||||
hitError = true;
|
||||
break;
|
||||
@@ -4525,6 +4532,7 @@ CSSParserImpl::ParseSupportsConditionNegation(bool& aConditionMet)
|
||||
|
||||
// supports_condition_in_parens
|
||||
// : '(' S* supports_condition_in_parens_inside_parens ')' S*
|
||||
// | supports_condition_pref
|
||||
// | general_enclosed
|
||||
// ;
|
||||
bool
|
||||
@@ -4540,6 +4548,12 @@ CSSParserImpl::ParseSupportsConditionInParens(bool& aConditionMet)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AgentRulesEnabled() &&
|
||||
mToken.mType == eCSSToken_Function &&
|
||||
mToken.mIdent.LowerCaseEqualsLiteral("-moz-bool-pref")) {
|
||||
return ParseSupportsMozBoolPrefName(aConditionMet);
|
||||
}
|
||||
|
||||
if (mToken.mType == eCSSToken_Function ||
|
||||
mToken.mType == eCSSToken_Bad_URL) {
|
||||
if (!SkipUntil(')')) {
|
||||
@@ -4574,6 +4588,32 @@ CSSParserImpl::ParseSupportsConditionInParens(bool& aConditionMet)
|
||||
return true;
|
||||
}
|
||||
|
||||
// supports_condition_pref
|
||||
// : '-moz-bool-pref(' bool_pref_name ')'
|
||||
// ;
|
||||
bool
|
||||
CSSParserImpl::ParseSupportsMozBoolPrefName(bool& aConditionMet)
|
||||
{
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mToken.mType != eCSSToken_String) {
|
||||
SkipUntil(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
aConditionMet = Preferences::GetBool(
|
||||
NS_ConvertUTF16toUTF8(mToken.mIdent).get());
|
||||
|
||||
if (!ExpectSymbol(')', true)) {
|
||||
SkipUntil(')');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// supports_condition_in_parens_inside_parens
|
||||
// : core_declaration
|
||||
// | supports_condition_negation
|
||||
@@ -5879,7 +5919,10 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask,
|
||||
((pseudoElementType < CSSPseudoElementType::Count &&
|
||||
nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) ||
|
||||
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
|
||||
nsCSSPseudoClasses::PseudoClassIsUASheetOnly(pseudoClassType)))) {
|
||||
nsCSSPseudoClasses::PseudoClassIsUASheetOnly(pseudoClassType)) ||
|
||||
(!ChromeRulesEnabled() &&
|
||||
(pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
|
||||
nsCSSPseudoClasses::PseudoClassIsUASheetAndChromeOnly(pseudoClassType))))) {
|
||||
// This pseudo-element or pseudo-class is not exposed to content.
|
||||
REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
|
||||
UngetToken();
|
||||
@@ -15860,11 +15903,11 @@ bool CSSParserImpl::ParseClipPath()
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCSSValueList* cur = value.SetListValue();
|
||||
|
||||
nsCSSValue referenceBox;
|
||||
bool hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
|
||||
|
||||
const bool boxCameFirst = hasBox;
|
||||
|
||||
nsCSSValue basicShape;
|
||||
bool basicShapeConsumedTokens = false;
|
||||
bool hasShape = ParseBasicShape(basicShape, &basicShapeConsumedTokens);
|
||||
@@ -15875,26 +15918,25 @@ bool CSSParserImpl::ParseClipPath()
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to preserve the specified order of arguments for inline style.
|
||||
if (hasBox) {
|
||||
cur->mValue = referenceBox;
|
||||
}
|
||||
|
||||
if (hasShape) {
|
||||
if (hasBox) {
|
||||
cur->mNext = new nsCSSValueList;
|
||||
cur = cur->mNext;
|
||||
}
|
||||
cur->mValue = basicShape;
|
||||
}
|
||||
|
||||
// Check if the second argument is a reference box if the first wasn't.
|
||||
if (!hasBox &&
|
||||
ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable)) {
|
||||
cur->mNext = new nsCSSValueList;
|
||||
cur = cur->mNext;
|
||||
cur->mValue = referenceBox;
|
||||
if (!hasBox) {
|
||||
hasBox = ParseEnum(referenceBox, nsCSSProps::kClipShapeSizingKTable);
|
||||
}
|
||||
|
||||
RefPtr<nsCSSValue::Array> fullValue =
|
||||
nsCSSValue::Array::Create((hasBox && hasShape) ? 2 : 1);
|
||||
|
||||
if (hasBox && hasShape) {
|
||||
fullValue->Item(boxCameFirst ? 0 : 1) = referenceBox;
|
||||
fullValue->Item(boxCameFirst ? 1 : 0) = basicShape;
|
||||
} else if (hasBox) {
|
||||
fullValue->Item(0) = referenceBox;
|
||||
} else {
|
||||
MOZ_ASSERT(hasShape, "should've bailed if we got neither box nor shape");
|
||||
fullValue->Item(0) = basicShape;
|
||||
}
|
||||
|
||||
value.SetArrayValue(fullValue, eCSSUnit_Array);
|
||||
}
|
||||
|
||||
AppendValue(eCSSProperty_clip_path, value);
|
||||
|
||||
@@ -522,7 +522,7 @@ CSS_PROP_BACKGROUND(
|
||||
CSS_PROPERTY_VALUE_LIST_USES_COMMAS,
|
||||
"",
|
||||
VARIANT_KEYWORD, // used by list parsing
|
||||
kImageLayerOriginKTable,
|
||||
kBackgroundClipKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_BACKGROUND(
|
||||
@@ -1644,7 +1644,7 @@ CSS_PROP_DISPLAY(
|
||||
VARIANT_HK,
|
||||
kDisplayKTable,
|
||||
offsetof(nsStyleDisplay, mDisplay),
|
||||
eStyleAnimType_EnumU8)
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_SVGRESET(
|
||||
dominant-baseline,
|
||||
dominant_baseline,
|
||||
|
||||
@@ -123,7 +123,8 @@ CSS_PSEUDO_CLASS(mozWindowInactive, ":-moz-window-inactive", 0, "")
|
||||
CSS_PSEUDO_CLASS(mozTableBorderNonzero, ":-moz-table-border-nonzero", 0, "")
|
||||
|
||||
// Matches HTML frame/iframe elements which are mozbrowser.
|
||||
CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz-browser-frame", 0, "")
|
||||
CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz-browser-frame",
|
||||
CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "")
|
||||
|
||||
// Matches whatever the contextual reference elements are for the
|
||||
// matching operation.
|
||||
|
||||
@@ -371,7 +371,7 @@ protected:
|
||||
|
||||
// This reference is not reference-counted. The rule object tells us
|
||||
// when it's about to go away.
|
||||
nsCSSKeyframeRule *mRule;
|
||||
nsCSSKeyframeRule* MOZ_NON_OWNING_REF mRule;
|
||||
};
|
||||
|
||||
class nsCSSKeyframeRule final : public mozilla::css::Rule,
|
||||
@@ -501,7 +501,7 @@ protected:
|
||||
|
||||
// This reference is not reference-counted. The rule object tells us
|
||||
// when it's about to go away.
|
||||
nsCSSPageRule *mRule;
|
||||
nsCSSPageRule* MOZ_NON_OWNING_REF mRule;
|
||||
};
|
||||
|
||||
class nsCSSPageRule final : public mozilla::css::Rule,
|
||||
|
||||
+85
-43
@@ -2170,9 +2170,13 @@ nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
size_t
|
||||
nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2205,9 +2209,12 @@ nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
|
||||
size_t
|
||||
nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
n += aMallocSizeOf(this);
|
||||
n += mHead->SizeOfIncludingThis(aMallocSizeOf);
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mHead->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2280,11 +2287,15 @@ void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
|
||||
size_t
|
||||
nsCSSRect_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mTop .SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRight .SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mLeft .SizeOfExcludingThis(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mTop .SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRight .SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mLeft .SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2325,9 +2336,13 @@ nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
size_t
|
||||
nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2352,10 +2367,14 @@ nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty,
|
||||
size_t
|
||||
nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2446,10 +2465,14 @@ nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) con
|
||||
size_t
|
||||
nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2536,16 +2559,18 @@ css::URLValue::GetURI() const
|
||||
size_t
|
||||
css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
|
||||
n += mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it is
|
||||
// worthwhile:
|
||||
// - mURI
|
||||
// - mReferrer
|
||||
// - mOriginPrincipal
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
||||
|
||||
// Measurement of the following members may be added later if DMD finds it
|
||||
// is worthwhile:
|
||||
// - mURI
|
||||
// - mReferrer
|
||||
// - mOriginPrincipal
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2638,14 +2663,18 @@ nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
|
||||
size_t
|
||||
nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mBgPos.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mAngle.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mStops.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mBgPos.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mAngle.SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mStops.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@@ -2668,8 +2697,12 @@ nsCSSValueTokenStream::~nsCSSValueTokenStream()
|
||||
size_t
|
||||
nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2756,7 +2789,11 @@ size_t
|
||||
nsCSSValueFloatColor::SizeOfIncludingThis(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -2804,7 +2841,12 @@ nsCSSCornerSizes::corners[4] = {
|
||||
size_t
|
||||
mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = mNamedAreas.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mTemplates.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
// Only measure it if it's unshared, to avoid double-counting.
|
||||
size_t n = 0;
|
||||
if (mRefCnt <= 1) {
|
||||
n += aMallocSizeOf(this);
|
||||
n += mNamedAreas.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
n += mTemplates.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement,
|
||||
}
|
||||
|
||||
// XXX the !aElement->IsHTMLElement(nsGkAtoms::area)
|
||||
// check is needed due to bug 135040 (to avoid using
|
||||
// check is needed due to bug 135040 (to avoid using
|
||||
// mPrimaryFrame). Remove it once that's fixed.
|
||||
if (!aPseudo && aStyleType == eAll && inDocWithShell &&
|
||||
!aElement->IsHTMLElement(nsGkAtoms::area)) {
|
||||
@@ -1117,7 +1117,7 @@ nsComputedDOMStyle::DoGetContent()
|
||||
switch (data.mType) {
|
||||
case eStyleContentType_String:
|
||||
{
|
||||
nsString str;
|
||||
nsAutoString str;
|
||||
nsStyleUtil::AppendEscapedCSSString(
|
||||
nsDependentString(data.mContent.mString), str);
|
||||
val->SetString(str);
|
||||
@@ -1491,7 +1491,7 @@ nsComputedDOMStyle::DoGetQuotes()
|
||||
RefPtr<nsROCSSPrimitiveValue> openVal = new nsROCSSPrimitiveValue;
|
||||
RefPtr<nsROCSSPrimitiveValue> closeVal = new nsROCSSPrimitiveValue;
|
||||
|
||||
nsString s;
|
||||
nsAutoString s;
|
||||
nsStyleUtil::AppendEscapedCSSString(quotePair.first, s);
|
||||
openVal->SetString(s);
|
||||
s.Truncate();
|
||||
@@ -1628,7 +1628,7 @@ nsComputedDOMStyle::DoGetFontLanguageOverride()
|
||||
if (font->mFont.languageOverride.IsEmpty()) {
|
||||
val->SetIdent(eCSSKeyword_normal);
|
||||
} else {
|
||||
nsString str;
|
||||
nsAutoString str;
|
||||
nsStyleUtil::AppendEscapedCSSString(font->mFont.languageOverride, str);
|
||||
val->SetString(str);
|
||||
}
|
||||
@@ -3430,7 +3430,7 @@ nsComputedDOMStyle::DoGetListStyleType()
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
CounterStyle* style = StyleList()->GetCounterStyle();
|
||||
AnonymousCounterStyle* anonymous = style->AsAnonymous();
|
||||
nsString tmp;
|
||||
nsAutoString tmp;
|
||||
if (!anonymous) {
|
||||
// want SetIdent
|
||||
nsString type;
|
||||
@@ -3722,7 +3722,7 @@ nsComputedDOMStyle::DoGetTextEmphasisStyle()
|
||||
}
|
||||
if (style == NS_STYLE_TEXT_EMPHASIS_STYLE_STRING) {
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
nsString tmp;
|
||||
nsAutoString tmp;
|
||||
nsStyleUtil::AppendEscapedCSSString(
|
||||
StyleText()->mTextEmphasisStyleString, tmp);
|
||||
val->SetString(tmp);
|
||||
@@ -3776,7 +3776,7 @@ nsComputedDOMStyle::DoGetTextOverflow()
|
||||
RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue;
|
||||
const nsStyleTextOverflowSide *side = style->mTextOverflow.GetFirstValue();
|
||||
if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
|
||||
nsString str;
|
||||
nsAutoString str;
|
||||
nsStyleUtil::AppendEscapedCSSString(side->mString, str);
|
||||
first->SetString(str);
|
||||
} else {
|
||||
@@ -3790,7 +3790,7 @@ nsComputedDOMStyle::DoGetTextOverflow()
|
||||
}
|
||||
RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue;
|
||||
if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
|
||||
nsString str;
|
||||
nsAutoString str;
|
||||
nsStyleUtil::AppendEscapedCSSString(side->mString, str);
|
||||
second->SetString(str);
|
||||
} else {
|
||||
|
||||
@@ -186,7 +186,7 @@ nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
|
||||
aPropID == eCSSProperty_background_position) {
|
||||
nsIFrame* frame = mElement->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID);
|
||||
ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID, aValue, this);
|
||||
}
|
||||
}
|
||||
return nsDOMCSSDeclaration::SetPropertyValue(aPropID, aValue);
|
||||
|
||||
@@ -85,10 +85,15 @@ nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
|
||||
case eCSSProperty_left:
|
||||
case eCSSProperty_bottom:
|
||||
case eCSSProperty_right:
|
||||
case eCSSProperty_margin:
|
||||
case eCSSProperty_margin_top:
|
||||
case eCSSProperty_margin_left:
|
||||
case eCSSProperty_margin_bottom:
|
||||
case eCSSProperty_margin_right:
|
||||
case eCSSProperty_margin_inline_start:
|
||||
case eCSSProperty_margin_inline_end:
|
||||
case eCSSProperty_margin_block_start:
|
||||
case eCSSProperty_margin_block_end:
|
||||
mozilla::layers::ScrollLinkedEffectDetector::PositioningPropertyMutated();
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -75,7 +75,7 @@ nsLayoutStylesheetCache::ScrollbarsSheet()
|
||||
if (!mScrollbarsSheet) {
|
||||
// Scrollbars don't need access to unsafe rules
|
||||
LoadSheetURL("chrome://global/skin/scrollbars.css",
|
||||
mScrollbarsSheet, eAuthorSheetFeatures);
|
||||
&mScrollbarsSheet, eAuthorSheetFeatures);
|
||||
}
|
||||
|
||||
return mScrollbarsSheet;
|
||||
@@ -87,7 +87,7 @@ nsLayoutStylesheetCache::FormsSheet()
|
||||
if (!mFormsSheet) {
|
||||
// forms.css needs access to unsafe rules
|
||||
LoadSheetURL("resource://gre-resources/forms.css",
|
||||
mFormsSheet, eAgentSheetFeatures);
|
||||
&mFormsSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mFormsSheet;
|
||||
@@ -102,7 +102,7 @@ nsLayoutStylesheetCache::NumberControlSheet()
|
||||
|
||||
if (!mNumberControlSheet) {
|
||||
LoadSheetURL("resource://gre-resources/number-control.css",
|
||||
mNumberControlSheet, eAgentSheetFeatures);
|
||||
&mNumberControlSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mNumberControlSheet;
|
||||
@@ -125,7 +125,7 @@ nsLayoutStylesheetCache::UASheet()
|
||||
{
|
||||
if (!mUASheet) {
|
||||
LoadSheetURL("resource://gre-resources/ua.css",
|
||||
mUASheet, eAgentSheetFeatures);
|
||||
&mUASheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mUASheet;
|
||||
@@ -136,7 +136,7 @@ nsLayoutStylesheetCache::HTMLSheet()
|
||||
{
|
||||
if (!mHTMLSheet) {
|
||||
LoadSheetURL("resource://gre-resources/html.css",
|
||||
mHTMLSheet, eAgentSheetFeatures);
|
||||
&mHTMLSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mHTMLSheet;
|
||||
@@ -171,7 +171,7 @@ nsLayoutStylesheetCache::MathMLSheet()
|
||||
{
|
||||
if (!mMathMLSheet) {
|
||||
LoadSheetURL("resource://gre-resources/mathml.css",
|
||||
mMathMLSheet, eAgentSheetFeatures);
|
||||
&mMathMLSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mMathMLSheet;
|
||||
@@ -188,7 +188,7 @@ nsLayoutStylesheetCache::NoScriptSheet()
|
||||
{
|
||||
if (!mNoScriptSheet) {
|
||||
LoadSheetURL("resource://gre-resources/noscript.css",
|
||||
mNoScriptSheet, eAgentSheetFeatures);
|
||||
&mNoScriptSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mNoScriptSheet;
|
||||
@@ -199,7 +199,7 @@ nsLayoutStylesheetCache::NoFramesSheet()
|
||||
{
|
||||
if (!mNoFramesSheet) {
|
||||
LoadSheetURL("resource://gre-resources/noframes.css",
|
||||
mNoFramesSheet, eAgentSheetFeatures);
|
||||
&mNoFramesSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mNoFramesSheet;
|
||||
@@ -209,7 +209,7 @@ StyleSheetHandle
|
||||
nsLayoutStylesheetCache::ChromePreferenceSheet(nsPresContext* aPresContext)
|
||||
{
|
||||
if (!mChromePreferenceSheet) {
|
||||
BuildPreferenceSheet(mChromePreferenceSheet, aPresContext);
|
||||
BuildPreferenceSheet(&mChromePreferenceSheet, aPresContext);
|
||||
}
|
||||
|
||||
return mChromePreferenceSheet;
|
||||
@@ -219,7 +219,7 @@ StyleSheetHandle
|
||||
nsLayoutStylesheetCache::ContentPreferenceSheet(nsPresContext* aPresContext)
|
||||
{
|
||||
if (!mContentPreferenceSheet) {
|
||||
BuildPreferenceSheet(mContentPreferenceSheet, aPresContext);
|
||||
BuildPreferenceSheet(&mContentPreferenceSheet, aPresContext);
|
||||
}
|
||||
|
||||
return mContentPreferenceSheet;
|
||||
@@ -230,7 +230,7 @@ nsLayoutStylesheetCache::ContentEditableSheet()
|
||||
{
|
||||
if (!mContentEditableSheet) {
|
||||
LoadSheetURL("resource://gre/res/contenteditable.css",
|
||||
mContentEditableSheet, eAgentSheetFeatures);
|
||||
&mContentEditableSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mContentEditableSheet;
|
||||
@@ -241,7 +241,7 @@ nsLayoutStylesheetCache::DesignModeSheet()
|
||||
{
|
||||
if (!mDesignModeSheet) {
|
||||
LoadSheetURL("resource://gre/res/designmode.css",
|
||||
mDesignModeSheet, eAgentSheetFeatures);
|
||||
&mDesignModeSheet, eAgentSheetFeatures);
|
||||
}
|
||||
|
||||
return mDesignModeSheet;
|
||||
@@ -323,15 +323,15 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache(StyleBackendType aType)
|
||||
// And make sure that we load our UA sheets. No need to do this
|
||||
// per-profile, since they're profile-invariant.
|
||||
LoadSheetURL("resource://gre-resources/counterstyles.css",
|
||||
mCounterStylesSheet, eAgentSheetFeatures);
|
||||
&mCounterStylesSheet, eAgentSheetFeatures);
|
||||
LoadSheetURL("chrome://global/content/minimal-xul.css",
|
||||
mMinimalXULSheet, eAgentSheetFeatures);
|
||||
&mMinimalXULSheet, eAgentSheetFeatures);
|
||||
LoadSheetURL("resource://gre-resources/quirk.css",
|
||||
mQuirkSheet, eAgentSheetFeatures);
|
||||
&mQuirkSheet, eAgentSheetFeatures);
|
||||
LoadSheetURL("resource://gre/res/svg.css",
|
||||
mSVGSheet, eAgentSheetFeatures);
|
||||
&mSVGSheet, eAgentSheetFeatures);
|
||||
LoadSheetURL("chrome://global/content/xul.css",
|
||||
mXULSheet, eAgentSheetFeatures);
|
||||
&mXULSheet, eAgentSheetFeatures);
|
||||
|
||||
// The remaining sheets are created on-demand do to their use being rarer
|
||||
// (which helps save memory for Firefox OS apps) or because they need to
|
||||
@@ -411,13 +411,13 @@ nsLayoutStylesheetCache::InitFromProfile()
|
||||
contentFile->Append(NS_LITERAL_STRING("userContent.css"));
|
||||
chromeFile->Append(NS_LITERAL_STRING("userChrome.css"));
|
||||
|
||||
LoadSheetFile(contentFile, mUserContentSheet, eUserSheetFeatures);
|
||||
LoadSheetFile(chromeFile, mUserChromeSheet, eUserSheetFeatures);
|
||||
LoadSheetFile(contentFile, &mUserContentSheet, eUserSheetFeatures);
|
||||
LoadSheetFile(chromeFile, &mUserChromeSheet, eUserSheetFeatures);
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::LoadSheetURL(const char* aURL,
|
||||
StyleSheetHandle::RefPtr& aSheet,
|
||||
StyleSheetHandle::RefPtr* aSheet,
|
||||
SheetParsingMode aParsingMode)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
@@ -430,7 +430,7 @@ nsLayoutStylesheetCache::LoadSheetURL(const char* aURL,
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile,
|
||||
StyleSheetHandle::RefPtr& aSheet,
|
||||
StyleSheetHandle::RefPtr* aSheet,
|
||||
SheetParsingMode aParsingMode)
|
||||
{
|
||||
bool exists = false;
|
||||
@@ -736,7 +736,7 @@ ErrorLoadingBuiltinSheet(nsIURI* aURI, const char* aMsg)
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
|
||||
StyleSheetHandle::RefPtr& aSheet,
|
||||
StyleSheetHandle::RefPtr* aSheet,
|
||||
SheetParsingMode aParsingMode)
|
||||
{
|
||||
if (!aURI) {
|
||||
@@ -759,7 +759,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
nsZipArchive::sFileCorruptedReason = nullptr;
|
||||
#endif
|
||||
nsresult rv = loader->LoadSheetSync(aURI, aParsingMode, true, &aSheet);
|
||||
nsresult rv = loader->LoadSheetSync(aURI, aParsingMode, true, aSheet);
|
||||
if (NS_FAILED(rv)) {
|
||||
ErrorLoadingBuiltinSheet(aURI,
|
||||
nsPrintfCString("LoadSheetSync failed with error %x", rv).get());
|
||||
@@ -773,18 +773,21 @@ nsLayoutStylesheetCache::InvalidateSheet(StyleSheetHandle::RefPtr* aGeckoSheet,
|
||||
MOZ_ASSERT(gCSSLoader_Gecko || gCSSLoader_Servo,
|
||||
"pref changed before we loaded a sheet?");
|
||||
|
||||
const bool gotGeckoSheet = aGeckoSheet && *aGeckoSheet;
|
||||
const bool gotServoSheet = aServoSheet && *aServoSheet;
|
||||
|
||||
// Make sure sheets have the expected types
|
||||
MOZ_ASSERT(!aGeckoSheet || (*aGeckoSheet)->IsGecko());
|
||||
MOZ_ASSERT(!aServoSheet || (*aServoSheet)->IsServo());
|
||||
MOZ_ASSERT(!gotGeckoSheet || (*aGeckoSheet)->IsGecko());
|
||||
MOZ_ASSERT(!gotServoSheet || (*aServoSheet)->IsServo());
|
||||
// Make sure the URIs match
|
||||
MOZ_ASSERT(!aGeckoSheet || !aServoSheet ||
|
||||
MOZ_ASSERT(!gotServoSheet || !gotGeckoSheet ||
|
||||
(*aGeckoSheet)->GetSheetURI() == (*aServoSheet)->GetSheetURI(),
|
||||
"Sheets passed should have the same URI");
|
||||
|
||||
nsIURI* uri;
|
||||
if (aGeckoSheet && *aGeckoSheet) {
|
||||
if (gotGeckoSheet) {
|
||||
uri = (*aGeckoSheet)->GetSheetURI();
|
||||
} else if (aServoSheet && *aServoSheet) {
|
||||
} else if (gotServoSheet) {
|
||||
uri = (*aServoSheet)->GetSheetURI();
|
||||
} else {
|
||||
return;
|
||||
@@ -796,10 +799,10 @@ nsLayoutStylesheetCache::InvalidateSheet(StyleSheetHandle::RefPtr* aGeckoSheet,
|
||||
if (gCSSLoader_Servo) {
|
||||
gCSSLoader_Servo->ObsoleteSheet(uri);
|
||||
}
|
||||
if (aGeckoSheet) {
|
||||
if (gotGeckoSheet) {
|
||||
*aGeckoSheet = nullptr;
|
||||
}
|
||||
if (aServoSheet) {
|
||||
if (gotServoSheet) {
|
||||
*aServoSheet = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -839,24 +842,26 @@ nsLayoutStylesheetCache::InvalidatePreferenceSheets()
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::BuildPreferenceSheet(StyleSheetHandle::RefPtr& aSheet,
|
||||
nsLayoutStylesheetCache::BuildPreferenceSheet(StyleSheetHandle::RefPtr* aSheet,
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
if (mBackendType == StyleBackendType::Gecko) {
|
||||
aSheet = new CSSStyleSheet(CORS_NONE, mozilla::net::RP_Default);
|
||||
*aSheet = new CSSStyleSheet(CORS_NONE, mozilla::net::RP_Default);
|
||||
} else {
|
||||
aSheet = new ServoStyleSheet(CORS_NONE, mozilla::net::RP_Default,
|
||||
dom::SRIMetadata());
|
||||
*aSheet = new ServoStyleSheet(CORS_NONE, mozilla::net::RP_Default,
|
||||
dom::SRIMetadata());
|
||||
}
|
||||
|
||||
aSheet->SetParsingMode(eAgentSheetFeatures);
|
||||
StyleSheetHandle sheet = *aSheet;
|
||||
|
||||
sheet->SetParsingMode(eAgentSheetFeatures);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
|
||||
MOZ_ASSERT(uri, "URI creation shouldn't fail");
|
||||
|
||||
aSheet->SetURIs(uri, uri, uri);
|
||||
aSheet->AsStyleSheet()->SetComplete();
|
||||
sheet->SetURIs(uri, uri, uri);
|
||||
sheet->AsStyleSheet()->SetComplete();
|
||||
|
||||
static const uint32_t kPreallocSize = 1024;
|
||||
|
||||
@@ -943,11 +948,11 @@ nsLayoutStylesheetCache::BuildPreferenceSheet(StyleSheetHandle::RefPtr& aSheet,
|
||||
"kPreallocSize should be big enough to build preference style "
|
||||
"sheet without reallocation");
|
||||
|
||||
if (aSheet->IsGecko()) {
|
||||
aSheet->AsGecko()->ReparseSheet(sheetText);
|
||||
if (sheet->IsGecko()) {
|
||||
sheet->AsGecko()->ReparseSheet(sheetText);
|
||||
} else {
|
||||
aSheet->AsServo()->ParseSheet(sheetText, uri, uri, nullptr, 0,
|
||||
SheetParsingMode::eAuthorSheetFeatures);
|
||||
sheet->AsServo()->ParseSheet(sheetText, uri, uri, nullptr, 0,
|
||||
SheetParsingMode::eAuthorSheetFeatures);
|
||||
}
|
||||
|
||||
#undef NS_GET_R_G_B
|
||||
|
||||
@@ -76,17 +76,17 @@ private:
|
||||
void InitFromProfile();
|
||||
void InitMemoryReporter();
|
||||
void LoadSheetURL(const char* aURL,
|
||||
mozilla::StyleSheetHandle::RefPtr& aSheet,
|
||||
mozilla::StyleSheetHandle::RefPtr* aSheet,
|
||||
mozilla::css::SheetParsingMode aParsingMode);
|
||||
void LoadSheetFile(nsIFile* aFile,
|
||||
mozilla::StyleSheetHandle::RefPtr& aSheet,
|
||||
mozilla::StyleSheetHandle::RefPtr* aSheet,
|
||||
mozilla::css::SheetParsingMode aParsingMode);
|
||||
void LoadSheet(nsIURI* aURI, mozilla::StyleSheetHandle::RefPtr& aSheet,
|
||||
void LoadSheet(nsIURI* aURI, mozilla::StyleSheetHandle::RefPtr* aSheet,
|
||||
mozilla::css::SheetParsingMode aParsingMode);
|
||||
static void InvalidateSheet(mozilla::StyleSheetHandle::RefPtr* aGeckoSheet,
|
||||
mozilla::StyleSheetHandle::RefPtr* aServoSheet);
|
||||
static void DependentPrefChanged(const char* aPref, void* aData);
|
||||
void BuildPreferenceSheet(mozilla::StyleSheetHandle::RefPtr& aSheet,
|
||||
void BuildPreferenceSheet(mozilla::StyleSheetHandle::RefPtr* aSheet,
|
||||
nsPresContext* aPresContext);
|
||||
|
||||
static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache_Gecko;
|
||||
|
||||
@@ -328,6 +328,9 @@ GetDisplayMode(nsPresContext* aPresContext, const nsMediaFeature*,
|
||||
baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
|
||||
int32_t displayMode;
|
||||
nsSizeMode mode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
|
||||
// Background tabs are always in 'browser' mode for now.
|
||||
// If new modes are supported, please ensure not cause the regression in
|
||||
// Bug 1259641.
|
||||
switch (mode) {
|
||||
case nsSizeMode_Fullscreen:
|
||||
displayMode = NS_STYLE_DISPLAY_MODE_FULLSCREEN;
|
||||
|
||||
+17
-21
@@ -9407,20 +9407,26 @@ nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions)
|
||||
{
|
||||
MOZ_ASSERT(aValue->GetUnit() != eCSSUnit_ListDep ||
|
||||
aValue->GetUnit() != eCSSUnit_List,
|
||||
MOZ_ASSERT(aValue->GetUnit() == eCSSUnit_Array,
|
||||
"expected a basic shape or reference box");
|
||||
|
||||
const nsCSSValueList* cur = aValue->GetListValue();
|
||||
const nsCSSValue::Array* array = aValue->GetArrayValue();
|
||||
MOZ_ASSERT(array->Count() == 1 || array->Count() == 2,
|
||||
"Expect one or both of a shape function and geometry-box");
|
||||
|
||||
uint8_t sizingBox = NS_STYLE_CLIP_SHAPE_SIZING_NOBOX;
|
||||
nsStyleBasicShape* basicShape = nullptr;
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
if (!cur) {
|
||||
break;
|
||||
}
|
||||
if (cur->mValue.GetUnit() == eCSSUnit_Function) {
|
||||
nsCSSValue::Array* shapeFunction = cur->mValue.GetArrayValue();
|
||||
RefPtr<nsStyleBasicShape> basicShape;
|
||||
for (size_t i = 0; i < array->Count(); ++i) {
|
||||
if (array->Item(i).GetUnit() == eCSSUnit_Enumerated) {
|
||||
int32_t type = array->Item(i).GetIntValue();
|
||||
if (type > NS_STYLE_CLIP_SHAPE_SIZING_VIEW ||
|
||||
type < NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
|
||||
NS_NOTREACHED("unexpected reference box");
|
||||
return;
|
||||
}
|
||||
sizingBox = (uint8_t)type;
|
||||
} else if (array->Item(i).GetUnit() == eCSSUnit_Function) {
|
||||
nsCSSValue::Array* shapeFunction = array->Item(i).GetArrayValue();
|
||||
nsCSSKeyword functionName =
|
||||
(nsCSSKeyword)shapeFunction->Item(0).GetIntValue();
|
||||
if (functionName == eCSSKeyword_polygon) {
|
||||
@@ -9557,19 +9563,10 @@ nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
|
||||
NS_NOTREACHED("unexpected basic shape function");
|
||||
return;
|
||||
}
|
||||
} else if (cur->mValue.GetUnit() == eCSSUnit_Enumerated) {
|
||||
int32_t type = cur->mValue.GetIntValue();
|
||||
if (type > NS_STYLE_CLIP_SHAPE_SIZING_VIEW ||
|
||||
type < NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
|
||||
NS_NOTREACHED("unexpected reference box");
|
||||
return;
|
||||
}
|
||||
sizingBox = (uint8_t)type;
|
||||
} else {
|
||||
NS_NOTREACHED("unexpected value");
|
||||
return;
|
||||
}
|
||||
cur = cur->mNext;
|
||||
}
|
||||
|
||||
if (basicShape) {
|
||||
@@ -9704,8 +9701,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eCSSUnit_List:
|
||||
case eCSSUnit_ListDep: {
|
||||
case eCSSUnit_Array: {
|
||||
svgReset->mClipPath = nsStyleClipPath();
|
||||
SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
|
||||
mPresContext, conditions);
|
||||
|
||||
@@ -346,17 +346,23 @@ nsStyleContext::MoveTo(nsStyleContext* aNewParent)
|
||||
MOZ_ASSERT(aNewParent != mParent);
|
||||
|
||||
// This function shouldn't be getting called if the parents have different
|
||||
// values for some flags in mBits, because if that were the case we would need
|
||||
// to recompute those bits for |this|.
|
||||
DebugOnly<uint64_t> mask = NS_STYLE_HAS_PSEUDO_ELEMENT_DATA |
|
||||
NS_STYLE_IN_DISPLAY_NONE_SUBTREE;
|
||||
MOZ_ASSERT((mParent->mBits & mask) == (aNewParent->mBits & mask));
|
||||
MOZ_ASSERT((mParent->mBits & NS_STYLE_HAS_TEXT_DECORATION_LINES) ==
|
||||
(aNewParent->mBits & NS_STYLE_HAS_TEXT_DECORATION_LINES) ||
|
||||
StyleTextReset()->HasTextDecorationLines());
|
||||
MOZ_ASSERT((mParent->mBits & NS_STYLE_RELEVANT_LINK_VISITED) ==
|
||||
(aNewParent->mBits & NS_STYLE_RELEVANT_LINK_VISITED) ||
|
||||
IsLinkContext());
|
||||
// values for some flags in mBits (unless the flag is also set on this style
|
||||
// context) because if that were the case we would need to recompute those
|
||||
// bits for |this|.
|
||||
|
||||
#define CHECK_FLAG(bit_) \
|
||||
MOZ_ASSERT((mParent->mBits & (bit_)) == (aNewParent->mBits & (bit_)) || \
|
||||
(mBits & (bit_)), \
|
||||
"MoveTo cannot be called if " #bit_ " value on old and new " \
|
||||
"style context parents do not match, unless the flag is set " \
|
||||
"on this style context");
|
||||
|
||||
CHECK_FLAG(NS_STYLE_HAS_PSEUDO_ELEMENT_DATA)
|
||||
CHECK_FLAG(NS_STYLE_IN_DISPLAY_NONE_SUBTREE)
|
||||
CHECK_FLAG(NS_STYLE_HAS_TEXT_DECORATION_LINES)
|
||||
CHECK_FLAG(NS_STYLE_RELEVANT_LINK_VISITED)
|
||||
|
||||
#undef CHECK_FLAG
|
||||
|
||||
// Assertions checking for visited style are just to avoid some tricky
|
||||
// cases we can't be bothered handling at the moment.
|
||||
|
||||
@@ -341,6 +341,12 @@ parsererror|sourcetext {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
div:-moz-native-anonymous.moz-accessiblecaret {
|
||||
/* Add transition effect to make caret size changing smoother. */
|
||||
transition-duration: 250ms;
|
||||
transition-property: width, height, margin-left;
|
||||
}
|
||||
|
||||
div:-moz-native-anonymous.moz-accessiblecaret,
|
||||
div:-moz-native-anonymous.moz-accessiblecaret > div.image,
|
||||
div:-moz-native-anonymous.moz-accessiblecaret > div.bar {
|
||||
|
||||
@@ -1097,6 +1097,9 @@ function run() {
|
||||
test_parseable(":-moz-window-inactive");
|
||||
test_parseable("div p:-moz-window-inactive:hover span");
|
||||
|
||||
// Chrome-only
|
||||
test_unbalanced_unparseable(":-moz-browser-frame");
|
||||
|
||||
// Plugin pseudoclasses are chrome-only:
|
||||
test_unbalanced_unparseable(":-moz-type-unsupported");
|
||||
test_unbalanced_unparseable(":-moz-user-disabled");
|
||||
|
||||
@@ -10,15 +10,13 @@
|
||||
#include "nsSVGEffects.h"
|
||||
#include "nsSVGFilters.h"
|
||||
|
||||
typedef nsFrame SVGFEUnstyledLeafFrameBase;
|
||||
|
||||
class SVGFEUnstyledLeafFrame : public SVGFEUnstyledLeafFrameBase
|
||||
class SVGFEUnstyledLeafFrame : public nsFrame
|
||||
{
|
||||
friend nsIFrame*
|
||||
NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
protected:
|
||||
explicit SVGFEUnstyledLeafFrame(nsStyleContext* aContext)
|
||||
: SVGFEUnstyledLeafFrameBase(aContext)
|
||||
: nsFrame(aContext)
|
||||
{
|
||||
AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
|
||||
}
|
||||
@@ -32,7 +30,7 @@ public:
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||
{
|
||||
return SVGFEUnstyledLeafFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
|
||||
return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
@@ -85,6 +83,5 @@ SVGFEUnstyledLeafFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(GetParent()->GetParent());
|
||||
}
|
||||
|
||||
return SVGFEUnstyledLeafFrameBase::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
return nsFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
}
|
||||
|
||||
+6
-108
@@ -3250,6 +3250,10 @@ SVGTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// painting.
|
||||
return;
|
||||
}
|
||||
if (!IsVisibleForPainting(aBuilder) &&
|
||||
aBuilder->IsForPainting()) {
|
||||
return;
|
||||
}
|
||||
aLists.Content()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplaySVGText(aBuilder, this));
|
||||
}
|
||||
@@ -3732,8 +3736,8 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
||||
|
||||
SVGTextContextPaint contextPaint;
|
||||
DrawMode drawMode =
|
||||
SetupContextPaint(&aDrawTarget, aContext.CurrentMatrix(),
|
||||
frame, outerContextPaint, &contextPaint);
|
||||
nsSVGUtils::SetupContextPaint(&aDrawTarget, aContext.CurrentMatrix(),
|
||||
frame, outerContextPaint, &contextPaint);
|
||||
|
||||
if (drawMode & DrawMode::GLYPH_STROKE) {
|
||||
// This may change the gfxContext's transform (for non-scaling stroke),
|
||||
@@ -5718,109 +5722,3 @@ SVGTextFrame::TransformFrameRectFromTextChild(const nsRect& aRect,
|
||||
return result - framePosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores in |aTargetPaint| information on how to reconstruct the current
|
||||
* fill or stroke pattern. Will also set the paint opacity to transparent if
|
||||
* the paint is set to "none".
|
||||
* @param aOuterContextPaint pattern information from the outer text context
|
||||
* @param aTargetPaint where to store the current pattern information
|
||||
* @param aFillOrStroke member pointer to the paint we are setting up
|
||||
* @param aProperty the frame property descriptor of the fill or stroke paint
|
||||
* server frame
|
||||
*/
|
||||
static void
|
||||
SetupInheritablePaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
float& aOpacity,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint::Paint& aTargetPaint,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
nsSVGEffects::ObserverPropertyDescriptor aProperty)
|
||||
{
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &(style->*aFillOrStroke), aProperty);
|
||||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern =
|
||||
ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
|
||||
aFillOrStroke, aOpacity);
|
||||
if (pattern) {
|
||||
aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aOuterContextPaint) {
|
||||
RefPtr<gfxPattern> pattern;
|
||||
switch ((style->*aFillOrStroke).mType) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
|
||||
aContextMatrix);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
|
||||
aContextMatrix);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nscolor color =
|
||||
nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
|
||||
aTargetPaint.SetColor(color);
|
||||
}
|
||||
|
||||
DrawMode
|
||||
SVGTextFrame::SetupContextPaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint)
|
||||
{
|
||||
DrawMode toDraw = DrawMode(0);
|
||||
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
|
||||
// fill:
|
||||
if (style->mFill.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetFillOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mFillOpacitySource,
|
||||
style->mFillOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
|
||||
opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mFillPaint, &nsStyleSVG::mFill,
|
||||
nsSVGEffects::FillProperty());
|
||||
|
||||
aThisContextPaint->SetFillOpacity(opacity);
|
||||
|
||||
toDraw |= DrawMode::GLYPH_FILL;
|
||||
}
|
||||
|
||||
// stroke:
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetStrokeOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mStrokeOpacitySource,
|
||||
style->mStrokeOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
|
||||
opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mStrokePaint, &nsStyleSVG::mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
|
||||
aThisContextPaint->SetStrokeOpacity(opacity);
|
||||
|
||||
toDraw |= DrawMode::GLYPH_STROKE;
|
||||
}
|
||||
|
||||
return toDraw;
|
||||
}
|
||||
|
||||
@@ -211,8 +211,7 @@ public:
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* Frame class for SVG <text> elements, used when the
|
||||
* layout.svg.css-text.enabled is true.
|
||||
* Frame class for SVG <text> elements.
|
||||
*
|
||||
* An SVGTextFrame manages SVG text layout, painting and interaction for
|
||||
* all descendent text content elements. The frame tree will look like this:
|
||||
@@ -609,12 +608,6 @@ private:
|
||||
gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
|
||||
gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);
|
||||
|
||||
DrawMode SetupContextPaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint);
|
||||
|
||||
/**
|
||||
* The MutationObserver we have registered for the <text> element subtree.
|
||||
*/
|
||||
|
||||
@@ -236,16 +236,20 @@ nsSVGClipPathFrame::GetClipMask(gfxContext& aReferenceContext,
|
||||
mat.Invert();
|
||||
|
||||
if (aExtraMask) {
|
||||
MOZ_ASSERT(!aExtraMasksTransform.HasNonTranslation());
|
||||
|
||||
// We could potentially due this more efficiently with OPERATOR_IN
|
||||
// but that operator does not work well on CG or D2D
|
||||
RefPtr<SourceSurface> currentMask = maskDT->Snapshot();
|
||||
Matrix transform = maskDT->GetTransform();
|
||||
maskDT->SetTransform(Matrix());
|
||||
maskDT->ClearRect(Rect(0, 0,
|
||||
devSpaceClipExtents.width,
|
||||
devSpaceClipExtents.height));
|
||||
maskDT->MaskSurface(SurfacePattern(currentMask, ExtendMode::CLAMP),
|
||||
maskDT->SetTransform(aExtraMasksTransform * transform);
|
||||
// draw currentMask with the inverse of the transform that we just so that
|
||||
// it ends up in the same spot with aExtraMask transformed by aExtraMasksTransform
|
||||
maskDT->MaskSurface(SurfacePattern(currentMask, ExtendMode::CLAMP, aExtraMasksTransform.Inverse() * ToMatrix(mat)),
|
||||
aExtraMask,
|
||||
Point(aExtraMasksTransform._31, aExtraMasksTransform._32));
|
||||
Point(0, 0));
|
||||
}
|
||||
|
||||
*aMaskTransform = ToMatrix(mat);
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "nsSVGMaskFrame.h"
|
||||
#include <arm_neon.h>
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
void
|
||||
ComputesRGBLuminanceMask_NEON(const uint8_t *aSourceData,
|
||||
int32_t aSourceStride,
|
||||
|
||||
@@ -6,16 +6,14 @@
|
||||
#ifndef __NS_SVGMASKFRAMENEON_H__
|
||||
#define __NS_SVGMASKFRAMENEON_H__
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
#include "mozilla/gfx/Point.h"
|
||||
|
||||
void
|
||||
ComputesRGBLuminanceMask_NEON(const uint8_t *aSourceData,
|
||||
int32_t aSourceStride,
|
||||
uint8_t *aDestData,
|
||||
int32_t aDestStride,
|
||||
const IntSize &aSize,
|
||||
const mozilla::gfx::IntSize &aSize,
|
||||
float aOpacity);
|
||||
|
||||
#endif /* __NS_SVGMASKFRAMENEON_H__ */
|
||||
|
||||
@@ -167,15 +167,33 @@ nsSVGOuterSVGFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
|
||||
DISPLAY_PREF_WIDTH(this, result);
|
||||
|
||||
SVGSVGElement *svg = static_cast<SVGSVGElement*>(mContent);
|
||||
nsSVGLength2 &width = svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH];
|
||||
WritingMode wm = GetWritingMode();
|
||||
const nsSVGLength2& isize = wm.IsVertical()
|
||||
? svg->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT]
|
||||
: svg->mLengthAttributes[SVGSVGElement::ATTR_WIDTH];
|
||||
|
||||
if (width.IsPercentage()) {
|
||||
// It looks like our containing block's width may depend on our width. In
|
||||
// that case our behavior is undefined according to CSS 2.1 section 10.3.2,
|
||||
// so return zero.
|
||||
if (isize.IsPercentage()) {
|
||||
// It looks like our containing block's isize may depend on our isize. In
|
||||
// that case our behavior is undefined according to CSS 2.1 section 10.3.2.
|
||||
// As a last resort, we'll fall back to returning zero.
|
||||
result = nscoord(0);
|
||||
|
||||
// Returning zero may be unhelpful, however, as it leads to unexpected
|
||||
// disappearance of %-sized SVGs in orthogonal contexts, where our
|
||||
// containing block wants to shrink-wrap. So let's look for an ancestor
|
||||
// with non-zero size in this dimension, and use that as a (somewhat
|
||||
// arbitrary) result instead.
|
||||
nsIFrame *parent = GetParent();
|
||||
while (parent) {
|
||||
nscoord parentISize = parent->GetLogicalSize(wm).ISize(wm);
|
||||
if (parentISize > 0 && parentISize != NS_UNCONSTRAINEDSIZE) {
|
||||
result = parentISize;
|
||||
break;
|
||||
}
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
} else {
|
||||
result = nsPresContext::CSSPixelsToAppUnits(width.GetAnimValue(svg));
|
||||
result = nsPresContext::CSSPixelsToAppUnits(isize.GetAnimValue(svg));
|
||||
if (result < 0) {
|
||||
result = nscoord(0);
|
||||
}
|
||||
@@ -728,7 +746,7 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayListSet set(contentList, contentList, contentList,
|
||||
contentList, contentList, contentList);
|
||||
BuildDisplayListForNonBlockChildren(aBuilder, aDirtyRect, set);
|
||||
} else {
|
||||
} else if (IsVisibleForPainting(aBuilder) || !aBuilder->IsForPainting()) {
|
||||
aLists.Content()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayOuterSVG(aBuilder, this));
|
||||
}
|
||||
|
||||
@@ -231,7 +231,8 @@ nsSVGPathGeometryFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
if (!static_cast<const nsSVGElement*>(mContent)->HasValidDimensions()) {
|
||||
if (!static_cast<const nsSVGElement*>(mContent)->HasValidDimensions() ||
|
||||
(!IsVisibleForPainting(aBuilder) && aBuilder->IsForPainting())) {
|
||||
return;
|
||||
}
|
||||
aLists.Content()->AppendNewToTop(
|
||||
|
||||
+112
-2
@@ -52,6 +52,7 @@
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "nsTextFrame.h"
|
||||
#include "SVGContentUtils.h"
|
||||
#include "SVGTextFrame.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@@ -384,8 +385,10 @@ nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(nsIFrame* aFrame, nsRect* aRect)
|
||||
if (outer == svg) {
|
||||
return nullptr;
|
||||
}
|
||||
*aRect = (aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY) ?
|
||||
nsRect(0, 0, 0, 0) : svg->GetCoveredRegion();
|
||||
nsMargin bp = outer->GetUsedBorderAndPadding();
|
||||
*aRect = ((aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY) ?
|
||||
nsRect(0, 0, 0, 0) : svg->GetCoveredRegion()) +
|
||||
nsPoint(bp.left, bp.top);
|
||||
return outer;
|
||||
}
|
||||
|
||||
@@ -1294,6 +1297,113 @@ nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores in |aTargetPaint| information on how to reconstruct the current
|
||||
* fill or stroke pattern. Will also set the paint opacity to transparent if
|
||||
* the paint is set to "none".
|
||||
* @param aOuterContextPaint pattern information from the outer text context
|
||||
* @param aTargetPaint where to store the current pattern information
|
||||
* @param aFillOrStroke member pointer to the paint we are setting up
|
||||
* @param aProperty the frame property descriptor of the fill or stroke paint
|
||||
* server frame
|
||||
*/
|
||||
static void
|
||||
SetupInheritablePaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
float& aOpacity,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint::Paint& aTargetPaint,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
nsSVGEffects::ObserverPropertyDescriptor aProperty)
|
||||
{
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &(style->*aFillOrStroke), aProperty);
|
||||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern =
|
||||
ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
|
||||
aFillOrStroke, aOpacity);
|
||||
if (pattern) {
|
||||
aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aOuterContextPaint) {
|
||||
RefPtr<gfxPattern> pattern;
|
||||
switch ((style->*aFillOrStroke).mType) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
|
||||
aContextMatrix);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
|
||||
aContextMatrix);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nscolor color =
|
||||
nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
|
||||
aTargetPaint.SetColor(color);
|
||||
}
|
||||
|
||||
/* static */ DrawMode
|
||||
nsSVGUtils::SetupContextPaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint)
|
||||
{
|
||||
DrawMode toDraw = DrawMode(0);
|
||||
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
|
||||
// fill:
|
||||
if (style->mFill.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetFillOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mFillOpacitySource,
|
||||
style->mFillOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
|
||||
opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mFillPaint, &nsStyleSVG::mFill,
|
||||
nsSVGEffects::FillProperty());
|
||||
|
||||
aThisContextPaint->SetFillOpacity(opacity);
|
||||
|
||||
toDraw |= DrawMode::GLYPH_FILL;
|
||||
}
|
||||
|
||||
// stroke:
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetStrokeOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mStrokeOpacitySource,
|
||||
style->mStrokeOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
|
||||
opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mStrokePaint, &nsStyleSVG::mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
|
||||
aThisContextPaint->SetStrokeOpacity(opacity);
|
||||
|
||||
toDraw |= DrawMode::GLYPH_STROKE;
|
||||
}
|
||||
|
||||
return toDraw;
|
||||
}
|
||||
|
||||
static float
|
||||
MaybeOptimizeOpacity(nsIFrame *aFrame, float aFillOrStrokeOpacity)
|
||||
{
|
||||
|
||||
+12
-1
@@ -9,6 +9,7 @@
|
||||
// include math.h to pick up definition of M_ maths defines e.g. M_PI
|
||||
#include <math.h>
|
||||
|
||||
#include "DrawMode.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "gfxPoint.h"
|
||||
@@ -46,6 +47,7 @@ struct nsStyleSVGPaint;
|
||||
struct nsRect;
|
||||
|
||||
namespace mozilla {
|
||||
struct SVGTextContextPaint;
|
||||
namespace dom {
|
||||
class Element;
|
||||
class UserSpaceMetrics;
|
||||
@@ -53,7 +55,7 @@ class UserSpaceMetrics;
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
class GeneralPattern;
|
||||
}
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
// maximum dimension of an offscreen surface - choose so that
|
||||
@@ -178,9 +180,11 @@ class nsSVGUtils
|
||||
public:
|
||||
typedef mozilla::dom::Element Element;
|
||||
typedef mozilla::gfx::AntialiasMode AntialiasMode;
|
||||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::gfx::FillRule FillRule;
|
||||
typedef mozilla::gfx::GeneralPattern GeneralPattern;
|
||||
typedef mozilla::gfx::Size Size;
|
||||
typedef mozilla::SVGTextContextPaint SVGTextContextPaint;
|
||||
|
||||
static void Init();
|
||||
|
||||
@@ -492,6 +496,13 @@ public:
|
||||
static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
|
||||
|
||||
static DrawMode
|
||||
SetupContextPaint(const DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint);
|
||||
|
||||
static void
|
||||
MakeFillPatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<style>
|
||||
p {
|
||||
writing-mode:tb;
|
||||
float:right;
|
||||
font-size:2000px;
|
||||
}
|
||||
#bb {
|
||||
position:sticky;
|
||||
display:table-footer-group;
|
||||
}
|
||||
#dd {
|
||||
transition:2s ease-in;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="dd"></div>
|
||||
<div id="bb">
|
||||
<p>grilling it up
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
dd.style.marginTop = "100px";
|
||||
</script>
|
||||
</html>
|
||||
@@ -151,3 +151,4 @@ load 1027611-1.html
|
||||
load 1031934.html
|
||||
load 1183896.html
|
||||
load 1223232.html
|
||||
load 1243623-1.html
|
||||
|
||||
@@ -289,11 +289,14 @@ nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
|
||||
nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame,
|
||||
nsIFrame* aDestructRoot)
|
||||
{
|
||||
// Retrieve the table frame, and ensure that we hit aDestructRoot on the way.
|
||||
// If we don't, that means that the table frame will be destroyed, so we don't
|
||||
// need to bother with unregistering this frame.
|
||||
nsTableFrame* tableFrame = GetTableFramePassingThrough(aDestructRoot, aFrame);
|
||||
if (!tableFrame) {
|
||||
// Retrieve the table frame, and check if we hit aDestructRoot on the way.
|
||||
bool didPassThrough;
|
||||
nsTableFrame* tableFrame = GetTableFramePassingThrough(aDestructRoot, aFrame,
|
||||
&didPassThrough);
|
||||
if (!didPassThrough && !tableFrame->GetPrevContinuation()) {
|
||||
// The table frame will be destroyed, and it's the first im flow (and thus
|
||||
// owning the PositionedTablePartArray), so we don't need to do
|
||||
// anything.
|
||||
return;
|
||||
}
|
||||
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
|
||||
@@ -3829,19 +3832,20 @@ nsTableFrame::GetTableFrame(nsIFrame* aFrame)
|
||||
|
||||
nsTableFrame*
|
||||
nsTableFrame::GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
|
||||
nsIFrame* aFrame)
|
||||
nsIFrame* aFrame,
|
||||
bool* aDidPassThrough)
|
||||
{
|
||||
MOZ_ASSERT(aMustPassThrough == aFrame ||
|
||||
nsLayoutUtils::IsProperAncestorFrame(aMustPassThrough, aFrame),
|
||||
"aMustPassThrough should be an ancestor");
|
||||
|
||||
// Retrieve the table frame, and ensure that we hit aMustPassThrough on the
|
||||
// way. If we don't, just return null.
|
||||
bool hitPassThroughFrame = false;
|
||||
// Retrieve the table frame, and check if we hit aMustPassThrough on the
|
||||
// way.
|
||||
*aDidPassThrough = false;
|
||||
nsTableFrame* tableFrame = nullptr;
|
||||
for (nsIFrame* ancestor = aFrame; ancestor; ancestor = ancestor->GetParent()) {
|
||||
if (ancestor == aMustPassThrough) {
|
||||
hitPassThroughFrame = true;
|
||||
*aDidPassThrough = true;
|
||||
}
|
||||
if (nsGkAtoms::tableFrame == ancestor->GetType()) {
|
||||
tableFrame = static_cast<nsTableFrame*>(ancestor);
|
||||
@@ -3850,7 +3854,7 @@ nsTableFrame::GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
|
||||
}
|
||||
|
||||
MOZ_ASSERT(tableFrame, "Should have a table frame here");
|
||||
return hitPassThroughFrame ? tableFrame : nullptr;
|
||||
return tableFrame;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -218,11 +218,12 @@ public:
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
|
||||
|
||||
/* Like GetTableFrame, but will return nullptr if we don't pass through
|
||||
* aMustPassThrough on the way to the table.
|
||||
/* Like GetTableFrame, but will set *aDidPassThrough to false if we don't
|
||||
* pass through aMustPassThrough on the way to the table.
|
||||
*/
|
||||
static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
|
||||
nsIFrame* aSourceFrame);
|
||||
nsIFrame* aSourceFrame,
|
||||
bool* aDidPassThrough);
|
||||
|
||||
typedef void (* DisplayGenericTablePartTraversal)
|
||||
(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
|
||||
|
||||
@@ -230,7 +230,7 @@ TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame,
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (tableData.IsVisible()) {
|
||||
result =
|
||||
result &=
|
||||
nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
|
||||
tableData.mFrame, mDirtyRect,
|
||||
tableData.mRect + mRenderPt,
|
||||
@@ -276,15 +276,16 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
|
||||
|
||||
if (rowGroups.Length() < 1) { //degenerate case
|
||||
if (aPaintTableBackground) {
|
||||
PaintTableFrame(aTableFrame, nullptr, nullptr, nsMargin(0,0,0,0));
|
||||
result &= PaintTableFrame(aTableFrame, nullptr, nullptr, nsMargin(0,0,0,0));
|
||||
}
|
||||
/* No cells; nothing else to paint */
|
||||
return result;
|
||||
}
|
||||
|
||||
if (aPaintTableBackground) {
|
||||
PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
|
||||
aDeflate);
|
||||
result &=
|
||||
PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
|
||||
aDeflate);
|
||||
}
|
||||
|
||||
/*Set up column background/border data*/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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/. */
|
||||
|
||||
const CC = Components.classes;
|
||||
var CC = Components.classes;
|
||||
const CI = Components.interfaces;
|
||||
|
||||
const NS_GFXINFO_CONTRACTID = "@mozilla.org/gfx/info;1";
|
||||
|
||||
@@ -124,3 +124,6 @@ user_pref("startup.homepage_override_url", "");
|
||||
user_pref("browser.usedOnWindows10.introURL", "");
|
||||
|
||||
user_pref("media.gmp-manager.url.override", "http://localhost/dummy-gmp-manager.xml");
|
||||
|
||||
// A fake bool pref for "@supports -moz-bool-pref" sanify test.
|
||||
user_pref("testing.supports.moz-bool-pref", true);
|
||||
|
||||
@@ -408,6 +408,11 @@ nsMenuBarListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
nsresult
|
||||
nsMenuBarListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// If the menu bar is collapsed, don't do anything.
|
||||
if (!mMenuBarFrame->StyleVisibility()->IsVisible()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
|
||||
|
||||
@@ -418,6 +418,7 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
else {
|
||||
if (!IsOpen()) {
|
||||
menuParent->ChangeMenuItem(this, false, false);
|
||||
OpenMenu(false);
|
||||
}
|
||||
}
|
||||
@@ -466,7 +467,11 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
if (IsMenu() && !onmenubar && IsOpen()) {
|
||||
// Submenus don't get closed up immediately.
|
||||
}
|
||||
else if (this == menuParent->GetCurrentMenuItem()) {
|
||||
else if (this == menuParent->GetCurrentMenuItem()
|
||||
#ifdef XP_WIN
|
||||
&& GetParentMenuListType() == eNotMenuList
|
||||
#endif
|
||||
) {
|
||||
menuParent->ChangeMenuItem(nullptr, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,5 +22,6 @@ skip-if = os == 'linux' # No native mousedown event
|
||||
[test_popupZoom.xul]
|
||||
[test_resizer.xul]
|
||||
[test_stack.xul]
|
||||
[test_submenuClose.xul]
|
||||
[test_windowminmaxsize.xul]
|
||||
skip-if = buildapp == 'mulet'
|
||||
|
||||
@@ -9,3 +9,5 @@ skip-if = toolkit == 'android' #bug 798806
|
||||
[test_resizer_incontent.xul]
|
||||
[test_splitter.xul]
|
||||
skip-if = toolkit == 'android' # no XUL theme
|
||||
[test_bug1197913.xul]
|
||||
skip-if = toolkit == 'android'
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1197913
|
||||
-->
|
||||
<window title="Mozilla Bug 1197913"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="SimpleTest.waitForFocus(nextTest, window)">
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1197913"
|
||||
target="_blank">Mozilla Bug 1197913</a>
|
||||
</body>
|
||||
|
||||
<menulist>
|
||||
<menupopup>
|
||||
<menuitem label="Car" />
|
||||
<menuitem label="Taxi" id="target" />
|
||||
<menuitem label="Bus" />
|
||||
</menupopup>
|
||||
</menulist>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let menulist = document.getElementsByTagName("menulist")[0];
|
||||
let menuitem = document.getElementById("target");
|
||||
|
||||
function onDOMMenuItemActive(e) {
|
||||
menuitem.removeEventListener("DOMMenuItemActive", onDOMMenuItemActive);
|
||||
|
||||
synthesizeMouse(menuitem, 0, 0, { type: "mousemove" });
|
||||
synthesizeMouse(menuitem, -1, 0, { type: "mousemove" });
|
||||
|
||||
setTimeout(() => {
|
||||
if (navigator.platform.toLowerCase().startsWith("win")) {
|
||||
ok(menuitem.getAttribute("_moz-menuactive"));
|
||||
} else {
|
||||
ok(!menuitem.getAttribute("_moz-menuactive"));
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
function onPopupShown(e) {
|
||||
menulist.removeEventListener("popupshown", onPopupShown);
|
||||
menuitem.addEventListener("DOMMenuItemActive", onDOMMenuItemActive);
|
||||
synthesizeMouse(menuitem, 0, 0, { type: "mousemove" });
|
||||
synthesizeMouse(menuitem, 1, 0, { type: "mousemove" });
|
||||
}
|
||||
|
||||
function nextTest(e) {
|
||||
menulist.addEventListener("popupshown", onPopupShown);
|
||||
synthesizeMouseAtCenter(menulist, {});
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1181560
|
||||
-->
|
||||
<window title="Mozilla Bug 1181560"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="SimpleTest.waitForFocus(nextTest, window)">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1181560"
|
||||
target="_blank">Mozilla Bug 1181560</a>
|
||||
</body>
|
||||
|
||||
<vbox>
|
||||
<menubar>
|
||||
<menu id="menu" label="MyMenu">
|
||||
<menupopup>
|
||||
<menuitem label="A"/>
|
||||
<menu id="b" label="B">
|
||||
<menupopup>
|
||||
<menuitem label="B1"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="c" label="C">
|
||||
<menupopup>
|
||||
<menuitem label="C1"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
</vbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 1181560 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let menuB, menuC, mainMenu, menuBOpen, menuCOpen;
|
||||
let menuBOpenCount = 0;
|
||||
|
||||
function handleBOpens() {
|
||||
menuBOpenCount++;
|
||||
menuBOpen = true;
|
||||
ok(!menuCOpen, "Menu C should not be open when menu B has opened");
|
||||
if (menuBOpenCount >= 2) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
sendKey("LEFT", window);
|
||||
sendKey("DOWN", window);
|
||||
sendKey("RIGHT", window);
|
||||
}
|
||||
|
||||
function handleBCloses() {
|
||||
menuBOpen = false;
|
||||
}
|
||||
|
||||
function handleCOpens() {
|
||||
menuCOpen = true;
|
||||
ok(!menuBOpen, "Menu B should not be open when menu C has opened");
|
||||
synthesizeMouseAtCenter(menuB, {}, window);
|
||||
}
|
||||
|
||||
function handleCCloses() {
|
||||
menuCOpen = false;
|
||||
}
|
||||
|
||||
function nextTest(e) {
|
||||
mainMenu = document.getElementById("menu");
|
||||
menuB = document.getElementById("b");
|
||||
menuC = document.getElementById("c");
|
||||
menuB.firstChild.addEventListener("popupshown", handleBOpens, false);
|
||||
menuB.firstChild.addEventListener("popuphidden", handleBCloses, false);
|
||||
menuC.firstChild.addEventListener("popupshown", handleCOpens, false);
|
||||
menuC.firstChild.addEventListener("popuphidden", handleCCloses, false);
|
||||
mainMenu.addEventListener("popupshown", ev => {
|
||||
synthesizeMouseAtCenter(menuB, {}, window);
|
||||
});
|
||||
mainMenu.open = true;
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
||||
@@ -1192,7 +1192,7 @@ nsTreeBodyFrame::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const n
|
||||
nsRect twistyRect(cellRect);
|
||||
nsStyleContext* twistyContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreetwisty);
|
||||
GetTwistyRect(aRow, currCol, imageRect, twistyRect, presContext,
|
||||
rc, twistyContext);
|
||||
twistyContext);
|
||||
|
||||
if (NS_LITERAL_CSTRING("twisty").Equals(aElement)) {
|
||||
// If we're looking for the twisty Rect, just return the size
|
||||
@@ -1557,7 +1557,7 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect,
|
||||
|
||||
nsRect imageSize;
|
||||
GetTwistyRect(aRowIndex, aColumn, imageSize, twistyRect, presContext,
|
||||
rc, twistyContext);
|
||||
twistyContext);
|
||||
|
||||
// We will treat a click as hitting the twisty if it happens on the margins, borders, padding,
|
||||
// or content of the twisty object. By allowing a "slop" into the margin, we make it a little
|
||||
@@ -1716,7 +1716,7 @@ nsTreeBodyFrame::GetCellWidth(int32_t aRow, nsTreeColumn* aCol,
|
||||
nsRect imageSize;
|
||||
nsRect twistyRect(cellRect);
|
||||
GetTwistyRect(aRow, aCol, imageSize, twistyRect, PresContext(),
|
||||
*aRenderingContext, twistyContext);
|
||||
twistyContext);
|
||||
|
||||
// Add in the margins of the twisty element.
|
||||
nsMargin twistyMargin;
|
||||
@@ -2060,7 +2060,6 @@ nsTreeBodyFrame::GetTwistyRect(int32_t aRowIndex,
|
||||
nsRect& aImageRect,
|
||||
nsRect& aTwistyRect,
|
||||
nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
nsStyleContext* aTwistyContext)
|
||||
{
|
||||
// The twisty rect extends all the way to the end of the cell. This is incorrect. We need to
|
||||
@@ -3262,7 +3261,7 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
|
||||
nsRect imageSize;
|
||||
nsRect twistyRect(aCellRect);
|
||||
GetTwistyRect(aRowIndex, aColumn, imageSize, twistyRect, aPresContext,
|
||||
aRenderingContext, twistyContext);
|
||||
twistyContext);
|
||||
|
||||
nsMargin twistyMargin;
|
||||
twistyContext->StyleMargin()->GetMargin(twistyMargin);
|
||||
@@ -3368,7 +3367,8 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
|
||||
switch (aColumn->GetType()) {
|
||||
case nsITreeColumn::TYPE_TEXT:
|
||||
case nsITreeColumn::TYPE_PASSWORD:
|
||||
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX);
|
||||
result &= PaintText(aRowIndex, aColumn, elementRect, aPresContext,
|
||||
aRenderingContext, aDirtyRect, currX);
|
||||
break;
|
||||
case nsITreeColumn::TYPE_CHECKBOX:
|
||||
result &= PaintCheckbox(aRowIndex, aColumn, elementRect, aPresContext,
|
||||
@@ -3386,7 +3386,8 @@ nsTreeBodyFrame::PaintCell(int32_t aRowIndex,
|
||||
break;
|
||||
case nsITreeView::PROGRESS_NONE:
|
||||
default:
|
||||
PaintText(aRowIndex, aColumn, elementRect, aPresContext, aRenderingContext, aDirtyRect, currX);
|
||||
result &= PaintText(aRowIndex, aColumn, elementRect, aPresContext,
|
||||
aRenderingContext, aDirtyRect, currX);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -3436,7 +3437,7 @@ nsTreeBodyFrame::PaintTwisty(int32_t aRowIndex,
|
||||
|
||||
nsRect imageSize;
|
||||
nsITheme* theme = GetTwistyRect(aRowIndex, aColumn, imageSize, twistyRect,
|
||||
aPresContext, aRenderingContext, twistyContext);
|
||||
aPresContext, twistyContext);
|
||||
|
||||
// Subtract out the remaining width. This is done even when we don't actually paint a twisty in
|
||||
// this cell, so that cells in different rows still line up.
|
||||
@@ -3611,26 +3612,44 @@ nsTreeBodyFrame::PaintImage(int32_t aRowIndex,
|
||||
// Deflate destRect for the border and padding.
|
||||
destRect.Deflate(bp);
|
||||
|
||||
// Get the image source rectangle - the rectangle containing the part of
|
||||
// the image that we are going to display.
|
||||
// sourceRect will be passed as the aSrcRect argument in the DrawImage method.
|
||||
nsRect sourceRect = GetImageSourceRect(imageContext, useImageRegion, image);
|
||||
|
||||
// Let's say that the image is 100 pixels tall and
|
||||
// that the CSS has specified that the destination height should be 50
|
||||
// pixels tall. Let's say that the cell height is only 20 pixels. So, in
|
||||
// those 20 visible pixels, we want to see the top 20/50ths of the image.
|
||||
// So, the sourceRect.height should be 100 * 20 / 50, which is 40 pixels.
|
||||
// Essentially, we are scaling the image as dictated by the CSS destination
|
||||
// height and width, and we are then clipping the scaled image by the cell
|
||||
// width and height.
|
||||
// Compute the area where our whole image would be mapped, to get the
|
||||
// desired subregion onto our actual destRect:
|
||||
nsRect wholeImageDest;
|
||||
CSSIntSize rawImageCSSIntSize;
|
||||
image->GetWidth(&rawImageCSSIntSize.width);
|
||||
image->GetHeight(&rawImageCSSIntSize.height);
|
||||
nsSize rawImageSize(CSSPixel::ToAppUnits(rawImageCSSIntSize));
|
||||
nsRect wholeImageDest =
|
||||
nsLayoutUtils::GetWholeImageDestination(rawImageSize, sourceRect,
|
||||
nsRect(destRect.TopLeft(), imageDestSize));
|
||||
if (NS_SUCCEEDED(image->GetWidth(&rawImageCSSIntSize.width)) &&
|
||||
NS_SUCCEEDED(image->GetHeight(&rawImageCSSIntSize.height))) {
|
||||
// Get the image source rectangle - the rectangle containing the part of
|
||||
// the image that we are going to display. sourceRect will be passed as
|
||||
// the aSrcRect argument in the DrawImage method.
|
||||
nsRect sourceRect = GetImageSourceRect(imageContext, useImageRegion, image);
|
||||
|
||||
// Let's say that the image is 100 pixels tall and that the CSS has
|
||||
// specified that the destination height should be 50 pixels tall. Let's
|
||||
// say that the cell height is only 20 pixels. So, in those 20 visible
|
||||
// pixels, we want to see the top 20/50ths of the image. So, the
|
||||
// sourceRect.height should be 100 * 20 / 50, which is 40 pixels.
|
||||
// Essentially, we are scaling the image as dictated by the CSS
|
||||
// destination height and width, and we are then clipping the scaled
|
||||
// image by the cell width and height.
|
||||
nsSize rawImageSize(CSSPixel::ToAppUnits(rawImageCSSIntSize));
|
||||
wholeImageDest =
|
||||
nsLayoutUtils::GetWholeImageDestination(rawImageSize, sourceRect,
|
||||
nsRect(destRect.TopLeft(),
|
||||
imageDestSize));
|
||||
} else {
|
||||
// GetWidth/GetHeight failed, so we can't easily map a subregion of the
|
||||
// source image onto the destination area.
|
||||
// * If this happens with a RasterImage, it probably means the image is
|
||||
// in an error state, and we shouldn't draw anything. Hence, we leave
|
||||
// wholeImageDest as an empty rect (its initial state).
|
||||
// * If this happens with a VectorImage, it probably means the image has
|
||||
// no explicit width or height attribute -- but we can still proceed and
|
||||
// just treat the destination area as our whole SVG image area. Hence, we
|
||||
// set wholeImageDest to the full destRect.
|
||||
if (image->GetType() == imgIContainer::TYPE_VECTOR) {
|
||||
wholeImageDest = destRect;
|
||||
}
|
||||
}
|
||||
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
if (opacity != 1.0f) {
|
||||
@@ -3658,7 +3677,7 @@ nsTreeBodyFrame::PaintImage(int32_t aRowIndex,
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
DrawResult
|
||||
nsTreeBodyFrame::PaintText(int32_t aRowIndex,
|
||||
nsTreeColumn* aColumn,
|
||||
const nsRect& aTextRect,
|
||||
@@ -3683,8 +3702,12 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
|
||||
// necessary
|
||||
CheckTextForBidi(text);
|
||||
|
||||
if (text.Length() == 0)
|
||||
return; // Don't paint an empty string. XXX What about background/borders? Still paint?
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (text.Length() == 0) {
|
||||
// Don't paint an empty string. XXX What about background/borders? Still paint?
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
|
||||
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
|
||||
@@ -3729,7 +3752,8 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
|
||||
if (!isRTL)
|
||||
aCurrX += textRect.width + textMargin.LeftRight();
|
||||
|
||||
PaintBackgroundLayer(textContext, aPresContext, aRenderingContext, textRect, aDirtyRect);
|
||||
result &= PaintBackgroundLayer(textContext, aPresContext, aRenderingContext,
|
||||
textRect, aDirtyRect);
|
||||
|
||||
// Time to paint our text.
|
||||
textRect.Deflate(bp);
|
||||
@@ -3783,6 +3807,7 @@ nsTreeBodyFrame::PaintText(int32_t aRowIndex,
|
||||
ctx->PopGroupAndBlend();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
@@ -4016,8 +4041,8 @@ nsTreeBodyFrame::PaintDropFeedback(const nsRect& aDropFeedbackRect,
|
||||
nsStyleContext* twistyContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreetwisty);
|
||||
nsRect imageSize;
|
||||
nsRect twistyRect;
|
||||
GetTwistyRect(mSlots->mDropRow, primaryCol, imageSize, twistyRect, aPresContext,
|
||||
aRenderingContext, twistyContext);
|
||||
GetTwistyRect(mSlots->mDropRow, primaryCol, imageSize, twistyRect,
|
||||
aPresContext, twistyContext);
|
||||
nsMargin twistyMargin;
|
||||
twistyContext->StyleMargin()->GetMargin(twistyMargin);
|
||||
twistyRect.Inflate(twistyMargin);
|
||||
|
||||
@@ -262,13 +262,13 @@ protected:
|
||||
nscoord& aCurrX);
|
||||
|
||||
// This method paints the text string inside a particular cell of the tree.
|
||||
void PaintText(int32_t aRowIndex,
|
||||
nsTreeColumn* aColumn,
|
||||
const nsRect& aTextRect,
|
||||
nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nscoord& aCurrX);
|
||||
DrawResult PaintText(int32_t aRowIndex,
|
||||
nsTreeColumn* aColumn,
|
||||
const nsRect& aTextRect,
|
||||
nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect,
|
||||
nscoord& aCurrX);
|
||||
|
||||
// This method paints the checkbox inside a particular cell of the tree.
|
||||
DrawResult PaintCheckbox(int32_t aRowIndex,
|
||||
@@ -332,7 +332,6 @@ protected:
|
||||
nsRect& aImageRect,
|
||||
nsRect& aTwistyRect,
|
||||
nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
nsStyleContext* aTwistyContext);
|
||||
|
||||
// Fetch an image from the image cache.
|
||||
|
||||
@@ -395,8 +395,7 @@ nsTreeColumn::Invalidate(mozilla::ErrorResult& aRv)
|
||||
}
|
||||
|
||||
nsTreeColumns::nsTreeColumns(nsTreeBodyFrame* aTree)
|
||||
: mTree(aTree),
|
||||
mFirstColumn(nullptr)
|
||||
: mTree(aTree)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -671,7 +670,7 @@ nsTreeColumns::InvalidateColumns()
|
||||
currCol = currCol->GetNext()) {
|
||||
currCol->SetColumns(nullptr);
|
||||
}
|
||||
NS_IF_RELEASE(mFirstColumn);
|
||||
mFirstColumn = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -761,7 +760,7 @@ nsTreeColumns::EnsureColumns()
|
||||
col->SetPrevious(currCol);
|
||||
}
|
||||
else {
|
||||
NS_ADDREF(mFirstColumn = col);
|
||||
mFirstColumn = col;
|
||||
}
|
||||
currCol = col;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ private:
|
||||
* XXX this means that new nsTreeColumn objects are unnecessarily created
|
||||
* for untouched columns.
|
||||
*/
|
||||
nsTreeColumn* mFirstColumn;
|
||||
RefPtr<nsTreeColumn> mFirstColumn;
|
||||
};
|
||||
|
||||
#endif // nsTreeColumns_h__
|
||||
|
||||
@@ -171,7 +171,7 @@ nsTreeContentView::GetRowProperties(int32_t aIndex, nsAString& aProps)
|
||||
if (aIndex < 0 || aIndex >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
nsIContent* realRow;
|
||||
if (row->IsSeparator())
|
||||
realRow = row->mContent;
|
||||
@@ -194,7 +194,7 @@ nsTreeContentView::GetCellProperties(int32_t aRow, nsITreeColumn* aCol,
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
if (realRow) {
|
||||
@@ -323,10 +323,10 @@ nsTreeContentView::HasNextSibling(int32_t aRowIndex, int32_t aAfterIndex, bool*
|
||||
if (parentIndex >= 0) {
|
||||
// Compute the last index in this subtree.
|
||||
int32_t lastIndex = parentIndex + (mRows[parentIndex])->mSubtreeSize;
|
||||
Row* row = mRows[lastIndex];
|
||||
Row* row = mRows[lastIndex].get();
|
||||
while (row->mParentIndex != parentIndex) {
|
||||
lastIndex = row->mParentIndex;
|
||||
row = mRows[lastIndex];
|
||||
row = mRows[lastIndex].get();
|
||||
}
|
||||
|
||||
*_retval = aRowIndex < lastIndex;
|
||||
@@ -346,10 +346,10 @@ nsTreeContentView::GetLevel(int32_t aIndex, int32_t* _retval)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
int32_t level = 0;
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
while (row->mParentIndex >= 0) {
|
||||
level++;
|
||||
row = mRows[row->mParentIndex];
|
||||
row = mRows[row->mParentIndex].get();
|
||||
}
|
||||
*_retval = level;
|
||||
|
||||
@@ -365,7 +365,7 @@ nsTreeContentView::GetImageSrc(int32_t aRow, nsITreeColumn* aCol, nsAString& _re
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -388,7 +388,7 @@ nsTreeContentView::GetProgressMode(int32_t aRow, nsITreeColumn* aCol, int32_t* _
|
||||
|
||||
*_retval = nsITreeView::PROGRESS_NONE;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -417,7 +417,7 @@ nsTreeContentView::GetCellValue(int32_t aRow, nsITreeColumn* aCol, nsAString& _r
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -441,7 +441,7 @@ nsTreeContentView::GetCellText(int32_t aRow, nsITreeColumn* aCol, nsAString& _re
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()) || !aCol)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
// Check for a "label" attribute - this is valid on an <treeitem>
|
||||
// with a single implied column.
|
||||
@@ -512,7 +512,7 @@ nsTreeContentView::ToggleOpenState(int32_t aIndex)
|
||||
|
||||
// We don't serialize content right here, since content might be generated
|
||||
// lazily.
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
|
||||
if (row->IsOpen())
|
||||
row->mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::open, NS_LITERAL_STRING("false"), true);
|
||||
@@ -587,7 +587,7 @@ nsTreeContentView::IsEditable(int32_t aRow, nsITreeColumn* aCol, bool* _retval)
|
||||
|
||||
*_retval = true;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -612,7 +612,7 @@ nsTreeContentView::IsSelectable(int32_t aRow, nsITreeColumn* aCol, bool* _retval
|
||||
|
||||
*_retval = true;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -635,7 +635,7 @@ nsTreeContentView::SetCellValue(int32_t aRow, nsITreeColumn* aCol, const nsAStri
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -656,7 +656,7 @@ nsTreeContentView::SetCellText(int32_t aRow, nsITreeColumn* aCol, const nsAStrin
|
||||
if (aRow < 0 || aRow >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aRow];
|
||||
Row* row = mRows[aRow].get();
|
||||
|
||||
nsIContent* realRow =
|
||||
nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treerow);
|
||||
@@ -695,7 +695,7 @@ nsTreeContentView::GetItemAtIndex(int32_t aIndex, nsIDOMElement** _retval)
|
||||
if (aIndex < 0 || aIndex >= int32_t(mRows.Length()))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
row->mContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)_retval);
|
||||
|
||||
return NS_OK;
|
||||
@@ -796,7 +796,7 @@ nsTreeContentView::AttributeChanged(nsIDocument* aDocument,
|
||||
else if (aElement->IsXULElement(nsGkAtoms::treeitem)) {
|
||||
int32_t index = FindContent(aElement);
|
||||
if (index >= 0) {
|
||||
Row* row = mRows[index];
|
||||
Row* row = mRows[index].get();
|
||||
if (aAttribute == nsGkAtoms::container) {
|
||||
bool isContainer =
|
||||
aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container,
|
||||
@@ -917,7 +917,7 @@ nsTreeContentView::ContentInserted(nsIDocument *aDocument,
|
||||
if (aChild->IsXULElement(nsGkAtoms::treechildren)) {
|
||||
int32_t index = FindContent(aContainer);
|
||||
if (index >= 0) {
|
||||
Row* row = mRows[index];
|
||||
Row* row = mRows[index].get();
|
||||
row->SetEmpty(false);
|
||||
if (mBoxObject)
|
||||
mBoxObject->InvalidateRow(index);
|
||||
@@ -987,7 +987,7 @@ nsTreeContentView::ContentRemoved(nsIDocument *aDocument,
|
||||
if (aChild->IsXULElement(nsGkAtoms::treechildren)) {
|
||||
int32_t index = FindContent(aContainer);
|
||||
if (index >= 0) {
|
||||
Row* row = mRows[index];
|
||||
Row* row = mRows[index].get();
|
||||
row->SetEmpty(true);
|
||||
int32_t count = RemoveSubtree(index);
|
||||
// Invalidate also the row to update twisty.
|
||||
@@ -1033,7 +1033,7 @@ nsTreeContentView::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
// Recursively serialize content, starting with aContent.
|
||||
void
|
||||
nsTreeContentView::Serialize(nsIContent* aContent, int32_t aParentIndex,
|
||||
int32_t* aIndex, nsTArray<nsAutoPtr<Row> >& aRows)
|
||||
int32_t* aIndex, nsTArray<UniquePtr<Row>>& aRows)
|
||||
{
|
||||
// Don't allow non-XUL nodes.
|
||||
if (!aContent->IsXULElement())
|
||||
@@ -1055,14 +1055,14 @@ nsTreeContentView::Serialize(nsIContent* aContent, int32_t aParentIndex,
|
||||
|
||||
void
|
||||
nsTreeContentView::SerializeItem(nsIContent* aContent, int32_t aParentIndex,
|
||||
int32_t* aIndex, nsTArray<nsAutoPtr<Row> >& aRows)
|
||||
int32_t* aIndex, nsTArray<UniquePtr<Row>>& aRows)
|
||||
{
|
||||
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
|
||||
nsGkAtoms::_true, eCaseMatters))
|
||||
return;
|
||||
|
||||
Row* row = new Row(aContent, aParentIndex);
|
||||
aRows.AppendElement(row);
|
||||
aRows.AppendElement(MakeUnique<Row>(aContent, aParentIndex));
|
||||
Row* row = aRows.LastElement().get();
|
||||
|
||||
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container,
|
||||
nsGkAtoms::_true, eCaseMatters)) {
|
||||
@@ -1091,15 +1091,15 @@ nsTreeContentView::SerializeItem(nsIContent* aContent, int32_t aParentIndex,
|
||||
void
|
||||
nsTreeContentView::SerializeSeparator(nsIContent* aContent,
|
||||
int32_t aParentIndex, int32_t* aIndex,
|
||||
nsTArray<nsAutoPtr<Row> >& aRows)
|
||||
nsTArray<UniquePtr<Row>>& aRows)
|
||||
{
|
||||
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
|
||||
nsGkAtoms::_true, eCaseMatters))
|
||||
return;
|
||||
|
||||
Row* row = new Row(aContent, aParentIndex);
|
||||
auto row = MakeUnique<Row>(aContent, aParentIndex);
|
||||
row->SetSeparator(true);
|
||||
aRows.AppendElement(row);
|
||||
aRows.AppendElement(Move(row));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1143,7 +1143,7 @@ nsTreeContentView::GetIndexInSubtree(nsIContent* aContainer,
|
||||
int32_t
|
||||
nsTreeContentView::EnsureSubtree(int32_t aIndex)
|
||||
{
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
|
||||
nsIContent* child;
|
||||
child = nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treechildren);
|
||||
@@ -1151,14 +1151,17 @@ nsTreeContentView::EnsureSubtree(int32_t aIndex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
AutoTArray<nsAutoPtr<Row>, 8> rows;
|
||||
AutoTArray<UniquePtr<Row>, 8> rows;
|
||||
int32_t index = 0;
|
||||
Serialize(child, aIndex, &index, rows);
|
||||
// We can't use InsertElementsAt since the destination can't steal
|
||||
// ownership from its const source argument.
|
||||
// Insert |rows| into |mRows| at position |aIndex|, by first creating empty
|
||||
// UniquePtr entries and then Move'ing |rows|'s entries into them. (Note
|
||||
// that we can't simply use InsertElementsAt with an array argument, since
|
||||
// the destination can't steal ownership from its const source argument.)
|
||||
UniquePtr<Row>* newRows = mRows.InsertElementsAt(aIndex + 1,
|
||||
rows.Length());
|
||||
for (nsTArray<Row>::index_type i = 0; i < rows.Length(); i++) {
|
||||
nsAutoPtr<Row>* newRow = mRows.InsertElementAt(aIndex + i + 1);
|
||||
*newRow = rows[i];
|
||||
newRows[i] = Move(rows[i]);
|
||||
}
|
||||
int32_t count = rows.Length();
|
||||
|
||||
@@ -1175,7 +1178,7 @@ nsTreeContentView::EnsureSubtree(int32_t aIndex)
|
||||
int32_t
|
||||
nsTreeContentView::RemoveSubtree(int32_t aIndex)
|
||||
{
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
int32_t count = row->mSubtreeSize;
|
||||
|
||||
mRows.RemoveElementsAt(aIndex + 1, count);
|
||||
@@ -1226,7 +1229,7 @@ nsTreeContentView::InsertRowFor(nsIContent* aParent, nsIContent* aChild)
|
||||
int32_t
|
||||
nsTreeContentView::InsertRow(int32_t aParentIndex, int32_t aIndex, nsIContent* aContent)
|
||||
{
|
||||
AutoTArray<nsAutoPtr<Row>, 8> rows;
|
||||
AutoTArray<UniquePtr<Row>, 8> rows;
|
||||
if (aContent->IsXULElement(nsGkAtoms::treeitem)) {
|
||||
SerializeItem(aContent, aParentIndex, &aIndex, rows);
|
||||
} else if (aContent->IsXULElement(nsGkAtoms::treeseparator)) {
|
||||
@@ -1235,11 +1238,10 @@ nsTreeContentView::InsertRow(int32_t aParentIndex, int32_t aIndex, nsIContent* a
|
||||
|
||||
// We can't use InsertElementsAt since the destination can't steal
|
||||
// ownership from its const source argument.
|
||||
for (nsTArray<Row>::index_type i = 0; i < rows.Length(); i++) {
|
||||
nsAutoPtr<Row>* newRow = mRows.InsertElementAt(aParentIndex + aIndex + i + 1);
|
||||
*newRow = rows[i];
|
||||
}
|
||||
int32_t count = rows.Length();
|
||||
for (nsTArray<Row>::index_type i = 0; i < size_t(count); i++) {
|
||||
mRows.InsertElementAt(aParentIndex + aIndex + i + 1, Move(rows[i]));
|
||||
}
|
||||
|
||||
UpdateSubtreeSizes(aParentIndex, count);
|
||||
|
||||
@@ -1253,7 +1255,7 @@ nsTreeContentView::InsertRow(int32_t aParentIndex, int32_t aIndex, nsIContent* a
|
||||
int32_t
|
||||
nsTreeContentView::RemoveRow(int32_t aIndex)
|
||||
{
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
int32_t count = row->mSubtreeSize + 1;
|
||||
int32_t parentIndex = row->mParentIndex;
|
||||
|
||||
@@ -1282,7 +1284,7 @@ nsTreeContentView::ClearRows()
|
||||
void
|
||||
nsTreeContentView::OpenContainer(int32_t aIndex)
|
||||
{
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
row->SetOpen(true);
|
||||
|
||||
int32_t count = EnsureSubtree(aIndex);
|
||||
@@ -1295,7 +1297,7 @@ nsTreeContentView::OpenContainer(int32_t aIndex)
|
||||
void
|
||||
nsTreeContentView::CloseContainer(int32_t aIndex)
|
||||
{
|
||||
Row* row = mRows[aIndex];
|
||||
Row* row = mRows[aIndex].get();
|
||||
row->SetOpen(false);
|
||||
|
||||
int32_t count = RemoveSubtree(aIndex);
|
||||
@@ -1321,7 +1323,7 @@ void
|
||||
nsTreeContentView::UpdateSubtreeSizes(int32_t aParentIndex, int32_t count)
|
||||
{
|
||||
while (aParentIndex >= 0) {
|
||||
Row* row = mRows[aParentIndex];
|
||||
Row* row = mRows[aParentIndex].get();
|
||||
row->mSubtreeSize += count;
|
||||
aParentIndex = row->mParentIndex;
|
||||
}
|
||||
@@ -1332,7 +1334,7 @@ nsTreeContentView::UpdateParentIndexes(int32_t aIndex, int32_t aSkip, int32_t aC
|
||||
{
|
||||
int32_t count = mRows.Length();
|
||||
for (int32_t i = aIndex + aSkip; i < count; i++) {
|
||||
Row* row = mRows[i];
|
||||
Row* row = mRows[i].get();
|
||||
if (row->mParentIndex > aIndex) {
|
||||
row->mParentIndex += aCount;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "nsITreeContentView.h"
|
||||
#include "nsITreeSelection.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
class nsIDocument;
|
||||
class Row;
|
||||
@@ -53,13 +54,13 @@ class nsTreeContentView final : public nsINativeTreeView,
|
||||
|
||||
// Recursive methods which deal with serializing of nested content.
|
||||
void Serialize(nsIContent* aContent, int32_t aParentIndex, int32_t* aIndex,
|
||||
nsTArray<nsAutoPtr<Row> >& aRows);
|
||||
nsTArray<mozilla::UniquePtr<Row>>& aRows);
|
||||
|
||||
void SerializeItem(nsIContent* aContent, int32_t aParentIndex,
|
||||
int32_t* aIndex, nsTArray<nsAutoPtr<Row> >& aRows);
|
||||
int32_t* aIndex, nsTArray<mozilla::UniquePtr<Row>>& aRows);
|
||||
|
||||
void SerializeSeparator(nsIContent* aContent, int32_t aParentIndex,
|
||||
int32_t* aIndex, nsTArray<nsAutoPtr<Row> >& aRows);
|
||||
int32_t* aIndex, nsTArray<mozilla::UniquePtr<Row>>& aRows);
|
||||
|
||||
void GetIndexInSubtree(nsIContent* aContainer, nsIContent* aContent, int32_t* aResult);
|
||||
|
||||
@@ -95,7 +96,7 @@ class nsTreeContentView final : public nsINativeTreeView,
|
||||
nsCOMPtr<nsIContent> mRoot;
|
||||
nsCOMPtr<nsIContent> mBody;
|
||||
nsIDocument* mDocument; // WEAK
|
||||
nsTArray<nsAutoPtr<Row> > mRows;
|
||||
nsTArray<mozilla::UniquePtr<Row>> mRows;
|
||||
};
|
||||
|
||||
#endif // nsTreeContentView_h__
|
||||
|
||||
+116
-43
@@ -562,9 +562,6 @@ pref("media.video-queue.send-to-compositor-size", 9999);
|
||||
// Whether to disable the video stats to prevent fingerprinting
|
||||
pref("media.video_stats.enabled", true);
|
||||
|
||||
// Whether to enable the audio writing APIs on the audio element
|
||||
pref("media.audio_data.enabled", false);
|
||||
|
||||
// Weather we allow AMD switchable graphics
|
||||
pref("layers.amd-switchable-gfx.enabled", true);
|
||||
|
||||
@@ -637,10 +634,10 @@ pref("apz.touch_start_tolerance", "0.2222222"); // 0.2222222 came from 1.0/4.5
|
||||
pref("apz.touch_move_tolerance", "0.0");
|
||||
pref("apz.velocity_bias", "1.0");
|
||||
pref("apz.velocity_relevance_time_ms", 150);
|
||||
pref("apz.x_stationary_size_multiplier", "3.0");
|
||||
pref("apz.y_stationary_size_multiplier", "3.5");
|
||||
pref("apz.x_skate_highmem_adjust", "0.0");
|
||||
pref("apz.y_skate_highmem_adjust", "0.0");
|
||||
pref("apz.x_stationary_size_multiplier", "3.0");
|
||||
pref("apz.y_stationary_size_multiplier", "3.5");
|
||||
pref("apz.zoom_animation_duration_ms", 250);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
@@ -665,8 +662,7 @@ pref("gfx.hidpi.enabled", 2);
|
||||
#endif
|
||||
|
||||
#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
|
||||
// Containerless scrolling for root frames does not yet pass tests on Android
|
||||
// or B2G.
|
||||
// Use containerless scrolling for now on desktop.
|
||||
pref("layout.scroll.root-frame-containers", false);
|
||||
#endif
|
||||
|
||||
@@ -910,6 +906,7 @@ sticky_pref("devtools.chrome.enabled", false);
|
||||
// Disable remote debugging protocol logging
|
||||
pref("devtools.debugger.log", false);
|
||||
pref("devtools.debugger.log.verbose", false);
|
||||
|
||||
// Disable remote debugging connections
|
||||
#ifdef MOZ_DEV_EDITION
|
||||
sticky_pref("devtools.debugger.remote-enabled", true);
|
||||
@@ -1252,6 +1249,9 @@ pref("nglayout.debug.paint_flashing_chrome", false);
|
||||
// BasicLayers (other layer managers always update the entire widget area)
|
||||
pref("nglayout.debug.widget_update_flashing", false);
|
||||
|
||||
// Enable/disable display list invalidation logging --- useful for debugging.
|
||||
pref("nglayout.debug.invalidation", false);
|
||||
|
||||
// Whether frame visibility tracking is enabled globally.
|
||||
pref("layout.framevisibility.enabled", true);
|
||||
|
||||
@@ -1327,7 +1327,7 @@ pref("print.print_edge_right", 0);
|
||||
pref("print.print_edge_bottom", 0);
|
||||
|
||||
// Print via the parent process. This is only used when e10s is enabled.
|
||||
#if defined(XP_WIN)
|
||||
#if defined(XP_WIN) && defined(NIGHTLY_BUILD)
|
||||
pref("print.print_via_parent", true);
|
||||
#else
|
||||
pref("print.print_via_parent", false);
|
||||
@@ -1338,9 +1338,6 @@ pref("print.print_via_parent", false);
|
||||
// in a document.
|
||||
pref("extensions.spellcheck.inline.max-misspellings", 500);
|
||||
|
||||
// Predefined convenience pref for overriding the dictionary
|
||||
pref("spellchecker.dictionary.override", "");
|
||||
|
||||
// Prefs used by libeditor. Prefs specific to seamonkey composer
|
||||
// belong in comm-central/editor/ui/composer.js
|
||||
|
||||
@@ -1404,6 +1401,10 @@ pref("dom.forms.autocomplete.experimental", false);
|
||||
// Enables requestAutocomplete DOM API on forms.
|
||||
pref("dom.forms.requestAutocomplete", false);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("dom.input.dirpicker", true);
|
||||
#endif
|
||||
|
||||
// Enables system messages and activities
|
||||
pref("dom.sysmsg.enabled", false);
|
||||
|
||||
@@ -1500,15 +1501,15 @@ pref("javascript.options.mem.gc_max_empty_chunk_count", 30);
|
||||
|
||||
pref("javascript.options.showInConsole", false);
|
||||
|
||||
pref("javascript.options.throw_on_debuggee_would_run", false);
|
||||
pref("javascript.options.dump_stack_on_debuggee_would_run", false);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("javascript.options.shared_memory", true);
|
||||
#else
|
||||
pref("javascript.options.shared_memory", false);
|
||||
#endif
|
||||
|
||||
pref("javascript.options.throw_on_debuggee_would_run", false);
|
||||
pref("javascript.options.dump_stack_on_debuggee_would_run", false);
|
||||
|
||||
// advanced prefs
|
||||
pref("advanced.mailftp", false);
|
||||
pref("image.animation_mode", "normal");
|
||||
@@ -2200,7 +2201,6 @@ pref("network.cookie.cookieBehavior", 0); // Keep the old default of accep
|
||||
#endif
|
||||
pref("network.cookie.thirdparty.sessionOnly", false);
|
||||
pref("network.cookie.lifetimePolicy", 0); // 0-accept, 2-acceptForSession, 3-acceptForNDays
|
||||
pref("network.cookie.alwaysAcceptSessionCookies", false);
|
||||
pref("network.cookie.prefsMigrated", false);
|
||||
pref("network.cookie.lifetime.days", 90);
|
||||
|
||||
@@ -2632,9 +2632,6 @@ pref("layout.css.isolation.enabled", true);
|
||||
// Is support for CSS Filters enabled?
|
||||
pref("layout.css.filters.enabled", true);
|
||||
|
||||
// Is support for scroll-snap enabled?
|
||||
pref("layout.css.scroll-snap.enabled", false);
|
||||
|
||||
// Set the threshold distance in CSS pixels below which scrolling will snap to
|
||||
// an edge, when scroll snapping is set to "proximity".
|
||||
pref("layout.css.scroll-snap.proximity-threshold", 200);
|
||||
@@ -2805,6 +2802,9 @@ pref("layout.css.scroll-behavior.spring-constant", "250.0");
|
||||
// at the greatest speed without overshooting.
|
||||
pref("layout.css.scroll-behavior.damping-ratio", "1.0");
|
||||
|
||||
// Is support for scroll-snap enabled?
|
||||
pref("layout.css.scroll-snap.enabled", true);
|
||||
|
||||
// Is support for document.fonts enabled?
|
||||
//
|
||||
// Don't enable the pref for the CSS Font Loading API until bug 1072101 is
|
||||
@@ -2893,7 +2893,6 @@ pref("editor.positioning.offset", 0);
|
||||
|
||||
pref("dom.use_watchdog", true);
|
||||
pref("dom.max_chrome_script_run_time", 20);
|
||||
pref("dom.max_child_script_run_time", 10);
|
||||
pref("dom.max_script_run_time", 10);
|
||||
|
||||
// Stop all scripts in a compartment when the "Stop script" button on the
|
||||
@@ -3931,22 +3930,22 @@ pref("font.name.serif.zh-CN", "Times");
|
||||
pref("font.name.sans-serif.zh-CN", "Helvetica");
|
||||
pref("font.name.monospace.zh-CN", "Courier");
|
||||
pref("font.name-list.serif.zh-CN", "Times,STSong,Heiti SC");
|
||||
pref("font.name-list.sans-serif.zh-CN", "Helvetica,STHeiti,Heiti SC");
|
||||
pref("font.name-list.monospace.zh-CN", "Courier,STHeiti,Heiti SC");
|
||||
pref("font.name-list.sans-serif.zh-CN", "Helvetica,PingFang SC,STHeiti,Heiti SC");
|
||||
pref("font.name-list.monospace.zh-CN", "Courier,PingFang SC,STHeiti,Heiti SC");
|
||||
|
||||
pref("font.name.serif.zh-TW", "Times");
|
||||
pref("font.name.sans-serif.zh-TW", "Helvetica");
|
||||
pref("font.name.monospace.zh-TW", "Courier");
|
||||
pref("font.name-list.serif.zh-TW", "Times,LiSong Pro,Heiti TC");
|
||||
pref("font.name-list.sans-serif.zh-TW", "Helvetica,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.monospace.zh-TW", "Courier,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.sans-serif.zh-TW", "Helvetica,PingFang TC,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.monospace.zh-TW", "Courier,PingFang TC,Heiti TC,LiHei Pro");
|
||||
|
||||
pref("font.name.serif.zh-HK", "Times");
|
||||
pref("font.name.sans-serif.zh-HK", "Helvetica");
|
||||
pref("font.name.monospace.zh-HK", "Courier");
|
||||
pref("font.name-list.serif.zh-HK", "Times,LiSong Pro,Heiti TC");
|
||||
pref("font.name-list.sans-serif.zh-HK", "Helvetica,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.monospace.zh-HK", "Courier,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.sans-serif.zh-HK", "Helvetica,PingFang TC,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.monospace.zh-HK", "Courier,PingFang TC,Heiti TC,LiHei Pro");
|
||||
|
||||
// XP_MACOSX changes to default font sizes
|
||||
pref("font.minimum-size.th", 10);
|
||||
@@ -4065,12 +4064,16 @@ pref("print.print_paper_size", 0);
|
||||
// around the content of the page for Print Preview only
|
||||
pref("print.print_extra_margin", 0); // twips
|
||||
|
||||
// CSSOM-View scroll-behavior smooth scrolling requires the C++ APZC
|
||||
// CSSOM-View scroll-behavior smooth scrolling and scroll snap requires the C++ APZC
|
||||
#ifdef MOZ_ANDROID_APZ
|
||||
pref("layout.css.scroll-behavior.enabled", true);
|
||||
pref("layout.css.scroll-behavior.property-enabled", true);
|
||||
pref("layout.css.scroll-snap.enabled", true);
|
||||
#else
|
||||
pref("layout.css.scroll-behavior.enabled", false);
|
||||
pref("layout.css.scroll-behavior.property-enabled", false);
|
||||
|
||||
// CSS Scroll Snapping requires the C++ APZC
|
||||
pref("layout.css.scroll-snap.enabled", false);
|
||||
#endif
|
||||
|
||||
/* PostScript print module prefs */
|
||||
// pref("print.postscript.enabled", true);
|
||||
@@ -4161,14 +4164,78 @@ pref("font.name.monospace.ko", "monospace");
|
||||
|
||||
pref("font.name.serif.th", "serif");
|
||||
pref("font.name.sans-serif.th", "sans-serif");
|
||||
pref("font.minimum-size.th", 13);
|
||||
pref("font.name.monospace.th", "monospace");
|
||||
pref("font.minimum-size.th", 13);
|
||||
|
||||
pref("font.name.serif.x-armn", "serif");
|
||||
pref("font.name.sans-serif.x-armn", "sans-serif");
|
||||
pref("font.name.monospace.x-armn", "monospace");
|
||||
|
||||
pref("font.name.serif.x-beng", "serif");
|
||||
pref("font.name.sans-serif.x-beng", "sans-serif");
|
||||
pref("font.name.monospace.x-beng", "monospace");
|
||||
|
||||
pref("font.name.serif.x-cans", "serif");
|
||||
pref("font.name.sans-serif.x-cans", "sans-serif");
|
||||
pref("font.name.monospace.x-cans", "monospace");
|
||||
|
||||
pref("font.name.serif.x-cyrillic", "serif");
|
||||
pref("font.name.sans-serif.x-cyrillic", "sans-serif");
|
||||
pref("font.name.monospace.x-cyrillic", "monospace");
|
||||
pref("font.size.fixed.x-cyrillic", 12);
|
||||
|
||||
pref("font.name.serif.x-devanagari", "serif");
|
||||
pref("font.name.sans-serif.x-devanagari", "sans-serif");
|
||||
pref("font.name.monospace.x-devanagari", "monospace");
|
||||
|
||||
pref("font.name.serif.x-ethi", "serif");
|
||||
pref("font.name.sans-serif.x-ethi", "sans-serif");
|
||||
pref("font.name.monospace.x-ethi", "monospace");
|
||||
|
||||
pref("font.name.serif.x-geor", "serif");
|
||||
pref("font.name.sans-serif.x-geor", "sans-serif");
|
||||
pref("font.name.monospace.x-geor", "monospace");
|
||||
|
||||
pref("font.name.serif.x-gujr", "serif");
|
||||
pref("font.name.sans-serif.x-gujr", "sans-serif");
|
||||
pref("font.name.monospace.x-gujr", "monospace");
|
||||
|
||||
pref("font.name.serif.x-guru", "serif");
|
||||
pref("font.name.sans-serif.x-guru", "sans-serif");
|
||||
pref("font.name.monospace.x-guru", "monospace");
|
||||
|
||||
pref("font.name.serif.x-khmr", "serif");
|
||||
pref("font.name.sans-serif.x-khmr", "sans-serif");
|
||||
pref("font.name.monospace.x-khmr", "monospace");
|
||||
|
||||
pref("font.name.serif.x-knda", "serif");
|
||||
pref("font.name.sans-serif.x-knda", "sans-serif");
|
||||
pref("font.name.monospace.x-knda", "monospace");
|
||||
|
||||
pref("font.name.serif.x-mlym", "serif");
|
||||
pref("font.name.sans-serif.x-mlym", "sans-serif");
|
||||
pref("font.name.monospace.x-mlym", "monospace");
|
||||
|
||||
pref("font.name.serif.x-orya", "serif");
|
||||
pref("font.name.sans-serif.x-orya", "sans-serif");
|
||||
pref("font.name.monospace.x-orya", "monospace");
|
||||
|
||||
pref("font.name.serif.x-sinh", "serif");
|
||||
pref("font.name.sans-serif.x-sinh", "sans-serif");
|
||||
pref("font.name.monospace.x-sinh", "monospace");
|
||||
|
||||
pref("font.name.serif.x-tamil", "serif");
|
||||
pref("font.name.sans-serif.x-tamil", "sans-serif");
|
||||
pref("font.name.monospace.x-tamil", "monospace");
|
||||
|
||||
pref("font.name.serif.x-telu", "serif");
|
||||
pref("font.name.sans-serif.x-telu", "sans-serif");
|
||||
pref("font.name.monospace.x-telu", "monospace");
|
||||
|
||||
pref("font.name.serif.x-tibt", "serif");
|
||||
pref("font.name.sans-serif.x-tibt", "sans-serif");
|
||||
pref("font.name.monospace.x-tibt", "monospace");
|
||||
|
||||
pref("font.name.serif.x-unicode", "serif");
|
||||
pref("font.name.sans-serif.x-unicode", "sans-serif");
|
||||
pref("font.name.monospace.x-unicode", "monospace");
|
||||
@@ -4183,8 +4250,6 @@ pref("font.name.serif.zh-CN", "serif");
|
||||
pref("font.name.sans-serif.zh-CN", "sans-serif");
|
||||
pref("font.name.monospace.zh-CN", "monospace");
|
||||
|
||||
// ming_uni.ttf (HKSCS-2001)
|
||||
// http://www.info.gov.hk/digital21/eng/hkscs/download/uime.exe
|
||||
pref("font.name.serif.zh-HK", "serif");
|
||||
pref("font.name.sans-serif.zh-HK", "sans-serif");
|
||||
pref("font.name.monospace.zh-HK", "monospace");
|
||||
@@ -4329,68 +4394,70 @@ pref("font.name.monospace.x-math", "Fira Mono");
|
||||
pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
|
||||
pref("font.name.sans-serif.el", "Clear Sans");
|
||||
pref("font.name.monospace.el", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.el", "Noto Serif");
|
||||
pref("font.name-list.sans-serif.el", "Clear Sans, Roboto, Droid Sans");
|
||||
|
||||
pref("font.name.serif.he", "Droid Serif");
|
||||
pref("font.name.sans-serif.he", "Clear Sans");
|
||||
pref("font.name.monospace.he", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.he", "Noto Serif");
|
||||
pref("font.name-list.sans-serif.he", "Droid Sans Hebrew, Clear Sans, Droid Sans");
|
||||
|
||||
pref("font.name.serif.ja", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.ja", "Clear Sans");
|
||||
pref("font.name.monospace.ja", "MotoyaLMaru");
|
||||
pref("font.name-list.serif.ja", "Droid Serif");
|
||||
pref("font.name-list.serif.ja", "Noto Serif, Droid Serif");
|
||||
pref("font.name-list.sans-serif.ja", "Clear Sans, Roboto, Droid Sans, MotoyaLMaru, MotoyaLCedar, Noto Sans JP, Droid Sans Japanese");
|
||||
pref("font.name-list.monospace.ja", "MotoyaLMaru, MotoyaLCedar, Droid Sans Mono");
|
||||
|
||||
pref("font.name.serif.ko", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.ko", "Clear Sans");
|
||||
pref("font.name.monospace.ko", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.ko", "Droid Serif, HYSerif");
|
||||
pref("font.name-list.serif.ko", "Noto Serif, Droid Serif, HYSerif");
|
||||
pref("font.name-list.sans-serif.ko", "SmartGothic, NanumGothic, Noto Sans KR, DroidSansFallback, Droid Sans Fallback");
|
||||
|
||||
pref("font.name.serif.th", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.th", "Clear Sans");
|
||||
pref("font.name.monospace.th", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.th", "Droid Serif");
|
||||
pref("font.name-list.serif.th", "Noto Serif, Droid Serif");
|
||||
pref("font.name-list.sans-serif.th", "Droid Sans Thai, Clear Sans, Droid Sans");
|
||||
|
||||
pref("font.name.serif.x-cyrillic", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.x-cyrillic", "Clear Sans");
|
||||
pref("font.name.monospace.x-cyrillic", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.x-cyrillic", "Droid Serif");
|
||||
pref("font.name-list.serif.x-cyrillic", "Noto Serif, Droid Serif");
|
||||
pref("font.name-list.sans-serif.x-cyrillic", "Clear Sans, Roboto, Droid Sans");
|
||||
|
||||
pref("font.name.serif.x-unicode", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.x-unicode", "Clear Sans");
|
||||
pref("font.name.monospace.x-unicode", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.x-unicode", "Droid Serif");
|
||||
pref("font.name-list.serif.x-unicode", "Noto Serif, Droid Serif");
|
||||
pref("font.name-list.sans-serif.x-unicode", "Clear Sans, Roboto, Droid Sans");
|
||||
|
||||
pref("font.name.serif.x-western", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.x-western", "Clear Sans");
|
||||
pref("font.name.monospace.x-western", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.x-western", "Droid Serif");
|
||||
pref("font.name-list.serif.x-western", "Noto Serif, Droid Serif");
|
||||
pref("font.name-list.sans-serif.x-western", "Clear Sans, Roboto, Droid Sans");
|
||||
|
||||
pref("font.name.serif.zh-CN", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.zh-CN", "Clear Sans");
|
||||
pref("font.name.monospace.zh-CN", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.zh-CN", "Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.serif.zh-CN", "Noto Serif, Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.sans-serif.zh-CN", "Roboto, Droid Sans, Noto Sans SC, Droid Sans Fallback");
|
||||
pref("font.name-list.monospace.zh-CN", "Droid Sans Fallback");
|
||||
|
||||
pref("font.name.serif.zh-HK", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.zh-HK", "Clear Sans");
|
||||
pref("font.name.monospace.zh-HK", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.zh-HK", "Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.serif.zh-HK", "Noto Serif, Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.sans-serif.zh-HK", "Roboto, Droid Sans, Noto Sans TC, Noto Sans SC, Droid Sans Fallback");
|
||||
pref("font.name-list.monospace.zh-HK", "Droid Sans Fallback");
|
||||
|
||||
pref("font.name.serif.zh-TW", "Charis SIL Compact");
|
||||
pref("font.name.sans-serif.zh-TW", "Clear Sans");
|
||||
pref("font.name.monospace.zh-TW", "Droid Sans Mono");
|
||||
pref("font.name-list.serif.zh-TW", "Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.serif.zh-TW", "Noto Serif, Droid Serif, Droid Sans Fallback");
|
||||
pref("font.name-list.sans-serif.zh-TW", "Roboto, Droid Sans, Noto Sans TC, Noto Sans SC, Droid Sans Fallback");
|
||||
pref("font.name-list.monospace.zh-TW", "Droid Sans Fallback");
|
||||
|
||||
@@ -5275,16 +5342,21 @@ pref("layout.accessiblecaret.timeout_ms", 3000);
|
||||
// or long tap events does not fired by APZ.
|
||||
pref("layout.accessiblecaret.use_long_tap_injector", true);
|
||||
|
||||
// Use AccessibleCaret default behaviours.
|
||||
pref("layout.accessiblecaret.extendedvisibility", false);
|
||||
|
||||
// By default, carets become tilt only when they are overlapping.
|
||||
pref("layout.accessiblecaret.always_tilt", false);
|
||||
|
||||
// By default, carets always show when scrolling (either panning for zooming)
|
||||
// the page.
|
||||
pref("layout.accessiblecaret.always_show_when_scrolling", true);
|
||||
|
||||
// Selection change notifications generated by Javascript hide
|
||||
// AccessibleCarets and close UI interaction by default.
|
||||
pref("layout.accessiblecaret.allow_script_change_updates", false);
|
||||
|
||||
// Allow one caret to be dragged across the other caret without any limitation.
|
||||
// This matches the built-in convention for all desktop platforms.
|
||||
pref("layout.accessiblecaret.allow_dragging_across_other_caret", true);
|
||||
|
||||
// Optionally provide haptic feedback on longPress selection events.
|
||||
pref("layout.accessiblecaret.hapticfeedback", false);
|
||||
|
||||
@@ -5338,6 +5410,7 @@ pref("dom.presentation.tcp_server.debug", false);
|
||||
pref("dom.presentation.discovery.enabled", false);
|
||||
pref("dom.presentation.discovery.timeout_ms", 10000);
|
||||
pref("dom.presentation.discoverable", false);
|
||||
pref("dom.presentation.session_transport.data_channel.enable", false);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Use raw ICU instead of CoreServices API in Unicode collation
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "nsAutodialWin.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#define AUTODIAL_DEFAULT AUTODIAL_NEVER
|
||||
|
||||
@@ -187,6 +188,9 @@ int nsAutodial::QueryAutodialBehavior()
|
||||
}
|
||||
}
|
||||
|
||||
// only do telemetry once per session
|
||||
static bool reportedAutoDial = false;
|
||||
|
||||
// If the RAS autodial service is running, use it. Otherwise, dial
|
||||
// the default RAS connection. There are two possible RAS dialogs:
|
||||
// one that dials a single entry, and one that lets the user choose which
|
||||
@@ -267,6 +271,10 @@ nsresult nsAutodial::DialDefault(const char16_t* hostName)
|
||||
return NS_ERROR_FAILURE; // don't retry
|
||||
}
|
||||
|
||||
if (!reportedAutoDial) {
|
||||
reportedAutoDial = true;
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::NETWORK_AUTODIAL, true);
|
||||
}
|
||||
LOGD(("Autodial: RAS dialup connection successful."));
|
||||
}
|
||||
|
||||
@@ -298,6 +306,10 @@ nsresult nsAutodial::DialDefault(const char16_t* hostName)
|
||||
return NS_ERROR_FAILURE; // don't retry
|
||||
}
|
||||
|
||||
if (!reportedAutoDial) {
|
||||
reportedAutoDial = true;
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::NETWORK_AUTODIAL, true);
|
||||
}
|
||||
LOGD(("Autodial: RAS dialup connection successful."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "nsChannelClassifier.h"
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICacheEntry.h"
|
||||
#include "nsICachingChannel.h"
|
||||
@@ -315,6 +316,18 @@ nsChannelClassifier::StartInternal()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// Skip whitelisted hostnames.
|
||||
nsAutoCString whitelisted;
|
||||
Preferences::GetCString("urlclassifier.skipHostnames", &whitelisted);
|
||||
if (!whitelisted.IsEmpty()) {
|
||||
ToLowerCase(whitelisted);
|
||||
LOG(("nsChannelClassifier[%p]:StartInternal whitelisted hostnames = %s",
|
||||
this, whitelisted.get()));
|
||||
if (IsHostnameWhitelisted(uri, whitelisted)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
||||
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
||||
if (rv == NS_ERROR_FACTORY_NOT_REGISTERED ||
|
||||
@@ -374,6 +387,30 @@ nsChannelClassifier::StartInternal()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsChannelClassifier::IsHostnameWhitelisted(nsIURI *aUri,
|
||||
const nsACString &aWhitelisted)
|
||||
{
|
||||
nsAutoCString host;
|
||||
nsresult rv = aUri->GetHost(host);
|
||||
if (NS_FAILED(rv) || host.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
ToLowerCase(host);
|
||||
|
||||
nsCCharSeparatedTokenizer tokenizer(aWhitelisted, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsCSubstring& token = tokenizer.nextToken();
|
||||
if (token.Equals(host)) {
|
||||
LOG(("nsChannelClassifier[%p]:StartInternal skipping %s (whitelisted)",
|
||||
this, host.get()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note in the cache entry that this URL was classified, so that future
|
||||
// cached loads don't need to be checked.
|
||||
void
|
||||
@@ -387,6 +424,17 @@ nsChannelClassifier::MarkEntryClassified(nsresult status)
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString errorName;
|
||||
mozilla::GetErrorName(status, errorName);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
nsAutoCString spec;
|
||||
uri->GetAsciiSpec(spec);
|
||||
LOG(("nsChannelClassifier::MarkEntryClassified[%s] %s",
|
||||
errorName.get(), spec.get()));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(mChannel);
|
||||
if (!cachingChannel) {
|
||||
return;
|
||||
|
||||
@@ -44,6 +44,8 @@ private:
|
||||
nsresult StartInternal();
|
||||
// Helper function to check a tracking URI against the whitelist
|
||||
nsresult IsTrackerWhitelisted();
|
||||
// Helper function to check a URI against the hostname whitelist
|
||||
bool IsHostnameWhitelisted(nsIURI *aUri, const nsACString &aWhitelisted);
|
||||
// Checks that the channel was loaded by the URI currently loaded in aDoc
|
||||
static bool SameLoadingURI(nsIDocument *aDoc, nsIChannel *aChannel);
|
||||
|
||||
|
||||
@@ -323,6 +323,8 @@ nsFileStreamBase::MaybeOpen(nsIFile* aFile, int32_t aIoFlags,
|
||||
|
||||
mOpenParams.localFile = aFile;
|
||||
|
||||
// Following call open() at main thread.
|
||||
// Main thread might be blocked, while open a remote file.
|
||||
return DoOpen();
|
||||
}
|
||||
|
||||
@@ -432,19 +434,23 @@ nsFileInputStream::Open(nsIFile* aFile, int32_t aIOFlags, int32_t aPerm)
|
||||
|
||||
rv = MaybeOpen(aFile, aIOFlags, aPerm,
|
||||
mBehaviorFlags & nsIFileInputStream::DEFER_OPEN);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mBehaviorFlags & DELETE_ON_CLOSE) {
|
||||
// POSIX compatible filesystems allow a file to be unlinked while a
|
||||
// file descriptor is still referencing the file. since we've already
|
||||
// opened the file descriptor, we'll try to remove the file. if that
|
||||
// fails, then we'll just remember the nsIFile and remove it after we
|
||||
// close the file descriptor.
|
||||
rv = aFile->Remove(false);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// No need to remove it later. Clear the flag.
|
||||
mBehaviorFlags &= ~DELETE_ON_CLOSE;
|
||||
}
|
||||
// if defer open is set, do not remove the file here.
|
||||
// remove the file while Close() is called.
|
||||
if ((mBehaviorFlags & DELETE_ON_CLOSE) &&
|
||||
!(mBehaviorFlags & nsIFileInputStream::DEFER_OPEN)) {
|
||||
// POSIX compatible filesystems allow a file to be unlinked while a
|
||||
// file descriptor is still referencing the file. since we've already
|
||||
// opened the file descriptor, we'll try to remove the file. if that
|
||||
// fails, then we'll just remember the nsIFile and remove it after we
|
||||
// close the file descriptor.
|
||||
rv = aFile->Remove(false);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// No need to remove it later. Clear the flag.
|
||||
mBehaviorFlags &= ~DELETE_ON_CLOSE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -514,9 +520,6 @@ nsFileInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* _retval)
|
||||
NS_IMETHODIMP
|
||||
nsFileInputStream::ReadLine(nsACString& aLine, bool* aResult)
|
||||
{
|
||||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mLineBuffer) {
|
||||
mLineBuffer = new nsLineBuffer<char>;
|
||||
}
|
||||
@@ -525,11 +528,19 @@ nsFileInputStream::ReadLine(nsACString& aLine, bool* aResult)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
{
|
||||
return SeekInternal(aWhence, aOffset);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFileInputStream::SeekInternal(int32_t aWhence, int64_t aOffset, bool aClearBuf)
|
||||
{
|
||||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mLineBuffer = nullptr;
|
||||
if (aClearBuf) {
|
||||
mLineBuffer = nullptr;
|
||||
}
|
||||
if (!mFD) {
|
||||
if (mBehaviorFlags & REOPEN_ON_REWIND) {
|
||||
rv = Open(mFile, mIOFlags, mPerm);
|
||||
@@ -699,19 +710,28 @@ nsPartialFileInputStream::Init(nsIFile* aFile, uint64_t aStart,
|
||||
|
||||
nsresult rv = nsFileInputStream::Init(aFile, aIOFlags, aPerm,
|
||||
aBehaviorFlags);
|
||||
|
||||
// aFile is a partial file, it must exist.
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return nsFileInputStream::Seek(NS_SEEK_SET, mStart);
|
||||
mDeferredSeek = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPartialFileInputStream::Tell(int64_t *aResult)
|
||||
{
|
||||
int64_t tell = 0;
|
||||
nsresult rv = nsFileInputStream::Tell(&tell);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = tell - mStart;
|
||||
}
|
||||
|
||||
nsresult rv = DoPendingSeek();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsFileInputStream::Tell(&tell);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
*aResult = tell - mStart;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -719,16 +739,23 @@ NS_IMETHODIMP
|
||||
nsPartialFileInputStream::Available(uint64_t* aResult)
|
||||
{
|
||||
uint64_t available = 0;
|
||||
nsresult rv = nsFileInputStream::Available(&available);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = TruncateSize(available);
|
||||
}
|
||||
|
||||
nsresult rv = DoPendingSeek();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsFileInputStream::Available(&available);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aResult = TruncateSize(available);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPartialFileInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
nsresult rv = DoPendingSeek();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t readsize = (uint32_t) TruncateSize(aCount);
|
||||
if (readsize == 0 && mBehaviorFlags & CLOSE_ON_EOF) {
|
||||
Close();
|
||||
@@ -736,16 +763,19 @@ nsPartialFileInputStream::Read(char* aBuf, uint32_t aCount, uint32_t* aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = nsFileInputStream::Read(aBuf, readsize, aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPosition += readsize;
|
||||
}
|
||||
rv = nsFileInputStream::Read(aBuf, readsize, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPosition += readsize;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPartialFileInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
{
|
||||
nsresult rv = DoPendingSeek();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
int64_t offset;
|
||||
switch (aWhence) {
|
||||
case NS_SEEK_SET:
|
||||
@@ -765,10 +795,10 @@ nsPartialFileInputStream::Seek(int32_t aWhence, int64_t aOffset)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv = nsFileInputStream::Seek(NS_SEEK_SET, offset);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPosition = offset - mStart;
|
||||
}
|
||||
rv = nsFileInputStream::Seek(NS_SEEK_SET, offset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPosition = offset - mStart;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -828,6 +858,19 @@ nsPartialFileInputStream::Deserialize(
|
||||
return NS_SUCCEEDED(nsFileInputStream::Seek(NS_SEEK_SET, mStart));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPartialFileInputStream::DoPendingSeek()
|
||||
{
|
||||
if (!mDeferredSeek) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDeferredSeek = false;
|
||||
|
||||
// This is the first time to open the file, don't clear mLinebuffer.
|
||||
// mLineBuffer might be already initialized by ReadLine().
|
||||
return nsFileInputStream::SeekInternal(NS_SEEK_SET, mStart, false);
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileOutputStream
|
||||
|
||||
|
||||
@@ -143,6 +143,8 @@ protected:
|
||||
Close();
|
||||
}
|
||||
|
||||
nsresult SeekInternal(int32_t aWhence, int64_t aOffset, bool aClearBuf=true);
|
||||
|
||||
nsAutoPtr<nsLineBuffer<char> > mLineBuffer;
|
||||
|
||||
/**
|
||||
@@ -184,7 +186,7 @@ public:
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
nsPartialFileInputStream()
|
||||
: mStart(0), mLength(0), mPosition(0)
|
||||
: mStart(0), mLength(0), mPosition(0), mDeferredSeek(false)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Tell(int64_t *aResult) override;
|
||||
@@ -199,6 +201,8 @@ protected:
|
||||
~nsPartialFileInputStream()
|
||||
{ }
|
||||
|
||||
inline nsresult DoPendingSeek();
|
||||
|
||||
private:
|
||||
uint64_t TruncateSize(uint64_t aSize) {
|
||||
return std::min<uint64_t>(mLength - mPosition, aSize);
|
||||
@@ -207,6 +211,7 @@ private:
|
||||
uint64_t mStart;
|
||||
uint64_t mLength;
|
||||
uint64_t mPosition;
|
||||
bool mDeferredSeek;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -39,4 +39,9 @@ interface nsIMIMEInputStream : nsIInputStream
|
||||
* @param stream stream containing the data for the stream
|
||||
*/
|
||||
void setData(in nsIInputStream stream);
|
||||
|
||||
/**
|
||||
* Get the wrapped data stream
|
||||
*/
|
||||
readonly attribute nsIInputStream data;
|
||||
};
|
||||
|
||||
@@ -1012,9 +1012,6 @@ nsIOService::SetOffline(bool offline)
|
||||
NS_IOSERVICE_GOING_OFFLINE_TOPIC,
|
||||
offlineString.get());
|
||||
|
||||
if (mDNSService)
|
||||
mDNSService->SetOffline(true);
|
||||
|
||||
if (mSocketTransportService)
|
||||
mSocketTransportService->SetOffline(true);
|
||||
|
||||
@@ -1026,7 +1023,6 @@ nsIOService::SetOffline(bool offline)
|
||||
else if (!offline && mOffline) {
|
||||
// go online
|
||||
if (mDNSService) {
|
||||
mDNSService->SetOffline(false);
|
||||
DebugOnly<nsresult> rv = mDNSService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
|
||||
}
|
||||
|
||||
@@ -159,6 +159,15 @@ nsMIMEInputStream::SetData(nsIInputStream *aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMIMEInputStream::GetData(nsIInputStream **aStream)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStream);
|
||||
*aStream = mData;
|
||||
NS_IF_ADDREF(*aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// set up the internal streams
|
||||
void nsMIMEInputStream::InitStreams()
|
||||
{
|
||||
|
||||
@@ -360,8 +360,11 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, uint32_t appId,
|
||||
|
||||
// Maybe Reload PAC
|
||||
if (!mPACURISpec.IsEmpty() && !mScheduledReload.IsNull() &&
|
||||
TimeStamp::Now() > mScheduledReload)
|
||||
TimeStamp::Now() > mScheduledReload) {
|
||||
LOG(("nsPACMan::AsyncGetProxyForURI reload as scheduled\n"));
|
||||
|
||||
LoadPACFromURI(EmptyCString());
|
||||
}
|
||||
|
||||
RefPtr<PendingPACQuery> query =
|
||||
new PendingPACQuery(this, uri, appId, isInBrowser, callback,
|
||||
@@ -403,6 +406,7 @@ nsPACMan::LoadPACFromURI(const nsCString &spec)
|
||||
do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
|
||||
NS_ENSURE_STATE(loader);
|
||||
|
||||
LOG(("nsPACMan::LoadPACFromURI %s\n", spec.get()));
|
||||
// Since we might get called from nsProtocolProxyService::Init, we need to
|
||||
// post an event back to the main thread before we try to use the IO service.
|
||||
//
|
||||
@@ -505,6 +509,9 @@ nsPACMan::OnLoadFailure()
|
||||
|
||||
mScheduledReload = TimeStamp::Now() + TimeDuration::FromSeconds(interval);
|
||||
|
||||
LOG(("OnLoadFailure: retry in %d seconds (%d fails)\n",
|
||||
interval, mLoadFailureCount));
|
||||
|
||||
// while we wait for the retry queued members should try direct
|
||||
// even if that means fast failure.
|
||||
PostCancelPendingQ(NS_ERROR_NOT_AVAILABLE);
|
||||
@@ -602,6 +609,7 @@ nsPACMan::ProcessPending()
|
||||
!PACURI.IsEmpty() &&
|
||||
!PACURI.Equals(mPACURISpec)) {
|
||||
query->UseAlternatePACFile(PACURI);
|
||||
LOG(("Use PAC from system settings: %s\n", PACURI.get()));
|
||||
completed = true;
|
||||
}
|
||||
|
||||
@@ -612,6 +620,7 @@ nsPACMan::ProcessPending()
|
||||
GetProxyForURI(query->mSpec, query->mScheme,
|
||||
query->mHost, query->mPort,
|
||||
pacString))) {
|
||||
LOG(("Use proxy from system settings: %s\n", pacString.get()));
|
||||
query->Complete(NS_OK, pacString);
|
||||
completed = true;
|
||||
}
|
||||
@@ -622,6 +631,7 @@ nsPACMan::ProcessPending()
|
||||
query->mAppId, query->mAppOrigin,
|
||||
query->mIsInBrowser,
|
||||
pacString);
|
||||
LOG(("Use proxy from PAC: %s\n", pacString.get()));
|
||||
query->Complete(status, pacString);
|
||||
}
|
||||
|
||||
@@ -645,10 +655,13 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
|
||||
// than once before the initial call completed. In this case, status
|
||||
// should be NS_ERROR_ABORT, and if so, then we know that we can and
|
||||
// should delay any processing.
|
||||
LOG(("OnStreamComplete: called more than once\n"));
|
||||
if (status == NS_ERROR_ABORT)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOG(("OnStreamComplete: entry\n"));
|
||||
|
||||
if (NS_SUCCEEDED(status) && HttpRequestSucceeded(loader)) {
|
||||
// Get the URI spec used to load this PAC script.
|
||||
nsAutoCString pacURI;
|
||||
@@ -680,12 +693,15 @@ nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
|
||||
if (mPACThread)
|
||||
mPACThread->Dispatch(pending, nsIEventTarget::DISPATCH_NORMAL);
|
||||
|
||||
LOG(("OnStreamComplete: process the PAC contents\n"));
|
||||
|
||||
// Even if the PAC file could not be parsed, we did succeed in loading the
|
||||
// data for it.
|
||||
mLoadFailureCount = 0;
|
||||
} else {
|
||||
// We were unable to load the PAC file (presumably because of a network
|
||||
// failure). Try again a little later.
|
||||
LOG(("OnStreamComplete: unable to load PAC, retry later\n"));
|
||||
OnLoadFailure();
|
||||
}
|
||||
|
||||
|
||||
@@ -216,12 +216,16 @@ private:
|
||||
|
||||
void DoCallback()
|
||||
{
|
||||
bool pacAvailable = true;
|
||||
if (mStatus == NS_ERROR_NOT_AVAILABLE && !mProxyInfo) {
|
||||
// If the PAC service is not avail (e.g. failed pac load
|
||||
// or shutdown) then we will be going direct. Make that
|
||||
// mapping now so that any filters are still applied.
|
||||
mPACString = NS_LITERAL_CSTRING("DIRECT;");
|
||||
mStatus = NS_OK;
|
||||
|
||||
LOG(("pac not available, use DIRECT\n"));
|
||||
pacAvailable = false;
|
||||
}
|
||||
|
||||
// Generate proxy info from the PAC string if appropriate
|
||||
@@ -239,7 +243,10 @@ private:
|
||||
else
|
||||
mProxyInfo = nullptr;
|
||||
|
||||
LOG(("pac thread callback %s\n", mPACString.get()));
|
||||
if(pacAvailable) {
|
||||
// if !pacAvailable, it was already logged above
|
||||
LOG(("pac thread callback %s\n", mPACString.get()));
|
||||
}
|
||||
if (NS_SUCCEEDED(mStatus))
|
||||
mPPS->MaybeDisableDNSPrefetch(mProxyInfo);
|
||||
mCallback->OnProxyAvailable(this, mChannel, mProxyInfo, mStatus);
|
||||
|
||||
@@ -1415,6 +1415,20 @@ nsSocketTransport::InitiateSocket()
|
||||
|
||||
NetAddrToPRNetAddr(&mNetAddr, &prAddr);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Find the real tcp socket and set non-blocking once again!
|
||||
// Bug 1158189.
|
||||
PRFileDesc *bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
|
||||
if (bottom) {
|
||||
PROsfd osfd = PR_FileDesc2NativeHandle(bottom);
|
||||
u_long nonblocking = 1;
|
||||
if (ioctlsocket(osfd, FIONBIO, &nonblocking) != 0) {
|
||||
NS_WARNING("Socket could not be set non-blocking!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = PR_Connect(fd, &prAddr, NS_SOCKET_CONNECT_TIMEOUT);
|
||||
if (status == PR_SUCCESS) {
|
||||
//
|
||||
@@ -2959,10 +2973,10 @@ nsSocketTransport::PRFileDescAutoLock::SetKeepaliveVals(bool aEnabled,
|
||||
#if defined(XP_WIN)
|
||||
// Windows allows idle time and retry interval to be set; NOT ping count.
|
||||
struct tcp_keepalive keepalive_vals = {
|
||||
(int)aEnabled,
|
||||
(u_long)aEnabled,
|
||||
// Windows uses msec.
|
||||
aIdleTime * 1000,
|
||||
aRetryInterval * 1000
|
||||
(u_long)(aIdleTime * 1000UL),
|
||||
(u_long)(aRetryInterval * 1000UL)
|
||||
};
|
||||
DWORD bytes_returned;
|
||||
int err = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &keepalive_vals,
|
||||
|
||||
@@ -819,26 +819,29 @@ nsSocketTransportService::Run()
|
||||
|
||||
gSocketThread = PR_GetCurrentThread();
|
||||
|
||||
mPollableEvent.reset(new PollableEvent());
|
||||
//
|
||||
// NOTE: per bug 190000, this failure could be caused by Zone-Alarm
|
||||
// or similar software.
|
||||
//
|
||||
// NOTE: per bug 191739, this failure could also be caused by lack
|
||||
// of a loopback device on Windows and OS/2 platforms (it creates
|
||||
// a loopback socket pair on these platforms to implement a pollable
|
||||
// event object). if we can't create a pollable event, then we'll
|
||||
// have to "busy wait" to implement the socket event queue :-(
|
||||
//
|
||||
if (!mPollableEvent->Valid()) {
|
||||
mPollableEvent = nullptr;
|
||||
NS_WARNING("running socket transport thread without a pollable event");
|
||||
SOCKET_LOG(("running socket transport thread without a pollable event"));
|
||||
}
|
||||
{
|
||||
DebugMutexAutoLock lock(mLock);
|
||||
mPollableEvent.reset(new PollableEvent());
|
||||
//
|
||||
// NOTE: per bug 190000, this failure could be caused by Zone-Alarm
|
||||
// or similar software.
|
||||
//
|
||||
// NOTE: per bug 191739, this failure could also be caused by lack
|
||||
// of a loopback device on Windows and OS/2 platforms (it creates
|
||||
// a loopback socket pair on these platforms to implement a pollable
|
||||
// event object). if we can't create a pollable event, then we'll
|
||||
// have to "busy wait" to implement the socket event queue :-(
|
||||
//
|
||||
if (!mPollableEvent->Valid()) {
|
||||
mPollableEvent = nullptr;
|
||||
NS_WARNING("running socket transport thread without a pollable event");
|
||||
SOCKET_LOG(("running socket transport thread without a pollable event"));
|
||||
}
|
||||
|
||||
mPollList[0].fd = mPollableEvent ? mPollableEvent->PollableFD() : nullptr;
|
||||
mPollList[0].in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
|
||||
mPollList[0].out_flags = 0;
|
||||
mPollList[0].fd = mPollableEvent ? mPollableEvent->PollableFD() : nullptr;
|
||||
mPollList[0].in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
|
||||
mPollList[0].out_flags = 0;
|
||||
}
|
||||
|
||||
mRawThread = NS_GetCurrentThread();
|
||||
|
||||
|
||||
@@ -1261,6 +1261,29 @@ nsStandardURL::GetOriginCharset(nsACString &result)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSpecialProtocol(const nsACString &input)
|
||||
{
|
||||
nsACString::const_iterator start, end;
|
||||
input.BeginReading(start);
|
||||
nsACString::const_iterator iterator(start);
|
||||
input.EndReading(end);
|
||||
|
||||
while (iterator != end && *iterator != ':') {
|
||||
iterator++;
|
||||
}
|
||||
|
||||
nsAutoCString protocol(nsDependentCSubstring(start.get(), iterator.get()));
|
||||
|
||||
return protocol.LowerCaseEqualsLiteral("http") ||
|
||||
protocol.LowerCaseEqualsLiteral("https") ||
|
||||
protocol.LowerCaseEqualsLiteral("ftp") ||
|
||||
protocol.LowerCaseEqualsLiteral("ws") ||
|
||||
protocol.LowerCaseEqualsLiteral("wss") ||
|
||||
protocol.LowerCaseEqualsLiteral("file") ||
|
||||
protocol.LowerCaseEqualsLiteral("gopher");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStandardURL::SetSpec(const nsACString &input)
|
||||
{
|
||||
@@ -1291,12 +1314,35 @@ nsStandardURL::SetSpec(const nsACString &input)
|
||||
Clear();
|
||||
|
||||
// filter out unexpected chars "\r\n\t" if necessary
|
||||
nsAutoCString buf1;
|
||||
if (net_FilterURIString(spec, buf1)) {
|
||||
spec = buf1.get();
|
||||
specLength = buf1.Length();
|
||||
nsAutoCString filteredURI;
|
||||
if (!net_FilterURIString(spec, filteredURI)) {
|
||||
// Copy the content into filteredURI even if no whitespace was stripped.
|
||||
// We need a non-const buffer to perform backslash replacement.
|
||||
filteredURI = input;
|
||||
}
|
||||
|
||||
if (IsSpecialProtocol(filteredURI)) {
|
||||
// Bug 652186: Replace all backslashes with slashes when parsing paths
|
||||
// Stop when we reach the query or the hash.
|
||||
nsAutoCString::iterator start;
|
||||
nsAutoCString::iterator end;
|
||||
filteredURI.BeginWriting(start);
|
||||
filteredURI.EndWriting(end);
|
||||
while (start != end) {
|
||||
if (*start == '?' || *start == '#') {
|
||||
break;
|
||||
}
|
||||
if (*start == '\\') {
|
||||
*start = '/';
|
||||
}
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
spec = filteredURI.get();
|
||||
specLength = filteredURI.Length();
|
||||
|
||||
|
||||
// parse the given URL...
|
||||
nsresult rv = ParseURL(spec, specLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@@ -2078,12 +2124,15 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out)
|
||||
// filter out unexpected chars "\r\n\t" if necessary
|
||||
nsAutoCString buf;
|
||||
int32_t relpathLen;
|
||||
if (net_FilterURIString(relpath, buf)) {
|
||||
relpath = buf.get();
|
||||
relpathLen = buf.Length();
|
||||
} else
|
||||
relpathLen = flat.Length();
|
||||
|
||||
if (!net_FilterURIString(relpath, buf)) {
|
||||
// Copy the content into filteredURI even if no whitespace was stripped.
|
||||
// We need a non-const buffer to perform backslash replacement.
|
||||
buf = in;
|
||||
}
|
||||
|
||||
relpath = buf.get();
|
||||
relpathLen = buf.Length();
|
||||
|
||||
char *result = nullptr;
|
||||
|
||||
LOG(("nsStandardURL::Resolve [this=%p spec=%s relpath=%s]\n",
|
||||
@@ -2120,6 +2169,30 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out)
|
||||
// reset the scheme and assume a relative url
|
||||
if (NS_FAILED(rv)) scheme.Reset();
|
||||
|
||||
nsAutoCString protocol(Segment(scheme));
|
||||
nsAutoCString baseProtocol(Scheme());
|
||||
|
||||
// We need to do backslash replacement for the following cases:
|
||||
// 1. The input is an absolute path with a http/https/ftp scheme
|
||||
// 2. The input is a relative path, and the base URL has a http/https/ftp scheme
|
||||
if ((protocol.IsEmpty() && IsSpecialProtocol(baseProtocol)) ||
|
||||
IsSpecialProtocol(protocol)) {
|
||||
|
||||
nsAutoCString::iterator start;
|
||||
nsAutoCString::iterator end;
|
||||
buf.BeginWriting(start);
|
||||
buf.EndWriting(end);
|
||||
while (start != end) {
|
||||
if (*start == '?' || *start == '#') {
|
||||
break;
|
||||
}
|
||||
if (*start == '\\') {
|
||||
*start = '/';
|
||||
}
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
if (scheme.mLen >= 0) {
|
||||
// add some flags to coalesceFlag if it is an ftp-url
|
||||
// need this later on when coalescing the resulting URL
|
||||
|
||||
@@ -236,7 +236,7 @@ net_CoalesceDirs(netCoalesceFlags flags, char* path)
|
||||
*/
|
||||
char *fwdPtr = path;
|
||||
char *urlPtr = path;
|
||||
char *lastslash = path;
|
||||
char *endPath = path;
|
||||
uint32_t traversal = 0;
|
||||
uint32_t special_ftp_len = 0;
|
||||
|
||||
@@ -253,34 +253,18 @@ net_CoalesceDirs(netCoalesceFlags flags, char* path)
|
||||
special_ftp_len = 2;
|
||||
}
|
||||
|
||||
/* find the last slash before # or ? */
|
||||
for(; (*fwdPtr != '\0') &&
|
||||
(*fwdPtr != '?') &&
|
||||
/* find the end of the path - places the cursor on \0, ? or # */
|
||||
for(; (*fwdPtr != '\0') &&
|
||||
(*fwdPtr != '?') &&
|
||||
(*fwdPtr != '#'); ++fwdPtr)
|
||||
{
|
||||
}
|
||||
|
||||
/* found nothing, but go back one only */
|
||||
/* if there is something to go back to */
|
||||
if (fwdPtr != path && *fwdPtr == '\0')
|
||||
{
|
||||
--fwdPtr;
|
||||
}
|
||||
|
||||
/* search the slash */
|
||||
for(; (fwdPtr != path) &&
|
||||
(*fwdPtr != '/'); --fwdPtr)
|
||||
{
|
||||
}
|
||||
lastslash = fwdPtr;
|
||||
endPath = fwdPtr;
|
||||
fwdPtr = path;
|
||||
|
||||
/* replace all %2E or %2e with . in the path */
|
||||
/* but stop at lastchar if non null */
|
||||
for(; (*fwdPtr != '\0') &&
|
||||
(*fwdPtr != '?') &&
|
||||
(*fwdPtr != '#') &&
|
||||
(*lastslash == '\0' || fwdPtr != lastslash); ++fwdPtr)
|
||||
for(; fwdPtr != endPath; ++fwdPtr)
|
||||
{
|
||||
if (*fwdPtr == '%' && *(fwdPtr+1) == '2' &&
|
||||
(*(fwdPtr+2) == 'E' || *(fwdPtr+2) == 'e'))
|
||||
|
||||
@@ -62,17 +62,21 @@ nsBaseURLParser::ParseURL(const char *spec, int32_t specLen,
|
||||
const char *stop = nullptr;
|
||||
const char *colon = nullptr;
|
||||
const char *slash = nullptr;
|
||||
const char *p;
|
||||
const char *p = spec;
|
||||
uint32_t offset = 0;
|
||||
int32_t len = specLen;
|
||||
for (p = spec; len && *p && !colon && !slash; ++p, --len) {
|
||||
// skip leading whitespace
|
||||
if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') {
|
||||
spec++;
|
||||
specLen--;
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip leading whitespace
|
||||
while (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') {
|
||||
spec++;
|
||||
specLen--;
|
||||
offset++;
|
||||
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
|
||||
for (; len && *p && !colon && !slash; ++p, --len) {
|
||||
switch (*p) {
|
||||
case ':':
|
||||
if (!colon)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user