Merge last PGO-green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2012-02-20 12:08:28 +00:00
commit efe21ddd01
82 changed files with 1437 additions and 649 deletions

View File

@ -94,8 +94,8 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
skipEnd++;
}
PRInt32 strLen1 = oldLen - aSkipStart - skipEnd;
PRInt32 strLen2 = newLen - aSkipStart - skipEnd;
PRUint32 strLen1 = oldLen - aSkipStart - skipEnd;
PRUint32 strLen2 = newLen - aSkipStart - skipEnd;
const nsAString& str1 = Substring(aOldText, aSkipStart, strLen1);
const nsAString& str2 = Substring(aNewText, aSkipStart, strLen2);
@ -187,7 +187,7 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1,
PRInt32 colLen = colEnd + 1;
PRUint32* row = aEntries + rowIdx * colLen;
PRInt32 dist = row[colIdx]; // current Levenshtein distance
PRUint32 dist = row[colIdx]; // current Levenshtein distance
while (rowIdx && colIdx) { // stop when we can't move diagonally
if (aStr1[colIdx - 1] == aStr2[rowIdx - 1]) { // match
if (rowIdx < rowEnd) { // deal with any pending insertion

View File

@ -1521,30 +1521,17 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
RETURN_LAYOUT_ANSWER(false, ">= kMaxLayoutRows (20) and non-bordered");
}
// Check for very wide table
nsAutoString styledWidth;
GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("width"), styledWidth);
if (styledWidth.EqualsLiteral("100%")) {
RETURN_LAYOUT_ANSWER(true, "<=4 columns and 100% width");
}
if (styledWidth.Find(NS_LITERAL_STRING("px"))) { // Hardcoded in pixels
nsIFrame *tableFrame = GetFrame();
NS_ENSURE_TRUE(tableFrame , NS_ERROR_FAILURE);
nsSize tableSize = tableFrame->GetSize();
nsDocAccessible* docAccessible = Document();
NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
nsIFrame *docFrame = docAccessible->GetFrame();
NS_ENSURE_TRUE(docFrame , NS_ERROR_FAILURE);
nsSize docSize = docFrame->GetSize();
if (docSize.width > 0) {
PRInt32 percentageOfDocWidth = (100 * tableSize.width) / docSize.width;
if (percentageOfDocWidth > 95) {
// 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
// Probably for layout
RETURN_LAYOUT_ANSWER(true, "<=4 columns, width hardcoded in pixels and 95% of document width");
}
// Check for very wide table.
nsIFrame* documentFrame = Document()->GetFrame();
nsSize documentSize = documentFrame->GetSize();
if (documentSize.width > 0) {
nsSize tableSize = GetFrame()->GetSize();
PRInt32 percentageOfDocWidth = (100 * tableSize.width) / documentSize.width;
if (percentageOfDocWidth > 95) {
// 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
// Probably for layout
RETURN_LAYOUT_ANSWER(true,
"<= 4 columns, table width is 95% of document width");
}
}

View File

@ -26,6 +26,7 @@ function test() {
// Now trigger the invalid URI test
executeSoon(function () {
info("Dialog closed? " + domwindow.closed + "\n");
let consoleListener = {
observe: function (m) {
info("m: " + m + "\n");
@ -44,6 +45,14 @@ function test() {
// The drop handler throws an exception when dragging URIs that inherit
// principal, e.g. javascript:
expectUncaughtException();
let originalHandler = homeButtonObserver.onDrop;
homeButtonObserver.onDrop = function (aEvent) {
info("homeButtonObserver.onDrop called");
originalHandler(aEvent);
};
registerCleanupFunction(function () {
homeButtonObserver.onDrop = originalHandler;
});
chromeUtils.synthesizeDrop(homeButton, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window, EventUtils);
})
});

View File

@ -181,9 +181,9 @@
/* Toolbar shadow behind tabs */
/* This code is only needed for restored windows (i.e. sizemode=normal)
because of the border radius on the toolbar below the tab bar. */
#main-window[sizemode=normal][tabsontop=true] #nav-bar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
#main-window[sizemode=normal][tabsontop=true][disablechrome] #navigator-toolbox:not(:-moz-lwtheme)::after {
border-top: 1px solid @toolbarShadowColor@;
border-top-left-radius: 3.5px;

View File

@ -2483,11 +2483,10 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
if (aAllowShortCircuit) {
nsIPrincipal *principal = doGetObjectPrincipal(origObj, false);
// Location is always wrapped (even for same-compartment), so we can
// loosen the check to same-origin instead of same-principal.
NS_ASSERTION(strcmp(jsClass->name, "Location") == 0 ?
NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)) :
result == principal,
// Because of inner window reuse, we can have objects with one principal
// living in a scope with a different (but same-origin) principal. So
// just check same-origin here.
NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
"Principal mismatch. Not good");
}
#endif

View File

@ -5,6 +5,7 @@ NSS_DIRS = (('dbm', 'mozilla/dbm'),
('security/nss', 'mozilla/security/nss'),
('security/coreconf', 'mozilla/security/coreconf'),
('security/dbm', 'mozilla/security/dbm'))
NSSCKBI_DIRS = (('security/nss/lib/ckfw/builtins', 'mozilla/security/nss/lib/ckfw/builtins'),)
LIBFFI_DIRS = (('js/ctypes/libffi', 'libffi'),)
CVSROOT_MOZILLA = ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'
@ -91,6 +92,13 @@ elif action in ('update_nss'):
options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
do_cvs_export(NSS_DIRS, tag, options.cvsroot, options.cvs)
print >>file("security/nss/TAG-INFO", "w"), tag
print >>file("security/nss/TAG-INFO-CKBI", "w"), tag
elif action in ('update_nssckbi'):
tag, = args[1:]
if not options.cvsroot:
options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
do_cvs_export(NSSCKBI_DIRS, tag, options.cvsroot, options.cvs)
print >>file("security/nss/TAG-INFO-CKBI", "w"), tag
elif action in ('update_libffi'):
tag, = args[1:]
if not options.cvsroot:

View File

@ -920,7 +920,7 @@ public:
/**
* Determing language. Look at the nearest ancestor element that has a lang
* attribute in the XML namespace or is an HTML element and has a lang in
* attribute in the XML namespace or is an HTML/SVG element and has a lang in
* no namespace attribute.
*/
void GetLang(nsAString& aResult) const {
@ -930,7 +930,7 @@ public:
// XHTML1 section C.7).
bool hasAttr = content->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang,
aResult);
if (!hasAttr && content->IsHTML()) {
if (!hasAttr && (content->IsHTML() || content->IsSVG())) {
hasAttr = content->GetAttr(kNameSpaceID_None, nsGkAtoms::lang,
aResult);
}

View File

@ -67,7 +67,7 @@ typedef unsigned long long nsContentViewId;
* These APIs are designed to be used with nsIDOMWindowUtils
* setDisplayPort() and setResolution().
*/
[scriptable, uuid(fbd25468-d2cf-487b-bc58-a0e105398b47)]
[scriptable, uuid(c04c5c40-fa2a-4e9c-94f5-b362a10a86cb)]
interface nsIContentView : nsISupports
{
/**
@ -265,6 +265,13 @@ interface nsIFrameLoader : nsISupports
* Defaults to true.
*/
attribute boolean clipSubdocument;
/**
* If false, then the subdocument's scroll coordinates will not be clamped
* to their scroll boundaries.
* Defaults to true.
*/
attribute boolean clampScrollPosition;
};
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);

View File

@ -554,10 +554,9 @@ mozSanitizingHTMLSerializer::IsAllowedAttribute(nsHTMLTag aTag,
NS_ENSURE_TRUE(attr_bag, false);
bool allowed;
nsAutoString attr(anAttributeName);
ToLowerCase(attr);
rv = attr_bag->Has(NS_LossyConvertUTF16toASCII(attr).get(),
&allowed);
nsCAutoString attr;
ToLowerCase(NS_ConvertUTF16toUTF8(anAttributeName), attr);
rv = attr_bag->Has(attr.get(), &allowed);
if (NS_FAILED(rv))
return false;

View File

@ -859,7 +859,7 @@ TransferZoomLevels(nsIDocument* aFromDoc,
return;
toCtxt->SetFullZoom(fromCtxt->GetFullZoom());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize());
toCtxt->SetMinFontSize(fromCtxt->MinFontSize(nsnull));
toCtxt->SetTextZoom(fromCtxt->TextZoom());
}
@ -2119,7 +2119,6 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
}
#endif
SetPrincipal(nsnull);
mSecurityInfo = nsnull;
mDocumentLoadGroup = nsnull;
@ -2169,6 +2168,12 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
// Release the stylesheets list.
mDOMStyleSheets = nsnull;
// Release our principal after tearing down the document, rather than before.
// This ensures that, during teardown, the document and the dying window (which
// already nulled out its document pointer and cached the principal) have
// matching principals.
SetPrincipal(nsnull);
// Clear the original URI so SetDocumentURI sets it.
mOriginalURI = nsnull;
@ -8527,7 +8532,7 @@ public:
NS_IMETHOD Run()
{
if (mDoc->GetWindow()) {
mDoc->GetWindow()->SetFullScreen(mValue);
mDoc->GetWindow()->SetFullScreenInternal(mValue, false);
}
return NS_OK;
}

View File

@ -76,6 +76,7 @@
#include "nsFrameLoader.h"
#include "nsIDOMEventTarget.h"
#include "nsIFrame.h"
#include "nsIScrollableFrame.h"
#include "nsSubDocumentFrame.h"
#include "nsDOMError.h"
#include "nsGUIEvent.h"
@ -330,6 +331,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
, mRemoteBrowserShown(false)
, mRemoteFrame(false)
, mClipSubdocument(true)
, mClampScrollPosition(true)
, mCurrentRemoteFrame(nsnull)
, mRemoteBrowser(nsnull)
, mRenderMode(RENDER_MODE_DEFAULT)
@ -1755,6 +1757,38 @@ nsFrameLoader::SetClipSubdocument(bool aClip)
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::GetClampScrollPosition(bool* aResult)
{
*aResult = mClampScrollPosition;
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::SetClampScrollPosition(bool aClamp)
{
mClampScrollPosition = aClamp;
// When turning clamping on, make sure the current position is clamped.
if (aClamp) {
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
if (frame) {
nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
if (subdocFrame) {
nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
if (subdocRootFrame) {
nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
GetRootScrollFrameAsScrollable();
if (subdocRootScrollFrame) {
subdocRootScrollFrame->ScrollTo(subdocRootScrollFrame->GetScrollPosition(), nsIScrollableFrame::INSTANT);
}
}
}
}
}
return NS_OK;
}
nsIntSize
nsFrameLoader::GetSubDocumentSize(const nsIFrame *aIFrame)
{

View File

@ -289,6 +289,8 @@ public:
bool ShouldClipSubdocument() { return mClipSubdocument; }
bool ShouldClampScrollPosition() { return mClampScrollPosition; }
private:
bool ShouldUseRemoteProcess();
@ -342,6 +344,7 @@ private:
bool mRemoteBrowserShown : 1;
bool mRemoteFrame : 1;
bool mClipSubdocument : 1;
bool mClampScrollPosition : 1;
// XXX leaking
nsCOMPtr<nsIObserver> mChildHost;

View File

@ -1100,6 +1100,7 @@ GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
GK_ATOM(headerCSP, "x-content-security-policy")
GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
GK_ATOM(headerXFO, "x-frame-options")
GK_ATOM(x_western, "x-western")
GK_ATOM(xml, "xml")
GK_ATOM(xml_stylesheet, "xml-stylesheet")
GK_ATOM(xmlns, "xmlns")

View File

@ -1324,6 +1324,14 @@ nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
// If the state is UNSENT or OPENED,
// return the empty string and terminate these steps.
if (mState & (XML_HTTP_REQUEST_UNSENT |
XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) {
*_retval = ToNewCString(EmptyString());
return NS_OK;
}
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
*_retval = ToNewCString(EmptyString());
return NS_OK;
@ -1336,8 +1344,23 @@ nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
nsresult rv = httpChannel->VisitResponseHeaders(visitor);
if (NS_SUCCEEDED(rv))
*_retval = ToNewCString(visitor->Headers());
} else if (mChannel) {
// Even non-http channels supply content type.
nsCString value;
if (NS_SUCCEEDED(mChannel->GetContentType(value))) {
nsCString headers;
headers.Append("Content-Type: ");
headers.Append(value);
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) &&
!value.IsEmpty()) {
headers.Append(";charset=");
headers.Append(value);
}
headers.Append('\n');
*_retval = ToNewCString(headers);
}
}
if (!*_retval) {
*_retval = ToNewCString(EmptyString());
}
@ -1356,6 +1379,37 @@ nsXMLHttpRequest::GetResponseHeader(const nsACString& header,
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
if (!httpChannel) {
// If the state is UNSENT or OPENED,
// return null and terminate these steps.
if (mState & (XML_HTTP_REQUEST_UNSENT |
XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT)) {
return NS_OK;
}
// Even non-http channels supply content type.
// Remember we don't leak header information from denied cross-site
// requests.
nsresult status;
if (!mChannel ||
NS_FAILED(mChannel->GetStatus(&status)) ||
NS_FAILED(status) ||
!header.LowerCaseEqualsASCII("content-type")) {
return NS_OK;
}
if (NS_FAILED(mChannel->GetContentType(_retval))) {
// Means no content type
_retval.SetIsVoid(true);
return NS_OK;
}
nsCString value;
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) &&
!value.IsEmpty()) {
_retval.Append(";charset=");
_retval.Append(value);
}
return NS_OK;
}

View File

@ -22,11 +22,15 @@ function runTests() {
var path = "/tests/content/base/test/";
var passFiles = [['file_XHR_pass1.xml', 'GET', 200],
['file_XHR_pass2.txt', 'GET', 200],
['file_XHR_pass3.txt', 'GET', 200],
['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0],
['data:text/plain,hello%20pass%0A', 'GET', 0],
var passFiles = [['file_XHR_pass1.xml', 'GET', 200, 'text/xml'],
['file_XHR_pass2.txt', 'GET', 200, 'text/plain'],
['file_XHR_pass3.txt', 'GET', 200, 'text/plain'],
['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0, 'text/xml'],
['data:text/plain,hello%20pass%0A', 'GET', 0, 'text/plain'],
['data:,foo', 'GET', 0, 'text/plain;charset=US-ASCII', 'foo'],
['data:text/plain;base64,Zm9v', 'GET', 0, 'text/plain', 'foo'],
['data:text/plain,foo#bar', 'GET', 0, 'text/plain', 'foo'],
['data:text/plain,foo%23bar', 'GET', 0, 'text/plain', 'foo#bar'],
];
var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
@ -36,19 +40,24 @@ var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
for (i = 0; i < passFiles.length; ++i) {
xhr = new XMLHttpRequest();
is(xhr.getResponseHeader("Content-Type"), null, "should be null");
is(xhr.getAllResponseHeaders(), "", "should be empty string");
is(xhr.responseType, "", "wrong initial responseType");
xhr.open(passFiles[i][1], passFiles[i][0], false);
xhr.send(null);
is(xhr.status, passFiles[i][2], "wrong status");
is(xhr.getResponseHeader("Content-Type"), passFiles[i][3], "wrong content type");
var headers = xhr.getAllResponseHeaders();
ok(/(?:^|\n)Content-Type:\s*([^\n]*)\n/i.test(headers) &&
RegExp.$1 === passFiles[i][3], "wrong response headers");
if (xhr.responseXML) {
is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement),
"<res>hello</res>",
"wrong responseXML");
is(xhr.response, "<res>hello</res>\n", "wrong response");
passFiles[i][4] || "<res>hello</res>", "wrong responseXML");
is(xhr.response, passFiles[i][4] || "<res>hello</res>\n", "wrong response");
}
else {
is(xhr.responseText, "hello pass\n", "wrong responseText");
is(xhr.response, "hello pass\n", "wrong response");
is(xhr.responseText, passFiles[i][4] || "hello pass\n", "wrong responseText");
is(xhr.response, passFiles[i][4] || "hello pass\n", "wrong response");
}
}

View File

@ -1292,26 +1292,24 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
mWidth = width;
mHeight = height;
mTarget = target;
// This first time this is called on this object is via
// nsHTMLCanvasElement::GetContext. If target was non-null then mTarget is
// non-null, otherwise we'll return an error here and GetContext won't
// return this context object and we'll never enter this code again.
// All other times this method is called, if target is null then
// mTarget won't be changed, i.e. it will remain non-null, or else it
// will be set to non-null.
// In all cases, any usable canvas context will have non-null mTarget.
if (target) {
mValid = true;
mTarget = target;
} else {
mValid = false;
}
mResetLayer = true;
/* Create dummy surfaces here - target can be null when a canvas was created
* that is too large to support.
*/
if (!target)
{
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
if (!mTarget) {
// SupportsAzure() is controlled by the "gfx.canvas.azure.prefer-skia"
// pref so that may be the reason rather than an OOM.
mValid = false;
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
mValid = true;
}
// set up the initial canvas defaults
mStyleStack.Clear();
mPathBuilder = nsnull;
@ -1325,11 +1323,12 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
state->shadowColor = NS_RGBA(0,0,0,0);
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
if (mTarget) {
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
}
return mValid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -456,6 +456,12 @@ protected:
*/
void SelectResource();
/**
* A wrapper function that allows us to cleanly reset flags after a call
* to SelectResource()
*/
void SelectResourceWrapper();
/**
* Asynchronously awaits a stable state, and then causes SelectResource()
* to be run on the main thread's event loop.
@ -739,6 +745,9 @@ protected:
// or while we're running SelectResource().
bool mIsRunningSelectResource;
// True when we already have select resource call queued
bool mHaveQueuedSelectResource;
// True if we suspended the decoder because we were paused,
// preloading metadata is enabled, autoplay was not enabled, and we loaded
// the first frame.

View File

@ -538,6 +538,7 @@ void nsHTMLMediaElement::AbortExistingLoads()
mIsLoadingFromSourceChildren = false;
mSuspendedAfterFirstFrame = false;
mAllowSuspendAfterFirstFrame = true;
mHaveQueuedSelectResource = false;
mLoadIsSuspended = false;
mSourcePointer = nsnull;
@ -625,11 +626,11 @@ void nsHTMLMediaElement::QueueLoadFromSourceTask()
void nsHTMLMediaElement::QueueSelectResourceTask()
{
// Don't allow multiple async select resource calls to be queued.
if (mIsRunningSelectResource)
if (mHaveQueuedSelectResource)
return;
mIsRunningSelectResource = true;
mHaveQueuedSelectResource = true;
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
AsyncAwaitStableState(this, &nsHTMLMediaElement::SelectResource);
AsyncAwaitStableState(this, &nsHTMLMediaElement::SelectResourceWrapper);
}
/* void load (); */
@ -658,6 +659,13 @@ static bool HasSourceChildren(nsIContent *aElement)
return false;
}
void nsHTMLMediaElement::SelectResourceWrapper()
{
SelectResource();
mIsRunningSelectResource = false;
mHaveQueuedSelectResource = false;
}
void nsHTMLMediaElement::SelectResource()
{
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::src) && !HasSourceChildren(this)) {
@ -666,7 +674,6 @@ void nsHTMLMediaElement::SelectResource()
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
ChangeDelayLoadStatus(false);
mIsRunningSelectResource = false;
return;
}
@ -677,6 +684,12 @@ void nsHTMLMediaElement::SelectResource()
// AddRemoveSelfReference, since it must still be held
DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
// Delay setting mIsRunningSeletResource until after UpdatePreloadAction
// so that we don't lose our state change by bailing out of the preload
// state update
UpdatePreloadAction();
mIsRunningSelectResource = true;
// If we have a 'src' attribute, use that exclusively.
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
@ -691,13 +704,11 @@ void nsHTMLMediaElement::SelectResource()
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();
mIsRunningSelectResource = false;
return;
}
rv = LoadResource();
if (NS_SUCCEEDED(rv)) {
mIsRunningSelectResource = false;
return;
}
} else {
@ -710,7 +721,6 @@ void nsHTMLMediaElement::SelectResource()
mIsLoadingFromSourceChildren = true;
LoadFromSourceChildren();
}
mIsRunningSelectResource = false;
}
void nsHTMLMediaElement::NotifyLoadError()
@ -1441,6 +1451,7 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mIsLoadingFromSourceChildren(false),
mDelayingLoadEvent(false),
mIsRunningSelectResource(false),
mHaveQueuedSelectResource(false),
mSuspendedAfterFirstFrame(false),
mAllowSuspendAfterFirstFrame(true),
mHasPlayedOrSeeked(false),

