merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-09-10 14:59:20 +02:00
commit 02d1b9b00e
144 changed files with 2095 additions and 846 deletions

View File

@ -885,6 +885,7 @@ var Input = {
},
setEditState: function setEditState(aEditState) {
Logger.debug(() => { return ['setEditState', JSON.stringify(aEditState)] });
this.editState = aEditState;
},

View File

@ -191,38 +191,18 @@ this.EventManager.prototype = {
}
case Events.TEXT_CARET_MOVED:
{
let acc = aEvent.accessible;
let characterCount = acc.
QueryInterface(Ci.nsIAccessibleText).characterCount;
let acc = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
let caretOffset = aEvent.
QueryInterface(Ci.nsIAccessibleCaretMoveEvent).caretOffset;
// Update editing state, both for presenter and other things
let state = Utils.getState(acc);
let editState = {
editing: state.contains(States.EDITABLE),
multiline: state.contains(States.MULTI_LINE),
atStart: caretOffset == 0,
atEnd: caretOffset == characterCount
};
// Not interesting
if (!editState.editing && editState.editing == this.editState.editing)
break;
if (editState.editing != this.editState.editing)
this.present(Presentation.editingModeChanged(editState.editing));
if (editState.editing != this.editState.editing ||
editState.multiline != this.editState.multiline ||
editState.atEnd != this.editState.atEnd ||
editState.atStart != this.editState.atStart)
this.sendMsgFunc("AccessFu:Input", editState);
// We could get a caret move in an accessible that is not focused,
// it doesn't mean we are not on any editable accessible. just not
// on this one..
if (Utils.getState(acc).contains(States.FOCUSED)) {
this._setEditingMode(aEvent, caretOffset);
}
this.present(Presentation.textSelectionChanged(acc.getText(0,-1),
caretOffset, caretOffset, 0, 0, aEvent.isFromUserInput));
this.editState = editState;
break;
}
case Events.OBJECT_ATTRIBUTE_CHANGED:
@ -268,6 +248,7 @@ this.EventManager.prototype = {
// Put vc where the focus is at
let acc = aEvent.accessible;
let doc = aEvent.accessibleDocument;
this._setEditingMode(aEvent);
if ([Roles.CHROME_WINDOW,
Roles.DOCUMENT,
Roles.APPLICATION].indexOf(acc.role) < 0) {
@ -293,6 +274,54 @@ this.EventManager.prototype = {
}
},
_setEditingMode: function _setEditingMode(aEvent, aCaretOffset) {
let acc = aEvent.accessible;
let accText, characterCount;
let caretOffset = aCaretOffset;
try {
accText = acc.QueryInterface(Ci.nsIAccessibleText);
} catch (e) {
// No text interface on this accessible.
}
if (accText) {
characterCount = accText.characterCount;
if (caretOffset === undefined) {
caretOffset = accText.caretOffset;
}
}
// Update editing state, both for presenter and other things
let state = Utils.getState(acc);
let editState = {
editing: state.contains(States.EDITABLE) &&
state.contains(States.FOCUSED),
multiline: state.contains(States.MULTI_LINE),
atStart: caretOffset === 0,
atEnd: caretOffset === characterCount
};
// Not interesting
if (!editState.editing && editState.editing === this.editState.editing) {
return;
}
if (editState.editing !== this.editState.editing) {
this.present(Presentation.editingModeChanged(editState.editing));
}
if (editState.editing !== this.editState.editing ||
editState.multiline !== this.editState.multiline ||
editState.atEnd !== this.editState.atEnd ||
editState.atStart !== this.editState.atStart) {
this.sendMsgFunc("AccessFu:Input", editState);
}
this.editState = editState;
},
_handleShow: function _handleShow(aEvent) {
let {liveRegion, isPolite} = this._handleLiveRegion(aEvent,
['additions', 'all']);

View File

@ -10,5 +10,6 @@
<p>You're a good guy, mon frere. That means brother in French.
I don't know how I know that. I took four years of Spanish.</p>
<textarea>Please refrain from Mayoneggs during this salmonella scare.</textarea>
<label>So we don't get dessert?</label><input type="text">
</body>
</html>

View File

@ -177,7 +177,8 @@ function AccessFuContentTest(aFuncResultPairs) {
}
AccessFuContentTest.prototype = {
currentPair: null,
expected: [],
currentAction: null,
start: function(aFinishedCallback) {
Logger.logLevel = Logger.DEBUG;
@ -236,6 +237,7 @@ AccessFuContentTest.prototype = {
}
aMessageManager.addMessageListener('AccessFu:Present', this);
aMessageManager.addMessageListener('AccessFu:Input', this);
aMessageManager.addMessageListener('AccessFu:CursorCleared', this);
aMessageManager.addMessageListener('AccessFu:Ready', function () {
aMessageManager.addMessageListener('AccessFu:ContentStarted', aCallback);
@ -252,17 +254,25 @@ AccessFuContentTest.prototype = {
},
pump: function() {
this.currentPair = this.queue.shift();
this.expected.shift();
if (this.expected.length) {
return;
}
if (this.currentPair) {
if (typeof this.currentPair[0] === 'function') {
this.currentPair[0](this.mms[0]);
} else if (this.currentPair[0]) {
this.mms[0].sendAsyncMessage(this.currentPair[0].name,
this.currentPair[0].json);
var currentPair = this.queue.shift();
if (currentPair) {
this.currentAction = currentPair[0];
if (typeof this.currentAction === 'function') {
this.currentAction(this.mms[0]);
} else if (this.currentAction) {
this.mms[0].sendAsyncMessage(this.currentAction.name,
this.currentAction.json);
}
if (!this.currentPair[1]) {
this.expected = currentPair.slice(1, currentPair.length);
if (!this.expected[0]) {
this.pump();
}
} else {
@ -271,12 +281,12 @@ AccessFuContentTest.prototype = {
},
receiveMessage: function(aMessage) {
if (!this.currentPair) {
var expected = this.expected[0];
if (!expected) {
return;
}
var expected = this.currentPair[1] || {};
// |expected| can simply be a name of a message, no more further testing.
if (aMessage.name === expected) {
ok(true, 'Received ' + expected);
@ -284,17 +294,20 @@ AccessFuContentTest.prototype = {
return;
}
var speech = this.extractUtterance(aMessage.json);
var android = this.extractAndroid(aMessage.json, expected.android);
if ((speech && expected.speak) || (android && expected.android)) {
var editState = this.extractEditeState(aMessage);
var speech = this.extractUtterance(aMessage);
var android = this.extractAndroid(aMessage, expected.android);
if ((speech && expected.speak)
|| (android && expected.android)
|| (editState && expected.editState)) {
if (expected.speak) {
var checkFunc = SimpleTest[expected.speak_checkFunc] || isDeeply;
checkFunc.apply(SimpleTest, [speech, expected.speak,
'spoken: ' + JSON.stringify(speech) +
' expected: ' + JSON.stringify(expected.speak) +
' after: ' + (typeof this.currentPair[0] === 'function' ?
this.currentPair[0].toString() :
JSON.stringify(this.currentPair[0]))]);
' after: ' + (typeof this.currentAction === 'function' ?
this.currentAction.toString() :
JSON.stringify(this.currentAction))]);
}
if (expected.android) {
@ -303,10 +316,20 @@ AccessFuContentTest.prototype = {
this.lazyCompare(android, expected.android));
}
if (expected.editState) {
var checkFunc = SimpleTest[expected.editState_checkFunc] || isDeeply;
checkFunc.apply(SimpleTest, [editState, expected.editState,
'editState: ' + JSON.stringify(editState) +
' expected: ' + JSON.stringify(expected.editState) +
' after: ' + (typeof this.currentAction === 'function' ?
this.currentAction.toString() :
JSON.stringify(this.currentAction))]);
}
if (expected.focused) {
var doc = currentTabDocument();
is(doc.activeElement, doc.querySelector(expected.focused),
'Correct element is focused');
'Correct element is focused: ' + expected.focused);
}
this.pump();
@ -337,12 +360,20 @@ AccessFuContentTest.prototype = {
return [matches, delta.join(' ')];
},
extractUtterance: function(aData) {
if (!aData) {
extractEditeState: function(aMessage) {
if (!aMessage || aMessage.name !== 'AccessFu:Input') {
return null;
}
for (var output of aData) {
return aMessage.json;
},
extractUtterance: function(aMessage) {
if (!aMessage || aMessage.name !== 'AccessFu:Present') {
return null;
}
for (var output of aMessage.json) {
if (output && output.type === 'B2G') {
if (output.details && output.details.data[0].string !== 'clickAction') {
return output.details.data;
@ -353,12 +384,12 @@ AccessFuContentTest.prototype = {
return null;
},
extractAndroid: function(aData, aExpectedEvents) {
if (!aData) {
extractAndroid: function(aMessage, aExpectedEvents) {
if (!aMessage || aMessage.name !== 'AccessFu:Present') {
return null;
}
for (var output of aData) {
for (var output of aMessage.json) {
if (output && output.type === 'Android') {
for (var i in output.details) {
// Only extract if event types match expected event types.

View File

@ -132,27 +132,36 @@
// Editable text tests.
[ContentMessages.focusSelector('textarea'), {
speak: ['Please refrain from Mayoneggs during this ' +
'salmonella scare.', {string: 'textarea'}]
}],
[null, { // When we first focus, caret is at 0.
android: [{
eventType: AndroidEvent.VIEW_TEXT_SELECTION_CHANGED,
brailleOutput: {
selectionStart: 0,
selectionEnd: 0
}
}]
editState: {
editing: true,
multiline: true,
atStart: true,
atEnd: false
}
],
}, {
speak: ['Please refrain from Mayoneggs during this ' +
'salmonella scare.', {string: 'textarea'}]
}, { // When we first focus, caret is at 0.
android: [{
eventType: AndroidEvent.VIEW_TEXT_SELECTION_CHANGED,
brailleOutput: {
selectionStart: 0,
selectionEnd: 0
}
}]
}],
[ContentMessages.activateCurrent(10), {
android: [{
eventType: AndroidEvent.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
fromIndex: 0,
toIndex: 10
}]
}],
[null, {
}, {
editState: { editing: true,
multiline: true,
atStart: false,
atEnd: false }
}, {
android: [{
eventType: AndroidEvent.VIEW_TEXT_SELECTION_CHANGED,
brailleOutput: {
@ -167,8 +176,7 @@
fromIndex: 10,
toIndex: 20
}]
}],
[null, {
}, {
android: [{
eventType: AndroidEvent.VIEW_TEXT_SELECTION_CHANGED,
brailleOutput: {
@ -217,7 +225,66 @@
eventType: AndroidEvent.VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
fromIndex: 53,
toIndex: 59
}]
}],
focused: 'textarea'
}],
// bug xxx
[ContentMessages.simpleMoveNext, {
speak: ['So we don\'t get dessert?', {string: 'label'}],
focused: 'html'
}, {
editState: {
editing: false,
multiline: false,
atStart: true,
atEnd: false }
}],
[ContentMessages.simpleMoveNext, {
speak: [{ string : 'entry' }],
focused: 'html'
}],
[ContentMessages.activateCurrent(0), {
editState: {
editing: true,
multiline: false,
atStart: true,
atEnd: true
},
focused: 'input[type=text]'
}],
[ContentMessages.simpleMovePrevious, {
editState: {
editing: false,
multiline: false,
atStart: true,
atEnd: false
},
focused: 'html'
}],
[ContentMessages.simpleMoveNext, {
speak: [{ string : 'entry' }],
focused: 'html'
}],
[ContentMessages.activateCurrent(0), {
editState: {
editing: true,
multiline: false,
atStart: true,
atEnd: true
},
focused: 'input[type=text]'
}],
[ContentMessages.simpleMovePrevious, {
speak: [ 'So we don\'t get dessert?', {string: 'label'} ]
}, {
editState: {
editing: false,
multiline: false,
atStart: true,
atEnd: false
},
focused: 'html'
}]
]);

View File

@ -748,10 +748,10 @@
@BINPATH@/chrome/pippki.manifest
; For process sandboxing
#if defined(MOZ_SANDBOX)
#if defined(XP_WIN)
@BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
#elif defined(XP_LINUX)
#if defined(MOZ_CONTENT_SANDBOX) || defined(MOZ_GMP_SANDBOX)
@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
#endif
#endif

View File

@ -753,10 +753,10 @@
@BINPATH@/components/pippki.xpt
; For process sandboxing
#if defined(MOZ_SANDBOX)
#if defined(XP_WIN)
@BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
#elif defined(XP_LINUX)
#if defined(MOZ_CONTENT_SANDBOX) || defined(MOZ_GMP_SANDBOX)
@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
#endif
#endif

View File

@ -25,6 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
/** Test for CAPS file:// URI prefs. **/
SimpleTest.waitForExplicitFinish();
SimpleTest.requestCompleteLog();
var profileDir = "file://" + Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)

View File

@ -2117,11 +2117,8 @@ ia64*-hpux*)
if test "$_CC_SUITE" -ge "12"; then
dnl VS2013+ requires -FS when parallel building by make -jN.
dnl If nothing, compiler sometimes causes C1041 error.
dnl
dnl Visual Studio 2013 supports -Gw flags
dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
CFLAGS="$CFLAGS -FS -Gw"
CXXFLAGS="$CXXFLAGS -FS -Gw"
CFLAGS="$CFLAGS -FS"
CXXFLAGS="$CXXFLAGS -FS"
fi
# khuey says we can safely ignore MSVC warning C4251
# MSVC warning C4244 (implicit type conversion may lose data) warns

View File

@ -28,13 +28,14 @@ template<class T> class nsTArray;
native nsDirection(nsDirection);
native ScrollAxis(nsIPresShell::ScrollAxis);
[scriptable, builtinclass, uuid(52629837-7b3f-4434-940d-a14de7ef9b7a)]
[scriptable, builtinclass, uuid(5a82ee9a-35ce-11e4-8c3e-b7043d68ad70)]
interface nsISelectionPrivate : nsISelection
{
const short ENDOFPRECEDINGLINE=0;
const short STARTOFNEXTLINE=1;
attribute boolean interlinePosition;
[noscript] attribute nsIContent ancestorLimiter;
/* startBatchChanges
match this up with endbatchChanges. will stop ui updates while multiple selection methods are called
@ -81,8 +82,6 @@ interface nsISelectionPrivate : nsISelection
*/
[noscript] void getCachedFrameOffset(in nsIFrame aFrame, in int32_t inOffset, in nsPointRef aPoint);
[noscript] void setAncestorLimiter(in nsIContent aContent);
/**
* Set the painting style for the range. The range must be a range in
* the selection. The textRangeStyle will be used by text frame

View File

@ -7,6 +7,7 @@ support-files =
[test_BufferedSeek.html]
[test_FrameSelection.html]
skip-if = os == "mac"
[test_MediaSource.html]
[test_SplitAppendDelay.html]
[test_SplitAppend.html]

View File

@ -865,7 +865,6 @@ bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip,
if (r == -1) {
return false;
}
mLastVideoFrameTime = tstamp;
// The end time of this frame is the start time of the next frame. Fetch
// the timestamp of the next packet for this track. If we've reached the
@ -883,6 +882,7 @@ bool WebMReader::DecodeVideoFrame(bool &aKeyframeSkip,
next_tstamp = tstamp;
next_tstamp += tstamp - mLastVideoFrameTime;
}
mLastVideoFrameTime = tstamp;
int64_t tstamp_usecs = tstamp / NS_PER_USEC;
for (uint32_t i = 0; i < count; ++i) {

View File

@ -59,7 +59,7 @@ public:
DOMHighResTimeStamp RedirectStart() const {
// We have to check if all the redirect URIs had the same origin (since
// there is no check in RedirectEndHighRes())
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->ShouldReportCrossOriginRedirect()
? mTiming->RedirectStartHighRes()
: 0;
}
@ -67,43 +67,43 @@ public:
DOMHighResTimeStamp RedirectEnd() const {
// We have to check if all the redirect URIs had the same origin (since
// there is no check in RedirectEndHighRes())
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->ShouldReportCrossOriginRedirect()
? mTiming->RedirectEndHighRes()
: 0;
}
DOMHighResTimeStamp DomainLookupStart() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->DomainLookupStartHighRes()
: 0;
}
DOMHighResTimeStamp DomainLookupEnd() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->DomainLookupEndHighRes()
: 0;
}
DOMHighResTimeStamp ConnectStart() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->ConnectStartHighRes()
: 0;
}
DOMHighResTimeStamp ConnectEnd() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->ConnectEndHighRes()
: 0;
}
DOMHighResTimeStamp RequestStart() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->RequestStartHighRes()
: 0;
}
DOMHighResTimeStamp ResponseStart() const {
return mTiming && mTiming->IsSameOriginAsReferral()
return mTiming && mTiming->TimingAllowed()
? mTiming->ResponseStartHighRes()
: 0;
}

View File

@ -12,6 +12,7 @@
#include "nsContentUtils.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIEditor.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
@ -815,8 +816,7 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
// element as well, but don't fire any events.
if (window == mFocusedWindow) {
mFocusedContent = nullptr;
}
else {
} else {
// Check if the node that was focused is an iframe or similar by looking
// if it has a subdocument. This would indicate that this focused iframe
// and its descendants will be going away. We will need to move the
@ -834,6 +834,27 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
}
}
// Notify the editor in case we removed its ancestor limiter.
if (content->IsEditable()) {
nsCOMPtr<nsIDocShell> docShell = aDocument->GetDocShell();
if (docShell) {
nsCOMPtr<nsIEditor> editor;
docShell->GetEditor(getter_AddRefs(editor));
if (editor) {
nsCOMPtr<nsISelection> s;
editor->GetSelection(getter_AddRefs(s));
nsCOMPtr<nsISelectionPrivate> selection = do_QueryInterface(s);
if (selection) {
nsCOMPtr<nsIContent> limiter;
selection->GetAncestorLimiter(getter_AddRefs(limiter));
if (limiter == content) {
editor->FinalizeSelection();
}
}
}
}
}
NotifyFocusStateChange(content, shouldShowFocusRing, false);
}

View File

@ -760,8 +760,6 @@ nsJSContext::InitContext()
if (!mContext)
return NS_ERROR_OUT_OF_MEMORY;
JS_SetErrorReporter(mContext, xpc::SystemErrorReporter);
JSOptionChangedCallback(js_options_dot_str, this);
return NS_OK;

View File

@ -19,6 +19,7 @@
#include "mozilla/dom/PerformanceNavigationBinding.h"
#include "mozilla/TimeStamp.h"
#include "nsThreadUtils.h"
#include "nsILoadInfo.h"
using namespace mozilla;
@ -35,7 +36,8 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance,
mChannel(aChannel),
mFetchStart(0.0),
mZeroTime(aZeroTime),
mReportCrossOriginResources(true)
mTimingAllowed(true),
mReportCrossOriginRedirect(true)
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
SetIsDOMBinding();
@ -43,7 +45,10 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance,
// is being used for the navigation timing (document) and has a non-null
// value for the resource timing (any resources within the page).
if (aHttpChannel) {
CheckRedirectCrossOrigin(aHttpChannel);
mTimingAllowed = CheckAllowedOrigin(aHttpChannel);
bool redirectsPassCheck = false;
mChannel->GetAllRedirectsPassTimingAllowCheck(&redirectsPassCheck);
mReportCrossOriginRedirect = mTimingAllowed && redirectsPassCheck;
}
}
@ -75,34 +80,31 @@ nsPerformanceTiming::FetchStart()
return static_cast<int64_t>(FetchStartHighRes());
}
// This method will implement the timing allow check algorithm
// http://w3c-test.org/webperf/specs/ResourceTiming/#timing-allow-check
// https://bugzilla.mozilla.org/show_bug.cgi?id=936814
void
nsPerformanceTiming::CheckRedirectCrossOrigin(nsIHttpChannel* aResourceChannel)
bool
nsPerformanceTiming::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel)
{
if (!IsInitialized()) {
return;
return false;
}
uint16_t redirectCount;
mChannel->GetRedirectCount(&redirectCount);
if (redirectCount == 0) {
return;
}
nsCOMPtr<nsIURI> resourceURI, referrerURI;
aResourceChannel->GetReferrer(getter_AddRefs(referrerURI));
aResourceChannel->GetURI(getter_AddRefs(resourceURI));
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
nsresult rv = ssm->CheckSameOriginURI(resourceURI, referrerURI, false);
if (!NS_SUCCEEDED(rv)) {
mReportCrossOriginResources = false;
// Check that the current document passes the ckeck.
nsCOMPtr<nsILoadInfo> loadInfo;
aResourceChannel->GetLoadInfo(getter_AddRefs(loadInfo));
if (!loadInfo) {
return false;
}
nsCOMPtr<nsIPrincipal> principal = loadInfo->LoadingPrincipal();
// Check if the resource is either same origin as the page that started
// the load, or if the response contains the proper Timing-Allow-Origin
// header with the domain of the page that started the load.
return mChannel->TimingAllowCheck(principal);
}
bool
nsPerformanceTiming::IsSameOriginAsReferral() const
nsPerformanceTiming::TimingAllowed() const
{
return mReportCrossOriginResources;
return mTimingAllowed;
}
uint16_t
@ -121,6 +123,21 @@ nsPerformanceTiming::GetRedirectCount() const
return redirectCount;
}
bool
nsPerformanceTiming::ShouldReportCrossOriginRedirect() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return false;
}
// If the redirect count is 0, or if one of the cross-origin
// redirects doesn't have the proper Timing-Allow-Origin header,
// then RedirectStart and RedirectEnd will be set to zero
uint16_t redirectCount;
mChannel->GetRedirectCount(&redirectCount);
return (redirectCount != 0) && mReportCrossOriginRedirect;
}
/**
* RedirectStartHighRes() is used by both the navigation timing and the
* resource timing. Since, navigation timing and resource timing check and

View File

@ -139,8 +139,18 @@ public:
}
uint16_t GetRedirectCount() const;
bool IsSameOriginAsReferral() const;
void CheckRedirectCrossOrigin(nsIHttpChannel* aResourceChannel);
// Checks if the resource is either same origin as the page that started
// the load, or if the response contains the Timing-Allow-Origin header
// with a value of * or matching the domain of the loading Principal
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel);
// Cached result of CheckAllowedOrigin. If false, security sensitive
// attributes of the resourceTiming object will be set to 0
bool TimingAllowed() const;
// If this is false the values of redirectStart/End will be 0
// This is false if no redirects occured, or if any of the responses failed
// the timing-allow-origin check in HttpBaseChannel::TimingAllowCheck
bool ShouldReportCrossOriginRedirect() const;
// High resolution (used by resource timing)
DOMHighResTimeStamp FetchStartHighRes();
@ -220,7 +230,12 @@ private:
// TimeStamp (results are absolute timstamps - wallclock); (2) "0" (results
// are relative to the navigation start).
DOMHighResTimeStamp mZeroTime;
bool mReportCrossOriginResources;
bool mTimingAllowed;
// If the resourceTiming object should have non-zero redirectStart and
// redirectEnd attributes. It is false if there were no redirects, or if
// any of the responses didn't pass the timing-allow-check
bool mReportCrossOriginRedirect;
};
// Script "performance.navigation" object

View File

@ -587,6 +587,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
RemovePostRefreshObserver();
Reset();
// Drop references from all CanvasRenderingContext2DUserData to this context
for (uint32_t i = 0; i < mUserDatas.Length(); ++i) {
@ -766,6 +767,14 @@ CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
mCanvasElement->InvalidateCanvasContent(&r);
}
void
CanvasRenderingContext2D::DidRefresh()
{
if (mStream && mStream->GLContext()) {
mStream->GLContext()->FlushIfHeavyGLCallsSinceLastFlush();
}
}
void
CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
{
@ -1092,7 +1101,9 @@ CanvasRenderingContext2D::InitializeWithSurface(nsIDocShell *shell,
int32_t width,
int32_t height)
{
RemovePostRefreshObserver();
mDocShell = shell;
AddPostRefreshObserverIfNecessary();
SetDimensions(width, height);
mTarget = gfxPlatform::GetPlatform()->

View File

@ -475,6 +475,18 @@ public:
virtual int32_t GetHeight() const MOZ_OVERRIDE;
#endif
// nsICanvasRenderingContextInternal
/**
* Gets the pres shell from either the canvas element or the doc shell
*/
virtual nsIPresShell *GetPresShell() MOZ_OVERRIDE {
if (mCanvasElement) {
return mCanvasElement->OwnerDoc()->GetShell();
}
if (mDocShell) {
return mDocShell->GetPresShell();
}
return nullptr;
}
NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
@ -505,6 +517,13 @@ public:
NS_IMETHOD Redraw(const gfxRect &r) MOZ_OVERRIDE { Redraw(ToRect(r)); return NS_OK; }
NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
/**
* An abstract base class to be implemented by callers wanting to be notified
* that a refresh has occurred. Callers must ensure an observer is removed
* before it is destroyed.
*/
virtual void DidRefresh() MOZ_OVERRIDE;
// this rect is in mTarget's current user space
void RedrawUser(const gfxRect &r);
@ -818,19 +837,6 @@ protected:
return CurrentState().op;
}
/**
* Gets the pres shell from either the canvas element or the doc shell
*/
nsIPresShell *GetPresShell() {
if (mCanvasElement) {
return mCanvasElement->OwnerDoc()->GetShell();
}
if (mDocShell) {
return mDocShell->GetPresShell();
}
return nullptr;
}
// text
public: // These enums are public only to accomodate non-C++11 legacy path of

View File

@ -324,6 +324,7 @@ WebGLContext::WebGLContext()
WebGLContext::~WebGLContext()
{
RemovePostRefreshObserver();
mContextObserver->Destroy();
DestroyResourcesAndContext();
@ -1740,6 +1741,14 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
return dt->Snapshot();
}
void
WebGLContext::DidRefresh()
{
if (gl) {
gl->FlushIfHeavyGLCallsSinceLastFlush();
}
}
bool WebGLContext::TexImageFromVideoElement(GLenum texImageTarget, GLint level,
GLenum internalformat, GLenum format, GLenum type,
mozilla::dom::Element& elt)

View File

@ -191,13 +191,15 @@ public:
JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
NS_IMETHOD SetIsIPC(bool b) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
int32_t x, int32_t y, int32_t w, int32_t h)
{ return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Swap(uint32_t nativeID,
int32_t x, int32_t y, int32_t w, int32_t h)
{ return NS_ERROR_NOT_IMPLEMENTED; }
/**
* An abstract base class to be implemented by callers wanting to be notified
* that a refresh has occurred. Callers must ensure an observer is removed
* before it is destroyed.
*/
virtual void DidRefresh() MOZ_OVERRIDE;
NS_IMETHOD Redraw(const gfxRect&) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
void SynthesizeGLError(GLenum err);
void SynthesizeGLError(GLenum err, const char *fmt, ...);

View File

@ -10,6 +10,7 @@
#include "nsISupports.h"
#include "nsIInputStream.h"
#include "nsIDocShell.h"
#include "nsRefreshDriver.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "GraphicsFilter.h"
#include "mozilla/RefPtr.h"
@ -27,15 +28,15 @@ namespace layers {
class CanvasLayer;
class LayerManager;
}
namespace ipc {
class Shmem;
}
namespace gfx {
class SourceSurface;
}
}
class nsICanvasRenderingContextInternal : public nsISupports {
class nsICanvasRenderingContextInternal :
public nsISupports,
public nsAPostRefreshObserver
{
public:
typedef mozilla::layers::CanvasLayer CanvasLayer;
typedef mozilla::layers::LayerManager LayerManager;
@ -44,8 +45,37 @@ public:
void SetCanvasElement(mozilla::dom::HTMLCanvasElement* aParentCanvas)
{
RemovePostRefreshObserver();
mCanvasElement = aParentCanvas;
AddPostRefreshObserverIfNecessary();
}
virtual nsIPresShell *GetPresShell() {
if (mCanvasElement) {
return mCanvasElement->OwnerDoc()->GetShell();
}
return nullptr;
}
void RemovePostRefreshObserver()
{
if (mRefreshDriver) {
mRefreshDriver->RemovePostRefreshObserver(this);
mRefreshDriver = nullptr;
}
}
void AddPostRefreshObserverIfNecessary()
{
if (!GetPresShell() ||
!GetPresShell()->GetPresContext() ||
!GetPresShell()->GetPresContext()->RefreshDriver()) {
return;
}
mRefreshDriver = GetPresShell()->GetPresContext()->RefreshDriver();
mRefreshDriver->AddPostRefreshObserver(this);
}
mozilla::dom::HTMLCanvasElement* GetParentObject() const
{
return mCanvasElement;
@ -130,14 +160,9 @@ public:
protected:
nsRefPtr<mozilla::dom::HTMLCanvasElement> mCanvasElement;
nsRefPtr<nsRefreshDriver> mRefreshDriver;
};
namespace mozilla {
namespace dom {
}
}
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)

View File

@ -14,6 +14,24 @@ support-files =
historyframes.html
resource_timing_iframe.html
resource_timing_main_test.html
resource_timing_cross_origin.html
res0.resource
res1.resource
res1.resource^headers^
res2.resource
res2.resource^headers^
res3.resource
res3.resource^headers^
res4.resource
res4.resource^headers^
res5.resource
res5.resource^headers^
res6.resource
res6.resource^headers^
res7.resource
res7.resource^headers^
res8.resource
res8.resource^headers^
[test_497898.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || toolkit == 'android' #Bug 931116, b2g desktop specific, initial triage
@ -57,6 +75,8 @@ skip-if = buildapp == 'mulet'
[test_picture_pref.html]
[test_resource_timing.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet' # b2g(No clipboard) b2g-debug(No clipboard) b2g-desktop(No clipboard)
[test_resource_timing_cross_origin.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_performance_now.html]
[test_srcset_pref.html]
[test_showModalDialog.html]

View File

@ -0,0 +1,2 @@
HTTP 200
Timing-Allow-Origin: *

View File

@ -0,0 +1,2 @@
HTTP 302 Moved
Location: http://test2.example.com/tests/image/test/mochitest/red.png

View File

@ -0,0 +1,2 @@
HTTP 200
Timing-Allow-Origin: http://mochi.test:8888

View File

@ -0,0 +1,3 @@
HTTP 302 Moved
Timing-Allow-Origin: *
Location: http://mochi.test:8888/tests/dom/tests/mochitest/general/res1.resource

View File

@ -0,0 +1,2 @@
HTTP 200
Timing-Allow-Origin: http://mochi.test:8889

View File

@ -0,0 +1,2 @@
HTTP 200
Timing-Allow-Origin:

View File

@ -0,0 +1,2 @@
HTTP 200
Timing-Allow-Origin: http://mochi.test:8888 http://test1.com

View File

@ -0,0 +1,2 @@
HTTP 302 Moved
Location: http://test1.example.com/tests/dom/tests/mochitest/general/res4.resource

View File

@ -0,0 +1,182 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
function ok(cond, message) {
window.opener.ok(cond, message)
}
function is(received, expected, message) {
window.opener.is(received, expected, message);
}
function isnot(received, notExpected, message) {
window.opener.isnot(received, notExpected, message);
}
var bufferFullCounter = 0;
const expectedBufferFullEvents = 0;
const properties = ["startTime", "redirectStart", "redirectEnd", "fetchStart",
"domainLookupStart", "domainLookupEnd", "connectStart",
"connectEnd", "requestStart", "responseStart", "responseEnd"];
window.onload = function() {
ok(!!window.performance, "Performance object should exist");
ok(!!window.performance.getEntries, "Performance.getEntries() should exist");
ok(!!window.performance.getEntriesByName, "Performance.getEntriesByName() should exist");
ok(!!window.performance.getEntriesByType, "Performance.getEntriesByType() should exist");
window.performance.onresourcetimingbufferfull = function() {
bufferFullCounter += 1;
}
makeXhr("http://mochi.test:8888/tests/dom/tests/mochitest/general/test-data.json", firstCheck);
};
function firstCheck() {
var entries = window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/test-data.json");
ok(!!entries[0], "same origin test-data.json is missing from entries");
checkSameOrigin(entries[0]);
var entries = window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/res0.resource");
ok(!!entries[0], "same origin res0.resource is missing from entries");
checkSameOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res0.resource");
ok(!!entries[0], "cross origin res0.resource is missing from entries");
checkCrossOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res1.resource");
ok(!!entries[0], "res1.resource is missing from entries");
checkSameOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res2.resource");
ok(!!entries[0], "redirected res2.resource is missing from entries");
checkRedirectedCrossOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res3.resource");
ok(!!entries[0], "cross origin res3.resource is missing from entries");
checkSameOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res4.resource");
ok(!!entries[0], "redirected res4.resource is missing from entries");
checkRedirectedSameOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res5.resource");
ok(!!entries[0], "cross origin res5.resource is missing from entries");
checkCrossOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res6.resource");
ok(!!entries[0], "cross origin res6.resource is missing from entries");
checkCrossOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res7.resource");
ok(!!entries[0], "cross origin res7.resource is missing from entries");
checkCrossOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://test1.example.com/tests/dom/tests/mochitest/general/res8.resource");
ok(!!entries[0], "redirected res8.resource is missing from entries");
checkRedirectCrossOriginResourceSameOrigin(entries[0]);
is(bufferFullCounter, expectedBufferFullEvents, "Buffer full was called");
finishTests();
}
function checkEntry(entry, checks) {
// If the entry is undefined, we return early so we don't get a JS error
if (entry == undefined)
return;
for (var j = 1; j < properties.length; ++j) {
var prop = properties[j];
if (checks[prop] != undefined) {
is(entry[prop], checks[prop], "Wrong value for prop " + prop + " for resource " + entry.name);
} else {
isnot(entry[prop], 0, "Wrong value for prop " + prop + " for resource " + entry.name);
}
}
}
// No redirects have occured so RedirectStart/End are 0
function checkSameOrigin(entry) {
const checks = { "redirectStart": 0, "redirectEnd": 0 };
checkEntry(entry, checks);
}
// This is a cross-origin resource that doesn't pass the check
// All of these attributes are 0. No redirects
function checkCrossOrigin(entry) {
const checks = { "redirectStart": 0, "redirectEnd": 0,
"domainLookupStart": 0, "domainLookupEnd": 0,
"connectStart": 0, "connectEnd": 0,
"requestStart": 0, "responseStart": 0 };
checkEntry(entry, checks);
}
// A cross-origin redirect has occured. RedirectStart/End and the rest of the
// attributes are 0.
function checkRedirectedCrossOrigin(entry) {
const checks = { "redirectStart": 0, "redirectEnd": 0,
"domainLookupStart": 0, "domainLookupEnd": 0,
"connectStart": 0, "connectEnd": 0,
"requestStart": 0, "responseStart": 0 };
checkEntry(entry, checks);
}
// The redirect is to the same origin as the initial document,
// so no entries are 0.
function checkRedirectedSameOrigin(entry) {
const checks = { };
checkEntry(entry, checks);
}
// The final entry passes the timing-allow-check,
// but one of the redirects does not. redirectStart/End are 0.
function checkRedirectCrossOriginResourceSameOrigin(entry) {
const checks = { "redirectStart": 0, "redirectEnd": 0 };
checkEntry(entry, checks);
}
function makeXhr(aUrl, aCallback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onload = aCallback;
xmlhttp.open("get", aUrl, true);
xmlhttp.send();
}
function finishTests() {
window.opener.finishTests();
}
</script>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=822480"
title="Add resource timing API.">
Bug #822480 - Add in the Resource Timing API
</a>
<p id="display"></p>
<div id="content">
<object data="http://mochi.test:8888/tests/dom/tests/mochitest/general/res0.resource"> <!-- same origin, no header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res0.resource"> <!-- cross origin, no header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res1.resource"> <!-- cross origin, Timing-Allow-Origin: * header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res2.resource"> <!-- cross origin redirect to test2.example.com, no header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res3.resource"> <!-- cross origin, Timing-Allow-Origin: http://mochi.test:8888 header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res4.resource"> <!-- cross origin redirect to mochi.test:8888/.../res1.resource, Timing-Allow-Origin: * -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res5.resource"> <!-- cross origin, Timing-Allow-Origin: http://mochi.test:8889 -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res6.resource"> <!-- cross origin, Timing-Allow-Origin: "" (empty string) -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res7.resource"> <!-- cross origin, Timing-Allow-Origin: http://mochi.test:8888 http://test1.com header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res8.resource"> <!-- double cross origin redirect -->
</div>
</body>
</html>

View File

@ -25,8 +25,8 @@
<script>
function doTest() {
window.parent.ok(!!window.performance.getEntriesByName(
"http://example.com/tests/image/test/mochitest/damon.jpg").length,
"http://example.com/tests/image/test/mochitest/damon.jpg should be a valid entry name");
"http://mochi.test:8888/tests/image/test/mochitest/damon.jpg").length,
"http://mochi.test:8888/tests/image/test/mochitest/damon.jpg should be a valid entry name");
window.parent.ok(!window.performance.getEntriesByName(
"http://mochi.test:8888/tests/dom/tests/mochitest/general/resource_timing_iframe.html").length,
"This iframe should NOT contain itself as an entry");
@ -43,6 +43,6 @@ function doTest() {
}
</script>
<body onLoad="doTest()">
<img src="http://example.com/tests/image/test/mochitest/damon.jpg"/>
<img src="http://mochi.test:8888/tests/image/test/mochitest/damon.jpg"/>
</body>
</html>

View File

@ -83,7 +83,7 @@ window.onload = function() {
ok(!!window.performance.getEntriesByType("resource").length,
"Performance.getEntriesByType() should return some results");
ok(!!window.performance.getEntriesByName("http://example.com/tests/image/test/mochitest/blue.png").length,
ok(!!window.performance.getEntriesByName("http://mochi.test:8888/tests/image/test/mochitest/blue.png").length,
"Performance.getEntriesByName() should return some results");
// Checks that two calls for "getEntries()" return a different array with the same
@ -169,6 +169,10 @@ function checkEntries(anEntryList) {
for (var j = 1; j < sequence.length; ++j) {
var prop = sequence[j];
var prevProp = sequence[j-1];
if (prop == 'redirectStart' && entry[prop] == 0)
continue;
if (prop == 'redirectEnd' && entry[prop] == 0)
continue;
ok(entry[prevProp] <= entry[prop],
['Expected ', prevProp, ' to happen before ', prop,
', got ', prevProp, ' = ', entry[prevProp],
@ -181,9 +185,9 @@ function checkEntries(anEntryList) {
// the order (the order might depend on the platform the tests are running).
allResources = {
"http://mochi.test:8888/tests/SimpleTest/test.css" : "link",
"http://example.com/tests/image/test/mochitest/blue.png" : "img",
"http://example.com/tests/image/test/mochitest/red.png" : "object",
"http://example.com/tests/image/test/mochitest/big.png" : "embed",
"http://mochi.test:8888/tests/image/test/mochitest/blue.png" : "img",
"http://mochi.test:8888/tests/image/test/mochitest/red.png" : "object",
"http://mochi.test:8888/tests/image/test/mochitest/big.png" : "embed",
"http://mochi.test:8888/tests/dom/tests/mochitest/general/resource_timing_iframe.html" : "subdocument"};
for (resourceName in allResources) {
@ -201,8 +205,8 @@ function checkEntries(anEntryList) {
}
// Check that the iframe's image was NOT added as an entry to this window's performance entry.
ok(!window.performance.getEntriesByName("http://example.com/tests/image/test/mochitest/damon.jpg").length,
"http://example.com/tests/image/test/mochitest/damon.jpg should be a valid entry name");
ok(!window.performance.getEntriesByName("http://mochi.test:8888/tests/image/test/mochitest/damon.jpg").length,
"http://mochi.test:8888/tests/image/test/mochitest/damon.jpg should be a valid entry name");
}
function firstCheck() {
@ -271,9 +275,9 @@ function iframeTestsCompleted() {
</a>
<p id="display"></p>
<div id="content">
<img src="http://example.com/tests/image/test/mochitest/blue.png">
<object data="http://example.com/tests/image/test/mochitest/red.png" type="image/png"/>
<embed src="http://example.com/tests/image/test/mochitest/big.png" type="image/png"/>
<img src="http://mochi.test:8888/tests/image/test/mochitest/blue.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/red.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/big.png" type="image/png"/>
<iframe sandbox="allow-same-origin allow-scripts" id="if_2" src="resource_timing_iframe.html" height="10" width="10"></iframe>
</div>
</body>

View File

@ -0,0 +1,45 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=822480
-->
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Resource timing is prefed off by default, so we had to use this workaround
var subwindow = null;
SpecialPowers.pushPrefEnv({"set": [["dom.enable_resource_timing", true]]}, start);
function start() {
subwindow = window.open("resource_timing_cross_origin.html");
}
function finishTests() {
subwindow.close();
SpecialPowers.pushPrefEnv({"clear":[["dom.enable_resource_timing"]]}, SimpleTest.finish);
}
</script>
</pre>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=936814"
title="Cross origin resource timing">
Bug #936814 - Implement the "timing allow check algorithm" for cross-origin Resource Timing
</a>
</body>
</html>

View File

@ -826,7 +826,7 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
rtPrivate->mWorkerPrivate = aWorkerPrivate;
JS_SetRuntimePrivate(aRuntime, rtPrivate);
JS_SetErrorReporter(workerCx, ErrorReporter);
JS_SetErrorReporter(aRuntime, ErrorReporter);
JS_SetInterruptCallback(aRuntime, InterruptCallback);

View File

@ -4806,30 +4806,30 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
return NS_OK;
}
void
NS_IMETHODIMP
nsEditor::FinalizeSelection()
{
nsCOMPtr<nsISelectionController> selCon;
nsresult rv = GetSelectionController(getter_AddRefs(selCon));
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelection> selection;
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selection));
NS_ENSURE_SUCCESS_VOID(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelectionPrivate> selectionPrivate = do_QueryInterface(selection);
NS_ENSURE_TRUE_VOID(selectionPrivate);
NS_ENSURE_TRUE(selectionPrivate, rv);
selectionPrivate->SetAncestorLimiter(nullptr);
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE_VOID(presShell);
NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_INITIALIZED);
selCon->SetCaretEnabled(false);
nsFocusManager* fm = nsFocusManager::GetFocusManager();
NS_ENSURE_TRUE_VOID(fm);
NS_ENSURE_TRUE(fm, NS_ERROR_NOT_INITIALIZED);
fm->UpdateCaretForCaretBrowsingMode();
if (!HasIndependentSelection()) {
@ -4860,6 +4860,7 @@ nsEditor::FinalizeSelection()
}
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
return NS_OK;
}
dom::Element *

View File

@ -801,9 +801,6 @@ public:
// nothing.
nsresult InitializeSelection(nsIDOMEventTarget* aFocusEventTarget);
// Finalizes selection and caret for the editor.
void FinalizeSelection();
// This method has to be called by nsEditorEventListener::Focus.
// All actions that have to be done when the editor is focused needs to be
// added here.

View File

@ -21,7 +21,7 @@ interface nsIEditActionListener;
interface nsIInlineSpellChecker;
interface nsITransferable;
[scriptable, uuid(04714a01-e02f-4ef5-a388-612451d0db16)]
[scriptable, uuid(a1ddae68-35d0-11e4-9329-cb55463f21c9)]
interface nsIEditor : nsISupports
{
@ -42,6 +42,11 @@ interface nsIEditor : nsISupports
readonly attribute nsISelection selection;
/**
* Finalizes selection and caret for the editor.
*/
[noscript] void finalizeSelection();
/**
* Init is to tell the implementation of nsIEditor to begin its services
* @param aDoc The dom document interface being observed

View File

@ -13,13 +13,3 @@ cairo_features_FILES := cairo-features.h
cairo_features_DEST = $(DIST)/include/cairo
cairo_features_TARGET := export
include $(topsrcdir)/config/rules.mk
ifdef GNU_CC
# Disable spammy "missing initializer" GCC warning
CFLAGS += -Wno-missing-field-initializers
# Disable spammy "implicit conversion from enumeration type 'cairo_" warnings.
CFLAGS += -Wno-conversion
endif # GNU_CC

View File

@ -210,6 +210,8 @@ if CONFIG['GNU_CC']:
'-Wno-int-to-pointer-cast',
'-Wno-sign-compare',
'-Wno-type-limits',
'-Wno-missing-field-initializers',
'-Wno-conversion',
]
if CONFIG['CLANG_CXX']:
CFLAGS += [

View File

@ -8,11 +8,6 @@ endif
include $(topsrcdir)/config/rules.mk
# Disable spammy "missing initializer" GCC warning
ifdef GNU_CC
CFLAGS += -Wno-missing-field-initializers
endif # GNU_CC
# The ARM asm functions here don't appreciate being called by functions
# compiled with -mapcs-frame. See bug 832752.
CXXFLAGS := $(filter-out -mapcs-frame,$(CXXFLAGS))

View File

@ -144,7 +144,8 @@ if use_arm_neon_gcc:
if CONFIG['GNU_CC']:
CFLAGS += [
'-Wno-address',
'-Wno-sign-compare'
'-Wno-sign-compare',
'-Wno-missing-field-initializers',
]
if CONFIG['CLANG_CXX']:
CFLAGS += [

View File

@ -289,7 +289,8 @@ GLContext::GLContext(const SurfaceCaps& caps,
mMaxTextureImageSize(0),
mMaxRenderbufferSize(0),
mNeedsTextureSizeChecks(false),
mWorkAroundDriverBugs(true)
mWorkAroundDriverBugs(true),
mHeavyGLCallsSinceLastFlush(false)
{
mOwningThreadId = PlatformThread::CurrentId();
}
@ -2140,6 +2141,16 @@ GLContext::ReadTexImageHelper()
return mReadTexImageHelper.get();
}
void
GLContext::FlushIfHeavyGLCallsSinceLastFlush()
{
if (!mHeavyGLCallsSinceLastFlush) {
return;
}
MakeCurrent();
fFlush();
}
bool
DoesStringMatch(const char* aString, const char *aWantedString)
{

View File

@ -782,8 +782,10 @@ private:
// if it's bound.
void AfterGLDrawCall()
{
if (mScreen)
if (mScreen) {
mScreen->AfterDrawCall();
}
mHeavyGLCallsSinceLastFlush = true;
}
// Do whatever setup is necessary to read from our offscreen FBO, if it's
@ -904,6 +906,7 @@ private:
BEFORE_GL_CALL;
mSymbols.fBufferData(target, size, data, usage);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
public:
@ -926,6 +929,7 @@ public:
BEFORE_GL_CALL;
mSymbols.fBufferSubData(target, offset, size, data);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
private:
@ -971,6 +975,7 @@ public:
BEFORE_GL_CALL;
mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) {
@ -978,6 +983,7 @@ public:
BEFORE_GL_CALL;
mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
@ -1127,12 +1133,14 @@ public:
BEFORE_GL_CALL;
mSymbols.fFinish();
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = false;
}
void fFlush() {
BEFORE_GL_CALL;
mSymbols.fFlush();
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = false;
}
void fFrontFace(GLenum face) {
@ -1524,6 +1532,7 @@ private:
BEFORE_GL_CALL;
mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
public:
@ -1626,6 +1635,7 @@ private:
BEFORE_GL_CALL;
mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
public:
@ -1646,6 +1656,7 @@ public:
BEFORE_GL_CALL;
mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
void fUniform1f(GLint location, GLfloat v0) {
@ -2263,6 +2274,7 @@ public:
ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
mSymbols.fEGLImageTargetTexture2D(target, image);
AFTER_GL_CALL;
mHeavyGLCallsSinceLastFlush = true;
}
void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
@ -3148,6 +3160,13 @@ public:
nsTArray<NamedResource> mTrackedBuffers;
nsTArray<NamedResource> mTrackedQueries;
#endif
protected:
bool mHeavyGLCallsSinceLastFlush;
public:
void FlushIfHeavyGLCallsSinceLastFlush();
};
bool DoesStringMatch(const char* aString, const char *aWantedString);

View File

@ -79,7 +79,7 @@ private:
int32_t mCurLine; // Line index of the image that's currently being decoded
uint32_t mRowBytes; // How many bytes of the row were already received
int32_t mOldLine; // Previous index of the line
nsAutoPtr<Decoder> mContainedDecoder; // Contains either a BMP or PNG resource
nsRefPtr<Decoder> mContainedDecoder; // Contains either a BMP or PNG resource
char mDirEntryArray[ICODIRENTRYSIZE]; // Holds the current dir entry buffer
IconDirEntry mDirEntry; // Holds a decoded dir entry

View File

@ -16,16 +16,6 @@
namespace mozilla {
namespace image {
class Decoder;
}
template<>
struct HasDangerousPublicDestructor<image::Decoder>
{
static const bool value = true;
};
namespace image {
class Decoder
@ -33,7 +23,6 @@ class Decoder
public:
explicit Decoder(RasterImage& aImage);
virtual ~Decoder();
/**
* Initialize an image decoder. Decoders may not be re-initialized.
@ -178,6 +167,7 @@ public:
}
protected:
virtual ~Decoder();
/*
* Internal hooks. Decoder implementations may override these and

View File

@ -378,12 +378,12 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
ok = JS_ExecuteScript(cx, obj, script, &result);
if (ok && result != JSVAL_VOID) {
/* Suppress error reports from JS::ToString(). */
older = JS_SetErrorReporter(cx, nullptr);
older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
str = JS::ToString(cx, result);
JSAutoByteString bytes;
if (str)
bytes.encodeLatin1(cx, str);
JS_SetErrorReporter(cx, older);
JS_SetErrorReporter(JS_GetRuntime(cx), older);
if (!!bytes)
fprintf(stdout, "%s\n", bytes.ptr());
@ -593,12 +593,12 @@ XPCShellEnvironment::EvaluateString(const nsString& aString,
JS::Rooted<JS::Value> result(cx);
bool ok = JS_ExecuteScript(cx, global, script, &result);
if (ok && result != JSVAL_VOID) {
JSErrorReporter old = JS_SetErrorReporter(cx, nullptr);
JSErrorReporter old = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
JSString* str = JS::ToString(cx, result);
nsAutoJSString autoStr;
if (str)
autoStr.init(cx, str);
JS_SetErrorReporter(cx, old);
JS_SetErrorReporter(JS_GetRuntime(cx), old);
if (!autoStr.IsEmpty() && aResult) {
aResult->Assign(autoStr);

View File

@ -1677,11 +1677,8 @@ ia64*-hpux*)
if test "$_CC_SUITE" -ge "12"; then
dnl VS2013+ requires -FS when parallel building by make -jN.
dnl If nothing, compiler sometimes causes C1041 error.
dnl
dnl Visual Studio 2013 supports -Gw flags
dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
CFLAGS="$CFLAGS -FS -Gw"
CXXFLAGS="$CXXFLAGS -FS -Gw"
CFLAGS="$CFLAGS -FS"
CXXFLAGS="$CXXFLAGS -FS"
fi
# khuey says we can safely ignore MSVC warning C4251
# MSVC warning C4244 (implicit type conversion may lose data) warns

View File

@ -67,7 +67,7 @@ main (int argc, const char **argv)
JS_SetNativeStackQuota(runtime, 5000000);
JSContext *cx = checkPtr(JS_NewContext(runtime, 8192));
JS_SetErrorReporter(cx, reportError);
JS_SetErrorReporter(runtime, reportError);
JSAutoRequest ar(cx);

View File

@ -19,7 +19,7 @@ BEGIN_TEST(testErrorCopying_columnCopied)
EXEC("function check() { Object; foo; }");
JS::RootedValue rval(cx);
JS_SetErrorReporter(cx, my_ErrorReporter);
JS_SetErrorReporter(rt, my_ErrorReporter);
CHECK(!JS_CallFunctionName(cx, global, "check", JS::HandleValueArray::empty(),
&rval));
CHECK(column == 27);

View File

@ -18,7 +18,7 @@ ErrorCounter(JSContext *cx, const char *message, JSErrorReport *report)
BEGIN_TEST(testGCOutOfMemory)
{
JS_SetErrorReporter(cx, ErrorCounter);
JS_SetErrorReporter(rt, ErrorCounter);
JS::RootedValue root(cx);

View File

@ -30,7 +30,7 @@ BEGIN_TEST(testOriginPrincipals)
CHECK(testOuter("(function(){return function(){return 10}}).bind()()"));
CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()"));
JS_SetErrorReporter(cx, ErrorReporter);
JS_SetErrorReporter(rt, ErrorReporter);
CHECK(testError("eval(-)"));
CHECK(testError("-"));
CHECK(testError("new Function('x', '-')"));

View File

@ -283,9 +283,9 @@ Error(JSContext *cx, const char (&input)[N], const char (&expectedLine)[M],
ContextPrivate p = {0, 0};
CHECK(!JS_GetContextPrivate(cx));
JS_SetContextPrivate(cx, &p);
JSErrorReporter old = JS_SetErrorReporter(cx, ReportJSONError);
JSErrorReporter old = JS_SetErrorReporter(rt, ReportJSONError);
bool ok = JS_ParseJSON(cx, str.chars(), str.length(), &dummy);
JS_SetErrorReporter(cx, old);
JS_SetErrorReporter(rt, old);
JS_SetContextPrivate(cx, nullptr);
CHECK(!ok);

View File

@ -13,7 +13,7 @@ static size_t uncaughtCount = 0;
BEGIN_TEST(testUncaughtError)
{
JSErrorReporter old = JS_SetErrorReporter(cx, UncaughtErrorReporter);
JSErrorReporter old = JS_SetErrorReporter(rt, UncaughtErrorReporter);
CHECK(uncaughtCount == 0);
@ -42,7 +42,7 @@ BEGIN_TEST(testUncaughtError)
CHECK(uncaughtCount == 1);
JS_SetErrorReporter(cx, old);
JS_SetErrorReporter(rt, old);
return true;
}

View File

@ -283,6 +283,7 @@ class JSAPITest
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024);
if (!rt)
return nullptr;
JS_SetErrorReporter(rt, &reportError);
setNativeStackQuota(rt);
JS::RuntimeOptionsRef(rt).setVarObjFix(true);
return rt;
@ -302,11 +303,7 @@ class JSAPITest
}
virtual JSContext * createContext() {
JSContext *cx = JS_NewContext(rt, 8192);
if (!cx)
return nullptr;
JS_SetErrorReporter(cx, &reportError);
return cx;
return JS_NewContext(rt, 8192);
}
virtual const JSClass * getGlobalClass() {

View File

@ -4569,7 +4569,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, HandleObject obj, const char *utf8, siz
Parser<frontend::FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
options, chars, length,
/* foldConstants = */ true, nullptr, nullptr);
JSErrorReporter older = JS_SetErrorReporter(cx, nullptr);
JSErrorReporter older = JS_SetErrorReporter(cx->runtime(), nullptr);
if (!parser.parse(obj)) {
// We ran into an error. If it was because we ran out of source, we
// return false so our caller knows to try to collect more buffered
@ -4579,7 +4579,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, HandleObject obj, const char *utf8, siz
cx->clearPendingException();
}
JS_SetErrorReporter(cx, older);
JS_SetErrorReporter(cx->runtime(), older);
js_free(chars);
return result;
@ -5767,18 +5767,18 @@ JS_ReportAllocationOverflow(JSContext *cx)
}
JS_PUBLIC_API(JSErrorReporter)
JS_GetErrorReporter(JSContext *cx)
JS_GetErrorReporter(JSRuntime *rt)
{
return cx->errorReporter;
return rt->errorReporter;
}
JS_PUBLIC_API(JSErrorReporter)
JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er)
{
JSErrorReporter older;
older = cx->errorReporter;
cx->errorReporter = er;
older = rt->errorReporter;
rt->errorReporter = er;
return older;
}
@ -6070,11 +6070,13 @@ JS::AutoSaveExceptionState::restore()
JS::AutoSaveExceptionState::~AutoSaveExceptionState()
{
if (wasPropagatingForcedReturn && !context->isPropagatingForcedReturn())
context->setPropagatingForcedReturn();
if (wasThrowing && !context->isExceptionPending()) {
context->throwing = true;
context->unwrappedException_ = exceptionValue;
if (!context->isExceptionPending()) {
if (wasPropagatingForcedReturn)
context->setPropagatingForcedReturn();
if (wasThrowing) {
context->throwing = true;
context->unwrappedException_ = exceptionValue;
}
}
}

View File

@ -4638,10 +4638,10 @@ struct JSErrorReport {
#define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) & \
JSREPORT_STRICT_MODE_ERROR) != 0)
extern JS_PUBLIC_API(JSErrorReporter)
JS_GetErrorReporter(JSContext *cx);
JS_GetErrorReporter(JSRuntime *rt);
extern JS_PUBLIC_API(JSErrorReporter)
JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);
namespace JS {

View File

@ -387,7 +387,7 @@ js_ReportOutOfMemory(ThreadSafeContext *cxArg)
PopulateReportBlame(cx, &report);
/* Report the error. */
if (JSErrorReporter onError = cx->errorReporter) {
if (JSErrorReporter onError = cx->runtime()->errorReporter) {
AutoSuppressGC suppressGC(cx);
onError(cx, msg, &report);
}
@ -877,7 +877,7 @@ js::CallErrorReporter(JSContext *cx, const char *message, JSErrorReport *reportp
JS_ASSERT(message);
JS_ASSERT(reportp);
if (JSErrorReporter onError = cx->errorReporter)
if (JSErrorReporter onError = cx->runtime()->errorReporter)
onError(cx, message, reportp);
}
@ -1108,7 +1108,6 @@ JSContext::JSContext(JSRuntime *rt)
generatingError(false),
savedFrameChains_(),
cycleDetectorSet(MOZ_THIS_IN_INITIALIZER_LIST()),
errorReporter(nullptr),
data(nullptr),
data2(nullptr),
outstandingRequests(0),

View File

@ -460,9 +460,6 @@ struct JSContext : public js::ExclusiveContext,
/* State for object and array toSource conversion. */
js::ObjectSet cycleDetectorSet;
/* Per-context optional error reporter. */
JSErrorReporter errorReporter;
/* Client opaque pointers. */
void *data;
void *data2;

View File

@ -216,13 +216,13 @@ struct SuppressErrorsGuard
explicit SuppressErrorsGuard(JSContext *cx)
: cx(cx),
prevReporter(JS_SetErrorReporter(cx, nullptr)),
prevReporter(JS_SetErrorReporter(cx->runtime(), nullptr)),
prevState(cx)
{}
~SuppressErrorsGuard()
{
JS_SetErrorReporter(cx, prevReporter);
JS_SetErrorReporter(cx->runtime(), prevReporter);
}
};

View File

@ -195,6 +195,8 @@ NewGlobalObject(JSContext *cx, JS::CompartmentOptions &options,
static const JSErrorFormatString *
my_GetErrorMessage(void *userRef, const unsigned errorNumber);
static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report);
/*
* A toy principals type for the shell.
@ -2699,6 +2701,7 @@ WorkerMain(void *arg)
js_delete(input);
return;
}
JS_SetErrorReporter(rt, my_ErrorReporter);
JSContext *cx = NewContext(rt);
if (!cx) {
@ -5545,7 +5548,6 @@ NewContext(JSRuntime *rt)
}
JS_SetContextPrivate(cx, data);
JS_SetErrorReporter(cx, my_ErrorReporter);
return cx;
}
@ -6182,6 +6184,7 @@ main(int argc, char **argv, char **envp)
if (!rt)
return 1;
JS_SetErrorReporter(rt, my_ErrorReporter);
JS::SetOutOfMemoryCallback(rt, my_OOMCallback, nullptr);
if (!SetRuntimeOptions(rt, op))
return 1;

View File

@ -190,6 +190,7 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
destroyPrincipals(nullptr),
structuredCloneCallbacks(nullptr),
telemetryCallback(nullptr),
errorReporter(nullptr),
propertyRemovals(0),
#if !EXPOSE_INTL_API
thousandsSeparator(0),

View File

@ -1095,6 +1095,9 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Call this to accumulate telemetry data. */
JSAccumulateTelemetryDataCallback telemetryCallback;
/* Optional error reporter. */
JSErrorReporter errorReporter;
/* AsmJSCache callbacks are runtime-wide. */
JS::AsmJSCacheOps asmJSCacheOps;

View File

@ -1030,7 +1030,7 @@ JSRuntime::initSelfHosting(JSContext *cx)
* early in the startup process for any other reporter to be registered
* and we don't want errors in self-hosted code to be silently swallowed.
*/
JSErrorReporter oldReporter = JS_SetErrorReporter(cx, selfHosting_ErrorReporter);
JSErrorReporter oldReporter = JS_SetErrorReporter(cx->runtime(), selfHosting_ErrorReporter);
RootedValue rv(cx);
bool ok = false;
@ -1053,7 +1053,7 @@ JSRuntime::initSelfHosting(JSContext *cx)
ok = Evaluate(cx, shg, options, src, srcLen, &rv);
}
JS_SetErrorReporter(cx, oldReporter);
JS_SetErrorReporter(cx->runtime(), oldReporter);
return ok;
}

View File

@ -122,6 +122,5 @@ XPCJSContextStack::InitSafeJSContext()
mSafeJSContext = JS_NewContext(XPCJSRuntime::Get()->Runtime(), 8192);
if (!mSafeJSContext)
MOZ_CRASH();
JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter);
return mSafeJSContext;
}

View File

@ -3202,6 +3202,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
kStackQuota - kSystemCodeBuffer,
kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer);
JS_SetErrorReporter(runtime, xpc::SystemErrorReporter);
JS_SetDestroyCompartmentCallback(runtime, CompartmentDestroyedCallback);
JS_SetCompartmentNameCallback(runtime, CompartmentNameCallback);
mPrevGCSliceCallback = JS::SetGCSliceCallback(runtime, GCSliceCallback);

View File

@ -960,9 +960,9 @@ ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj, const char *filename, FILE
ok = JS_ExecuteScript(cx, obj, script, &result);
if (ok && result != JSVAL_VOID) {
/* Suppress error reports from JS::ToString(). */
older = JS_SetErrorReporter(cx, nullptr);
older = JS_SetErrorReporter(JS_GetRuntime(cx), nullptr);
str = ToString(cx, result);
JS_SetErrorReporter(cx, older);
JS_SetErrorReporter(JS_GetRuntime(cx), older);
JSAutoByteString bytes;
if (str && bytes.encodeLatin1(cx, str))
fprintf(gOutFile, "%s\n", bytes.ptr());
@ -1265,14 +1265,6 @@ XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
xpc::SystemErrorReporter(cx, message, rep);
}
static bool
ContextCallback(JSContext *cx, unsigned contextOp)
{
if (contextOp == JSCONTEXT_NEW)
JS_SetErrorReporter(cx, XPCShellErrorReporter);
return true;
}
static bool
GetCurrentWorkingDirectory(nsAString& workingDirectory)
{
@ -1454,14 +1446,14 @@ XRE_XPCShellMain(int argc, char **argv, char **envp)
return 1;
}
rtsvc->RegisterContextCallback(ContextCallback);
// Override the default XPConnect interrupt callback. We could store the
// old one and restore it before shutting down, but there's not really a
// reason to bother.
sScriptedInterruptCallback.emplace(rt, UndefinedValue());
JS_SetInterruptCallback(rt, XPCShellInterruptCallback);
JS_SetErrorReporter(rt, XPCShellErrorReporter);
dom::AutoJSAPI jsapi;
jsapi.Init();
cx = jsapi.cx();

View File

@ -2654,24 +2654,6 @@ IsScrollLayerItemAndOverlayScrollbarForScrollFrame(
return false;
}
bool
ContainerState::ItemCoversScrollableArea(nsDisplayItem* aItem, const nsRegion& aOpaque)
{
nsIPresShell* presShell = aItem->Frame()->PresContext()->PresShell();
nsIFrame* rootFrame = presShell->GetRootFrame();
if (mContainerFrame != rootFrame) {
return false;
}
nsRect scrollableArea;
if (presShell->IsScrollPositionClampingScrollPortSizeSet()) {
scrollableArea = nsRect(nsPoint(0, 0),
presShell->GetScrollPositionClampingScrollPortSize());
} else {
scrollableArea = rootFrame->GetRectRelativeToSelf();
}
return aOpaque.Contains(scrollableArea);
}
nsIntRegion
ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
const nsIFrame* aAnimatedGeometryRoot,
@ -2692,8 +2674,8 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
}
if (aAnimatedGeometryRoot == mContainerAnimatedGeometryRoot &&
aFixedPosFrame == mContainerFixedPosFrame &&
!aList->IsOpaque() &&
opaqueClipped.Contains(mContainerBounds)) {
*aHideAllLayersBelow = true;
aList->SetIsOpaque();
}
// Add opaque areas to the "exclude glass" region. Only do this when our
@ -2704,9 +2686,6 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
mBuilder->AddWindowOpaqueRegion(opaqueClipped);
}
opaquePixels = ScaleRegionToInsidePixels(opaqueClipped, snapOpaque);
if (aFixedPosFrame && ItemCoversScrollableArea(aItem, opaque)) {
*aHideAllLayersBelow = true;
}
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
if (sf) {
@ -3552,15 +3531,22 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions,
e->mAnimatedGeometryRoot, e->mFixedPosFrameForLayerData);
SetupScrollingMetadata(e);
if (hideAll) {
e->mVisibleRegion.SetEmpty();
} else if (data) {
e->mVisibleRegion.Sub(e->mVisibleRegion, data->mOpaqueRegion);
} else {
const nsIntRect* clipRect = e->mLayer->GetClipRect();
if (clipRect && opaqueRegionForContainer >= 0 &&
opaqueRegions[opaqueRegionForContainer].mOpaqueRegion.Contains(*clipRect)) {
e->mVisibleRegion.SetEmpty();
} else if (data) {
e->mVisibleRegion.Sub(e->mVisibleRegion, data->mOpaqueRegion);
}
}
SetOuterVisibleRegionForLayer(e->mLayer, e->mVisibleRegion,
e->mLayerContentsVisibleRect.width >= 0 ? &e->mLayerContentsVisibleRect : nullptr);
SetupScrollingMetadata(e);
if (!e->mOpaqueRegion.IsEmpty()) {
const nsIFrame* animatedGeometryRootToCover = e->mAnimatedGeometryRoot;
@ -3575,7 +3561,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
if (!data) {
if (animatedGeometryRootToCover == mContainerAnimatedGeometryRoot &&
!e->mFixedPosFrameForLayerData) {
e->mFixedPosFrameForLayerData == mContainerFixedPosFrame) {
NS_ASSERTION(opaqueRegionForContainer == -1, "Already found it?");
opaqueRegionForContainer = opaqueRegions.Length();
}

View File

@ -928,14 +928,12 @@ nsDisplayListBuilder::GetCaret() {
}
void
nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
const nsRect& aDirtyRect) {
nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame)
{
PresShellState* state = mPresShellStates.AppendElement();
state->mPresShell = aReferenceFrame->PresContext()->PresShell();
state->mCaretFrame = nullptr;
state->mFirstFrameMarkedForDisplay = mFramesMarkedForDisplay.Length();
state->mPrevDirtyRect = mDirtyRect;
mDirtyRect = aDirtyRect;
state->mPresShell->UpdateCanvasBackground();
@ -968,12 +966,11 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
}
void
nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame,
const nsRect& aDirtyRect) {
nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame)
{
NS_ASSERTION(CurrentPresShellState()->mPresShell ==
aReferenceFrame->PresContext()->PresShell(),
"Presshell mismatch");
mDirtyRect = CurrentPresShellState()->mPrevDirtyRect;
ResetMarkedFramesForDisplayList();
mPresShellStates.SetLength(mPresShellStates.Length() - 1);
}

View File

@ -367,10 +367,9 @@ public:
nsCaret* GetCaret();
/**
* Notify the display list builder that we're entering a presshell.
* aReferenceFrame should be a frame in the new presshell and aDirtyRect
* should be the current dirty rect in aReferenceFrame's coordinate space.
* aReferenceFrame should be a frame in the new presshell.
*/
void EnterPresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
void EnterPresShell(nsIFrame* aReferenceFrame);
/**
* For print-preview documents, we sometimes need to build display items for
* the same frames multiple times in the same presentation, with different
@ -382,7 +381,7 @@ public:
/**
* Notify the display list builder that we're leaving a presshell.
*/
void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
void LeavePresShell(nsIFrame* aReferenceFrame);
/**
* Returns true if we're currently building a display list that's
@ -710,7 +709,6 @@ private:
nsIPresShell* mPresShell;
nsIFrame* mCaretFrame;
nsRect mCaretRect;
nsRect mPrevDirtyRect;
uint32_t mFirstFrameMarkedForDisplay;
bool mIsBackgroundOnly;
};

View File

@ -2632,7 +2632,6 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
nsDisplayListBuilder builder(aFrame, nsDisplayListBuilder::EVENT_DELIVERY,
false);
nsDisplayList list;
nsRect target(aRect);
if (aFlags & IGNORE_PAINT_SUPPRESSION) {
builder.IgnorePaintSuppression();
@ -2649,9 +2648,9 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
builder.SetDescendIntoSubdocuments(false);
}
builder.EnterPresShell(aFrame, target);
aFrame->BuildDisplayListForStackingContext(&builder, target, &list);
builder.LeavePresShell(aFrame, target);
builder.EnterPresShell(aFrame);
aFrame->BuildDisplayListForStackingContext(&builder, aRect, &list);
builder.LeavePresShell(aFrame);
#ifdef MOZ_DUMP_PAINTING
if (gDumpEventList) {
@ -2664,7 +2663,7 @@ nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
#endif
nsDisplayItem::HitTestState hitTestState;
list.HitTest(&builder, target, &hitTestState, &aOutFrames);
list.HitTest(&builder, aRect, &hitTestState, &aOutFrames);
list.DeleteAll();
return NS_OK;
}
@ -2881,8 +2880,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
}
}
builder.EnterPresShell(aFrame);
nsRect dirtyRect = visibleRegion.GetBounds();
builder.EnterPresShell(aFrame, dirtyRect);
{
// If a scrollable container layer is created in nsDisplayList::PaintForFrame,
// it will be the scroll parent for display items that are built in the
@ -2929,6 +2928,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) {
nsRect bounds = nsRect(builder.ToReferenceFrame(aFrame),
aFrame->GetSize());
nsDisplayListBuilder::AutoBuildingDisplayList
buildingDisplayList(&builder, aFrame, bounds, false);
presShell->AddPrintPreviewBackgroundItem(builder, list, aFrame, bounds);
} else if (frameType != nsGkAtoms::pageFrame) {
// For printing, this function is first called on an nsPageFrame, which
@ -2941,6 +2942,8 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
// happens after we've built the list so that AddCanvasBackgroundColorItem
// can monkey with the contents if necessary.
canvasArea.IntersectRect(canvasArea, visibleRegion.GetBounds());
nsDisplayListBuilder::AutoBuildingDisplayList
buildingDisplayList(&builder, aFrame, canvasArea, false);
presShell->AddCanvasBackgroundColorItem(
builder, list, aFrame, canvasArea, aBackstop);
@ -2961,7 +2964,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
}
}
builder.LeavePresShell(aFrame, dirtyRect);
builder.LeavePresShell(aFrame);
if (builder.GetHadToIgnorePaintSuppression()) {
willFlushRetainedLayers = true;

View File

@ -716,8 +716,8 @@ public:
/**
* Gets the transform for aFrame relative to aAncestor. Pass null for aAncestor
* to go up to the root frame.
* Gets the transform for aFrame relative to aAncestor. Pass null for
* aAncestor to go up to the root frame.
*/
static Matrix4x4 GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor);
@ -765,8 +765,8 @@ public:
/**
* Given a point in the global coordinate space, returns that point expressed
* in the coordinate system of aFrame. This effectively inverts all transforms
* between this point and the root frame.
* in the coordinate system of aFrame. This effectively inverts all
* transforms between this point and the root frame.
*
* @param aFrame The frame that acts as the coordinate space container.
* @param aPoint The point, in the global space, to get in the frame-local space.
@ -887,9 +887,9 @@ public:
* or the root of a popup) with an associated widget and we draw using
* the layer manager for the frame's widget.
* @param aDirtyRegion the region that must be painted, in the coordinates
* of aFrame
* of aFrame.
* @param aBackstop paint the dirty area with this color before drawing
* the actual content; pass NS_RGBA(0,0,0,0) to draw no background
* the actual content; pass NS_RGBA(0,0,0,0) to draw no background.
* @param aFlags if PAINT_IN_TRANSFORM is set, then we assume
* this is inside a transform or SVG foreignObject. If
* PAINT_SYNC_DECODE_IMAGES is set, we force synchronous decode on all
@ -905,15 +905,15 @@ public:
* If PAINT_EXISTING_TRANSACTION is set, then BeginTransaction() has already
* been called on aFrame's widget's layer manager and should not be
* called again.
* If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode
* to avoid short cut optimizations.
* If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to
* compressed mode to avoid short cut optimizations.
*
* So there are three possible behaviours:
* 1) PAINT_WIDGET_LAYERS is set and aRenderingContext is null; we paint
* by calling BeginTransaction on the widget's layer manager
* by calling BeginTransaction on the widget's layer manager.
* 2) PAINT_WIDGET_LAYERS is set and aRenderingContext is non-null; we
* paint by calling BeginTransactionWithTarget on the widget's layer
* maanger
* manager.
* 3) PAINT_WIDGET_LAYERS is not set and aRenderingContext is non-null;
* we paint by construct a BasicLayerManager and calling
* BeginTransactionWithTarget on it. This is desirable if we're doing
@ -927,15 +927,16 @@ public:
/**
* Uses a binary search for find where the cursor falls in the line of text
* It also keeps track of the part of the string that has already been measured
* so it doesn't have to keep measuring the same text over and over
* It also keeps track of the part of the string that has already been
* measured so it doesn't have to keep measuring the same text over and over.
*
* @param "aBaseWidth" contains the width in twips of the portion
* of the text that has already been measured, and aBaseInx contains
* the index of the text that has already been measured.
*
* @param aTextWidth returns the (in twips) the length of the text that falls
* before the cursor aIndex contains the index of the text where the cursor falls
* @param aTextWidth returns (in twips) the length of the text that falls
* before the cursor aIndex contains the index of the text where the cursor
* falls.
*/
static bool
BinarySearchForPosition(nsRenderingContext* acx,
@ -1145,8 +1146,8 @@ public:
/**
* Check whether aFrame is a part of the scrollbar or scrollcorner of
* the root content.
* @param aFrame the checking frame
* @return if TRUE, the frame is a part of the scrollbar or scrollcorner of
* @param aFrame the checking frame.
* @return true if the frame is a part of the scrollbar or scrollcorner of
* the root content.
*/
static bool IsViewportScrollbarFrame(nsIFrame* aFrame);
@ -1184,7 +1185,7 @@ public:
* not handle 'auto'. It ensures that the result is nonnegative.
*
* @param aRenderingContext Rendering context for font measurement/metrics.
* @param aFrame Frame whose (min-/max-/)width is being computed
* @param aFrame Frame whose (min-/max-/)width is being computed.
* @param aContainingBlockWidth Width of aFrame's containing block.
* @param aContentEdgeToBoxSizing The sum of any left/right padding and
* border that goes inside the rect chosen by box-sizing.
@ -1425,8 +1426,7 @@ public:
* that size.)
* @param aDest The position and scaled area where one copy of
* the image should be drawn.
* @param aFill The area to be filled with copies of the
* image.
* @param aFill The area to be filled with copies of the image.
* @param aAnchor A point in aFill which we will ensure is
* pixel-aligned in the output.
* @param aDirty Pixels outside this area may be skipped.
@ -1487,7 +1487,7 @@ public:
* appropriate scale and transform for drawing in
* app units.
* @param aImage The image.
* @param aDest The top-left where the image should be drawn
* @param aDest The top-left where the image should be drawn.
* @param aDirty If non-null, then pixels outside this area may
* be skipped.
* @param aImageFlags Image flags of the imgIContainer::FLAG_* variety
@ -1512,7 +1512,7 @@ public:
* appropriate scale and transform for drawing in
* app units.
* @param aImage The image.
* @param aDest The area that the image should fill
* @param aDest The area that the image should fill.
* @param aDirty Pixels outside this area may be skipped.
* @param aSVGContext If non-null, SVG-related rendering context
* such as overridden attributes on the image
@ -1619,7 +1619,7 @@ public:
* the widget's transparency. For menupopups,
* aBackgroundFrame and aCSSRootFrame will be the
* same.
* @return a value suitable for passing to SetWindowTranslucency
* @return a value suitable for passing to SetWindowTranslucency.
*/
static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
nsIFrame* aCSSRootFrame);

View File

@ -5005,16 +5005,14 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange,
info = new RangePaintInfo(range, ancestorFrame);
nsRect ancestorRect = ancestorFrame->GetVisualOverflowRect();
// get a display list containing the range
info->mBuilder.SetIncludeAllOutOfFlows();
if (aForPrimarySelection) {
info->mBuilder.SetSelectedFramesOnly();
}
info->mBuilder.EnterPresShell(ancestorFrame, ancestorRect);
info->mBuilder.EnterPresShell(ancestorFrame);
ancestorFrame->BuildDisplayListForStackingContext(&info->mBuilder,
ancestorRect, &info->mList);
ancestorFrame->GetVisualOverflowRect(), &info->mList);
#ifdef DEBUG
if (gDumpRangePaintList) {
@ -5025,7 +5023,7 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange,
nsRect rangeRect = ClipListToRange(&info->mBuilder, &info->mList, range);
info->mBuilder.LeavePresShell(ancestorFrame, ancestorRect);
info->mBuilder.LeavePresShell(ancestorFrame);
#ifdef DEBUG
if (gDumpRangePaintList) {
@ -6074,10 +6072,10 @@ public:
nsDisplayList list;
nsAutoTArray<nsIFrame*, 100> outFrames;
nsDisplayItem::HitTestState hitTestState;
builder.EnterPresShell(mFrame);
nsRect bounds = mShell->GetPresContext()->GetVisibleArea();
builder.EnterPresShell(mFrame, bounds);
mFrame->BuildDisplayListForStackingContext(&builder, bounds, &list);
builder.LeavePresShell(mFrame, bounds);
builder.LeavePresShell(mFrame);
list.HitTest(&builder, bounds, &hitTestState, &outFrames);
list.DeleteAll();
for (int32_t i = outFrames.Length() - 1; i >= 0; --i) {
@ -7585,6 +7583,7 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus)
isHandlingUserInput = true;
break;
case NS_TOUCH_START: {
isHandlingUserInput = true;
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
// if there is only one touch in this touchstart event, assume that it is
// the start of a new touch session and evict any old touches in the
@ -7609,8 +7608,10 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus)
}
break;
}
case NS_TOUCH_CANCEL:
case NS_TOUCH_END: {
case NS_TOUCH_END:
isHandlingUserInput = true;
// Fall through to touchcancel code
case NS_TOUCH_CANCEL: {
// Remove the changed touches
// need to make sure we only remove touches that are ending here
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();

View File

@ -0,0 +1,13 @@
<html>
<head></head>
<body>
<div id="firstDiv">
Parent1
</div>
<div id="secondDiv">
Parent2<div contenteditable id="editable">Testing 1</div></div>
</body>
</html>

View File

@ -0,0 +1,40 @@
<html>
<head>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script>
function runTest() {
var sel = window.getSelection();
var r = new Range()
r.setStart(document.querySelector("#firstDiv"),0);
r.setEnd(document.querySelector("#firstDiv"),1);
sel.addRange(r)
document.querySelector("#editable").focus();
document.querySelector("#secondDiv").appendChild(document.querySelector("#editable"));
is(sel.rangeCount, 1, "still have a range in Selection")
var s=""
try {
var r2 = sel.getRangeAt(0)
s+=r2.startContainer.tagName
s+=r2.startOffset
s+=r2.endContainer.tagName
s+=r2.endOffset
} catch(e) {}
is(s, "DIV1DIV1", "the range gravitated correctly")
}
</script>
</head>
<body onload="runTest()">
<div id="firstDiv">
Parent1
<div contenteditable id="editable">Testing 1</div>
</div>
<div id="secondDiv">
Parent2</div>
</body>
</html>

View File

@ -52,6 +52,8 @@ support-files =
bug570378-persian-5.html
bug570378-persian-5-ref.html
bug644768.html
bug1061468.html
bug1061468-ref.html
[test_preserve3d_sorting_hit_testing.html]
[test_after_paint_pref.html]

View File

@ -143,6 +143,7 @@ var tests = [
[ 'bug746993-1.html' , 'bug746993-1-ref.html' ] ,
[ 'bug1007065-1.html' , 'bug1007065-1-ref.html' ] ,
[ 'bug1007067-1.html' , 'bug1007067-1-ref.html' ] ,
[ 'bug1061468.html' , 'bug1061468-ref.html' ] ,
function() {SpecialPowers.clearUserPref("touchcaret.enabled");} ,
];

View File

@ -3036,18 +3036,18 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
nsRect* aClipRect,
nsTArray<FrameMetrics>* aOutput) const
{
nsRect viewport = mScrollPort +
mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
if (!(mIsRoot && mOuter->PresContext()->PresShell()->GetIsViewportOverridden())) {
*aClipRect = viewport;
}
if (!mShouldBuildScrollableLayer || BuildScrollContainerLayers()) {
return;
}
MOZ_ASSERT(mScrolledFrame->GetContent());
nsRect viewport = mScrollPort +
mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
if (!(mIsRoot && mOuter->PresContext()->PresShell()->GetIsViewportOverridden())) {
*aClipRect = viewport;
}
*aOutput->AppendElement() =
nsDisplayScrollLayer::ComputeFrameMetrics(mScrolledFrame, mOuter,
aContainerReferenceFrame, aLayer, mScrollParentID,

View File

@ -4265,6 +4265,16 @@ Selection::GetCachedFrameOffset(nsIFrame* aFrame, int32_t inOffset,
return rv;
}
NS_IMETHODIMP
Selection::GetAncestorLimiter(nsIContent** aContent)
{
if (mFrameSelection) {
nsCOMPtr<nsIContent> c = mFrameSelection->GetAncestorLimiter();
c.forget(aContent);
}
return NS_OK;
}
NS_IMETHODIMP
Selection::SetAncestorLimiter(nsIContent* aContent)
{

View File

@ -429,7 +429,9 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
aBuilder->EnterPresShell(subdocRootFrame, dirty);
aBuilder->EnterPresShell(subdocRootFrame);
} else {
dirty = aDirtyRect;
}
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
@ -489,19 +491,24 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
*aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this,
bounds);
} else {
// Invoke AutoBuildingDisplayList to ensure that the correct dirty rect
// is used to compute the visible rect if AddCanvasBackgroundColorItem
// creates a display item.
nsIFrame* frame = subdocRootFrame ? subdocRootFrame : this;
nsDisplayListBuilder::AutoBuildingDisplayList
building(aBuilder, frame, dirty, true);
// Add the canvas background color to the bottom of the list. This
// happens after we've built the list so that AddCanvasBackgroundColorItem
// can monkey with the contents if necessary.
uint32_t flags = nsIPresShell::FORCE_DRAW;
presShell->AddCanvasBackgroundColorItem(
*aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this,
bounds, NS_RGBA(0,0,0,0), flags);
*aBuilder, childItems, frame, bounds, NS_RGBA(0,0,0,0), flags);
}
}
}
if (subdocRootFrame) {
aBuilder->LeavePresShell(subdocRootFrame, dirty);
aBuilder->LeavePresShell(subdocRootFrame);
if (ignoreViewportScrolling) {
aBuilder->SetIgnoreScrollFrame(savedIgnoreScrollFrame);

View File

@ -2,11 +2,6 @@
# 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/.
ifdef GNU_CC
OS_CFLAGS := $(OS_CFLAGS) -Wshadow
OS_CXXFLAGS := $(OS_CXXFLAGS) -Wshadow
endif
INSTALL_TARGETS += structlist
structlist_FILES := nsStyleStructList.h
structlist_DEST = $(DIST)/include

View File

@ -558,6 +558,15 @@ StyleAnimationValue::ComputeDistance(nsCSSProperty aProperty,
aDistance = sqrt(difflen * difflen + diffpct * diffpct);
return true;
}
case eUnit_ObjectPosition: {
const nsCSSValue* position1 = aStartValue.GetCSSValueValue();
const nsCSSValue* position2 = aEndValue.GetCSSValueValue();
double squareDistance =
CalcPositionSquareDistance(*position1,
*position2);
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_CSSValuePair: {
const nsCSSValuePair *pair1 = aStartValue.GetCSSValuePairValue();
const nsCSSValuePair *pair2 = aEndValue.GetCSSValuePairValue();
@ -2067,6 +2076,18 @@ StyleAnimationValue::AddWeighted(nsCSSProperty aProperty,
aResultValue.SetAndAdoptCSSValueValue(val, eUnit_Calc);
return true;
}
case eUnit_ObjectPosition: {
const nsCSSValue* position1 = aValue1.GetCSSValueValue();
const nsCSSValue* position2 = aValue2.GetCSSValueValue();
nsAutoPtr<nsCSSValue> result(new nsCSSValue);
AddPositions(aCoeff1, *position1,
aCoeff2, *position2, *result);
aResultValue.SetAndAdoptCSSValueValue(result.forget(),
eUnit_ObjectPosition);
return true;
}
case eUnit_CSSValuePair: {
const nsCSSValuePair *pair1 = aValue1.GetCSSValuePairValue();
const nsCSSValuePair *pair2 = aValue2.GetCSSValuePairValue();
@ -2609,7 +2630,8 @@ StyleAnimationValue::UncomputeValue(nsCSSProperty aProperty,
const StyleAnimationValue& aComputedValue,
nsCSSValue& aSpecifiedValue)
{
switch (aComputedValue.GetUnit()) {
Unit unit = aComputedValue.GetUnit();
switch (unit) {
case eUnit_Normal:
aSpecifiedValue.SetNormalValue();
break;
@ -2642,9 +2664,15 @@ StyleAnimationValue::UncomputeValue(nsCSSProperty aProperty,
// colors can be alone, or part of a paint server
aSpecifiedValue.SetColorValue(aComputedValue.GetColorValue());
break;
case eUnit_Calc: {
nsCSSValue *val = aComputedValue.GetCSSValueValue();
NS_ABORT_IF_FALSE(val->GetUnit() == eCSSUnit_Calc, "unexpected unit");
case eUnit_Calc:
case eUnit_ObjectPosition: {
nsCSSValue* val = aComputedValue.GetCSSValueValue();
// Sanity-check that the underlying unit in the nsCSSValue is what we
// expect for our StyleAnimationValue::Unit:
MOZ_ASSERT((unit == eUnit_Calc && val->GetUnit() == eCSSUnit_Calc) ||
(unit == eUnit_ObjectPosition &&
val->GetUnit() == eCSSUnit_Array),
"unexpected unit");
aSpecifiedValue = *val;
break;
}
@ -3180,6 +3208,18 @@ StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
break;
}
case eCSSProperty_object_position: {
const nsStylePosition* stylePos =
static_cast<const nsStylePosition*>(styleStruct);
nsAutoPtr<nsCSSValue> val(new nsCSSValue);
SetPositionValue(stylePos->mObjectPosition, *val);
aComputedValue.SetAndAdoptCSSValueValue(val.forget(),
eUnit_ObjectPosition);
break;
}
case eCSSProperty_background_position: {
const nsStyleBackground *bg =
static_cast<const nsStyleBackground*>(styleStruct);
@ -3574,6 +3614,9 @@ StyleAnimationValue::operator=(const StyleAnimationValue& aOther)
mValue.mColor = aOther.mValue.mColor;
break;
case eUnit_Calc:
case eUnit_ObjectPosition:
NS_ABORT_IF_FALSE(IsCSSValueUnit(mUnit),
"This clause is for handling nsCSSValue-backed units");
NS_ABORT_IF_FALSE(aOther.mValue.mCSSValue, "values may not be null");
mValue.mCSSValue = new nsCSSValue(*aOther.mValue.mCSSValue);
if (!mValue.mCSSValue) {
@ -3836,6 +3879,9 @@ StyleAnimationValue::operator==(const StyleAnimationValue& aOther) const
case eUnit_Color:
return mValue.mColor == aOther.mValue.mColor;
case eUnit_Calc:
case eUnit_ObjectPosition:
NS_ABORT_IF_FALSE(IsCSSValueUnit(mUnit),
"This clause is for handling nsCSSValue-backed units");
return *mValue.mCSSValue == *aOther.mValue.mCSSValue;
case eUnit_CSSValuePair:
return *mValue.mCSSValuePair == *aOther.mValue.mCSSValuePair;

View File

@ -214,6 +214,8 @@ public:
eUnit_Color,
eUnit_Calc, // nsCSSValue* (never null), always with a single
// calc() expression that's either length or length+percent
eUnit_ObjectPosition, // nsCSSValue* (never null), always with a
// 4-entry nsCSSValue::Array
eUnit_CSSValuePair, // nsCSSValuePair* (never null)
eUnit_CSSValueTriplet, // nsCSSValueTriplet* (never null)
eUnit_CSSRect, // nsCSSRect* (never null)
@ -374,7 +376,8 @@ private:
aUnit == eUnit_Integer;
}
static bool IsCSSValueUnit(Unit aUnit) {
return aUnit == eUnit_Calc;
return aUnit == eUnit_Calc ||
aUnit == eUnit_ObjectPosition;
}
static bool IsCSSValuePairUnit(Unit aUnit) {
return aUnit == eUnit_CSSValuePair;

View File

@ -168,3 +168,7 @@ RESOURCE_FILES += [
'TopLevelImageDocument.css',
'TopLevelVideoDocument.css',
]
if CONFIG['GNU_CC']:
CFLAGS += ['-Wshadow']
CXXFLAGS += ['-Wshadow']

View File

@ -441,6 +441,7 @@ CSS_KEY(s-resize, s_resize)
CSS_KEY(saturate, saturate)
CSS_KEY(saturation, saturation)
CSS_KEY(scale, scale)
CSS_KEY(scale-down, scale_down)
CSS_KEY(scale3d, scale3d)
CSS_KEY(scalex, scalex)
CSS_KEY(scaley, scaley)

View File

@ -781,6 +781,7 @@ protected:
bool ParseMargin();
bool ParseMarks(nsCSSValue& aValue);
bool ParseTransform(bool aIsPrefixed);
bool ParseObjectPosition();
bool ParseOutline();
bool ParseOverflow();
bool ParsePadding();
@ -9788,6 +9789,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
case eCSSProperty_margin_start:
return ParseDirectionalBoxProperty(eCSSProperty_margin_start,
NS_BOXPROP_SOURCE_LOGICAL);
case eCSSProperty_object_position:
return ParseObjectPosition();
case eCSSProperty_outline:
return ParseOutline();
case eCSSProperty_overflow:
@ -12892,6 +12895,18 @@ CSSParserImpl::ParseMarks(nsCSSValue& aValue)
return false;
}
bool
CSSParserImpl::ParseObjectPosition()
{
nsCSSValue value;
if (!ParseVariant(value, VARIANT_INHERIT, nullptr) &&
!ParsePositionValue(value)) {
return false;
}
AppendValue(eCSSProperty_object_position, value);
return true;
}
bool
CSSParserImpl::ParseOutline()
{

View File

@ -2521,6 +2521,27 @@ CSS_PROP_DISPLAY(
kBlendModeKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_POSITION(
object-fit,
object_fit,
ObjectFit,
CSS_PROPERTY_PARSE_VALUE,
"layout.css.object-fit-and-position.enabled",
VARIANT_HK,
kObjectFitKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_POSITION(
object-position,
object_position,
ObjectPosition,
CSS_PROPERTY_PARSE_FUNCTION |
CSS_PROPERTY_STORES_CALC,
"layout.css.object-fit-and-position.enabled",
0,
kBackgroundPositionKTable,
offsetof(nsStylePosition, mObjectPosition),
eStyleAnimType_Custom)
CSS_PROP_DISPLAY(
opacity,
opacity,

View File

@ -1432,6 +1432,15 @@ const KTableValue nsCSSProps::kContextPatternKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
const KTableValue nsCSSProps::kObjectFitKTable[] = {
eCSSKeyword_fill, NS_STYLE_OBJECT_FIT_FILL,
eCSSKeyword_contain, NS_STYLE_OBJECT_FIT_CONTAIN,
eCSSKeyword_cover, NS_STYLE_OBJECT_FIT_COVER,
eCSSKeyword_none, NS_STYLE_OBJECT_FIT_NONE,
eCSSKeyword_scale_down, NS_STYLE_OBJECT_FIT_SCALE_DOWN,
eCSSKeyword_UNKNOWN, -1
};
const KTableValue nsCSSProps::kOrientKTable[] = {
eCSSKeyword_horizontal, NS_STYLE_ORIENT_HORIZONTAL,
eCSSKeyword_vertical, NS_STYLE_ORIENT_VERTICAL,

View File

@ -601,6 +601,7 @@ public:
static const KTableValue kMathDisplayKTable[];
static const KTableValue kContextOpacityKTable[];
static const KTableValue kContextPatternKTable[];
static const KTableValue kObjectFitKTable[];
static const KTableValue kOrientKTable[];
static const KTableValue kOutlineStyleKTable[];
static const KTableValue kOutlineColorKTable[];

View File

@ -4187,6 +4187,23 @@ nsComputedDOMStyle::DoGetMixBlendMode()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetObjectFit()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
val->SetIdent(nsCSSProps::ValueToKeywordEnum(StylePosition()->mObjectFit,
nsCSSProps::kObjectFitKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetObjectPosition()
{
nsDOMCSSValueList* valueList = GetROCSSValueList(false);
SetValueToPosition(StylePosition()->mObjectPosition, valueList);
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetLeft()
{

Some files were not shown because too many files have changed in this diff Show More