View File

@ -70,6 +70,12 @@ function nextTest() {
}
}
try {
window.fullScreen = true;
} catch (e) {
}
is(window.fullScreen, false, "Shouldn't be able to set window fullscreen from content");
addLoadEvent(nextTest);
SimpleTest.waitForExplicitFinish();

View File

@ -385,17 +385,16 @@ var tests = [
v.preload = "metadata";
},
},
{
// 13. Change preload value from metadata to none after load started,
// should still load up to metadata, should not halt immediately.
loadeddata:
// 13. Change preload value from auto to none after specifying a src
// should load according to preload none, no buffering should have taken place
suspend:
function(e) {
var v = e.target;
is(v._gotLoadStart, true, "(13) Must get loadstart.");
is(v._gotLoadedMetaData, true, "(13) Must get loadedmetadata.");
ok(v.readyState >= v.HAVE_CURRENT_DATA, "(13) ReadyState must be >= HAVE_CURRENT_DATA.");
is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE.");
is(v._gotLoadedMetaData, false, "(13) Must not get loadedmetadata.");
is(v.readyState, v.HAVE_NOTHING, "(13) ReadyState must be HAVE_NOTHING");
is(v.networkState, v.NETWORK_IDLE, "(13) NetworkState must be NETWORK_IDLE");
maybeFinish(v, 13);
},
@ -403,14 +402,15 @@ var tests = [
function(v) {
v._gotLoadStart = false;
v._gotLoadedMetaData = false;
v.preload = "metadata";
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadeddata", this.loadeddata, false);
v.src = test.name; // Causes implicit load.
document.body.appendChild(v);
v.preload = "auto";
v.src = test.name;
v.preload = "none";
},
v.addEventListener("loadedmetadata", function(e){v._gotLoadedMetaData = true;}, false);
v.addEventListener("loadstart", function(e){v._gotLoadStart = true;}, false);
v.addEventListener("suspend", this.suspend, false);
document.body.appendChild(v); // Causes implicit load, should load according to preload none
var s = document.createElement("source");
}
},
{
// 14. Add preload:metadata video with src to document. Play(), should play through.
@ -521,7 +521,35 @@ var tests = [
document.body.appendChild(v);
v.play(); // Should cause preload:none to be overridden.
},
},
{
// 19. Set preload='auto' on first video source then switching preload='none' and swapping the video source to another.
// The second video should not start playing as it's preload state has been changed to 'none' from 'auto'
loadedmetadata: function(e) {
var v = e.target;
is(v.preload === "auto", true, "(19) preload is initially auto");
setTimeout(function() {
// set preload state to none and switch video sources
v.preload="none";
v.src = test.name + "?asdf";
setTimeout(function() {
is(v.readyState === 0, true, "(19) no buffering has taken place");
maybeFinish(v, 19);
}, 2000);
}, 2000);
},
setup:
function(v) {
var that = this;
v.preload = "auto";
v.src = test.name;
// add a listener for when the video has loaded, so we know preload auto has worked
v.addEventListener( "loadedmetadata", this.loadedmetadata, false);
document.body.appendChild(v);
}
}
];
var iterationCount = 0;

View File

@ -535,7 +535,8 @@ SVGPathData::ToFlattenedPath(const gfxMatrix& aMatrix) const
return ctx->GetFlattenedPath();
}
static float AngleOfVector(gfxPoint v)
static double
AngleOfVector(const gfxPoint& aVector)
{
// C99 says about atan2 "A domain error may occur if both arguments are
// zero" and "On a domain error, the function returns an implementation-
@ -543,18 +544,13 @@ static float AngleOfVector(gfxPoint v)
// seems to commonly be zero, but it could just as easily be a NaN value.
// We specifically want zero in this case, hence the check:
return (v != gfxPoint(0.0f, 0.0f)) ? atan2(v.y, v.x) : 0.0f;
return (aVector != gfxPoint(0.0, 0.0)) ? atan2(aVector.y, aVector.x) : 0.0;
}
// TODO replace callers with calls to AngleOfVector
static double
CalcVectorAngle(double ux, double uy, double vx, double vy)
static float
AngleOfVectorF(const gfxPoint& aVector)
{
double ta = atan2(uy, ux);
double tb = atan2(vy, vx);
if (tb >= ta)
return tb-ta;
return 2 * M_PI - (ta-tb);
return static_cast<float>(AngleOfVector(aVector));
}
void
@ -588,7 +584,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
{
case nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH:
segEnd = pathStart;
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
break;
case nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS:
@ -601,7 +597,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
pathStart = segEnd;
// If authors are going to specify multiple consecutive moveto commands
// with markers, me might as well make the angle do something useful:
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
i += 2;
break;
@ -612,7 +608,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + gfxPoint(mData[i], mData[i+1]);
}
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
i += 2;
break;
@ -636,8 +632,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
if (cp2 == segEnd) {
cp2 = cp1;
}
segStartAngle = AngleOfVector(cp1 - segStart);
segEndAngle = AngleOfVector(segEnd - cp2);
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp2);
i += 6;
break;
}
@ -654,8 +650,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
segEnd = segStart + gfxPoint(mData[i+2], mData[i+3]);
}
prevCP = cp1;
segStartAngle = AngleOfVector(cp1 - segStart);
segEndAngle = AngleOfVector(segEnd - cp1);
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp1);
i += 4;
break;
}
@ -695,7 +691,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
if (rx == 0.0 || ry == 0.0) {
// F.6.6 step 1 - straight line or coincidental points
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
i += 7;
break;
}
@ -736,9 +732,10 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
double cyp = -root * ry * x1p / rx;
double theta, delta;
theta = CalcVectorAngle(1.0, 0.0, (x1p-cxp)/rx, (y1p-cyp)/ry); // F.6.5.5
delta = CalcVectorAngle((x1p-cxp)/rx, (y1p-cyp)/ry,
(-x1p-cxp)/rx, (-y1p-cyp)/ry); // F.6.5.6
theta = AngleOfVector(gfxPoint((x1p-cxp)/rx, (y1p-cyp)/ry) - // F.6.5.5
gfxPoint(1.0, 0.0));
delta = AngleOfVector(gfxPoint((-x1p-cxp)/rx, (-y1p-cyp)/ry) - // F.6.5.6
gfxPoint((x1p-cxp)/rx, (y1p-cyp)/ry));
if (!sweepFlag && delta > 0)
delta -= 2.0 * M_PI;
else if (sweepFlag && delta < 0)
@ -757,8 +754,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
ty2 = -ty2;
}
segStartAngle = atan2(ty1, tx1);
segEndAngle = atan2(ty2, tx2);
segStartAngle = static_cast<float>(atan2(ty1, tx1));
segEndAngle = static_cast<float>(atan2(ty2, tx2));
i += 7;
break;
}
@ -770,7 +767,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + gfxPoint(mData[i++], 0.0f);
}
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
break;
case nsIDOMSVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:
@ -780,7 +777,7 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
} else {
segEnd = segStart + gfxPoint(0.0f, mData[i++]);
}
segStartAngle = segEndAngle = AngleOfVector(segEnd - segStart);
segStartAngle = segEndAngle = AngleOfVectorF(segEnd - segStart);
break;
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
@ -803,8 +800,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
if (cp2 == segEnd) {
cp2 = cp1;
}
segStartAngle = AngleOfVector(cp1 - segStart);
segEndAngle = AngleOfVector(segEnd - cp2);
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp2);
i += 4;
break;
}
@ -821,8 +818,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
segEnd = segStart + gfxPoint(mData[i], mData[i+1]);
}
prevCP = cp1;
segStartAngle = AngleOfVector(cp1 - segStart);
segEndAngle = AngleOfVector(segEnd - cp1);
segStartAngle = AngleOfVectorF(cp1 - segStart);
segEndAngle = AngleOfVectorF(segEnd - cp1);
i += 2;
break;
}
@ -852,7 +849,8 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
}
// Add the mark at the end of this segment, and set its position:
if (!aMarks->AppendElement(nsSVGMark(segEnd.x, segEnd.y, 0))) {
if (!aMarks->AppendElement(nsSVGMark(static_cast<float>(segEnd.x),
static_cast<float>(segEnd.y), 0))) {
aMarks->Clear(); // OOM, so try to free some
return;
}

View File

@ -908,6 +908,15 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
return NS_OK;
}
NS_IMETHODIMP_(bool)
nsSVGElement::IsAttributeMapped(const nsIAtom* name) const
{
if (name == nsGkAtoms::lang) {
return true;
}
return nsSVGElementBase::IsAttributeMapped(name);
}
// PresentationAttributes-FillStroke
/* static */ const nsGenericElement::MappedAttributeEntry
nsSVGElement::sFillStrokeMap[] = {
@ -1155,9 +1164,24 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
// Get the nsCSSProperty ID for our mapped attribute.
nsCSSProperty propertyID =
nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName));
bool changed; // outparam for ParseProperty. (ignored)
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
mNodePrincipal, mDecl, &changed, false);
if (propertyID != eCSSProperty_UNKNOWN) {
bool changed; // outparam for ParseProperty. (ignored)
mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
mNodePrincipal, mDecl, &changed, false);
return;
}
NS_ABORT_IF_FALSE(aMappedAttrName == nsGkAtoms::lang,
"Only 'lang' should be unrecognized!");
// nsCSSParser doesn't know about 'lang', so we need to handle it specially.
if (aMappedAttrName == nsGkAtoms::lang) {
propertyID = eCSSProperty__x_lang;
nsCSSExpandedDataBlock block;
mDecl->ExpandTo(&block);
nsCSSValue cssValue(PromiseFlatString(aMappedAttrValue), eCSSUnit_Ident);
block.AddLonghandProperty(propertyID, cssValue);
mDecl->ValueAppended(propertyID);
mDecl->CompressFrom(&block);
}
}
already_AddRefed<css::StyleRule>
@ -1203,6 +1227,16 @@ nsSVGElement::UpdateContentStyleRule()
if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom()))
continue;
if (attrName->NamespaceID() != kNameSpaceID_None &&
!attrName->Equals(nsGkAtoms::lang, kNameSpaceID_XML)) {
continue;
}
if (attrName->Equals(nsGkAtoms::lang, kNameSpaceID_None) &&
HasAttr(kNameSpaceID_XML, nsGkAtoms::lang)) {
continue; // xml:lang has precedence
}
if (Tag() == nsGkAtoms::svg) {
// Special case: we don't want <svg> 'width'/'height' mapped into style
// if the attribute value isn't a valid <length> according to SVG (which

View File

@ -124,6 +124,8 @@ public:
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
static const MappedAttributeEntry sFillStrokeMap[];
static const MappedAttributeEntry sGraphicsMap[];
static const MappedAttributeEntry sTextContentElementsMap[];
@ -233,22 +235,22 @@ public:
PRUint8 aAttrEnum,
const nsAttrValue& aEmptyOrOldValue);
virtual void DidAnimateLength(PRUint8 aAttrEnum);
virtual void DidAnimateNumber(PRUint8 aAttrEnum);
virtual void DidAnimateNumberPair(PRUint8 aAttrEnum);
virtual void DidAnimateInteger(PRUint8 aAttrEnum);
virtual void DidAnimateIntegerPair(PRUint8 aAttrEnum);
virtual void DidAnimateAngle(PRUint8 aAttrEnum);
virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
virtual void DidAnimateEnum(PRUint8 aAttrEnum);
virtual void DidAnimateViewBox();
virtual void DidAnimatePreserveAspectRatio();
virtual void DidAnimateNumberList(PRUint8 aAttrEnum);
virtual void DidAnimateLengthList(PRUint8 aAttrEnum);
virtual void DidAnimatePointList();
virtual void DidAnimatePathSegList();
virtual void DidAnimateTransformList();
virtual void DidAnimateString(PRUint8 aAttrEnum);
void DidAnimateLength(PRUint8 aAttrEnum);
void DidAnimateNumber(PRUint8 aAttrEnum);
void DidAnimateNumberPair(PRUint8 aAttrEnum);
void DidAnimateInteger(PRUint8 aAttrEnum);
void DidAnimateIntegerPair(PRUint8 aAttrEnum);
void DidAnimateAngle(PRUint8 aAttrEnum);
void DidAnimateBoolean(PRUint8 aAttrEnum);
void DidAnimateEnum(PRUint8 aAttrEnum);
void DidAnimateViewBox();
void DidAnimatePreserveAspectRatio();
void DidAnimateNumberList(PRUint8 aAttrEnum);
void DidAnimateLengthList(PRUint8 aAttrEnum);
void DidAnimatePointList();
void DidAnimatePathSegList();
void DidAnimateTransformList();
void DidAnimateString(PRUint8 aAttrEnum);
nsSVGLength2* GetAnimatedLength(const nsIAtom *aAttrName);
void GetAnimatedLengthValues(float *aFirst, ...);

View File

@ -1001,6 +1001,10 @@ nsSVGSVGElement::GetViewBoxTransform() const
viewportHeight = mViewportHeight;
}
if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
}
nsSVGViewBoxRect viewBox;
if (mViewBox.IsValid()) {
viewBox = mViewBox.GetAnimValue();

View File

@ -74,6 +74,7 @@ _TEST_FILES = \
test_getSubStringLength.xhtml \
getSubStringLength-helper.svg \
test_isSupported.xhtml \
test_lang.xhtml \
test_nonAnimStrings.xhtml \
test_pathAnimInterpolation.xhtml \
test_pathSeg.xhtml \

View File

@ -17,6 +17,9 @@
<svg id="inner" x="30" y="40" width="100" height="100">
<g id="g1"/>
</svg>
<svg id="inner-2" viewBox="0 0 10 10" width="-10" height="10">
<g id="g5"/>
</svg>
<foreignObject id="fO" x="30" y="40" width="100" height="100" transform="translate(1, 1)">
<!-- current layout implementation ignores x="50" and y="60".
thus, I made getCTM and getScreenCTM do the same. -->

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -35,6 +35,7 @@ function runTest()
var g2 = doc.getElementById("g2");
var g3 = doc.getElementById("g3");
var g4 = doc.getElementById("g4");
var g5 = doc.getElementById("g5");
var sym = doc.getElementById("sym");
var symbolRect = doc.getElementById("symbolRect");
var fO = doc.getElementById("fO");
@ -61,9 +62,11 @@ function runTest()
// symbolRect.nearestViewportElement == sym
is((function(){try{return symbolRect.getCTM().e}catch(e){return e}})(), 70, "symbolRect.getCTM().e");
is((function(){try{return symbolRect.getCTM().f}catch(e){return e}})(), 80, "symbolRect.getCTM().f");
// fO.nearestViewportElement = <svg> with no 'id'
// fO.nearestViewportElement == <svg> with no 'id'
is((function(){try{return fO.getCTM().e}catch(e){return e}})(), 2, "fO.getCTM().e");
is((function(){try{return fO.getCTM().f}catch(e){return e}})(), 3, "fO.getCTM().f");
// g5.nearestViewportElement == inner-2
is((function(){try{return g5.getCTM()}catch(e){return e}})(), null, "g5.getCTM()");
/* Tests the consistency with farthestViewportElement
(code is from test_viewport.html) */
@ -90,6 +93,8 @@ function runTest()
// fO.farthestViewportElement == root
is((function(){try{return fO.getScreenCTM().e}catch(e){return e}})(), 16, "symbolRect.getScreenCTM().e");
is((function(){try{return fO.getScreenCTM().f}catch(e){return e}})(), 29, "symbolRect.getScreenCTM().f");
// g5.farthestViewportElement == root
is((function(){try{return g5.getScreenCTM()}catch(e){return e}})(), null, "g5.getScreenCTM()");
SimpleTest.finish();
}

View File

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=721920
-->
<head>
<title>Test for Bug 721920</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
svg text { word-spacing: 1em; }
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=721920">Mozilla Bug 721920</a>
<p id="display">
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300">
<g lang="zh-Hans">
<text id="s0" y="40" style="font-size: 0">汉字</text>
<text id="s4" y="80" style="font-size: 4px">汉字</text>
<text id="s12" y="120" style="font-size: 12px">汉字</text>
<text id="s28" y="160" style="font-size: 28px">汉字</text>
</g>
</svg>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
//<![CDATA[
/** Test for Bug 721920 **/
SimpleTest.waitForExplicitFinish();
var elts = [
document.getElementById("s0"),
document.getElementById("s4"),
document.getElementById("s12"),
document.getElementById("s28")
];
function fs(idx) {
// The computed font size actually *doesn't* currently reflect the
// minimum font size preference, but things in em units do. Hence
// why we use word-spacing here.
// test_bug401046.html uses margin-bottom instead, but there's an
// SVG bug that prevents that working in SVG (bug 728723).
return getComputedStyle(elts[idx], "").wordSpacing;
}
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, step1);
function step1() {
is(fs(0), "0px", "at min font size 0, 0px should compute to 0px");
is(fs(1), "4px", "at min font size 0, 4px should compute to 4px");
is(fs(2), "12px", "at min font size 0, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 0, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 7]]}, step2);
}
function step2() {
is(fs(0), "0px", "at min font size 7, 0px should compute to 0px");
is(fs(1), "7px", "at min font size 7, 4px should compute to 7px");
is(fs(2), "12px", "at min font size 7, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 7, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 18]]}, step3);
}
function step3() {
is(fs(0), "0px", "at min font size 18, 0px should compute to 0px");
is(fs(1), "18px", "at min font size 18, 4px should compute to 18px");
is(fs(2), "18px", "at min font size 18, 12px should compute to 18px");
is(fs(3), "28px", "at min font size 18, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, SimpleTest.finish);
}
//]]>
</script>
</pre>
</body>
</html>

View File

@ -4457,6 +4457,12 @@ nsGlobalWindow::GetNearestWidget()
NS_IMETHODIMP
nsGlobalWindow::SetFullScreen(bool aFullScreen)
{
return SetFullScreenInternal(aFullScreen, true);
}
nsresult
nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aRequireTrust)
{
FORWARD_TO_OUTER(SetFullScreen, (aFullScreen), NS_ERROR_NOT_INITIALIZED);
@ -4464,11 +4470,10 @@ nsGlobalWindow::SetFullScreen(bool aFullScreen)
bool rootWinFullScreen;
GetFullScreen(&rootWinFullScreen);
// Only chrome can change our fullScreen mode, unless the DOM full-screen
// API is enabled.
if ((aFullScreen == rootWinFullScreen ||
!nsContentUtils::IsCallerTrustedForWrite()) &&
!nsContentUtils::IsFullScreenApiEnabled()) {
// Only chrome can change our fullScreen mode, unless we're running in
// untrusted mode.
if (aFullScreen == rootWinFullScreen ||
(aRequireTrust && !nsContentUtils::IsCallerTrustedForWrite())) {
return NS_OK;
}
@ -4478,11 +4483,11 @@ nsGlobalWindow::SetFullScreen(bool aFullScreen)
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
nsCOMPtr<nsIDocShellTreeItem> rootItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootItem));
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(rootItem);
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(rootItem);
if (!window)
return NS_ERROR_FAILURE;
if (rootItem != treeItem)
return window->SetFullScreen(aFullScreen);
return window->SetFullScreenInternal(aFullScreen, aRequireTrust);
// make sure we don't try to set full screen on a non-chrome window,
// which might happen in embedding world

View File

@ -398,6 +398,7 @@ public:
virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
virtual NS_HIDDEN_(void) UpdateTouchState();
virtual NS_HIDDEN_(bool) DispatchCustomEvent(const char *aEventName);
virtual NS_HIDDEN_(nsresult) SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust);
// nsIDOMStorageIndexedDB
NS_DECL_NSIDOMSTORAGEINDEXEDDB

View File

@ -80,8 +80,8 @@ class nsIArray;
class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \
{ 0x1352de12, 0x7a07, 0x4610, \
{ 0x93, 0xd5, 0xb8, 0x76, 0xfe, 0x93, 0x09, 0x50 } }
{ 0x9aef58e9, 0x5225, 0x4e58, \
{ 0x9a, 0xfb, 0xe6, 0x63, 0x97, 0x1d, 0x86, 0x88 } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -457,6 +457,13 @@ public:
return mMayHaveTouchEventListener;
}
/**
* Moves the top-level window into fullscreen mode if aIsFullScreen is true,
* otherwise exits fullscreen. If aRequireTrust is true, this method only
* changes window state in a context trusted for write.
*/
virtual nsresult SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust) = 0;
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a "MozAudioAvailable" event listener.

View File

@ -48,13 +48,14 @@ include $(topsrcdir)/dom/dom-config.mk
XPIDLSRCS = \
nsIDOMNavigatorSms.idl \
nsIDOMSmsManager.idl \
nsISmsService.idl \
nsIDOMSmsMessage.idl \
nsIDOMSmsEvent.idl \
nsISmsDatabaseService.idl \
nsIDOMSmsRequest.idl \
nsIDOMSmsFilter.idl \
nsIDOMSmsCursor.idl \
nsISmsDatabaseService.idl \
nsISmsRequestManager.idl \
nsISmsService.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,80 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMMozSmsMessage;
interface nsIDOMMozSmsRequest;
interface nsPIDOMWindow;
interface nsIScriptContext;
%{C++
#define SMS_REQUEST_MANAGER_CID \
{ 0xa97a3129, 0x1e0b, 0x45da, \
{ 0xa3, 0x85, 0xcf, 0xe5, 0xb0, 0xb1, 0xc4, 0x8f } }
#define SMS_REQUEST_MANAGER_CONTRACTID "@mozilla.org/sms/smsrequestmanager;1"
%}
[scriptable, uuid(1638b963-3a45-4937-b6a9-280c1bfb166c)]
interface nsISmsRequestManager : nsISupports
{
/**
* All SMS related errors that could apply to SmsRequest objects.
* Make sure to keep this list in sync with the list in:
* embedding/android/GeckoSmsManager.java
*/
const unsigned short SUCCESS_NO_ERROR = 0;
const unsigned short NO_SIGNAL_ERROR = 1;
const unsigned short NOT_FOUND_ERROR = 2;
const unsigned short UNKNOWN_ERROR = 3;
const unsigned short INTERNAL_ERROR = 4;
/**
* Create a new request object.
*
* @return the request ID.
*/
long createRequest(in nsPIDOMWindow aWindow,
in nsIScriptContext aScriptContext,
out nsIDOMMozSmsRequest aRequest);
/**
* Track an already existing request object.
*
* @return the request ID.
*/
long addRequest(in nsIDOMMozSmsRequest aRequest);
void notifySmsSent(in long aRequestId,
in nsIDOMMozSmsMessage aMessage);
void notifySmsSendFailed(in long aRequestId,
in long aError);
void notifyGotSms(in long aRequestId,
in nsIDOMMozSmsMessage aMessage);
void notifyGetSmsFailed(in long aRequestId,
in long aError);
void notifySmsDeleted(in long aRequestId,
in bool aDeleted);
void notifySmsDeleteFailed(in long aRequestId,
in long aError);
void notifyNoMessageInList(in long aRequestId);
void notifyCreateMessageList(in long aRequestId,
in long aListId,
in nsIDOMMozSmsMessage aMessage);
void notifyGotNextMessage(in long aRequestId,
in nsIDOMMozSmsMessage aMessage);
void notifyReadMessageListFailed(in long aRequestId,
in long aError);
};

View File

@ -115,7 +115,11 @@ SmsCursor::Continue()
mMessage = nsnull;
static_cast<SmsRequest*>(mRequest.get())->Reset();
PRInt32 requestId = SmsRequestManager::GetInstance()->AddRequest(mRequest);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
PRInt32 requestId;
nsresult rv = requestManager->AddRequest(mRequest, &requestId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISmsDatabaseService> smsDBService =
do_GetService(SMS_DATABASE_SERVICE_CONTRACTID);

View File

@ -146,17 +146,23 @@ SmsManager::Send(JSContext* aCx, JSObject* aGlobal, JSString* aNumber,
nsCOMPtr<nsIDOMMozSmsRequest> request;
int requestId =
SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext,
getter_AddRefs(request));
NS_ASSERTION(request, "The request object must have been created!");
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
PRInt32 requestId;
nsresult rv = requestManager->CreateRequest(mOwner, mScriptContext,
getter_AddRefs(request),
&requestId);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the request!");
return rv;
}
nsDependentJSString number;
number.init(aCx, aNumber);
smsService->Send(number, aMessage, requestId, 0);
nsresult rv = nsContentUtils::WrapNative(aCx, aGlobal, request, aRequest);
rv = nsContentUtils::WrapNative(aCx, aGlobal, request, aRequest);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the js value!");
return rv;
@ -217,9 +223,15 @@ SmsManager::Send(const jsval& aNumber, const nsAString& aMessage, jsval* aReturn
NS_IMETHODIMP
SmsManager::GetMessageMoz(PRInt32 aId, nsIDOMMozSmsRequest** aRequest)
{
int requestId =
SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext, aRequest);
NS_ASSERTION(*aRequest, "The request object must have been created!");
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
PRInt32 requestId;
nsresult rv = requestManager->CreateRequest(mOwner, mScriptContext, aRequest,
&requestId);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the request!");
return rv;
}
nsCOMPtr<nsISmsDatabaseService> smsDBService =
do_GetService(SMS_DATABASE_SERVICE_CONTRACTID);
@ -233,9 +245,15 @@ SmsManager::GetMessageMoz(PRInt32 aId, nsIDOMMozSmsRequest** aRequest)
nsresult
SmsManager::Delete(PRInt32 aId, nsIDOMMozSmsRequest** aRequest)
{
int requestId =
SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext, aRequest);
NS_ASSERTION(*aRequest, "The request object must have been created!");
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
PRInt32 requestId;
nsresult rv = requestManager->CreateRequest(mOwner, mScriptContext, aRequest,
&requestId);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the request!");
return rv;
}
nsCOMPtr<nsISmsDatabaseService> smsDBService =
do_GetService(SMS_DATABASE_SERVICE_CONTRACTID);
@ -278,9 +296,15 @@ SmsManager::GetMessages(nsIDOMMozSmsFilter* aFilter, bool aReverse,
filter = new SmsFilter();
}
int requestId =
SmsRequestManager::GetInstance()->CreateRequest(mOwner, mScriptContext, aRequest);
NS_ASSERTION(*aRequest, "The request object must have been created!");
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
PRInt32 requestId;
nsresult rv = requestManager->CreateRequest(mOwner, mScriptContext, aRequest,
&requestId);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create the request!");
return rv;
}
nsCOMPtr<nsISmsDatabaseService> smsDBService =
do_GetService(SMS_DATABASE_SERVICE_CONTRACTID);

View File

@ -41,6 +41,7 @@
#include "nsContentUtils.h"
#include "nsIDOMSmsMessage.h"
#include "nsIDOMSmsCursor.h"
#include "nsISmsRequestManager.h"
DOMCI_DATA(MozSmsRequest, mozilla::dom::sms::SmsRequest)
@ -92,7 +93,7 @@ NS_IMPL_EVENT_HANDLER(SmsRequest, error)
SmsRequest::SmsRequest(nsPIDOMWindow* aWindow, nsIScriptContext* aScriptContext)
: mResult(JSVAL_VOID)
, mResultRooted(false)
, mError(eNoError)
, mError(nsISmsRequestManager::SUCCESS_NO_ERROR)
, mDone(false)
{
// Those vars come from nsDOMEventTargetHelper.
@ -112,7 +113,8 @@ SmsRequest::Reset()
{
NS_ASSERTION(mDone, "mDone should be true if we try to reset!");
NS_ASSERTION(mResult != JSVAL_VOID, "mResult should be set if we try to reset!");
NS_ASSERTION(mError == eNoError, "There should be no error if we try to reset!");
NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
"There should be no error if we try to reset!");
if (mResultRooted) {
UnrootResult();
@ -148,7 +150,8 @@ void
SmsRequest::SetSuccess(bool aResult)
{
NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
NS_PRECONDITION(mError == eNoError, "mError shouldn't have been set!");
NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
"mError shouldn't have been set!");
NS_PRECONDITION(mResult == JSVAL_NULL, "mResult shouldn't have been set!");
mResult.setBoolean(aResult);
@ -174,7 +177,8 @@ bool
SmsRequest::SetSuccessInternal(nsISupports* aObject)
{
NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
NS_PRECONDITION(mError == eNoError, "mError shouldn't have been set!");
NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
"mError shouldn't have been set!");
NS_PRECONDITION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
JSContext* cx = mScriptContext->GetNativeContext();
@ -186,7 +190,7 @@ SmsRequest::SetSuccessInternal(nsISupports* aObject)
JSAutoRequest ar(cx);
JSAutoEnterCompartment ac;
if (!ac.enter(cx, global)) {
SetError(eInternalError);
SetError(nsISmsRequestManager::INTERNAL_ERROR);
return false;
}
@ -195,7 +199,7 @@ SmsRequest::SetSuccessInternal(nsISupports* aObject)
if (NS_FAILED(nsContentUtils::WrapNative(cx, global, aObject, &mResult))) {
UnrootResult();
mResult = JSVAL_VOID;
SetError(eInternalError);
SetError(nsISmsRequestManager::INTERNAL_ERROR);
return false;
}
@ -204,10 +208,11 @@ SmsRequest::SetSuccessInternal(nsISupports* aObject)
}
void
SmsRequest::SetError(ErrorType aError)
SmsRequest::SetError(PRInt32 aError)
{
NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
NS_PRECONDITION(mError == eNoError, "mError shouldn't have been set!");
NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
"mError shouldn't have been set!");
NS_PRECONDITION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
mDone = true;
@ -231,32 +236,35 @@ NS_IMETHODIMP
SmsRequest::GetError(nsAString& aError)
{
if (!mDone) {
NS_ASSERTION(mError == eNoError,
NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
"There should be no error if the request is still processing!");
SetDOMStringToNull(aError);
return NS_OK;
}
NS_ASSERTION(mError == eNoError || mResult == JSVAL_VOID,
NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR ||
mResult == JSVAL_VOID,
"mResult should be void when there is an error!");
switch (mError) {
case eNoError:
case nsISmsRequestManager::SUCCESS_NO_ERROR:
SetDOMStringToNull(aError);
break;
case eNoSignalError:
case nsISmsRequestManager::NO_SIGNAL_ERROR:
aError.AssignLiteral("NoSignalError");
break;
case eNotFoundError:
case nsISmsRequestManager::NOT_FOUND_ERROR:
aError.AssignLiteral("NotFoundError");
break;
case eUnknownError:
case nsISmsRequestManager::UNKNOWN_ERROR:
aError.AssignLiteral("UnknownError");
break;
case eInternalError:
case nsISmsRequestManager::INTERNAL_ERROR:
aError.AssignLiteral("InternalError");
break;
default:
MOZ_ASSERT(false, "Unknown error value.");
}
return NS_OK;

View File

@ -54,19 +54,6 @@ class SmsRequest : public nsIDOMMozSmsRequest
public:
friend class SmsRequestManager;
/**
* All SMS related errors that could apply to SmsRequest objects.
* Make sure to keep this list in sync with the list in:
* embedding/android/GeckoSmsManager.java
*/
enum ErrorType {
eNoError = 0,
eNoSignalError,
eNotFoundError,
eUnknownError,
eInternalError,
};
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZSMSREQUEST
@ -111,7 +98,7 @@ private:
/**
* Set the object in an error state with the error type being aError.
*/
void SetError(ErrorType aError);
void SetError(PRInt32 aError);
/**
* Set the object in a success state with the result being the nsISupports
@ -129,7 +116,7 @@ private:
jsval mResult;
bool mResultRooted;
ErrorType mError;
PRInt32 mError;
bool mDone;
nsCOMPtr<nsIDOMMozSmsCursor> mCursor;

View File

@ -51,33 +51,11 @@ namespace mozilla {
namespace dom {
namespace sms {
SmsRequestManager* SmsRequestManager::sInstance = nsnull;
NS_IMPL_ISUPPORTS1(SmsRequestManager, nsISmsRequestManager)
void
SmsRequestManager::Init()
{
NS_PRECONDITION(!sInstance,
"sInstance shouldn't be set. Did you call Init() twice?");
sInstance = new SmsRequestManager();
}
void
SmsRequestManager::Shutdown()
{
NS_PRECONDITION(sInstance, "sInstance should be set. Did you call Init()?");
delete sInstance;
sInstance = nsnull;
}
/* static */ SmsRequestManager*
SmsRequestManager::GetInstance()
{
return sInstance;
}
PRInt32
SmsRequestManager::AddRequest(nsIDOMMozSmsRequest* aRequest)
NS_IMETHODIMP
SmsRequestManager::AddRequest(nsIDOMMozSmsRequest* aRequest,
PRInt32* aRequestId)
{
// TODO: merge with CreateRequest
PRInt32 size = mRequests.Count();
@ -89,17 +67,21 @@ SmsRequestManager::AddRequest(nsIDOMMozSmsRequest* aRequest)
}
mRequests.ReplaceObjectAt(aRequest, i);
return i;
*aRequestId = i;
return NS_OK;
}
mRequests.AppendObject(aRequest);
return size;
*aRequestId = size;
return NS_OK;
}
PRInt32
NS_IMETHODIMP
SmsRequestManager::CreateRequest(nsPIDOMWindow* aWindow,
nsIScriptContext* aScriptContext,
nsIDOMMozSmsRequest** aRequest)
nsIDOMMozSmsRequest** aRequest,
PRInt32* aRequestId)
{
nsCOMPtr<nsIDOMMozSmsRequest> request =
new SmsRequest(aWindow, aScriptContext);
@ -114,12 +96,14 @@ SmsRequestManager::CreateRequest(nsPIDOMWindow* aWindow,
mRequests.ReplaceObjectAt(request, i);
NS_ADDREF(*aRequest = request);
return i;
*aRequestId = i;
return NS_OK;
}
mRequests.AppendObject(request);
NS_ADDREF(*aRequest = request);
return size;
*aRequestId = size;
return NS_OK;
}
nsresult
@ -149,66 +133,67 @@ SmsRequestManager::GetRequest(PRInt32 aRequestId)
}
template <class T>
void
nsresult
SmsRequestManager::NotifySuccess(PRInt32 aRequestId, T aParam)
{
SmsRequest* request = GetRequest(aRequestId);
request->SetSuccess(aParam);
DispatchTrustedEventToRequest(SUCCESS_EVENT_NAME, request);
nsresult rv = DispatchTrustedEventToRequest(SUCCESS_EVENT_NAME, request);
mRequests.ReplaceObjectAt(nsnull, aRequestId);
return rv;
}
void
SmsRequestManager::NotifyError(PRInt32 aRequestId, SmsRequest::ErrorType aError)
nsresult
SmsRequestManager::NotifyError(PRInt32 aRequestId, PRInt32 aError)
{
SmsRequest* request = GetRequest(aRequestId);
request->SetError(aError);
DispatchTrustedEventToRequest(ERROR_EVENT_NAME, request);
nsresult rv = DispatchTrustedEventToRequest(ERROR_EVENT_NAME, request);
mRequests.ReplaceObjectAt(nsnull, aRequestId);
return rv;
}
void
NS_IMETHODIMP
SmsRequestManager::NotifySmsSent(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage)
{
NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
return NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
}
void
SmsRequestManager::NotifySmsSendFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError)
NS_IMETHODIMP
SmsRequestManager::NotifySmsSendFailed(PRInt32 aRequestId, PRInt32 aError)
{
NotifyError(aRequestId, aError);
return NotifyError(aRequestId, aError);
}
void
NS_IMETHODIMP
SmsRequestManager::NotifyGotSms(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage)
{
NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
return NotifySuccess<nsIDOMMozSmsMessage*>(aRequestId, aMessage);
}
void
SmsRequestManager::NotifyGetSmsFailed(PRInt32 aRequestId,
SmsRequest::ErrorType aError)
NS_IMETHODIMP
SmsRequestManager::NotifyGetSmsFailed(PRInt32 aRequestId, PRInt32 aError)
{
NotifyError(aRequestId, aError);
return NotifyError(aRequestId, aError);
}
void
NS_IMETHODIMP
SmsRequestManager::NotifySmsDeleted(PRInt32 aRequestId, bool aDeleted)
{
NotifySuccess<bool>(aRequestId, aDeleted);
return NotifySuccess<bool>(aRequestId, aDeleted);
}
void
SmsRequestManager::NotifySmsDeleteFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError)
NS_IMETHODIMP
SmsRequestManager::NotifySmsDeleteFailed(PRInt32 aRequestId, PRInt32 aError)
{
NotifyError(aRequestId, aError);
return NotifyError(aRequestId, aError);
}
void
NS_IMETHODIMP
SmsRequestManager::NotifyNoMessageInList(PRInt32 aRequestId)
{
SmsRequest* request = GetRequest(aRequestId);
@ -220,10 +205,10 @@ SmsRequestManager::NotifyNoMessageInList(PRInt32 aRequestId)
static_cast<SmsCursor*>(cursor.get())->Disconnect();
}
NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
return NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
}
void
NS_IMETHODIMP
SmsRequestManager::NotifyCreateMessageList(PRInt32 aRequestId, PRInt32 aListId,
nsIDOMMozSmsMessage* aMessage)
{
@ -232,10 +217,10 @@ SmsRequestManager::NotifyCreateMessageList(PRInt32 aRequestId, PRInt32 aListId,
nsCOMPtr<SmsCursor> cursor = new SmsCursor(aListId, request);
cursor->SetMessage(aMessage);
NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
return NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
}
void
NS_IMETHODIMP
SmsRequestManager::NotifyGotNextMessage(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage)
{
SmsRequest* request = GetRequest(aRequestId);
@ -244,12 +229,11 @@ SmsRequestManager::NotifyGotNextMessage(PRInt32 aRequestId, nsIDOMMozSmsMessage*
NS_ASSERTION(cursor, "Request should have an cursor in that case!");
cursor->SetMessage(aMessage);
NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
return NotifySuccess<nsIDOMMozSmsCursor*>(aRequestId, cursor);
}
void
SmsRequestManager::NotifyReadMessageListFailed(PRInt32 aRequestId,
SmsRequest::ErrorType aError)
NS_IMETHODIMP
SmsRequestManager::NotifyReadMessageListFailed(PRInt32 aRequestId, PRInt32 aError)
{
SmsRequest* request = GetRequest(aRequestId);
@ -258,7 +242,7 @@ SmsRequestManager::NotifyReadMessageListFailed(PRInt32 aRequestId,
static_cast<SmsCursor*>(cursor.get())->Disconnect();
}
NotifyError(aRequestId, aError);
return NotifyError(aRequestId, aError);
}
} // namespace sms

View File

@ -41,50 +41,26 @@
#include "nsCOMArray.h"
#include "SmsRequest.h"
class nsIDOMMozSmsRequest;
class nsPIDOMWindow;
class nsIScriptContext;
class nsIDOMMozSmsMessage;
#include "nsISmsRequestManager.h"
namespace mozilla {
namespace dom {
namespace sms {
class SmsRequestManager
class SmsRequestManager : nsISmsRequestManager
{
public:
static void Init();
static void Shutdown();
static SmsRequestManager* GetInstance();
PRInt32 CreateRequest(nsPIDOMWindow* aWindow,
nsIScriptContext* aScriptContext,
nsIDOMMozSmsRequest** aRequest);
PRInt32 AddRequest(nsIDOMMozSmsRequest* aRequest);
void NotifySmsSent(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage);
void NotifySmsSendFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
void NotifyGotSms(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage);
void NotifyGetSmsFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
void NotifySmsDeleted(PRInt32 aRequestId, bool aDeleted);
void NotifySmsDeleteFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
void NotifyNoMessageInList(PRInt32 aRequestId);
void NotifyCreateMessageList(PRInt32 aRequestId, PRInt32 aListId, nsIDOMMozSmsMessage* aMessage);
void NotifyGotNextMessage(PRInt32 aRequestId, nsIDOMMozSmsMessage* aMessage);
void NotifyReadMessageListFailed(PRInt32 aRequestId, SmsRequest::ErrorType aError);
NS_DECL_ISUPPORTS
NS_DECL_NSISMSREQUESTMANAGER
private:
static SmsRequestManager* sInstance;
nsresult DispatchTrustedEventToRequest(const nsAString& aEventName,
nsIDOMMozSmsRequest* aRequest);
SmsRequest* GetRequest(PRInt32 aRequestId);
template <class T>
void NotifySuccess(PRInt32 aRequestId, T aParam);
void NotifyError(PRInt32 aRequestId, SmsRequest::ErrorType aError);
nsresult NotifySuccess(PRInt32 aRequestId, T aParam);
nsresult NotifyError(PRInt32 aRequestId, PRInt32 aError);
nsCOMArray<nsIDOMMozSmsRequest> mRequests;
};

View File

@ -100,7 +100,8 @@ SmsChild::RecvNotifyRequestSmsSent(const SmsMessageData& aMessage,
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(aMessage);
SmsRequestManager::GetInstance()->NotifySmsSent(aRequestId, message);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifySmsSent(aRequestId, message);
return true;
}
@ -114,8 +115,8 @@ SmsChild::RecvNotifyRequestSmsSendFailed(const PRInt32& aError,
return true;
}
SmsRequestManager::GetInstance()->NotifySmsSendFailed(aRequestId,
SmsRequest::ErrorType(aError));
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifySmsSendFailed(aRequestId, aError);
return true;
}
@ -130,7 +131,8 @@ SmsChild::RecvNotifyRequestGotSms(const SmsMessageData& aMessage,
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(aMessage);
SmsRequestManager::GetInstance()->NotifyGotSms(aRequestId, message);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyGotSms(aRequestId, message);
return true;
}
@ -144,8 +146,8 @@ SmsChild::RecvNotifyRequestGetSmsFailed(const PRInt32& aError,
return true;
}
SmsRequestManager::GetInstance()->NotifyGetSmsFailed(aRequestId,
SmsRequest::ErrorType(aError));
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyGetSmsFailed(aRequestId, aError);
return true;
}
@ -159,7 +161,8 @@ SmsChild::RecvNotifyRequestSmsDeleted(const bool& aDeleted,
return true;
}
SmsRequestManager::GetInstance()->NotifySmsDeleted(aRequestId, aDeleted);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifySmsDeleted(aRequestId, aDeleted);
return true;
}
@ -173,8 +176,8 @@ SmsChild::RecvNotifyRequestSmsDeleteFailed(const PRInt32& aError,
return true;
}
SmsRequestManager::GetInstance()->NotifySmsDeleteFailed(aRequestId,
SmsRequest::ErrorType(aError));
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifySmsDeleteFailed(aRequestId, aError);
return true;
}
@ -187,7 +190,8 @@ SmsChild::RecvNotifyRequestNoMessageInList(const PRInt32& aRequestId,
return true;
}
SmsRequestManager::GetInstance()->NotifyNoMessageInList(aRequestId);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyNoMessageInList(aRequestId);
return true;
}
@ -202,7 +206,8 @@ SmsChild::RecvNotifyRequestCreateMessageList(const PRInt32& aListId,
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(aMessageData);
SmsRequestManager::GetInstance()->NotifyCreateMessageList(aRequestId, aListId, message);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyCreateMessageList(aRequestId, aListId, message);
return true;
}
@ -216,7 +221,8 @@ SmsChild::RecvNotifyRequestGotNextMessage(const SmsMessageData& aMessageData,
}
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(aMessageData);
SmsRequestManager::GetInstance()->NotifyGotNextMessage(aRequestId, message);
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyGotNextMessage(aRequestId, message);
return true;
}
@ -229,8 +235,8 @@ SmsChild::RecvNotifyRequestReadListFailed(const PRInt32& aError,
return true;
}
SmsRequestManager::GetInstance()->NotifyReadMessageListFailed(aRequestId,
SmsRequest::ErrorType(aError));
nsCOMPtr<nsISmsRequestManager> requestManager = do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
requestManager->NotifyReadMessageListFailed(aRequestId, aError);
return true;
}

View File

@ -89,7 +89,7 @@ SmsService::Send(const nsAString& aNumber,
return NS_OK;
}
mRIL->SendSMS(aNumber, aMessage);
mRIL->SendSMS(aNumber, aMessage, aRequestId, aProcessId);
return NS_OK;
}

View File

@ -59,11 +59,16 @@ const nsIRadioInterfaceLayer = Ci.nsIRadioInterfaceLayer;
const kSmsReceivedObserverTopic = "sms-received";
const DOM_SMS_DELIVERY_RECEIVED = "received";
const DOM_SMS_DELIVERY_SENT = "sent";
XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
"@mozilla.org/sms/smsservice;1",
"nsISmsService");
XPCOMUtils.defineLazyServiceGetter(this, "gSmsRequestManager",
"@mozilla.org/sms/smsrequestmanager;1",
"nsISmsRequestManager");
function convertRILCallState(state) {
switch (state) {
case RIL.CALL_STATE_ACTIVE:
@ -201,6 +206,9 @@ RadioInterfaceLayer.prototype = {
case "sms-received":
this.handleSmsReceived(message);
return;
case "sms-sent":
this.handleSmsSent(message);
return;
case "datacallstatechange":
this.handleDataCallState(message.datacall);
break;
@ -310,6 +318,18 @@ RadioInterfaceLayer.prototype = {
Services.obs.notifyObservers(sms, kSmsReceivedObserverTopic, null);
},
handleSmsSent: function handleSmsSent(message) {
let message = gSmsService.createSmsMessage(-1,
DOM_SMS_DELIVERY_SENT,
message.SMSC,
message.number,
message.body,
Date.now());
//TODO At this point we should save the sms into the DB (bug 712809)
//TODO handle errors (bug XXX)
gSmsRequestManager.notifySmsSent(message.requestId, message);
},
/**
* Handle data call state changes.
*/
@ -402,10 +422,12 @@ RadioInterfaceLayer.prototype = {
return Math.ceil(text.length / 160);
},
sendSMS: function sendSMS(number, message) {
sendSMS: function sendSMS(number, message, requestId, processId) {
this.worker.postMessage({type: "sendSMS",
number: number,
body: message});
body: message,
requestId: requestId,
processId: processId});
},
_callbacks: null,

View File

@ -116,7 +116,7 @@ interface nsIRILDataCallback : nsISupports
in unsigned long length);
};
[scriptable, uuid(9b7e3a01-9c45-4af3-81bb-1bf08a842226)]
[scriptable, uuid(aeb7ffe7-7d3a-4b7d-9b59-b6d3ae1c72ed)]
interface nsIRadioInterfaceLayer : nsISupports
{
const unsigned short CALL_STATE_UNKNOWN = 0;
@ -177,7 +177,7 @@ interface nsIRadioInterfaceLayer : nsISupports
void deactivateDataCall(in DOMString cid,
in DOMString reason);
void getDataCallList();
void registerDataCallCallback(in nsIRILDataCallback callback);
void unregisterDataCallCallback(in nsIRILDataCallback callback);
@ -185,5 +185,8 @@ interface nsIRadioInterfaceLayer : nsISupports
* SMS-related functionality.
*/
unsigned short getNumberOfMessagesForText(in DOMString text);
void sendSMS(in DOMString number, in DOMString message);
void sendSMS(in DOMString number,
in DOMString message,
in long requestId,
in unsigned long long processId);
};

View File

@ -438,12 +438,14 @@ let Buf = {
let response_type = this.readUint32();
let length = this.readIncoming - UINT32_SIZE;
let request_type;
let request_type, options;
if (response_type == RESPONSE_TYPE_SOLICITED) {
let token = this.readUint32();
let error = this.readUint32();
length -= 2 * UINT32_SIZE;
request_type = this.tokenRequestMap[token];
options = this.tokenRequestMap[token];
request_type = options.rilRequestType;
if (error) {
//TODO
if (DEBUG) {
@ -467,7 +469,7 @@ let Buf = {
return;
}
RIL.handleParcel(request_type, length);
RIL.handleParcel(request_type, length, options);
},
/**
@ -475,15 +477,23 @@ let Buf = {
*
* @param type
* Integer specifying the request type.
* @param options [optional]
* Object containing information about the request, e.g. the
* original main thread message object that led to the RIL request.
*/
newParcel: function newParcel(type) {
newParcel: function newParcel(type, options) {
if (DEBUG) debug("New outgoing parcel of type " + type);
// We're going to leave room for the parcel size at the beginning.
this.outgoingIndex = PARCEL_SIZE_SIZE;
this.writeUint32(type);
let token = this.token;
this.writeUint32(token);
this.tokenRequestMap[token] = type;
if (!options) {
options = {};
}
options.rilRequestType = type;
this.tokenRequestMap[token] = options;
this.token++;
return token;
},
@ -753,9 +763,11 @@ let RIL = {
/**
* Send an SMS.
*
* @param smscPDU
* The `options` parameter object should contain the following attributes:
*
* @param SMSC
* String containing the SMSC PDU in hex format.
* @param address
* @param number
* String containing the recipients address.
* @param body
* String containing the message body.
@ -765,15 +777,18 @@ let RIL = {
* @param bodyLengthInOctets
* Byte length of the message body when encoded with the given DCS.
*/
sendSMS: function sendSMS(smscPDU, address, body, dcs, bodyLengthInOctets) {
let token = Buf.newParcel(REQUEST_SEND_SMS);
sendSMS: function sendSMS(options) {
let token = Buf.newParcel(REQUEST_SEND_SMS, options);
//TODO we want to map token to the input values so that on the
// response from the RIL device we know which SMS request was successful
// or not. Maybe we should build that functionality into newParcel() and
// handle it within tokenRequestMap[].
Buf.writeUint32(2);
Buf.writeString(smscPDU);
GsmPDUHelper.writeMessage(address, body, dcs, bodyLengthInOctets);
Buf.writeString(options.SMSC);
GsmPDUHelper.writeMessage(options.number,
options.body,
options.dcs,
options.bodyLengthInOctets);
Buf.sendParcel();
},
@ -907,11 +922,11 @@ let RIL = {
* _is_ the method name, so that's easy.
*/
handleParcel: function handleParcel(request_type, length) {
handleParcel: function handleParcel(request_type, length, options) {
let method = this[request_type];
if (typeof method == "function") {
if (DEBUG) debug("Handling parcel as " + method.name);
method.call(this, length);
method.call(this, length, options);
}
}
};
@ -1064,11 +1079,11 @@ RIL[REQUEST_RADIO_POWER] = null;
RIL[REQUEST_DTMF] = function REQUEST_DTMF() {
Phone.onSendTone();
};
RIL[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS() {
let messageRef = Buf.readUint32();
let ackPDU = Buf.readString();
let errorCode = Buf.readUint32();
Phone.onSendSMS(messageRef, ackPDU, errorCode);
RIL[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS(length, options) {
options.messageRef = Buf.readUint32();
options.ackPDU = Buf.readString();
options.errorCode = Buf.readUint32();
Phone.onSendSMS(options);
};
RIL[REQUEST_SEND_SMS_EXPECT_MORE] = null;
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL() {
@ -1753,8 +1768,9 @@ let Phone = {
onSetSMSCAddress: function onSetSMSCAddress() {
},
onSendSMS: function onSendSMS(messageRef, ackPDU, errorCode) {
//TODO
onSendSMS: function onSendSMS(options) {
options.type = "sms-sent";
this.sendDOMMessage(options);
},
onNewSMS: function onNewSMS(payloadLength) {
@ -2013,6 +2029,10 @@ let Phone = {
* String containing the recipient number.
* @param body
* String containing the message text.
* @param requestId
* String identifying the sms request used by the SmsRequestManager.
* @param processId
* String containing the processId for the SmsRequestManager.
*/
sendSMS: function sendSMS(options) {
// Get the SMS Center address
@ -2025,12 +2045,17 @@ let Phone = {
}
return;
}
// We explicitly save this information on the options object so that we
// can refer to it later, in particular on the main thread (where this
// object may get sent eventually.)
options.SMSC = this.SMSC;
//TODO: verify values on 'options'
//TODO: the data encoding and length in octets should eventually be
// computed on the mainthread and passed down to us.
RIL.sendSMS(this.SMSC, options.number, options.body,
PDU_DCS_MSG_CODING_7BITS_ALPHABET, //TODO: hard-coded for now,
Math.ceil(options.body.length * 7 / 8)); //TODO: ditto
options.dcs = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
options.bodyLengthInOctets = Math.ceil(options.body.length * 7 / 8);
RIL.sendSMS(options);
},
/**

View File

@ -327,9 +327,9 @@ public class GeckoSmsManager
public final static String ACTION_SMS_DELIVERED = "org.mozilla.gecko.SMS_DELIVERED";
/*
* Make sure that the following error codes are in sync with |ErrorType| in:
* dom/sms/src/Types.h
* The error code are owned by the DOM.
* Make sure that the following error codes are in sync with the ones
* defined in dom/sms/interfaces/nsISmsRequestManager.idl. They are owned
* owned by the interface.
*/
public final static int kNoError = 0;
public final static int kNoSignalError = 1;

View File

@ -775,8 +775,8 @@ bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
counts_.push_back(i);
count += i;
}
DCHECK_EQ(count, redundant_count_);
return count == redundant_count_;
return true;
}
//------------------------------------------------------------------------------

View File

@ -100,6 +100,20 @@ class BaseCompiler : public MacroAssemblerTypedefs
{ }
};
#ifdef JS_CPU_X64
inline bool
VerifyRange(void *start1, size_t size1, void *start2, size_t size2)
{
uintptr_t end1 = uintptr_t(start1) + size1;
uintptr_t end2 = uintptr_t(start2) + size2;
uintptr_t lowest = JS_MIN(uintptr_t(start1), uintptr_t(start2));
uintptr_t highest = JS_MAX(end1, end2);
return (highest - lowest < INT_MAX);
}
#endif
// This class wraps JSC::LinkBuffer for Mozilla-specific memory handling.
// Every return |false| guarantees an OOM that has been correctly propagated,
// and should continue to propagate.
@ -128,13 +142,7 @@ class LinkerHelper : public JSC::LinkBuffer
verifiedRange = true;
#endif
#ifdef JS_CPU_X64
uintptr_t lowest = JS_MIN(uintptr_t(m_code), uintptr_t(other.start()));
uintptr_t myEnd = uintptr_t(m_code) + m_size;
uintptr_t otherEnd = uintptr_t(other.start()) + other.size();
uintptr_t highest = JS_MAX(myEnd, otherEnd);
return (highest - lowest < INT_MAX);
return VerifyRange(m_code, m_size, other.start(), other.size());
#else
return true;
#endif

View File

@ -666,19 +666,12 @@ MakeJITScript(JSContext *cx, JSScript *script, bool construct)
Vector<ChunkDescriptor> chunks(cx);
Vector<CrossChunkEdge> edges(cx);
/*
* Chunk compilation is not supported on x64, since there is no guarantee
* that cross chunk jumps will be patchable even to go to the default shim.
*/
#ifndef JS_CPU_X64
if (script->length < CHUNK_LIMIT || !cx->typeInferenceEnabled()) {
#endif
ChunkDescriptor desc;
desc.begin = 0;
desc.end = script->length;
if (!chunks.append(desc))
return NULL;
#ifndef JS_CPU_X64
} else {
if (!script->ensureRanInference(cx))
return NULL;
@ -871,7 +864,6 @@ MakeJITScript(JSContext *cx, JSScript *script, bool construct)
return NULL;
}
}
#endif /* !JS_CPU_X64 */
size_t dataSize = sizeof(JITScript)
+ (chunks.length() * sizeof(ChunkDescriptor))
@ -1259,6 +1251,15 @@ mjit::Compiler::generateEpilogue()
CompileStatus
mjit::Compiler::finishThisUp()
{
#ifdef JS_CPU_X64
/* Generate trampolines to ensure that cross chunk edges are patchable. */
for (unsigned i = 0; i < chunkEdges.length(); i++) {
chunkEdges[i].sourceTrampoline = stubcc.masm.label();
stubcc.masm.move(ImmPtr(NULL), Registers::ScratchReg);
stubcc.masm.jump(Registers::ScratchReg);
}
#endif
RETURN_IF_OOM(Compile_Error);
/*
@ -1789,8 +1790,6 @@ mjit::Compiler::finishThisUp()
outerChunk.chunk = chunk;
Repatcher repatch(chunk);
/* Patch all incoming and outgoing cross-chunk jumps. */
CrossChunkEdge *crossEdges = jit->edges();
for (unsigned i = 0; i < jit->nedges; i++) {
@ -1837,12 +1836,15 @@ mjit::Compiler::finishThisUp()
* jump is never taken.
*/
edge.sourceJump1 = fullCode.locationOf(oedge.fastJump).executableAddress();
repatch.relink(CodeLocationJump(edge.sourceJump1), targetLabel);
if (oedge.slowJump.isSet()) {
edge.sourceJump2 =
stubCode.locationOf(oedge.slowJump.get()).executableAddress();
repatch.relink(CodeLocationJump(edge.sourceJump2), targetLabel);
}
#ifdef JS_CPU_X64
edge.sourceTrampoline =
stubCode.locationOf(oedge.sourceTrampoline).executableAddress();
#endif
jit->patchEdge(edge, label);
break;
}
}

View File

@ -380,6 +380,10 @@ class Compiler : public BaseCompiler
uint32_t source;
uint32_t target;
#ifdef JS_CPU_X64
Label sourceTrampoline;
#endif
Jump fastJump;
MaybeJump slowJump;
};

View File

@ -1230,13 +1230,34 @@ JITScript::patchEdge(const CrossChunkEdge &edge, void *label)
{
if (edge.sourceJump1 || edge.sourceJump2) {
JITChunk *sourceChunk = chunk(script->code + edge.source);
JSC::CodeLocationLabel targetLabel(label);
ic::Repatcher repatch(sourceChunk);
#ifdef JS_CPU_X64
JS_ASSERT(edge.sourceTrampoline);
static const uint32_t JUMP_LENGTH = 10;
if (edge.sourceJump1) {
JSC::CodeLocationLabel targetLabel(VerifyRange(edge.sourceJump1, JUMP_LENGTH, label, 0)
? label
: edge.sourceTrampoline);
repatch.relink(JSC::CodeLocationJump(edge.sourceJump1), targetLabel);
}
if (edge.sourceJump2) {
JSC::CodeLocationLabel targetLabel(VerifyRange(edge.sourceJump2, JUMP_LENGTH, label, 0)
? label
: edge.sourceTrampoline);
repatch.relink(JSC::CodeLocationJump(edge.sourceJump2), targetLabel);
}
JSC::CodeLocationDataLabelPtr sourcePatch((char*)edge.sourceTrampoline + JUMP_LENGTH);
repatch.repatch(sourcePatch, label);
#else
JSC::CodeLocationLabel targetLabel(label);
if (edge.sourceJump1)
repatch.relink(JSC::CodeLocationJump(edge.sourceJump1), targetLabel);
if (edge.sourceJump2)
repatch.relink(JSC::CodeLocationJump(edge.sourceJump2), targetLabel);
#endif
}
if (edge.jumpTableEntries) {
for (unsigned i = 0; i < edge.jumpTableEntries->length(); i++)
@ -1317,6 +1338,9 @@ JITScript::destroyChunk(JSContext *cx, unsigned chunkIndex, bool resetUses)
CrossChunkEdge &edge = edges[i];
if (edge.source >= desc.begin && edge.source < desc.end) {
edge.sourceJump1 = edge.sourceJump2 = NULL;
#ifdef JS_CPU_X64
edge.sourceTrampoline = NULL;
#endif
if (edge.jumpTableEntries) {
cx->delete_(edge.jumpTableEntries);
edge.jumpTableEntries = NULL;

View File

@ -761,6 +761,14 @@ struct CrossChunkEdge
void *sourceJump1;
void *sourceJump2;
#ifdef JS_CPU_X64
/*
* Location of a trampoline for the edge to perform an indirect jump if
* out of range, NULL if the source is not compiled.
*/
void *sourceTrampoline;
#endif
/* Any jump table entries along this edge. */
typedef Vector<void**,4,SystemAllocPolicy> JumpTableEntryVector;
JumpTableEntryVector *jumpTableEntries;

View File

@ -2917,9 +2917,18 @@ XPCWrappedNative::GetObjectPrincipal() const
{
nsIPrincipal* principal = GetScope()->GetPrincipal();
#ifdef DEBUG
// Because of inner window reuse, we can have objects with one principal
// living in a scope with a different (but same-origin) principal. So
// just check same-origin here.
nsCOMPtr<nsIScriptObjectPrincipal> objPrin(do_QueryInterface(mIdentity));
NS_ASSERTION(!objPrin || objPrin->GetPrincipal() == principal,
"Principal mismatch. Expect bad things to happen");
if (objPrin) {
bool equal;
if (!principal)
equal = !objPrin->GetPrincipal();
else
principal->Equals(objPrin->GetPrincipal(), &equal);
NS_ASSERTION(equal, "Principal mismatch. Expect bad things to happen");
}
#endif
return principal;
}

View File

@ -2873,7 +2873,7 @@ DocumentViewerImpl::SetMinFontSize(PRInt32 aMinFontSize)
// Now change our own min font
nsPresContext* pc = GetPresContext();
if (pc && aMinFontSize != mPresContext->MinFontSize()) {
if (pc && aMinFontSize != mPresContext->MinFontSize(nsnull)) {
pc->SetMinFontSize(aMinFontSize);
}
@ -2889,7 +2889,7 @@ DocumentViewerImpl::GetMinFontSize(PRInt32* aMinFontSize)
{
NS_ENSURE_ARG_POINTER(aMinFontSize);
nsPresContext* pc = GetPresContext();
*aMinFontSize = pc ? pc->MinFontSize() : 0;
*aMinFontSize = pc ? pc->MinFontSize(nsnull) : 0;
return NS_OK;
}

View File

@ -212,27 +212,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
: mType(aType), mDocument(aDocument), mMinFontSize(0),
mTextZoom(1.0), mFullZoom(1.0), mPageSize(-1, -1), mPPScale(1.0f),
mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
mImageAnimationModePref(imgIContainer::kNormalAnimMode),
// Font sizes default to zero; they will be set in GetFontPreferences
mDefaultVariableFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultFixedFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultSerifFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultSansSerifFont("sans-serif", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultMonospaceFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0),
mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
mImageAnimationModePref(imgIContainer::kNormalAnimMode)
{
// NOTE! nsPresContext::operator new() zeroes out all members, so don't
// bother initializing members to 0.
@ -443,9 +423,51 @@ static bool sLookAndFeelChanged;
// one prescontext.
static bool sThemeChanged;
void
nsPresContext::GetFontPreferences()
const nsPresContext::LangGroupFontPrefs*
nsPresContext::GetFontPrefsForLang(nsIAtom *aLanguage) const
{
// Get language group for aLanguage:
nsresult rv;
nsIAtom *langGroupAtom = nsnull;
if (!aLanguage) {
aLanguage = mLanguage;
}
if (aLanguage && mLangService) {
langGroupAtom = mLangService->GetLanguageGroup(aLanguage, &rv);
}
if (NS_FAILED(rv) || !langGroupAtom) {
langGroupAtom = nsGkAtoms::x_western; // Assume x-western is safe...
}
// Look for cached prefs for this lang group.
// Most documents will only use one (or very few) language groups. Rather
// than have the overhead of a hash lookup, we simply look along what will
// typically be a very short (usually of length 1) linked list. There are 31
// language groups, so in the worst case scenario we'll need to traverse 31
// link items.
LangGroupFontPrefs *prefs =
const_cast<LangGroupFontPrefs*>(&mLangGroupFontPrefs);
if (prefs->mLangGroup) { // if initialized
DebugOnly<PRUint32> count = 0;
for (;;) {
NS_ASSERTION(++count < 35, "Lang group count exceeded!!!");
if (prefs->mLangGroup == langGroupAtom) {
return prefs;
}
if (!prefs->mNext) {
break;
}
prefs = prefs->mNext;
}
// nothing cached, so go on and fetch the prefs for this lang group:
prefs = prefs->mNext = new LangGroupFontPrefs;
}
prefs->mLangGroup = langGroupAtom;
/* Fetch the font prefs to be used -- see bug 61883 for details.
Not all prefs are needed upfront. Some are fallback prefs intended
for the GFX font sub-system...
@ -454,7 +476,7 @@ nsPresContext::GetFontPreferences()
font.size.unit = px | pt XXX could be folded in the size... bug 90440
2) attributes for generic fonts --------------------------------------
font.default = serif | sans-serif - fallback generic font
font.default.[langGroup] = serif | sans-serif - fallback generic font
font.name.[generic].[langGroup] = current user' selected font on the pref dialog
font.name-list.[generic].[langGroup] = fontname1, fontname2, ... [factory pre-built list]
font.size.[generic].[langGroup] = integer - settable by the user
@ -462,24 +484,11 @@ nsPresContext::GetFontPreferences()
font.minimum-size.[langGroup] = integer - settable by the user
*/
mDefaultVariableFont.size = CSSPixelsToAppUnits(16);
mDefaultFixedFont.size = CSSPixelsToAppUnits(13);
// the font prefs are based on langGroup, not actual language
nsCAutoString langGroup;
if (mLanguage && mLangService) {
nsresult rv;
nsIAtom *group = mLangService->GetLanguageGroup(mLanguage, &rv);
if (NS_SUCCEEDED(rv) && group) {
group->ToUTF8String(langGroup);
}
else {
langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
}
}
else {
langGroup.AssignLiteral("x-western"); // Assume x-western is safe...
}
langGroupAtom->ToUTF8String(langGroup);
prefs->mDefaultVariableFont.size = CSSPixelsToAppUnits(16);
prefs->mDefaultFixedFont.size = CSSPixelsToAppUnits(13);
nsCAutoString pref;
@ -498,6 +507,8 @@ nsPresContext::GetFontPreferences()
unit = eUnit_pt;
}
else {
// XXX should really send this warning to the user (Error Console?).
// And just default to unit = eUnit_px?
NS_WARNING("unexpected font-size unit -- expected: 'px' or 'pt'");
unit = eUnit_unknown;
}
@ -505,29 +516,32 @@ nsPresContext::GetFontPreferences()
// get font.minimum-size.[langGroup]
pref.Assign("font.minimum-size.");
pref.Append(langGroup);
MAKE_FONT_PREF_KEY(pref, "font.minimum-size.", langGroup);
PRInt32 size = Preferences::GetInt(pref.get());
if (unit == eUnit_px) {
mMinimumFontSizePref = CSSPixelsToAppUnits(size);
prefs->mMinimumFontSize = CSSPixelsToAppUnits(size);
}
else if (unit == eUnit_pt) {
mMinimumFontSizePref = CSSPointsToAppUnits(size);
prefs->mMinimumFontSize = CSSPointsToAppUnits(size);
}
nsFont* fontTypes[] = {
&mDefaultVariableFont,
&mDefaultFixedFont,
&mDefaultSerifFont,
&mDefaultSansSerifFont,
&mDefaultMonospaceFont,
&mDefaultCursiveFont,
&mDefaultFantasyFont
&prefs->mDefaultVariableFont,
&prefs->mDefaultFixedFont,
&prefs->mDefaultSerifFont,
&prefs->mDefaultSansSerifFont,
&prefs->mDefaultMonospaceFont,
&prefs->mDefaultCursiveFont,
&prefs->mDefaultFantasyFont
};
PR_STATIC_ASSERT(NS_ARRAY_LENGTH(fontTypes) == eDefaultFont_COUNT);
// get attributes specific to each generic font
// Get attributes specific to each generic font. We do not get the user's
// generic-font-name-to-specific-family-name preferences because its the
// generic name that should be fed into the cascade. It is up to the GFX
// code to look up the font prefs to convert generic names to specific
// family names as necessary.
nsCAutoString generic_dot_langGroup;
for (PRUint32 eType = 0; eType < ArrayLength(fontTypes); ++eType) {
generic_dot_langGroup.Assign(kGenericFont[eType]);
@ -538,17 +552,17 @@ nsPresContext::GetFontPreferences()
// set the default variable font (the other fonts are seen as 'generic' fonts
// in GFX and will be queried there when hunting for alternative fonts)
if (eType == eDefaultFont_Variable) {
MAKE_FONT_PREF_KEY(pref, "font.name", generic_dot_langGroup);
MAKE_FONT_PREF_KEY(pref, "font.name.variable.", langGroup);
nsAdoptingString value = Preferences::GetString(pref.get());
if (!value.IsEmpty()) {
font->name.Assign(value);
prefs->mDefaultVariableFont.name.Assign(value);
}
else {
MAKE_FONT_PREF_KEY(pref, "font.default.", langGroup);
value = Preferences::GetString(pref.get());
if (!value.IsEmpty()) {
mDefaultVariableFont.name.Assign(value);
prefs->mDefaultVariableFont.name.Assign(value);
}
}
}
@ -558,12 +572,12 @@ nsPresContext::GetFontPreferences()
// to have the same default font-size as "-moz-fixed" (this tentative
// size may be overwritten with the specific value for "monospace" when
// "font.size.monospace.[langGroup]" is read -- see below)
font->size = mDefaultFixedFont.size;
prefs->mDefaultMonospaceFont.size = prefs->mDefaultFixedFont.size;
}
else if (eType != eDefaultFont_Fixed) {
// all the other generic fonts are initialized with the size of the
// variable font, but their specific size can supersede later -- see below
font->size = mDefaultVariableFont.size;
font->size = prefs->mDefaultVariableFont.size;
}
}
@ -600,6 +614,8 @@ nsPresContext::GetFontPreferences()
font->sizeAdjust);
#endif
}
return prefs;
}
void
@ -740,7 +756,7 @@ nsPresContext::GetUserPreferences()
mPrefScrollbarSide = Preferences::GetInt("layout.scrollbar.side");
GetFontPreferences();
ResetCachedFontPrefs();
// * image animation
const nsAdoptingCString& animatePref =
@ -1123,7 +1139,7 @@ nsPresContext::UpdateCharSet(const nsCString& aCharSet)
NS_RELEASE(mLanguage);
NS_IF_ADDREF(mLanguage = mLangService->GetLocaleLanguage());
}
GetFontPreferences();
ResetCachedFontPrefs();
}
#ifdef IBMBIDI
//ahmed
@ -1305,32 +1321,34 @@ nsPresContext::SetImageAnimationModeExternal(PRUint16 aMode)
}
const nsFont*
nsPresContext::GetDefaultFont(PRUint8 aFontID) const
nsPresContext::GetDefaultFont(PRUint8 aFontID, nsIAtom *aLanguage) const
{
const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage);
const nsFont *font;
switch (aFontID) {
// Special (our default variable width font and fixed width font)
case kPresContext_DefaultVariableFont_ID:
font = &mDefaultVariableFont;
font = &prefs->mDefaultVariableFont;
break;
case kPresContext_DefaultFixedFont_ID:
font = &mDefaultFixedFont;
font = &prefs->mDefaultFixedFont;
break;
// CSS
case kGenericFont_serif:
font = &mDefaultSerifFont;
font = &prefs->mDefaultSerifFont;
break;
case kGenericFont_sans_serif:
font = &mDefaultSansSerifFont;
font = &prefs->mDefaultSansSerifFont;
break;
case kGenericFont_monospace:
font = &mDefaultMonospaceFont;
font = &prefs->mDefaultMonospaceFont;
break;
case kGenericFont_cursive:
font = &mDefaultCursiveFont;
font = &prefs->mDefaultCursiveFont;
break;
case kGenericFont_fantasy:
font = &mDefaultFantasyFont;
font = &prefs->mDefaultFantasyFont;
break;
default:
font = nsnull;

View File

@ -119,8 +119,7 @@ enum nsPresContext_CachedBoolPrefType {
// supported values for cached integer pref types
enum nsPresContext_CachedIntPrefType {
kPresContext_MinimumFontSize = 1,
kPresContext_ScrollbarSide,
kPresContext_ScrollbarSide = 1,
kPresContext_BidiDirection
};
@ -304,23 +303,26 @@ public:
}
/**
* Get the default font corresponding to the given ID. This object is
* read-only, you must copy the font to modify it.
* Get the default font for the given language and generic font ID.
* If aLanguage is nsnull, the document's language is used.
*
* This object is read-only, you must copy the font to modify it.
*
* When aFontID is kPresContext_DefaultVariableFontID or
* kPresContext_DefaultFixedFontID (which equals
* kGenericFont_moz_fixed, which is used for the -moz-fixed generic),
* the nsFont returned has its name as a CSS generic family (serif or
* sans-serif for the former, monospace for the latter), and its size
* as the default font size for variable or fixed fonts for the pres
* context's language group.
* as the default font size for variable or fixed fonts for the
* language group.
*
* For aFontID corresponds to a CSS Generic, the nsFont returned has
* its name as the name or names of the fonts in the user's
* preferences for the given generic and the pres context's language
* group, and its size set to the default variable font size.
* For aFontID corresponding to a CSS Generic, the nsFont returned has
* its name set to that generic font's name, and its size set to
* the user's preference for font size for that generic and the
* given language.
*/
NS_HIDDEN_(const nsFont*) GetDefaultFont(PRUint8 aFontID) const;
NS_HIDDEN_(const nsFont*) GetDefaultFont(PRUint8 aFontID,
nsIAtom *aLanguage) const;
/** Get a cached boolean pref, by its type */
// * - initially created for bugs 31816, 20760, 22963
@ -349,8 +351,6 @@ public:
// If called with a constant parameter, the compiler should optimize
// this switch statement away.
switch (aPrefType) {
case kPresContext_MinimumFontSize:
return mMinimumFontSizePref;
case kPresContext_ScrollbarSide:
return mPrefScrollbarSide;
case kPresContext_BidiDirection:
@ -528,15 +528,20 @@ public:
mTextZoom = aZoom;
if (HasCachedStyleData()) {
// Media queries could have changed since we changed the meaning
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged(true);
RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
}
}
PRInt32 MinFontSize() const {
return NS_MAX(mMinFontSize, mMinimumFontSizePref);
/**
* Get the minimum font size for the specified language. If aLanguage
* is nsnull, then the document's language is used.
*/
PRInt32 MinFontSize(nsIAtom *aLanguage) const {
const LangGroupFontPrefs *prefs = GetFontPrefsForLang(aLanguage);
return NS_MAX(mMinFontSize, prefs->mMinimumFontSize);
}
void SetMinFontSize(PRInt32 aMinFontSize) {
@ -545,7 +550,7 @@ public:
mMinFontSize = aMinFontSize;
if (HasCachedStyleData()) {
// Media queries could have changed since we changed the meaning
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged(true);
RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
@ -965,7 +970,14 @@ public:
virtual NS_MUST_OVERRIDE size_t
SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
return 0;
size_t n = 0;
LangGroupFontPrefs *langGroupfontPrefs = mLangGroupFontPrefs.mNext;
while (langGroupfontPrefs) {
// XXX this doesn't include allocations made by the nsFont members
n += sizeof(LangGroupFontPrefs);
langGroupfontPrefs = langGroupfontPrefs->mNext;
}
return n;
// Measurement of other members may be added later if DMD finds it is
// worthwhile.
@ -994,7 +1006,62 @@ protected:
static NS_HIDDEN_(void) PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure);
NS_HIDDEN_(void) GetUserPreferences();
NS_HIDDEN_(void) GetFontPreferences();
// Allow nsAutoPtr<LangGroupFontPrefs> dtor to access this protected struct's
// dtor:
struct LangGroupFontPrefs;
friend class nsAutoPtr<LangGroupFontPrefs>;
struct LangGroupFontPrefs {
// Font sizes default to zero; they will be set in GetFontPreferences
LangGroupFontPrefs()
: mLangGroup(nsnull)
, mMinimumFontSize(0)
, mDefaultVariableFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFixedFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSerifFont("serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultSansSerifFont("sans-serif", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultMonospaceFont("monospace", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
, mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL,
NS_FONT_VARIANT_NORMAL, NS_FONT_WEIGHT_NORMAL,
NS_FONT_STRETCH_NORMAL, 0, 0)
{}
nsCOMPtr<nsIAtom> mLangGroup;
nscoord mMinimumFontSize;
nsFont mDefaultVariableFont;
nsFont mDefaultFixedFont;
nsFont mDefaultSerifFont;
nsFont mDefaultSansSerifFont;
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
nsAutoPtr<LangGroupFontPrefs> mNext;
};
/**
* Fetch the user's font preferences for the given aLanguage's
* langugage group.
*/
const LangGroupFontPrefs* GetFontPrefsForLang(nsIAtom *aLanguage) const;
void ResetCachedFontPrefs() {
// Throw away any other LangGroupFontPrefs objects:
mLangGroupFontPrefs.mNext = nsnull;
// Make GetFontPreferences reinitialize mLangGroupFontPrefs:
mLangGroupFontPrefs.mLangGroup = nsnull;
}
NS_HIDDEN_(void) UpdateCharSet(const nsCString& aCharSet);
@ -1089,9 +1156,6 @@ protected:
// container for per-context fonts (downloadable, SVG, etc.)
nsUserFontSet* mUserFontSet;
PRInt32 mFontScaler;
nscoord mMinimumFontSizePref;
nsRect mVisibleArea;
nsSize mPageSize;
float mPageScale;
@ -1115,13 +1179,7 @@ protected:
PRUint16 mImageAnimationMode;
PRUint16 mImageAnimationModePref;
nsFont mDefaultVariableFont;
nsFont mDefaultFixedFont;
nsFont mDefaultSerifFont;
nsFont mDefaultSansSerifFont;
nsFont mDefaultMonospaceFont;
nsFont mDefaultCursiveFont;
nsFont mDefaultFantasyFont;
LangGroupFontPrefs mLangGroupFontPrefs;
nscoord mBorderWidthTable[3];

View File

@ -688,8 +688,6 @@ PresShell::MemoryReporter::SizeEnumerator(PresShellPtrKey *aEntry,
return PL_DHASH_NEXT;
}
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(GfxTextrunWordCacheMallocSizeOf, "gfx/textrun-word-cache")
NS_IMETHODIMP
PresShell::MemoryReporter::GetName(nsACString &aName)
{
@ -977,8 +975,8 @@ PresShell::~PresShell()
"post-reflow queues not empty. This means we're leaking");
#ifdef DEBUG
NS_ASSERTION(mPresArenaAllocCount == 0,
"Some pres arena objects were not freed");
MOZ_ASSERT(mPresArenaAllocCount == 0,
"Some pres arena objects were not freed");
#endif
delete mStyleSet;

View File

@ -252,6 +252,7 @@ static void Shutdown();
#include "nsCSPService.h"
#include "nsISmsService.h"
#include "nsISmsDatabaseService.h"
#include "mozilla/dom/sms/SmsRequestManager.h"
#include "mozilla/dom/sms/SmsServicesFactory.h"
#include "nsIPowerManagerService.h"
@ -309,6 +310,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsService, SmsServicesFactory::Crea
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsDatabaseService, SmsServicesFactory::CreateSmsDatabaseService)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService,
PowerManagerService::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(SmsRequestManager)
//-----------------------------------------------------------------------------
@ -800,6 +802,7 @@ NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CID);
#endif
NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
NS_DEFINE_NAMED_CID(SMS_DATABASE_SERVICE_CID);
NS_DEFINE_NAMED_CID(SMS_REQUEST_MANAGER_CID);
NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
static nsresult
@ -1071,6 +1074,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_STRUCTUREDCLONECONTAINER_CID, false, NULL, nsStructuredCloneContainerConstructor },
{ &kSMS_SERVICE_CID, false, NULL, nsISmsServiceConstructor },
{ &kSMS_DATABASE_SERVICE_CID, false, NULL, nsISmsDatabaseServiceConstructor },
{ &kSMS_REQUEST_MANAGER_CID, false, NULL, SmsRequestManagerConstructor },
{ &kNS_POWERMANAGERSERVICE_CID, false, NULL, nsIPowerManagerServiceConstructor },
{ NULL }
};
@ -1207,6 +1211,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ NS_STRUCTUREDCLONECONTAINER_CONTRACTID, &kNS_STRUCTUREDCLONECONTAINER_CID },
{ SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
{ SMS_DATABASE_SERVICE_CONTRACTID, &kSMS_DATABASE_SERVICE_CID },
{ SMS_REQUEST_MANAGER_CONTRACTID, &kSMS_REQUEST_MANAGER_CID },
{ POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID },
{ NULL }
};

View File

@ -125,7 +125,6 @@
#include "nsHyphenationManager.h"
#include "nsEditorSpellCheck.h"
#include "nsDOMMemoryReporter.h"
#include "mozilla/dom/sms/SmsRequestManager.h"
extern void NS_ShutdownChainItemPool();
@ -272,16 +271,12 @@ nsLayoutStatics::Initialize()
nsDOMMemoryMultiReporter::Init();
sms::SmsRequestManager::Init();
return NS_OK;
}
void
nsLayoutStatics::Shutdown()
{
sms::SmsRequestManager::Shutdown();
// Don't need to shutdown nsDOMMemoryReporter, that will be done by the memory
// reporter manager.

View File

@ -1550,7 +1550,11 @@ void
nsGfxScrollFrameInner::ScrollTo(nsPoint aScrollPosition,
nsIScrollableFrame::ScrollMode aMode)
{
mDestination = ClampScrollPosition(aScrollPosition);
if (ShouldClampScrollPosition()) {
mDestination = ClampScrollPosition(aScrollPosition);
} else {
mDestination = aScrollPosition;
}
if (aMode == nsIScrollableFrame::INSTANT) {
// Asynchronous scrolling is not allowed, so we'll kill any existing
@ -1713,6 +1717,15 @@ bool nsGfxScrollFrameInner::IsIgnoringViewportClipping() const
return subdocFrame && !subdocFrame->ShouldClipSubdocument();
}
bool nsGfxScrollFrameInner::ShouldClampScrollPosition() const
{
if (!mIsRoot)
return true;
nsSubDocumentFrame* subdocFrame = static_cast<nsSubDocumentFrame*>
(nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresContext()->PresShell()->GetRootFrame()));
return !subdocFrame || subdocFrame->ShouldClampScrollPosition();
}
bool nsGfxScrollFrameInner::IsAlwaysActive() const
{
// The root scrollframe for a non-chrome document which is the direct
@ -1812,17 +1825,23 @@ ClampInt(nscoord aLower, nscoord aVal, nscoord aUpper, nscoord aAppUnitsPerPixel
}
nsPoint
nsGfxScrollFrameInner::ClampAndRestrictToDevPixels(const nsPoint& aPt,
nsIntPoint* aPtDevPx) const
nsGfxScrollFrameInner::RestrictToDevPixels(const nsPoint& aPt,
nsIntPoint* aPtDevPx,
bool aShouldClamp) const
{
nsPresContext* presContext = mOuter->PresContext();
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
// Convert to device pixels so we scroll to an integer offset of device
// pixels. But we also need to make sure that our position remains
// inside the allowed region.
nsRect scrollRange = GetScrollRange();
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
if (aShouldClamp) {
nsRect scrollRange = GetScrollRange();
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
} else {
*aPtDevPx = nsIntPoint(NSAppUnitsToIntPixels(aPt.x, appUnitsPerDevPixel),
NSAppUnitsToIntPixels(aPt.y, appUnitsPerDevPixel));
}
return nsPoint(NSIntPixelsToAppUnits(aPtDevPx->x, appUnitsPerDevPixel),
NSIntPixelsToAppUnits(aPtDevPx->y, appUnitsPerDevPixel));
}
@ -1858,7 +1877,8 @@ nsGfxScrollFrameInner::ScrollToImpl(nsPoint aPt)
nsPresContext* presContext = mOuter->PresContext();
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
nsIntPoint ptDevPx;
nsPoint pt = ClampAndRestrictToDevPixels(aPt, &ptDevPx);
nsPoint pt = RestrictToDevPixels(aPt, &ptDevPx, ShouldClampScrollPosition());
nsPoint curPos = GetScrollPosition();
if (pt == curPos) {

View File

@ -177,7 +177,7 @@ public:
}
nsRect GetScrollRange() const;
nsPoint ClampAndRestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx) const;
nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const;
nsPoint ClampScrollPosition(const nsPoint& aPt) const;
static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);
void ScrollTo(nsPoint aScrollPosition, nsIScrollableFrame::ScrollMode aMode);
@ -261,6 +261,8 @@ public:
bool IsIgnoringViewportClipping() const;
bool ShouldClampScrollPosition() const;
bool IsAlwaysActive() const;
void MarkActive();
void MarkInactive();

View File

@ -123,7 +123,9 @@ nsSimplePageSequenceFrame::nsSimplePageSequenceFrame(nsStyleContext* aContext) :
// XXX Unsafe to assume successful allocation
mPageData = new nsSharedPageData();
mPageData->mHeadFootFont = new nsFont(*PresContext()->GetDefaultFont(kGenericFont_serif));
mPageData->mHeadFootFont =
new nsFont(*PresContext()->GetDefaultFont(kGenericFont_serif,
aContext->GetStyleFont()->mLanguage));
mPageData->mHeadFootFont->size = nsPresContext::CSSPointsToAppUnits(10);
nsresult rv;

View File

@ -130,6 +130,12 @@ public:
return !frameLoader || frameLoader->ShouldClipSubdocument();
}
bool ShouldClampScrollPosition()
{
nsFrameLoader* frameLoader = FrameLoader();
return !frameLoader || frameLoader->ShouldClampScrollPosition();
}
protected:
friend class AsyncFrameInit;

View File

@ -0,0 +1,38 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" >
<title>Testcase for fallback colours</title>
<defs>
<filter id="erode">
<feMorphology operator="dilate" radius="3"/>
</filter>
</defs>
<rect x="0%" y="0%" width="100%" height="100%" fill="lime"/>
<text x="10" y="50" font-size="50"
stroke-width="8" stroke="red" fill="none">
A B
</text>
<text x="10" y="50" font-size="50"
stroke-width="8" stroke="url(#null) lime" fill="none" filter="url(#erode)">
A B
</text>
<text x="200" y="50" font-size="50" fill="red">
A B
</text>
<text x="200" y="50" font-size="50" fill="url(#null) lime" filter="url(#erode)">
A B
</text>
<text x="10" y="200" font-size="50" fill="red"
stroke-width="1" stroke="red">
A B
</text>
<text x="10" y="200" font-size="50" fill="url(#null) lime"
stroke-width="1" stroke="url(#null) lime" filter="url(#erode)">
A B
</text>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,16 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" lang="foo">
<title>Test the 'lang' attribute in SVG</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=368840 -->
<style type="text/css">
rect:lang(foo) {
fill: lime;
}
</style>
<rect width="100%" height="100%" fill="red"/>
</svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@ -0,0 +1,16 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="foo">
<title>Test the 'xml:lang' attribute in SVG</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=368840 -->
<style type="text/css">
rect:lang(foo) {
fill: lime;
}
</style>
<rect width="100%" height="100%" fill="red"/>
</svg>

After

Width:  |  Height:  |  Size: 423 B

View File

@ -0,0 +1,16 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="foo" lang="bar">
<title>Test the 'xml:lang' attribute in SVG</title>
<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=368840 -->
<style type="text/css">
rect:lang(foo) {
fill: lime;
}
</style>
<rect width="100%" height="100%" fill="red"/>
</svg>

After

Width:  |  Height:  |  Size: 434 B

View File

@ -121,6 +121,7 @@ random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498
== fallback-color-02a.svg fallback-color-02-ref.svg
== fallback-color-02b.svg fallback-color-02-ref.svg
== fallback-color-03.svg pass.svg
== fallback-color-04.svg pass.svg
== filter-basic-01.svg pass.svg
== filter-basic-02.svg pass.svg
== filter-basic-03.svg pass.svg
@ -152,6 +153,9 @@ fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated) == gr
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated) == gradient-live-01d.svg gradient-live-01-ref.svg # bug 696674
fails == inline-in-xul-basic-01.xul pass.svg
== invalid-text-01.svg pass.svg
== lang-attribute-01.svg pass.svg
== lang-attribute-02.svg pass.svg
== lang-attribute-03.svg pass.svg
== linearGradient-basic-01.svg pass.svg
== linearGradient-basic-02.svg pass.svg
== markers-and-group-opacity-01.svg markers-and-group-opacity-01-ref.svg

View File

@ -118,6 +118,7 @@ public:
/**
* Transfer all of the state from |aExpandedData| into this declaration.
* After calling, |aExpandedData| should be in its initial state.
* Callers must make sure mOrder is updated as necessary.
*/
void CompressFrom(nsCSSExpandedDataBlock *aExpandedData) {
NS_ABORT_IF_FALSE(!mData, "oops");

View File

@ -1222,7 +1222,8 @@ nsComputedDOMStyle::DoGetFontFamily()
const nsString& fontName = font->mFont.name;
if (font->mGenericID == kGenericFont_NONE && !font->mFont.systemFont) {
const nsFont* defaultFont =
presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
font->mLanguage);
PRInt32 lendiff = fontName.Length() - defaultFont->name.Length();
if (lendiff > 0) {

View File

@ -1982,7 +1982,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
{
nsStyleFont* fontData = new (mPresContext) nsStyleFont(mPresContext);
if (NS_LIKELY(fontData != nsnull)) {
nscoord minimumFontSize = mPresContext->MinFontSize();
nscoord minimumFontSize = mPresContext->MinFontSize(fontData->mLanguage);
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
fontData->mFont.size = NS_MAX(fontData->mSize, minimumFontSize);
@ -2543,7 +2543,7 @@ nsRuleNode::SetFontSize(nsPresContext* aPresContext,
{
bool zoom = false;
PRInt32 baseSize = (PRInt32) aPresContext->
GetDefaultFont(aFont->mGenericID)->size;
GetDefaultFont(aFont->mGenericID, aFont->mLanguage)->size;
const nsCSSValue* sizeValue = aRuleData->ValueForFontSize();
if (eCSSUnit_Enumerated == sizeValue->GetUnit()) {
PRInt32 value = sizeValue->GetIntValue();
@ -2654,7 +2654,6 @@ static PRInt8 ClampTo8Bit(PRInt32 aValue) {
/* static */ void
nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
nscoord aMinFontSize,
PRUint8 aGenericFontID, const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
nsStyleFont* aFont, bool aUsedStartStruct,
@ -2662,12 +2661,12 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
{
bool atRoot = !aContext->GetParent();
// mLanguage must be set before before any of the CalcLengthWith (direct
// calls or calls via SetFontSize) for the cases where |aParentFont| is the
// same as |aFont|.
// mLanguage must be set before before any of the CalcLengthWith calls
// (direct calls or calls via SetFontSize) for the cases where |aParentFont|
// is the same as |aFont|.
//
// -x-lang: string, inherit
// this is not a real CSS property, it is a html attribute mapped to CSS
// This is not a real CSS property, it is an HTML attribute mapped to CSS.
const nsCSSValue* langValue = aRuleData->ValueForLang();
if (eCSSUnit_Ident == langValue->GetUnit()) {
nsAutoString lang;
@ -2678,7 +2677,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
}
const nsFont* defaultVariableFont =
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
aFont->mLanguage);
// -moz-system-font: enum (never inherit!)
nsFont systemFont;
@ -2958,12 +2958,21 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
NS_ASSERTION(aFont->mScriptUnconstrainedSize <= aFont->mSize,
"scriptminsize should never be making things bigger");
nscoord fontSize = aFont->mSize;
// enforce the user' specified minimum font-size on the value that we expose
// (but don't change font-size:0)
if (0 < aFont->mSize && aFont->mSize < aMinFontSize)
aFont->mFont.size = aMinFontSize;
else
aFont->mFont.size = aFont->mSize;
// (but don't change font-size:0, since that would unhide hidden text)
if (fontSize > 0) {
nscoord minFontSize = aPresContext->MinFontSize(aFont->mLanguage);
if (minFontSize < 0) {
minFontSize = 0;
}
if (fontSize < minFontSize && !aPresContext->IsChrome()) {
// override the minimum font-size constraint
fontSize = minFontSize;
}
}
aFont->mFont.size = fontSize;
// font-size-adjust: number, none, inherit, initial, -moz-system-font
const nsCSSValue* sizeAdjustValue = aRuleData->ValueForFontSizeAdjust();
@ -2975,6 +2984,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
SETFCT_NONE);
}
// This should die (bug 380915).
//
// SetGenericFont:
// - backtrack to an ancestor with the same generic font name (possibly
// up to the root where default values come from the presentation context)
@ -2982,7 +2993,7 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
/* static */ void
nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
PRUint8 aGenericFontID, nscoord aMinFontSize,
PRUint8 aGenericFontID,
nsStyleFont* aFont)
{
// walk up the contexts until a context with the desired generic font
@ -3003,7 +3014,8 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
// If we stopped earlier because we reached the root of the style tree,
// we will start with the default generic font from the presentation
// context. Otherwise we start with the higher context.
const nsFont* defaultFont = aPresContext->GetDefaultFont(aGenericFontID);
const nsFont* defaultFont =
aPresContext->GetDefaultFont(aGenericFontID, aFont->mLanguage);
nsStyleFont parentFont(*defaultFont, aPresContext);
if (higherContext) {
const nsStyleFont* tmpFont = higherContext->GetStyleFont();
@ -3053,7 +3065,7 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
if (i != 0)
ruleData.ValueForFontFamily()->Reset();
nsRuleNode::SetFont(aPresContext, context, aMinFontSize,
nsRuleNode::SetFont(aPresContext, context,
aGenericFontID, &ruleData, &parentFont, aFont,
false, dummy);
@ -3099,24 +3111,16 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// (although there is a pretty good chance they'll fully specify it
// using the 'font' shorthand).
// See if there is a minimum font-size constraint to honor
nscoord minimumFontSize = mPresContext->MinFontSize();
if (minimumFontSize < 0)
minimumFontSize = 0;
bool useDocumentFonts =
mPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
// See if we are in the chrome
// We only need to know this to determine if we have to use the
// document fonts (overriding the useDocumentFonts flag), or to
// determine if we have to override the minimum font-size constraint.
if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
// document fonts (overriding the useDocumentFonts flag).
if (!useDocumentFonts && mPresContext->IsChrome()) {
// if we are not using document fonts, but this is a XUL document,
// then we use the document fonts anyway
useDocumentFonts = true;
minimumFontSize = 0;
}
// Figure out if we are a generic font
@ -3157,7 +3161,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// Now compute our font struct
if (generic == kGenericFont_NONE) {
// continue the normal processing
nsRuleNode::SetFont(mPresContext, aContext, minimumFontSize, generic,
nsRuleNode::SetFont(mPresContext, aContext, generic,
aRuleData, parentFont, font,
aStartStruct != nsnull, canStoreInRuleTree);
}
@ -3165,7 +3169,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct,
// re-calculate the font as a generic font
canStoreInRuleTree = false;
nsRuleNode::SetGenericFont(mPresContext, aContext, generic,
minimumFontSize, font);
font);
}
COMPUTE_END_INHERITED(Font, font)
@ -3326,14 +3330,12 @@ nsRuleNode::ComputeTextData(void* aStartStruct,
!lineHeightValue->IsRelativeLengthUnit()) {
nscoord lh = nsStyleFont::ZoomText(mPresContext,
text->mLineHeight.GetCoordValue());
nscoord minimumFontSize = mPresContext->MinFontSize();
canStoreInRuleTree = false;
const nsStyleFont *font = aContext->GetStyleFont();
nscoord minimumFontSize = mPresContext->MinFontSize(font->mLanguage);
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
// If we applied a minimum font size, scale the line height by
// the same ratio. (If we *might* have applied a minimum font
// size, we can't cache in the rule tree.)
canStoreInRuleTree = false;
const nsStyleFont *font = aContext->GetStyleFont();
if (font->mSize != 0) {
lh = nscoord(float(lh) * float(font->mFont.size) / float(font->mSize));
} else {

View File

@ -610,7 +610,6 @@ protected:
static void SetFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
nscoord aMinFontSize,
PRUint8 aGenericFontID,
const nsRuleData* aRuleData,
const nsStyleFont* aParentFont,
@ -621,7 +620,6 @@ protected:
static void SetGenericFont(nsPresContext* aPresContext,
nsStyleContext* aContext,
PRUint8 aGenericFontID,
nscoord aMinFontSize,
nsStyleFont* aFont);
void AdjustLogicalBoxProp(nsStyleContext* aContext,

View File

@ -147,7 +147,8 @@ nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
}
nsStyleFont::nsStyleFont(nsPresContext* aPresContext)
: mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID))),
// passing nsnull to GetDefaultFont make it use the doc language
: mFont(*(aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, nsnull))),
mGenericID(kGenericFont_NONE)
{
MOZ_COUNT_CTOR(nsStyleFont);

View File

@ -16,22 +16,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=401046
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401046">Mozilla Bug 401046</a>
<!-- FIXME tried changing the zh-CN pref instead of x-western, but the language
is based only on the document *charset* -->
<!--
<p id="display" lang="zh-Hans">
<span id="s0" style="font-size: 0">汉字</span>
<span id="s4" style="font-size: 4px">汉字</span>
<span id="s12" style="font-size: 12px">汉字</span>
<span id="s28" style="font-size: 28px">汉字</span>
</p>
-->
<p id="display">
<span id="s0" style="font-size: 0">Ép</span>
<span id="s4" style="font-size: 4px">Ép</span>
<span id="s12" style="font-size: 12px">Ép</span>
<span id="s28" style="font-size: 28px">Ép</span>
</p>
<div id="content" style="display: none">
</div>
@ -56,7 +46,7 @@ function fs(idx) {
return getComputedStyle(elts[idx], "").marginBottom;
}
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, step1);
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, step1);
function step1() {
is(fs(0), "0px", "at min font size 0, 0px should compute to 0px");
@ -64,7 +54,7 @@ function step1() {
is(fs(2), "12px", "at min font size 0, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 0, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 7]]}, step2);
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 7]]}, step2);
}
function step2() {
@ -73,7 +63,7 @@ function step2() {
is(fs(2), "12px", "at min font size 7, 12px should compute to 12px");
is(fs(3), "28px", "at min font size 7, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.x-western', 18]]}, step3);
SpecialPowers.pushPrefEnv({'set': [['font.minimum-size.zh-CN', 18]]}, step3);
}
function step3() {
@ -82,7 +72,7 @@ function step3() {
is(fs(2), "18px", "at min font size 18, 12px should compute to 18px");
is(fs(3), "28px", "at min font size 18, 28px should compute to 28px");
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.x-western']]}, SimpleTest.finish);
SpecialPowers.pushPrefEnv({'clear': [['font.minimum-size.zh-CN']]}, SimpleTest.finish);
}
</script>

View File

@ -721,15 +721,17 @@ SpdySession::GenerateGoAway()
}
void
SpdySession::CleanupStream(SpdyStream *aStream, nsresult aResult)
SpdySession::CleanupStream(SpdyStream *aStream, nsresult aResult,
rstReason aResetCode)
{
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
LOG3(("SpdySession::CleanupStream %p %p 0x%x %X\n",
this, aStream, aStream->StreamID(), aResult));
if (!aStream->RecvdFin() && aStream->StreamID()) {
LOG3(("Stream had not processed recv FIN, sending RST"));
GenerateRstStream(RST_CANCEL, aStream->StreamID());
LOG3(("Stream had not processed recv FIN, sending RST code %X\n",
aResetCode));
GenerateRstStream(aResetCode, aStream->StreamID());
--mConcurrent;
ProcessPending();
}
@ -842,9 +844,21 @@ SpdySession::HandleSynReply(SpdySession *self)
if (self->mInputFrameDataSize < 8) {
LOG3(("SpdySession::HandleSynReply %p SYN REPLY too short data=%d",
self, self->mInputFrameDataSize));
// A framing error is a session wide error that cannot be recovered
return NS_ERROR_ILLEGAL_VALUE;
}
// Uncompress the headers into mDecompressBuffer, leaving them in
// spdy format for the time being. Make certain to do this
// step before any error handling that might abort the stream but not
// the session becuase the session compression context will become
// inconsistent if all of the compressed data is not processed.
if (NS_FAILED(self->DownstreamUncompress(self->mInputFrameBuffer + 14,
self->mInputFrameDataSize - 6))) {
LOG(("SpdySession::HandleSynReply uncompress failed\n"));
return NS_ERROR_FAILURE;
}
PRUint32 streamID =
PR_ntohl(reinterpret_cast<PRUint32 *>(self->mInputFrameBuffer.get())[2]);
self->mInputFrameDataStream = self->mStreamIDHash.Get(streamID);
@ -854,81 +868,81 @@ SpdySession::HandleSynReply(SpdySession *self)
self->mNextStreamID));
if (streamID >= self->mNextStreamID)
self->GenerateRstStream(RST_INVALID_STREAM, streamID);
// It is likely that this is a reply to a stream ID that has been canceled.
// For the most part we would like to ignore it, but the header needs to be
// be parsed to keep the compression context synchronized
self->DownstreamUncompress(self->mInputFrameBuffer + 14,
self->mInputFrameDataSize - 6);
self->ResetDownstreamState();
return NS_OK;
}
self->mInputFrameDataStream->UpdateTransportReadEvents(
self->mInputFrameDataSize);
nsresult rv = self->HandleSynReplyForValidStream();
if (rv == NS_ERROR_ILLEGAL_VALUE) {
LOG3(("SpdySession::HandleSynReply %p PROTOCOL_ERROR detected 0x%X\n",
self, streamID));
self->CleanupStream(self->mInputFrameDataStream, rv, RST_PROTOCOL_ERROR);
self->ResetDownstreamState();
rv = NS_OK;
}
if (self->mInputFrameDataStream->GetFullyOpen()) {
return rv;
}
// HandleSynReplyForValidStream() returns NS_ERROR_ILLEGAL_VALUE when the stream
// should be reset with a PROTOCOL_ERROR, NS_OK when the SYN_REPLY was
// fine, and any other error is fatal to the session.
nsresult
SpdySession::HandleSynReplyForValidStream()
{
if (mInputFrameDataStream->GetFullyOpen()) {
// "If an endpoint receives multiple SYN_REPLY frames for the same active
// stream ID, it must drop the stream, and send a RST_STREAM for the
// stream with the error PROTOCOL_ERROR."
//
// In addition to that we abort the session - this is a serious protocol
// violation.
self->GenerateRstStream(RST_PROTOCOL_ERROR, streamID);
return NS_ERROR_ILLEGAL_VALUE;
// If the stream is open then just RST_STREAM and move on, otherwise
// abort the session
return mInputFrameDataStream->RecvdFin() ?
NS_ERROR_ALREADY_OPENED : NS_ERROR_ILLEGAL_VALUE;
}
self->mInputFrameDataStream->SetFullyOpen();
mInputFrameDataStream->SetFullyOpen();
self->mInputFrameDataLast = self->mInputFrameBuffer[4] & kFlag_Data_FIN;
mInputFrameDataLast = mInputFrameBuffer[4] & kFlag_Data_FIN;
if (self->mInputFrameBuffer[4] & kFlag_Data_UNI) {
if (mInputFrameBuffer[4] & kFlag_Data_UNI) {
LOG3(("SynReply had unidirectional flag set on it - nonsensical"));
return NS_ERROR_ILLEGAL_VALUE;
}
LOG3(("SpdySession::HandleSynReply %p SYN_REPLY for 0x%X fin=%d",
self, streamID, self->mInputFrameDataLast));
// The spdystream needs to see flattened http headers
// The Frame Buffer currently holds the complete SYN_REPLY
// frame. The interesting data is at offset 14, where the
// compressed name/value header block lives.
// We unpack that into the mDecompressBuffer - we can't do
// it streamed because the version and status information
// is not guaranteed to be first. This is then finally
// converted to HTTP format in mFlatHTTPResponseHeaders
nsresult rv = self->DownstreamUncompress(self->mInputFrameBuffer + 14,
self->mInputFrameDataSize - 6);
if (NS_FAILED(rv)) {
LOG(("SpdySession::HandleSynReply uncompress failed\n"));
return rv;
}
LOG3(("SpdySession::HandleSynReplyForValidStream %p SYN_REPLY for 0x%X "
"fin=%d",
this, mInputFrameDataStream->StreamID(), mInputFrameDataLast));
Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_SIZE,
self->mInputFrameDataSize - 6);
if (self->mDecompressBufferUsed) {
mInputFrameDataSize - 6);
if (mDecompressBufferUsed) {
PRUint32 ratio =
(self->mInputFrameDataSize - 6) * 100 / self->mDecompressBufferUsed;
(mInputFrameDataSize - 6) * 100 / mDecompressBufferUsed;
Telemetry::Accumulate(Telemetry::SPDY_SYN_REPLY_RATIO, ratio);
}
// status and version are required.
nsDependentCSubstring status, version;
rv = self->FindHeader(NS_LITERAL_CSTRING("status"), status);
nsresult rv = FindHeader(NS_LITERAL_CSTRING("status"), status);
if (NS_FAILED(rv))
return (rv == NS_ERROR_NOT_AVAILABLE) ? NS_ERROR_ILLEGAL_VALUE : rv;
rv = FindHeader(NS_LITERAL_CSTRING("version"), version);
if (NS_FAILED(rv))
return (rv == NS_ERROR_NOT_AVAILABLE) ? NS_ERROR_ILLEGAL_VALUE : rv;
// The spdystream needs to see flattened http headers
// Uncompressed spdy format headers currently live in
// mDeccompressBuffer - convert that to HTTP format in
// mFlatHTTPResponseHeaders in ConvertHeaders()
rv = ConvertHeaders(status, version);
if (NS_FAILED(rv))
return rv;
rv = self->FindHeader(NS_LITERAL_CSTRING("version"), version);
if (NS_FAILED(rv))
return rv;
rv = self->ConvertHeaders(status, version);
if (NS_FAILED(rv))
return rv;
self->ChangeDownstreamState(PROCESSING_CONTROL_SYN_REPLY);
mInputFrameDataStream->UpdateTransportReadEvents(mInputFrameDataSize);
ChangeDownstreamState(PROCESSING_CONTROL_SYN_REPLY);
return NS_OK;
}
@ -1474,7 +1488,7 @@ SpdySession::WriteSegments(nsAHttpSegmentWriter *writer,
// mInputFrameDataStream is reset by ChangeDownstreamState
SpdyStream *stream = mInputFrameDataStream;
ResetDownstreamState();
CleanupStream(stream, rv);
CleanupStream(stream, rv, RST_CANCEL);
return NS_OK;
}
@ -1491,13 +1505,13 @@ SpdySession::WriteSegments(nsAHttpSegmentWriter *writer,
SpdyStream *stream = mInputFrameDataStream;
if (mInputFrameDataRead == mInputFrameDataSize)
ResetDownstreamState();
CleanupStream(stream, NS_OK);
CleanupStream(stream, NS_OK, RST_CANCEL);
NS_ABORT_IF_FALSE(!mNeedsCleanup, "double cleanup out of data frame");
return NS_OK;
}
if (mNeedsCleanup) {
CleanupStream(mNeedsCleanup, NS_OK);
CleanupStream(mNeedsCleanup, NS_OK, RST_CANCEL);
mNeedsCleanup = nsnull;
}
@ -1622,7 +1636,7 @@ SpdySession::CloseTransaction(nsAHttpTransaction *aTransaction,
LOG3(("SpdySession::CloseTranscation probably a cancel. "
"this=%p, trans=%p, result=%x, streamID=0x%X stream=%p",
this, aTransaction, aResult, stream->StreamID(), stream));
CleanupStream(stream, aResult);
CleanupStream(stream, aResult, RST_CANCEL);
ResumeRecv();
}

View File

@ -105,7 +105,7 @@ public:
CONTROL_TYPE_LAST = 10
};
enum
enum rstReason
{
RST_PROTOCOL_ERROR = 1,
RST_INVALID_STREAM = 2,
@ -181,6 +181,7 @@ private:
PROCESSING_CONTROL_RST_STREAM
};
nsresult HandleSynReplyForValidStream();
PRUint32 GetWriteQueueSize();
void ChangeDownstreamState(enum stateType);
void ResetDownstreamState();
@ -192,7 +193,7 @@ private:
void GeneratePing(PRUint32);
void GenerateRstStream(PRUint32, PRUint32);
void GenerateGoAway();
void CleanupStream(SpdyStream *, nsresult);
void CleanupStream(SpdyStream *, nsresult, rstReason);
void SetWriteCallbacks();
void FlushOutputQueue();

View File

@ -452,16 +452,31 @@ SpdyStream::ParseHttpRequestHeaders(const char *buf,
NS_ABORT_IF_FALSE(!mTxInlineFrame[4],
"Size greater than 24 bits");
// For methods other than POST and PUT, we will set the fin bit
// right on the syn stream packet.
// Determine whether to put the fin bit on the syn stream frame or whether
// to wait for a data packet to put it on.
if (mTransaction->RequestHead()->Method() == nsHttp::Get ||
mTransaction->RequestHead()->Method() == nsHttp::Connect ||
mTransaction->RequestHead()->Method() == nsHttp::Head) {
// for GET, CONNECT, and HEAD place the fin bit right on the
// syn stream packet
if (mTransaction->RequestHead()->Method() != nsHttp::Post &&
mTransaction->RequestHead()->Method() != nsHttp::Put &&
mTransaction->RequestHead()->Method() != nsHttp::Options) {
mSentFinOnData = 1;
mTxInlineFrame[4] = SpdySession::kFlag_Data_FIN;
}
else if (mTransaction->RequestHead()->Method() == nsHttp::Post ||
mTransaction->RequestHead()->Method() == nsHttp::Put ||
mTransaction->RequestHead()->Method() == nsHttp::Options) {
// place fin in a data frame even for 0 length messages, I've seen
// the google gateway be unhappy with fin-on-syn for 0 length POST
}
else if (!mRequestBodyLenRemaining) {
// for other HTTP extension methods, rely on the content-length
// to determine whether or not to put fin on syn
mSentFinOnData = 1;
mTxInlineFrame[4] = SpdySession::kFlag_Data_FIN;
}
Telemetry::Accumulate(Telemetry::SPDY_SYN_SIZE, mTxInlineFrameUsed - 18);
// The size of the input headers is approximate

View File

@ -66,6 +66,11 @@ function server_report(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
}
// Hook for test code.
let hooks = {
onGET: function onGET(request) {}
}
function ServerChannel() {
this.data = "";
this.etag = "";
@ -83,6 +88,7 @@ ServerChannel.prototype = {
let etag = request.getHeader("If-None-Match");
if (etag == this.etag) {
response.setStatusLine(request.httpVersion, 304, "Not Modified");
hooks.onGET(request);
return;
}
}
@ -95,6 +101,7 @@ ServerChannel.prototype = {
if (this.getCount == SERVER_MAX_GETS) {
this.clear();
}
hooks.onGET(request);
},
PUT: function PUT(request, response) {
@ -294,9 +301,15 @@ add_test(function test_lastMsgMaxTries() {
// to 2 times for other exchanges). So let's pretend it took
// 150ms to come up with the final payload, which should require
// 3 polls.
_("Pairing successful, waiting 150ms to send final payload.");
Utils.namedTimer(function() { snd.sendAndComplete(DATA); },
150, this, "_sendTimer");
// Rather than using an imprecise timer, we hook into the channel's
// GET handler to know how long to wait.
let count = 0;
hooks.onGET = function onGET(request) {
if (++count == 3) {
_("Third GET. Triggering send.");
Utils.nextTick(function() { snd.sendAndComplete(DATA); });
}
};
},
onComplete: function onComplete() {}
});
@ -314,6 +327,9 @@ add_test(function test_lastMsgMaxTries() {
// Ensure channel was cleared, no error report.
do_check_eq(channels[this.cid].data, undefined);
do_check_eq(error_report, undefined);
// Clean up.
hooks.onGET = function onGET(request) {};
run_next_test();
}
});

View File

@ -156,6 +156,9 @@ function doApply(fun, invocant, args) {
return Function.prototype.apply.call(fun, invocant, args);
}
// Use a weak map to cache wrappers. This allows the wrappers to preserve identity.
var wrapperCache = WeakMap();
function wrapPrivileged(obj) {
// Primitives pass straight through.
@ -166,10 +169,15 @@ function wrapPrivileged(obj) {
if (isWrapper(obj))
throw "Trying to double-wrap object!";
// Try the cache.
if (wrapperCache.has(obj))
return wrapperCache.get(obj);
// Make our core wrapper object.
var handler = new SpecialPowersHandler(obj);
// If the object is callable, make a function proxy.
var wrapper;
if (typeof obj === "function") {
var callTrap = function() {
// The invocant and arguments may or may not be wrappers. Unwrap them if necessary.
@ -193,11 +201,16 @@ function wrapPrivileged(obj) {
return wrapPrivileged(new FakeConstructor());
};
return Proxy.createFunction(handler, callTrap, constructTrap);
wrapper = Proxy.createFunction(handler, callTrap, constructTrap);
}
// Otherwise, just make a regular object proxy.
else {
wrapper = Proxy.create(handler);
}
// Otherwise, just make a regular object proxy.
return Proxy.create(handler);
// Cache the wrapper and return it.
wrapperCache.set(obj, wrapper);
return wrapper;
};
function unwrapPrivileged(x) {
@ -408,9 +421,6 @@ SpecialPowersAPI.prototype = {
*
* Known Issues:
*
* - The wrapping function does not preserve identity, so
* SpecialPowers.wrap(foo) !== SpecialPowers.wrap(foo). See bug 718543.
*
* - The wrapper cannot see expando properties on unprivileged DOM objects.
* That is to say, the wrapper uses Xray delegation.
*

View File

@ -134,6 +134,13 @@ function starttest(){
noxray.b = 122;
is(noxray_wrapper.b, 122, "Should be able to shadow.");
// Check that the wrapper preserves identity.
var someIdentityObject = {a: 2};
ok(SpecialPowers.wrap(someIdentityObject) === SpecialPowers.wrap(someIdentityObject),
"SpecialPowers wrapping should preserve identity!");
ok(webnav === SpecialPowers.wrap(SpecialPowers.unwrap(webnav)),
"SpecialPowers wrapping should preserve identity!");
info("\nProfile::SpecialPowersRunTime: " + (new Date() - startTime) + "\n");
SimpleTest.finish();
}

View File

@ -65,9 +65,8 @@
#include "mozilla/dom/sms/Constants.h"
#include "mozilla/dom/sms/Types.h"
#include "mozilla/dom/sms/PSms.h"
#include "mozilla/dom/sms/SmsRequestManager.h"
#include "mozilla/dom/sms/SmsRequest.h"
#include "mozilla/dom/sms/SmsParent.h"
#include "nsISmsRequestManager.h"
#include "nsISmsDatabaseService.h"
using namespace mozilla;
@ -345,7 +344,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsSent(JNIEnv* jenv, jclass,
obs->NotifyObservers(message, kSmsSentObserverTopic, nsnull);
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifySmsSent(mRequestId, message);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifySmsSent(mRequestId, message);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -419,8 +422,9 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsSendFailed(JNIEnv* jenv, jclass,
{
class NotifySmsSendFailedRunnable : public nsRunnable {
public:
NotifySmsSendFailedRunnable(SmsRequest::ErrorType aError,
PRInt32 aRequestId, PRUint64 aProcessId)
NotifySmsSendFailedRunnable(PRInt32 aError,
PRInt32 aRequestId,
PRUint64 aProcessId)
: mError(aError)
, mRequestId(aRequestId)
, mProcessId(aProcessId)
@ -428,7 +432,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsSendFailed(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifySmsSendFailed(mRequestId, mError);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifySmsSendFailed(mRequestId, mError);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -444,14 +452,14 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsSendFailed(JNIEnv* jenv, jclass,
}
private:
SmsRequest::ErrorType mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
PRInt32 mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsSendFailedRunnable(SmsRequest::ErrorType(aError), aRequestId, aProcessId);
new NotifySmsSendFailedRunnable(aError, aRequestId, aProcessId);
NS_DispatchToMainThread(runnable);
}
@ -477,7 +485,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGetSms(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessageData);
SmsRequestManager::GetInstance()->NotifyGotSms(mRequestId, message);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyGotSms(mRequestId, message);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -517,8 +529,9 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGetSmsFailed(JNIEnv* jenv, jclass,
{
class NotifyGetSmsFailedRunnable : public nsRunnable {
public:
NotifyGetSmsFailedRunnable(SmsRequest::ErrorType aError,
PRInt32 aRequestId, PRUint64 aProcessId)
NotifyGetSmsFailedRunnable(PRInt32 aError,
PRInt32 aRequestId,
PRUint64 aProcessId)
: mError(aError)
, mRequestId(aRequestId)
, mProcessId(aProcessId)
@ -526,7 +539,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGetSmsFailed(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifyGetSmsFailed(mRequestId, mError);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyGetSmsFailed(mRequestId, mError);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -542,14 +559,14 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGetSmsFailed(JNIEnv* jenv, jclass,
}
private:
SmsRequest::ErrorType mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
PRInt32 mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifyGetSmsFailedRunnable(SmsRequest::ErrorType(aError), aRequestId, aProcessId);
new NotifyGetSmsFailedRunnable(aError, aRequestId, aProcessId);
NS_DispatchToMainThread(runnable);
}
@ -570,7 +587,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleted(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifySmsDeleted(mRequestId, mDeleted);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifySmsDeleted(mRequestId, mDeleted);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -605,8 +626,9 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleteFailed(JNIEnv* jenv, jclass,
{
class NotifySmsDeleteFailedRunnable : public nsRunnable {
public:
NotifySmsDeleteFailedRunnable(SmsRequest::ErrorType aError,
PRInt32 aRequestId, PRUint64 aProcessId)
NotifySmsDeleteFailedRunnable(PRInt32 aError,
PRInt32 aRequestId,
PRUint64 aProcessId)
: mError(aError)
, mRequestId(aRequestId)
, mProcessId(aProcessId)
@ -614,7 +636,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleteFailed(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifySmsDeleteFailed(mRequestId, mError);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifySmsDeleteFailed(mRequestId, mError);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -630,14 +656,14 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleteFailed(JNIEnv* jenv, jclass,
}
private:
SmsRequest::ErrorType mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
PRInt32 mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifySmsDeleteFailedRunnable(SmsRequest::ErrorType(aError), aRequestId, aProcessId);
new NotifySmsDeleteFailedRunnable(aError, aRequestId, aProcessId);
NS_DispatchToMainThread(runnable);
}
@ -655,7 +681,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyNoMessageInList(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifyNoMessageInList(mRequestId);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyNoMessageInList(mRequestId);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -705,9 +735,13 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyListCreated(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessage);
SmsRequestManager::GetInstance()->NotifyCreateMessageList(mRequestId,
mListId,
message);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyCreateMessageList(mRequestId,
mListId,
message);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -765,8 +799,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyGotNextMessage(JNIEnv* jenv, jclass,
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
nsCOMPtr<nsIDOMMozSmsMessage> message = new SmsMessage(mMessage);
SmsRequestManager::GetInstance()->NotifyGotNextMessage(mRequestId,
message);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyGotNextMessage(mRequestId, message);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -808,8 +845,9 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyReadingMessageListFailed(JNIEnv* jenv
{
class NotifyReadListFailedRunnable : public nsRunnable {
public:
NotifyReadListFailedRunnable(SmsRequest::ErrorType aError,
PRInt32 aRequestId, PRUint64 aProcessId)
NotifyReadListFailedRunnable(PRInt32 aError,
PRInt32 aRequestId,
PRUint64 aProcessId)
: mError(aError)
, mRequestId(aRequestId)
, mProcessId(aProcessId)
@ -817,7 +855,11 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyReadingMessageListFailed(JNIEnv* jenv
NS_IMETHODIMP Run() {
if (mProcessId == 0) { // Parent process.
SmsRequestManager::GetInstance()->NotifyReadMessageListFailed(mRequestId, mError);
nsCOMPtr<nsISmsRequestManager> requestManager
= do_GetService(SMS_REQUEST_MANAGER_CONTRACTID);
if (requestManager) {
requestManager->NotifyReadMessageListFailed(mRequestId, mError);
}
} else { // Content process.
nsTArray<SmsParent*> spList;
SmsParent::GetAll(spList);
@ -833,14 +875,14 @@ Java_org_mozilla_gecko_GeckoAppShell_notifyReadingMessageListFailed(JNIEnv* jenv
}
private:
SmsRequest::ErrorType mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
PRInt32 mError;
PRInt32 mRequestId;
PRUint64 mProcessId;
};
nsCOMPtr<nsIRunnable> runnable =
new NotifyReadListFailedRunnable(SmsRequest::ErrorType(aError), aRequestId, aProcessId);
new NotifyReadListFailedRunnable(aError, aRequestId, aProcessId);
NS_DispatchToMainThread(runnable);
}

View File

@ -93,6 +93,9 @@ public:
return FromMilliseconds(aSeconds * 1000.0);
}
static TimeDuration FromMilliseconds(double aMilliseconds);
static inline TimeDuration FromMicroseconds(double aMicroseconds) {
return FromMilliseconds(aMicroseconds / 1000.0);
}
TimeDuration operator+(const TimeDuration& aOther) const {
return TimeDuration::FromTicks(mValue + aOther.mValue);

View File

@ -395,7 +395,7 @@ main(int argc, char **argv)
if (absfwurl) {
CFURLRef xulurl =
CFURLCreateCopyAppendingPathComponent(NULL, absfwurl,
CFSTR("XUL.Framework"),
CFSTR("XUL.framework"),
true);
if (xulurl) {