This commit is contained in:
Richard Newman 2011-12-05 09:37:18 -08:00
Родитель 6ec3002445 ab6e074472
Коммит c96f2d2bc2
428 изменённых файлов: 14596 добавлений и 15757 удалений

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

@ -81,24 +81,6 @@ getDocumentLocaleCB(AtkDocument *aDocument)
return nsAccessibleWrap::ReturnString(locale);
}
const gchar *
getDocumentTypeCB(AtkDocument *aDocument)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
if (!accWrap)
return nsnull;
nsCOMPtr<nsIAccessibleDocument> accDocument;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleDocument),
getter_AddRefs(accDocument));
NS_ENSURE_TRUE(accDocument, nsnull);
nsAutoString mimeType;
nsresult rv = accDocument->GetMimeType(mimeType);
NS_ENSURE_SUCCESS(rv, nsnull);
return nsAccessibleWrap::ReturnString(mimeType);
}
static inline GSList *
prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue)
{

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

@ -660,22 +660,6 @@ nsCoreUtils::GetFirstSensibleColumn(nsITreeBoxObject *aTree)
return column.forget();
}
already_AddRefed<nsITreeColumn>
nsCoreUtils::GetLastSensibleColumn(nsITreeBoxObject *aTree)
{
nsCOMPtr<nsITreeColumns> cols;
aTree->GetColumns(getter_AddRefs(cols));
if (!cols)
return nsnull;
nsCOMPtr<nsITreeColumn> column;
cols->GetLastColumn(getter_AddRefs(column));
if (column && IsColumnHidden(column))
return GetPreviousSensibleColumn(column);
return column.forget();
}
PRUint32
nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree)
{

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

@ -327,12 +327,6 @@ public:
static already_AddRefed<nsITreeColumn>
GetFirstSensibleColumn(nsITreeBoxObject *aTree);
/**
* Return last sensible column for the given tree box object.
*/
static already_AddRefed<nsITreeColumn>
GetLastSensibleColumn(nsITreeBoxObject *aTree);
/**
* Return sensible columns count for the given tree box object.
*/

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

@ -86,6 +86,7 @@ if [ ! "$LIBXUL_SDK" ]; then
if [ "$MOZ_WIDGET_TOOLKIT" = "android" ]; then
add_makefiles "
other-licenses/android/Makefile
other-licenses/skia-npapi/Makefile
"
fi
fi
@ -115,6 +116,9 @@ if [ "$COMPILER_DEPEND" = "" -a "$MOZ_NATIVE_MAKEDEPEND" = "" ]; then
fi
if [ "$ENABLE_TESTS" ]; then
add_makefiles "
build/autoconf/test/Makefile
"
if [ "$_MSC_VER" -a "$OS_TEST" != "x86_64" ]; then
add_makefiles "
build/win32/vmwarerecordinghelper/Makefile

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

@ -3478,10 +3478,29 @@ const BrowserSearch = {
if (!submission)
return;
let newTab;
function newTabHandler(event) {
newTab = event.target;
}
gBrowser.tabContainer.addEventListener("TabOpen", newTabHandler);
openLinkIn(submission.uri.spec,
useNewTab ? "tab" : "current",
{ postData: submission.postData,
relatedToCurrent: true });
gBrowser.tabContainer.removeEventListener("TabOpen", newTabHandler);
if (newTab && !newTab.selected) {
let tabSelected = false;
function tabSelectHandler() {
tabSelected = true;
}
newTab.addEventListener("TabSelect", tabSelectHandler);
setTimeout(function () {
newTab.removeEventListener("TabSelect", tabSelectHandler);
Services.telemetry.getHistogramById("FX_CONTEXT_SEARCH_AND_TAB_SELECT").add(tabSelected);
}, 5000);
}
},
/**
@ -7659,7 +7678,8 @@ var FeedHandler = {
if (browserForLink == gBrowser.selectedBrowser) {
// Batch updates to avoid updating the UI for multiple onLinkAdded events
// fired within 100ms of each other.
clearTimeout(this._updateFeedTimeout);
if (this._updateFeedTimeout)
clearTimeout(this._updateFeedTimeout);
this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
}
}

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

@ -992,7 +992,7 @@ function makePreview(row)
}
#endif
else {
// fallback image for protocols not allowed (e.g., data: or javascript:)
// fallback image for protocols not allowed (e.g., javascript:)
// or elements not [yet] handled (e.g., object, embed).
document.getElementById("brokenimagecontainer").collapsed = false;
document.getElementById("theimagecontainer").collapsed = true;
@ -1228,8 +1228,6 @@ function selectImage()
function checkProtocol(img)
{
var url = img[COL_IMAGE_ADDRESS];
if (/^data:/.test(url) && /^image\//.test(img[COL_IMAGE_NODE].type))
return true;
const regex = /^(https?|ftp|file|about|chrome|resource):/;
return regex.test(url);
return /^data:image\//i.test(url) ||
/^(https?|ftp|file|about|chrome|resource):/.test(url);
}

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

@ -69,8 +69,10 @@ browser/components/shell/src/Makefile
browser/components/tabview/Makefile
browser/devtools/Makefile
browser/devtools/highlighter/Makefile
browser/devtools/scratchpad/Makefile
browser/devtools/shared/Makefile
browser/devtools/sourceeditor/Makefile
browser/devtools/styleeditor/Makefile
browser/devtools/styleinspector/Makefile
browser/devtools/webconsole/Makefile
browser/fuel/Makefile
@ -140,6 +142,7 @@ if [ "$ENABLE_TESTS" ]; then
browser/devtools/scratchpad/test/Makefile
browser/devtools/shared/test/Makefile
browser/devtools/sourceeditor/test/Makefile
browser/devtools/styleeditor/test/Makefile
browser/devtools/styleinspector/test/browser/Makefile
browser/devtools/webconsole/test/browser/Makefile
browser/fuel/test/Makefile

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

@ -188,3 +188,7 @@ https://www.bank2.com:443 privileged,cert=escapeattack2
#
https://redirproxy.example.com:443 privileged,redir=test1.example.com
# Host used for IndexedDB Quota testing
http://bug704464-1.example.com:80 privileged
http://bug704464-2.example.com:80 privileged
http://bug704464-3.example.com:80 privileged

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

@ -1738,7 +1738,7 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
#ifdef DEBUG
{
JS_ASSERT(JS_ObjectIsFunction(aCx, (JSObject *)aFunObj));
JSFunction *fun = (JSFunction *)JS_GetPrivate(aCx, (JSObject *)aFunObj);
JSFunction *fun = JS_GetObjectFunction((JSObject *)aFunObj);
JSScript *script = JS_GetFunctionScript(aCx, fun);
NS_ASSERTION(!script, "Null principal for non-native function!");
@ -2219,7 +2219,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
return result;
}
JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
JSFunction *fun = JS_GetObjectFunction(obj);
JSScript *script = JS_GetFunctionScript(cx, fun);
if (!script)
@ -2243,7 +2243,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
script = frameScript;
}
else if (JS_GetFunctionObject(fun) != obj)
else if (!js::IsOriginalScriptFunction(fun))
{
// Here, obj is a cloned function object. In this case, the
// clone's prototype may have been precompiled from brutally
@ -2285,7 +2285,7 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
#ifdef DEBUG
if (NS_SUCCEEDED(*rv) && !result)
{
JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
JSFunction *fun = JS_GetObjectFunction(obj);
JSScript *script = JS_GetFunctionScript(cx, fun);
NS_ASSERTION(!script, "Null principal for non-native function!");
@ -2432,7 +2432,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
jsClass = js::GetObjectClass(aObj);
if (jsClass == &js::CallClass) {
aObj = js::GetObjectParent(aObj);
aObj = js::GetObjectParentMaybeScope(aObj);
if (!aObj)
return nsnull;
@ -2484,7 +2484,7 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
}
}
aObj = js::GetObjectParent(aObj);
aObj = js::GetObjectParentMaybeScope(aObj);
if (!aObj)
break;

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

@ -366,31 +366,6 @@ nsAttrAndChildArray::AttrAt(PRUint32 aPos) const
return &ATTRS(mImpl)[aPos - mapped].mValue;
}
nsresult
nsAttrAndChildArray::SetAttr(nsIAtom* aLocalName, const nsAString& aValue)
{
PRUint32 i, slotCount = AttrSlotCount();
for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) {
ATTRS(mImpl)[i].mValue.SetTo(aValue);
return NS_OK;
}
}
NS_ENSURE_TRUE(slotCount < ATTRCHILD_ARRAY_MAX_ATTR_COUNT,
NS_ERROR_FAILURE);
if (i == slotCount && !AddAttrSlot()) {
return NS_ERROR_OUT_OF_MEMORY;
}
new (&ATTRS(mImpl)[i].mName) nsAttrName(aLocalName);
new (&ATTRS(mImpl)[i].mValue) nsAttrValue(aValue);
return NS_OK;
}
nsresult
nsAttrAndChildArray::SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue)
{

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

@ -103,7 +103,6 @@ public:
PRUint32 AttrCount() const;
const nsAttrValue* GetAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
const nsAttrValue* AttrAt(PRUint32 aPos) const;
nsresult SetAttr(nsIAtom* aLocalName, const nsAString& aValue);
nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue);
nsresult SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue);

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

@ -594,6 +594,9 @@ GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
GK_ATOM(msthemecompatible, "msthemecompatible")
GK_ATOM(multicol, "multicol")
GK_ATOM(multiple, "multiple")
#ifdef MOZ_MEDIA
GK_ATOM(muted, "muted")
#endif
GK_ATOM(name, "name")
GK_ATOM(_namespace, "namespace")
GK_ATOM(namespaceAlias, "namespace-alias")

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

@ -179,11 +179,11 @@ PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
return linkMask;
nsAString::const_iterator current(start);
bool inString = !nsCRT::IsAsciiSpace(*current);
bool inString = !nsContentUtils::IsHTMLWhitespace(*current);
nsAutoString subString;
while (current != done) {
if (nsCRT::IsAsciiSpace(*current)) {
if (nsContentUtils::IsHTMLWhitespace(*current)) {
if (inString) {
ToLowerCase(Substring(start, current), subString);
linkMask |= ToLinkMask(subString);

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

@ -253,6 +253,9 @@ nsIAtom** const kAttributesHTML[] = {
&nsGkAtoms::min,
&nsGkAtoms::mozdonotsend,
&nsGkAtoms::multiple,
#ifdef MOZ_MEDIA
&nsGkAtoms::muted,
#endif
&nsGkAtoms::name,
&nsGkAtoms::nohref,
&nsGkAtoms::noshade,

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

@ -743,7 +743,7 @@ nsXHTMLContentSerializer::IsShorthandAttr(const nsIAtom* aAttrName,
#ifdef MOZ_MEDIA
// autoplay and controls
if ((aElementName == nsGkAtoms::video || aElementName == nsGkAtoms::audio) &&
(aAttrName == nsGkAtoms::autoplay ||
(aAttrName == nsGkAtoms::autoplay || aAttrName == nsGkAtoms::muted ||
aAttrName == nsGkAtoms::controls)) {
return true;
}

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

@ -1152,21 +1152,6 @@ nsXMLContentSerializer::CheckElementEnd(nsIContent * aContent,
return aContent->GetChildCount() > 0;
}
void
nsXMLContentSerializer::AppendToString(const PRUnichar* aStr,
PRInt32 aLength,
nsAString& aOutputStr)
{
if (mBodyOnly && !mInBody) {
return;
}
PRInt32 length = (aLength == -1) ? nsCRT::strlen(aStr) : aLength;
mColPos += length;
aOutputStr.Append(aStr, length);
}
void
nsXMLContentSerializer::AppendToString(const PRUnichar aChar,
nsAString& aOutputStr)

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

@ -102,13 +102,6 @@ class nsXMLContentSerializer : public nsIContentSerializer {
protected:
/**
* Appends a PRUnichar string and increments the column position
*/
void AppendToString(const PRUnichar* aStr,
PRInt32 aLength,
nsAString& aOutputStr);
/**
* Appends a PRUnichar character and increments the column position
*/

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

@ -101,34 +101,6 @@ DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
aCanvasElement->SetWriteOnly();
}
void
LogMessage (const nsCString& errorString)
{
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (!console)
return;
console->LogStringMessage(NS_ConvertUTF8toUTF16(errorString).get());
fprintf(stderr, "%s\n", errorString.get());
}
void
LogMessagef (const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char buf[256];
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
if (console) {
PR_vsnprintf(buf, 256, fmt, ap);
console->LogStringMessage(NS_ConvertUTF8toUTF16(nsDependentCString(buf)).get());
fprintf(stderr, "%s\n", buf);
}
va_end(ap);
}
bool
CoerceDouble(jsval v, double* d)
{

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

@ -77,9 +77,6 @@ void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
bool forceWriteOnly,
bool CORSUsed);
void LogMessage (const nsCString& errorString);
void LogMessagef (const char *fmt, ...);
// Make a double out of |v|, treating undefined values as 0.0 (for
// the sake of sparse arrays). Return true iff coercion
// succeeded.

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

@ -1162,9 +1162,21 @@ WebGLContext::MaybeRestoreContext()
if (mContextLost || mAllowRestore)
return;
gl->MakeCurrent();
GLContext::ContextResetARB resetStatus =
(GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
if (mHasRobustness) {
gl->MakeCurrent();
resetStatus = (GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
// This call is safe as it does not actually interact with GL, so the
// context does not have to be current.
} else if (gl->GetContextType() == GLContext::ContextTypeEGL) {
// Simulate a ARB_robustness guilty context loss for when we
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
// but we can't make any distinction, so we must assume the worst
// case.
if (!gl->MakeCurrent(true) && gl->IsContextLost()) {
resetStatus = GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB;
}
}
if (resetStatus != GLContext::CONTEXT_NO_ERROR) {
// It's already lost, but clean up after it and signal to JS that it is

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

@ -57,6 +57,7 @@
#include "nsIDOMHTMLElement.h"
#include "nsIJSNativeInitializer.h"
#include "nsIMemoryReporter.h"
#include "nsContentUtils.h"
#include "GLContextProvider.h"
#include "Layers.h"
@ -449,7 +450,7 @@ public:
// Sets up the GL_ARB_robustness timer if it isn't already, so that if the
// driver gets restarted, the context may get reset with it.
void SetupRobustnessTimer() {
if (mContextLost || !mHasRobustness)
if (mContextLost || (!mHasRobustness && gl->GetContextType() != gl::GLContext::ContextTypeEGL))
return;
// If the timer was already running, don't restart it here. Instead,

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

@ -3993,7 +3993,10 @@ nsresult
WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
gfxImageSurface **imageOut, int *format)
{
gfxImageSurface *surf = nsnull;
nsCOMPtr<nsIContent> content = do_QueryInterface(imageOrCanvas);
if (!content) {
return NS_ERROR_FAILURE;
}
PRUint32 flags =
nsLayoutUtils::SFE_WANT_NEW_SURFACE |
@ -4005,7 +4008,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags);
if (!res.mSurface)
return NS_ERROR_FAILURE;
if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) {
@ -4034,11 +4037,10 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
}
}
// part 2: if the DOM element is a canvas, check that it's not write-only. That would indicate a tainted canvas,
// i.e. a canvas that could contain cross-domain image data.
nsCOMPtr<nsIContent> maybeDOMCanvas = do_QueryInterface(imageOrCanvas);
if (maybeDOMCanvas && maybeDOMCanvas->IsHTML(nsGkAtoms::canvas)) {
nsHTMLCanvasElement *canvas = static_cast<nsHTMLCanvasElement*>(maybeDOMCanvas.get());
// part 2: if the DOM element is a canvas, check that it's not write-only.
// That would indicate a tainted canvas, i.e. a canvas that could contain
// cross-domain image data.
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) {
if (canvas->IsWriteOnly()) {
LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
"to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
@ -4052,7 +4054,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
// Notice that there is never a need to mark the WebGL canvas as write-only, since we reject write-only/cross-domain
// texture sources in the first place.
surf = static_cast<gfxImageSurface*>(res.mSurface.get());
gfxImageSurface* surf = static_cast<gfxImageSurface*>(res.mSurface.get());
res.mSurface.forget();
*imageOut = surf;

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

@ -1813,11 +1813,12 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
const nsAString& repeat,
nsIDOMCanvasPattern **_retval)
{
if (!image) {
nsCOMPtr<nsIContent> content = do_QueryInterface(image);
if (!content) {
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
}
gfxPattern::GraphicsExtend extend;
gfxPattern::GraphicsExtend extend;
if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) {
extend = gfxPattern::EXTEND_REPEAT;
} else if (repeat.EqualsLiteral("repeat-x")) {
@ -1833,7 +1834,6 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
return NS_ERROR_DOM_SYNTAX_ERR;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(image);
nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
if (canvas) {
nsIntSize size = canvas->GetSize();
@ -1845,8 +1845,8 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
// The canvas spec says that createPattern should use the first frame
// of animated images
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_FIRST_FRAME |
nsLayoutUtils::SFE_WANT_NEW_SURFACE);
nsLayoutUtils::SurfaceFromElement(content->AsElement(),
nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE);
if (!res.mSurface)
return NS_ERROR_NOT_AVAILABLE;
@ -3399,11 +3399,11 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
if (!EnsureSurface())
return NS_ERROR_FAILURE;
if (!imgElt) {
nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
if (!content) {
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
if (canvas) {
nsIntSize size = canvas->GetSize();
@ -3423,7 +3423,7 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
// of animated images
PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags);
nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags);
if (!res.mSurface) {
// Spec says to silently do nothing if the element is still loading.
return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE;
@ -3433,7 +3433,8 @@ nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
// as a source to work around some Cairo self-copy semantics issues.
if (res.mSurface == mSurface) {
sfeFlags |= nsLayoutUtils::SFE_WANT_NEW_SURFACE;
res = nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags);
res = nsLayoutUtils::SurfaceFromElement(content->AsElement(),
sfeFlags);
if (!res.mSurface)
return NS_ERROR_NOT_AVAILABLE;
}

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

@ -1889,7 +1889,8 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
const nsAString& repeat,
nsIDOMCanvasPattern **_retval)
{
if (!image) {
nsCOMPtr<nsIContent> content = do_QueryInterface(image);
if (!content) {
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
}
@ -1908,9 +1909,7 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
return NS_ERROR_DOM_SYNTAX_ERR;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(image);
nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
if (canvas) {
nsIntSize size = canvas->GetSize();
if (size.width == 0 || size.height == 0) {
@ -1939,8 +1938,8 @@ nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
// The canvas spec says that createPattern should use the first frame
// of animated images
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_FIRST_FRAME |
nsLayoutUtils::SFE_WANT_NEW_SURFACE);
nsLayoutUtils::SurfaceFromElement(content->AsElement(),
nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE);
if (!res.mSurface) {
return NS_ERROR_NOT_AVAILABLE;
@ -3570,7 +3569,8 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
float a6, float a7, float a8,
PRUint8 optional_argc)
{
if (!imgElt) {
nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
if (!content) {
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
}
@ -3591,7 +3591,6 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
double sx,sy,sw,sh;
double dx,dy,dw,dh;
nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
if (canvas) {
nsIntSize size = canvas->GetSize();
@ -3643,7 +3642,7 @@ nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
// of animated images
PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(imgElt, sfeFlags);
nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags);
if (!res.mSurface) {
// Spec says to silently do nothing if the element is still loading.

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

@ -48,6 +48,14 @@ public:
nsHTMLVideoElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsHTMLVideoElement();
static nsHTMLVideoElement* FromContent(nsIContent* aPossibleVideo)
{
if (!aPossibleVideo || !aPossibleVideo->IsHTML(nsGkAtoms::video)) {
return NULL;
}
return static_cast<nsHTMLVideoElement*>(aPossibleVideo);
}
// nsISupports
NS_DECL_ISUPPORTS_INHERITED

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

@ -1516,6 +1516,9 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
Load();
}
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::muted) {
mMuted = true;
}
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::autoplay) {
StopSuspendingAfterFirstFrame();
@ -2687,18 +2690,17 @@ nsHTMLMediaElement::CopyInnerTo(nsGenericElement* aDest) const
dest->mMediaSize = mMediaSize;
} else {
nsIFrame* frame = GetPrimaryFrame();
nsCOMPtr<nsIDOMElement> elem;
Element* element;
if (frame && frame->GetType() == nsGkAtoms::HTMLVideoFrame &&
static_cast<nsVideoFrame*>(frame)->ShouldDisplayPoster()) {
elem = do_QueryInterface(static_cast<nsVideoFrame*>(frame)->
GetPosterImage());
nsIContent* content = static_cast<nsVideoFrame*>(frame)->GetPosterImage();
element = content ? content->AsElement() : NULL;
} else {
elem = do_QueryInterface(
static_cast<nsGenericElement*>(const_cast<nsHTMLMediaElement*>(this)));
element = const_cast<nsHTMLMediaElement*>(this);
}
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(elem,
nsLayoutUtils::SurfaceFromElement(element,
nsLayoutUtils::SFE_WANT_NEW_SURFACE);
dest->mPrintSurface = res.mSurface;
dest->mMediaSize = nsIntSize(res.mSize.width, res.mSize.height);

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

@ -1745,7 +1745,8 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
if (oldScope && newScope != oldScope) {
nsContentUtils::ReparentContentWrappersInScope(cx, oldScope, newScope);
rv = nsContentUtils::ReparentContentWrappersInScope(cx, oldScope, newScope);
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -1954,6 +1955,8 @@ nsHTMLDocument::WriteCommon(JSContext *cx,
if (NS_FAILED(rv) || !mParser) {
return rv;
}
NS_ABORT_IF_FALSE(!JS_IsExceptionPending(cx),
"Open() succeeded but JS exception is pending");
}
static NS_NAMED_LITERAL_STRING(new_line, "\n");

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

@ -2364,23 +2364,6 @@ nsXULDocument::ContextStack::SetTopIndex(PRInt32 aIndex)
}
bool
nsXULDocument::ContextStack::IsInsideXULTemplate()
{
if (mDepth) {
for (nsIContent* element = mTop->mElement; element;
element = element->GetParent()) {
if (element->NodeInfo()->Equals(nsGkAtoms::_template,
kNameSpaceID_XUL)) {
return true;
}
}
}
return false;
}
//----------------------------------------------------------------------
//
// Content model walking routines

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

@ -357,8 +357,6 @@ protected:
nsresult Peek(nsXULPrototypeElement** aPrototype, nsIContent** aElement, PRInt32* aIndex);
nsresult SetTopIndex(PRInt32 aIndex);
bool IsInsideXULTemplate();
};
friend class ContextStack;

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

@ -454,13 +454,6 @@ TestNode::Constrain(InstantiationSet& aInstantiations)
}
bool
TestNode::HasAncestor(const ReteNode* aNode) const
{
return aNode == this || (mParent && mParent->HasAncestor(aNode));
}
//----------------------------------------------------------------------
ReteNodeSet::ReteNodeSet()

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

@ -878,14 +878,6 @@ public:
bool* aCantHandleYet) const = 0;
//XXX probably better named "ApplyConstraints" or "Discrminiate" or something
/**
* Determine if this node has another node as its direct ancestor.
* @param aNode the node to look for.
* @return true if aNode is a direct ancestor of this node, false
* otherwise.
*/
bool HasAncestor(const ReteNode* aNode) const;
/**
* Add another node as a child of this node.
* @param aNode the node to add.

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

@ -869,10 +869,18 @@ nsDOMWindowUtils::NodesFromRect(float aX, float aY,
}
static already_AddRefed<gfxImageSurface>
CanvasToImageSurface(nsIDOMHTMLCanvasElement *canvas)
CanvasToImageSurface(nsIDOMHTMLCanvasElement* aCanvas)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
if (!node) {
return nsnull;
}
NS_ABORT_IF_FALSE(node->IsElement(),
"An nsINode that implements nsIDOMHTMLCanvasElement should "
"be an element.");
nsLayoutUtils::SurfaceFromElementResult result =
nsLayoutUtils::SurfaceFromElement(canvas,
nsLayoutUtils::SurfaceFromElement(node->AsElement(),
nsLayoutUtils::SFE_WANT_IMAGE_SURFACE);
return static_cast<gfxImageSurface*>(result.mSurface.forget().get());
}
@ -1442,44 +1450,20 @@ nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
}
NS_IMETHODIMP
nsDOMWindowUtils::GetClassName(char **aName)
nsDOMWindowUtils::GetClassName(const JS::Value& aObject, JSContext* aCx, char** aName)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// get the xpconnect native call context
nsAXPCNativeCallContext *cc = nsnull;
nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&cc);
if(!cc)
return NS_ERROR_FAILURE;
// Get JSContext of current call
JSContext* cx;
nsresult rv = cc->GetJSContext(&cx);
if(NS_FAILED(rv) || !cx)
return NS_ERROR_FAILURE;
// get argc and argv and verify arg count
PRUint32 argc;
rv = cc->GetArgc(&argc);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
if(argc < 1)
return NS_ERROR_XPC_NOT_ENOUGH_ARGS;
jsval* argv;
rv = cc->GetArgvPtr(&argv);
if(NS_FAILED(rv) || !argv)
return NS_ERROR_FAILURE;
// Our argument must be a non-null object.
if(JSVAL_IS_PRIMITIVE(argv[0]))
if (JSVAL_IS_PRIMITIVE(aObject)) {
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
*aName = NS_strdup(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0]))->name);
return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
*aName = NS_strdup(JS_GET_CLASS(aCx, JSVAL_TO_OBJECT(aObject))->name);
NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
return NS_OK;
}
NS_IMETHODIMP

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

@ -279,7 +279,7 @@ AsyncConnectionHelper::Run()
if (NS_SUCCEEDED(rv)) {
bool hasSavepoint = false;
if (mDatabase) {
IndexedDatabaseManager::SetCurrentDatabase(mDatabase);
IndexedDatabaseManager::SetCurrentWindow(mDatabase->Owner());
// Make the first savepoint.
if (mTransaction) {
@ -292,7 +292,7 @@ AsyncConnectionHelper::Run()
mResultCode = DoDatabaseWork(connection);
if (mDatabase) {
IndexedDatabaseManager::SetCurrentDatabase(nsnull);
IndexedDatabaseManager::SetCurrentWindow(nsnull);
// Release or roll back the savepoint depending on the error code.
if (hasSavepoint) {

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

@ -98,11 +98,9 @@ GetQuotaPermissions(const nsACString& aASCIIOrigin,
} // anonymous namespace
CheckQuotaHelper::CheckQuotaHelper(IDBDatabase* aDatabase,
CheckQuotaHelper::CheckQuotaHelper(nsPIDOMWindow* aWindow,
mozilla::Mutex& aMutex)
: mWindow(aDatabase->Owner()),
mWindowSerial(mWindow->GetSerial()),
mOrigin(aDatabase->Origin()),
: mWindow(aWindow),
mMutex(aMutex),
mCondVar(mMutex, "CheckQuotaHelper::mCondVar"),
mPromptResult(0),
@ -175,51 +173,59 @@ CheckQuotaHelper::Run()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mHasPrompted) {
mPromptResult = GetQuotaPermissions(mOrigin, mWindow);
nsresult rv = NS_OK;
if (mASCIIOrigin.IsEmpty()) {
rv = IndexedDatabaseManager::GetASCIIOriginFromWindow(mWindow,
mASCIIOrigin);
}
nsresult rv;
if (mHasPrompted) {
// Add permissions to the database, but only if we are in the parent
// process (if we are in the child process, we have already
// set the permission when the prompt was shown in the parent, as
// we cannot set the permission from the child).
if (mPromptResult != nsIPermissionManager::UNKNOWN_ACTION &&
XRE_GetProcessType() == GeckoProcessType_Default) {
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), mOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_STATE(permissionManager);
rv = permissionManager->Add(uri, PERMISSION_INDEXEDDB_UNLIMITED,
mPromptResult,
nsIPermissionManager::EXPIRE_NEVER, 0);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_SUCCEEDED(rv)) {
if (!mHasPrompted) {
mPromptResult = GetQuotaPermissions(mASCIIOrigin, mWindow);
}
}
else if (mPromptResult == nsIPermissionManager::UNKNOWN_ACTION) {
PRUint32 quota = IndexedDatabaseManager::GetIndexedDBQuotaMB();
nsString quotaString;
quotaString.AppendInt(quota);
if (mHasPrompted) {
// Add permissions to the database, but only if we are in the parent
// process (if we are in the child process, we have already
// set the permission when the prompt was shown in the parent, as
// we cannot set the permission from the child).
if (mPromptResult != nsIPermissionManager::UNKNOWN_ACTION &&
XRE_GetProcessType() == GeckoProcessType_Default) {
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), mASCIIOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_STATE(permissionManager);
rv = permissionManager->Add(uri, PERMISSION_INDEXEDDB_UNLIMITED,
mPromptResult,
nsIPermissionManager::EXPIRE_NEVER, 0);
NS_ENSURE_SUCCESS(rv, rv);
}
}
else if (mPromptResult == nsIPermissionManager::UNKNOWN_ACTION) {
PRUint32 quota = IndexedDatabaseManager::GetIndexedDBQuotaMB();
nsCOMPtr<nsIObserverService> obs = GetObserverService();
NS_ENSURE_STATE(obs);
nsString quotaString;
quotaString.AppendInt(quota);
// We have to watch to make sure that the window doesn't go away without
// responding to us. Otherwise our database threads will hang.
rv = obs->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, false);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIObserverService> obs = GetObserverService();
NS_ENSURE_STATE(obs);
rv = obs->NotifyObservers(static_cast<nsIRunnable*>(this),
TOPIC_QUOTA_PROMPT, quotaString.get());
NS_ENSURE_SUCCESS(rv, rv);
// We have to watch to make sure that the window doesn't go away without
// responding to us. Otherwise our database threads will hang.
rv = obs->AddObserver(this, DOM_WINDOW_DESTROYED_TOPIC, false);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
rv = obs->NotifyObservers(static_cast<nsIRunnable*>(this),
TOPIC_QUOTA_PROMPT, quotaString.get());
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
}
MutexAutoLock lock(mMutex);

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

@ -65,23 +65,17 @@ public:
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIOBSERVER
CheckQuotaHelper(IDBDatabase* aDatabase,
CheckQuotaHelper(nsPIDOMWindow* aWindow,
mozilla::Mutex& aMutex);
bool PromptAndReturnQuotaIsDisabled();
void Cancel();
PRUint32 WindowSerial()
{
return mWindowSerial;
}
private:
nsPIDOMWindow* mWindow;
PRUint32 mWindowSerial;
nsCString mOrigin;
nsCString mASCIIOrigin;
mozilla::Mutex& mMutex;
mozilla::CondVar mCondVar;
PRUint32 mPromptResult;

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

@ -64,12 +64,6 @@ USING_INDEXEDDB_NAMESPACE
namespace {
PRUint32 gDatabaseInstanceCount = 0;
mozilla::Mutex* gPromptHelpersMutex = nsnull;
// Protected by gPromptHelpersMutex.
nsTArray<nsRefPtr<CheckQuotaHelper> >* gPromptHelpers = nsnull;
class CreateObjectStoreHelper : public AsyncConnectionHelper
{
public:
@ -195,11 +189,6 @@ IDBDatabase::IDBDatabase()
mRunningVersionChange(false)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!gDatabaseInstanceCount++) {
NS_ASSERTION(!gPromptHelpersMutex, "Should be null!");
gPromptHelpersMutex = new mozilla::Mutex("IDBDatabase gPromptHelpersMutex");
}
}
IDBDatabase::~IDBDatabase()
@ -218,86 +207,20 @@ IDBDatabase::~IDBDatabase()
if (mListenerManager) {
mListenerManager->Disconnect();
}
if (!--gDatabaseInstanceCount) {
NS_ASSERTION(gPromptHelpersMutex, "Should not be null!");
delete gPromptHelpers;
gPromptHelpers = nsnull;
delete gPromptHelpersMutex;
gPromptHelpersMutex = nsnull;
}
}
bool
IDBDatabase::IsQuotaDisabled()
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(gPromptHelpersMutex, "This should never be null!");
MutexAutoLock lock(*gPromptHelpersMutex);
if (!gPromptHelpers) {
gPromptHelpers = new nsAutoTArray<nsRefPtr<CheckQuotaHelper>, 10>();
}
CheckQuotaHelper* foundHelper = nsnull;
PRUint32 count = gPromptHelpers->Length();
for (PRUint32 index = 0; index < count; index++) {
nsRefPtr<CheckQuotaHelper>& helper = gPromptHelpers->ElementAt(index);
if (helper->WindowSerial() == Owner()->GetSerial()) {
foundHelper = helper;
break;
}
}
if (!foundHelper) {
nsRefPtr<CheckQuotaHelper>* newHelper = gPromptHelpers->AppendElement();
if (!newHelper) {
NS_WARNING("Out of memory!");
return false;
}
*newHelper = new CheckQuotaHelper(this, *gPromptHelpersMutex);
foundHelper = *newHelper;
{
// Unlock before calling out to XPCOM.
MutexAutoUnlock unlock(*gPromptHelpersMutex);
nsresult rv = NS_DispatchToMainThread(foundHelper, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, false);
}
}
return foundHelper->PromptAndReturnQuotaIsDisabled();
}
void
IDBDatabase::Invalidate()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(gPromptHelpersMutex, "This should never be null!");
// Make sure we're closed too.
Close();
// Cancel any quota prompts that are currently being displayed.
{
MutexAutoLock lock(*gPromptHelpersMutex);
if (gPromptHelpers) {
PRUint32 count = gPromptHelpers->Length();
for (PRUint32 index = 0; index < count; index++) {
nsRefPtr<CheckQuotaHelper>& helper = gPromptHelpers->ElementAt(index);
if (helper->WindowSerial() == Owner()->GetSerial()) {
helper->Cancel();
break;
}
}
}
}
// When the IndexedDatabaseManager needs to invalidate databases, all it has
// is an origin, so we call back into the manager to cancel any prompts for
// our owner.
IndexedDatabaseManager::CancelPromptsForWindow(Owner());
mInvalidated = true;
}

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

@ -122,8 +122,6 @@ public:
return doc.forget();
}
bool IsQuotaDisabled();
nsCString& Origin()
{
return mASCIIOrigin;

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

@ -403,24 +403,10 @@ IDBFactory::OpenCommon(const nsAString& aName,
nsIScriptContext* context = sgo->GetContext();
NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = nsContentUtils::GetSecurityManager()->
GetSubjectPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCString origin;
if (nsContentUtils::IsSystemPrincipal(principal)) {
origin.AssignLiteral("chrome");
}
else {
rv = nsContentUtils::GetASCIIOrigin(principal, origin);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (origin.EqualsLiteral("null")) {
NS_WARNING("IndexedDB databases not allowed for this principal!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
nsresult rv =
IndexedDatabaseManager::GetASCIIOriginFromWindow(window, origin);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<IDBOpenDBRequest> request =
IDBOpenDBRequest::Create(context, window);

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

@ -887,7 +887,7 @@ CommitHelper::Run()
}
if (mConnection) {
IndexedDatabaseManager::SetCurrentDatabase(database);
IndexedDatabaseManager::SetCurrentWindow(database->Owner());
if (!mAborted) {
NS_NAMED_LITERAL_CSTRING(release, "COMMIT TRANSACTION");
@ -923,7 +923,7 @@ CommitHelper::Run()
mConnection->Close();
mConnection = nsnull;
IndexedDatabaseManager::SetCurrentDatabase(nsnull);
IndexedDatabaseManager::SetCurrentWindow(nsnull);
}
return NS_OK;

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

@ -41,6 +41,8 @@
#include "nsIFile.h"
#include "nsIObserverService.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIScriptSecurityManager.h"
#include "nsISHEntry.h"
#include "nsISimpleEnumerator.h"
#include "nsITimer.h"
@ -54,6 +56,7 @@
#include "nsXPCOMPrivate.h"
#include "AsyncConnectionHelper.h"
#include "CheckQuotaHelper.h"
#include "IDBDatabase.h"
#include "IDBEvents.h"
#include "IDBFactory.h"
@ -75,7 +78,7 @@
#define PREF_INDEXEDDB_QUOTA "dom.indexedDB.warningQuota"
// A bad TLS index number.
#define BAD_TLS_INDEX (PRUintn)-1
#define BAD_TLS_INDEX (PRUintn)-1
USING_INDEXEDDB_NAMESPACE
using namespace mozilla::services;
@ -88,8 +91,6 @@ PRInt32 gShutdown = 0;
// Does not hold a reference.
IndexedDatabaseManager* gInstance = nsnull;
PRUintn gCurrentDatabaseIndex = BAD_TLS_INDEX;
PRInt32 gIndexedDBQuotaMB = DEFAULT_QUOTA_MB;
class QuotaCallback : public mozIStorageQuotaCallback
@ -104,13 +105,7 @@ public:
nsISupports* aUserData,
PRInt64* _retval)
{
NS_ASSERTION(gCurrentDatabaseIndex != BAD_TLS_INDEX,
"This should be impossible!");
IDBDatabase* database =
static_cast<IDBDatabase*>(PR_GetThreadPrivate(gCurrentDatabaseIndex));
if (database && database->IsQuotaDisabled()) {
if (IndexedDatabaseManager::QuotaIsLifted()) {
*_retval = 0;
return NS_OK;
}
@ -146,6 +141,8 @@ EnumerateToTArray(const nsACString& aKey,
} // anonymous namespace
IndexedDatabaseManager::IndexedDatabaseManager()
: mCurrentWindowIndex(BAD_TLS_INDEX),
mQuotaHelperMutex("IndexedDatabaseManager.mQuotaHelperMutex")
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!gInstance, "More than one instance!");
@ -172,30 +169,31 @@ IndexedDatabaseManager::GetOrCreate()
nsRefPtr<IndexedDatabaseManager> instance(gInstance);
if (!instance) {
// We need a thread-local to hold our current database.
if (gCurrentDatabaseIndex == BAD_TLS_INDEX) {
if (PR_NewThreadPrivateIndex(&gCurrentDatabaseIndex, nsnull) !=
PR_SUCCESS) {
NS_ERROR("PR_NewThreadPrivateIndex failed!");
gCurrentDatabaseIndex = BAD_TLS_INDEX;
return nsnull;
}
if (NS_FAILED(Preferences::AddIntVarCache(&gIndexedDBQuotaMB,
PREF_INDEXEDDB_QUOTA,
DEFAULT_QUOTA_MB))) {
NS_WARNING("Unable to respond to quota pref changes!");
gIndexedDBQuotaMB = DEFAULT_QUOTA_MB;
}
if (NS_FAILED(Preferences::AddIntVarCache(&gIndexedDBQuotaMB,
PREF_INDEXEDDB_QUOTA,
DEFAULT_QUOTA_MB))) {
NS_WARNING("Unable to respond to quota pref changes!");
gIndexedDBQuotaMB = DEFAULT_QUOTA_MB;
}
instance = new IndexedDatabaseManager();
if (!instance->mLiveDatabases.Init()) {
if (!instance->mLiveDatabases.Init() ||
!instance->mQuotaHelperHash.Init()) {
NS_WARNING("Out of memory!");
return nsnull;
}
// We need a thread-local to hold the current window.
NS_ASSERTION(instance->mCurrentWindowIndex == BAD_TLS_INDEX, "Huh?");
if (PR_NewThreadPrivateIndex(&instance->mCurrentWindowIndex, nsnull) !=
PR_SUCCESS) {
NS_ERROR("PR_NewThreadPrivateIndex failed, IndexedDB disabled");
instance->mCurrentWindowIndex = BAD_TLS_INDEX;
return nsnull;
}
// Make a timer here to avoid potential failures later. We don't actually
// initialize the timer until shutdown.
instance->mShutdownTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
@ -548,30 +546,23 @@ IndexedDatabaseManager::OnDatabaseClosed(IDBDatabase* aDatabase)
}
}
// static
bool
IndexedDatabaseManager::SetCurrentDatabase(IDBDatabase* aDatabase)
void
IndexedDatabaseManager::SetCurrentWindowInternal(nsPIDOMWindow* aWindow)
{
NS_ASSERTION(gCurrentDatabaseIndex != BAD_TLS_INDEX,
"This should have been set already!");
if (aWindow) {
#ifdef DEBUG
if (aDatabase) {
NS_ASSERTION(!PR_GetThreadPrivate(gCurrentDatabaseIndex),
"Someone forgot to unset gCurrentDatabaseIndex!");
NS_ASSERTION(!PR_GetThreadPrivate(mCurrentWindowIndex),
"Somebody forgot to clear the current window!");
#endif
PR_SetThreadPrivate(mCurrentWindowIndex, aWindow);
}
else {
NS_ASSERTION(PR_GetThreadPrivate(gCurrentDatabaseIndex),
"Someone forgot to set gCurrentDatabaseIndex!");
}
#ifdef DEBUG
NS_ASSERTION(PR_GetThreadPrivate(mCurrentWindowIndex),
"Somebody forgot to clear the current window!");
#endif
if (PR_SetThreadPrivate(gCurrentDatabaseIndex, aDatabase) != PR_SUCCESS) {
NS_WARNING("Failed to set gCurrentDatabaseIndex!");
return false;
PR_SetThreadPrivate(mCurrentWindowIndex, nsnull);
}
return true;
}
// static
@ -662,6 +653,102 @@ IndexedDatabaseManager::EnsureQuotaManagementForDirectory(nsIFile* aDirectory)
return rv;
}
bool
IndexedDatabaseManager::QuotaIsLiftedInternal()
{
nsPIDOMWindow* window = nsnull;
nsRefPtr<CheckQuotaHelper> helper = nsnull;
bool createdHelper = false;
window =
static_cast<nsPIDOMWindow*>(PR_GetThreadPrivate(mCurrentWindowIndex));
// Once IDB is supported outside of Windows this should become an early
// return true.
NS_ASSERTION(window, "Why don't we have a Window here?");
// Hold the lock from here on.
MutexAutoLock autoLock(mQuotaHelperMutex);
mQuotaHelperHash.Get(window, getter_AddRefs(helper));
if (!helper) {
helper = new CheckQuotaHelper(window, mQuotaHelperMutex);
createdHelper = true;
bool result = mQuotaHelperHash.Put(window, helper);
NS_ENSURE_TRUE(result, result);
// Unlock while calling out to XPCOM
{
MutexAutoUnlock autoUnlock(mQuotaHelperMutex);
nsresult rv = NS_DispatchToMainThread(helper);
NS_ENSURE_SUCCESS(rv, false);
}
// Relocked. If any other threads hit the quota limit on the same Window,
// they are using the helper we created here and are now blocking in
// PromptAndReturnQuotaDisabled.
}
bool result = helper->PromptAndReturnQuotaIsDisabled();
// If this thread created the helper and added it to the hash, this thread
// must remove it.
if (createdHelper) {
mQuotaHelperHash.Remove(window);
}
return result;
}
void
IndexedDatabaseManager::CancelPromptsForWindowInternal(nsPIDOMWindow* aWindow)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsRefPtr<CheckQuotaHelper> helper;
MutexAutoLock autoLock(mQuotaHelperMutex);
mQuotaHelperHash.Get(aWindow, getter_AddRefs(helper));
if (helper) {
helper->Cancel();
}
}
// static
nsresult
IndexedDatabaseManager::GetASCIIOriginFromWindow(nsPIDOMWindow* aWindow,
nsCString& aASCIIOrigin)
{
NS_ASSERTION(NS_IsMainThread(),
"We're about to touch a window off the main thread!");
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow);
NS_ENSURE_TRUE(sop, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
NS_ENSURE_TRUE(principal, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (nsContentUtils::IsSystemPrincipal(principal)) {
aASCIIOrigin.AssignLiteral("chrome");
}
else {
nsresult rv = nsContentUtils::GetASCIIOrigin(principal, aASCIIOrigin);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (aASCIIOrigin.EqualsLiteral("null")) {
NS_WARNING("IndexedDB databases not allowed for this principal!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
return NS_OK;
}
// static
nsresult
IndexedDatabaseManager::DispatchHelper(AsyncConnectionHelper* aHelper)

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

@ -44,6 +44,8 @@
#include "mozilla/dom/indexedDB/IDBDatabase.h"
#include "mozilla/dom/indexedDB/IDBRequest.h"
#include "mozilla/Mutex.h"
#include "nsIIndexedDatabaseManager.h"
#include "nsIObserver.h"
#include "nsIRunnable.h"
@ -51,6 +53,7 @@
#include "nsIURI.h"
#include "nsClassHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsHashKeys.h"
#define INDEXEDDB_MANAGER_CONTRACTID "@mozilla.org/dom/indexeddb/manager;1"
@ -62,6 +65,8 @@ BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
class CheckQuotaHelper;
class IndexedDatabaseManager : public nsIIndexedDatabaseManager,
public nsIObserver
{
@ -129,14 +134,45 @@ public:
// Used to check if there are running transactions in a given window.
bool HasOpenTransactions(nsPIDOMWindow* aWindow);
static bool
SetCurrentDatabase(IDBDatabase* aDatabase);
// Set the Window that the current thread is doing operations for.
// The caller is responsible for ensuring that aWindow is held alive.
static inline void
SetCurrentWindow(nsPIDOMWindow* aWindow)
{
IndexedDatabaseManager* mgr = Get();
NS_ASSERTION(mgr, "Must have a manager here!");
return mgr->SetCurrentWindowInternal(aWindow);
}
static PRUint32
GetIndexedDBQuotaMB();
nsresult EnsureQuotaManagementForDirectory(nsIFile* aDirectory);
// Determine if the quota is lifted for the Window the current thread is
// using.
static inline bool
QuotaIsLifted()
{
IndexedDatabaseManager* mgr = Get();
NS_ASSERTION(mgr, "Must have a manager here!");
return mgr->QuotaIsLiftedInternal();
}
static inline void
CancelPromptsForWindow(nsPIDOMWindow* aWindow)
{
IndexedDatabaseManager* mgr = Get();
NS_ASSERTION(mgr, "Must have a manager here!");
mgr->CancelPromptsForWindowInternal(aWindow);
}
static nsresult
GetASCIIOriginFromWindow(nsPIDOMWindow* aWindow, nsCString& aASCIIOrigin);
private:
IndexedDatabaseManager();
~IndexedDatabaseManager();
@ -147,6 +183,10 @@ private:
WaitingOnDatabasesCallback aCallback,
void* aClosure);
void SetCurrentWindowInternal(nsPIDOMWindow* aWindow);
bool QuotaIsLiftedInternal();
void CancelPromptsForWindowInternal(nsPIDOMWindow* aWindow);
// Called when a database is created.
bool RegisterDatabase(IDBDatabase* aDatabase);
@ -267,6 +307,15 @@ private:
// Maintains a list of live databases per origin.
nsClassHashtable<nsCStringHashKey, nsTArray<IDBDatabase*> > mLiveDatabases;
// TLS storage index for the current thread's window
PRUintn mCurrentWindowIndex;
// Lock protecting mQuotaHelperHash
mozilla::Mutex mQuotaHelperMutex;
// A map of Windows to the corresponding quota helper.
nsRefPtrHashtable<nsPtrHashKey<nsPIDOMWindow>, CheckQuotaHelper> mQuotaHelperHash;
// Maintains a list of origins that we're currently enumerating to gather
// usage statistics.
nsAutoTArray<nsRefPtr<AsyncUsageRunnable>, 1> mUsageRunnables;
@ -290,6 +339,21 @@ private:
nsTArray<nsCString> mTrackedQuotaPaths;
};
class AutoEnterWindow
{
public:
AutoEnterWindow(nsPIDOMWindow* aWindow)
{
NS_ASSERTION(aWindow, "This should never be null!");
IndexedDatabaseManager::SetCurrentWindow(aWindow);
}
~AutoEnterWindow()
{
IndexedDatabaseManager::SetCurrentWindow(nsnull);
}
};
END_INDEXEDDB_NAMESPACE
#endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */

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

@ -1090,6 +1090,14 @@ OpenDatabaseHelper::DoDatabaseWork()
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
NS_ASSERTION(mOpenDBRequest, "This should never be null!");
// Once we support IDB outside of Windows this assertion will no longer hold.
nsPIDOMWindow* window = mOpenDBRequest->Owner();
NS_ASSERTION(window, "This should never be null");
AutoEnterWindow autoWindow(window);
nsCOMPtr<nsIFile> dbFile;
nsresult rv = GetDatabaseFile(mASCIIOrigin, mName, getter_AddRefs(dbFile));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

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

@ -129,6 +129,8 @@ BROWSER_TEST_FILES = \
browser_quotaPrompt.html \
browser_quotaPromptAllow.js \
browser_quotaPromptDeny.js \
browser_quotaPromptDatabases.html \
browser_quotaPromptDatabases.js \
head.js \
$(NULL)

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

@ -4,7 +4,7 @@
*/
// Make sure this is a unique origin or the tests will randomly fail!
const testPageURL = "http://test1.example.org/browser/" +
const testPageURL = "http://bug704464-1.example.com/browser/" +
"dom/indexedDB/test/browser_quotaPrompt.html";
const notificationID = "indexedDB-quota-prompt";

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

@ -0,0 +1,55 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Test</title>
<script type="text/javascript;version=1.7">
const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
let db;
let i = 0;
function onAddMore() {
const name = window.location.pathname + i++;
let request = mozIndexedDB.open(name, 1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
request.onsuccess = function(event) {
setTimeout(testFinishedCallback, 0, "complete");
}
request.onerror = function(event) {
setTimeout(testFinishedCallback, 0, "abort");
}
}
function onDone() {
window.removeEventListener("indexedDB-addMore", onAddMore, true);
window.removeEventListener("indexedDB-done", onDone, true);
testResult = "finished";
testException = undefined;
finishTest();
}
function testSteps()
{
window.addEventListener("indexedDB-addMore", onAddMore, true);
window.addEventListener("indexedDB-done", onDone, true);
setTimeout(testFinishedCallback, 0, "ready");
yield;
}
</script>
<script type="text/javascript;version=1.7" src="browserHelpers.js"></script>
</head>
<body onload="runTest();" onunload="finishTestNow();"></body>
</html>

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

@ -0,0 +1,76 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Make sure this is a unique origin or the tests will randomly fail!
const testPageURL = "http://bug704464-3.example.com/browser/" +
"dom/indexedDB/test/browser_quotaPromptDatabases.html";
const notificationID = "indexedDB-quota-prompt";
function test()
{
waitForExplicitFinish();
requestLongerTimeout(10);
setPermission(testPageURL, "indexedDB");
removePermission(testPageURL, "indexedDB-unlimited");
Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
executeSoon(test1);
}
let addMoreTest1Count = 0;
function test1()
{
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function () {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
let seenPopupCount;
setFinishedCallback(function(result) {
is(result, "ready", "Got 'ready' result");
setFinishedCallback(function(result) {
is(result, "complete", "Got 'complete' result");
if (addMoreTest1Count >= seenPopupCount + 5) {
setFinishedCallback(function(result) {
is(result, "finished", "Got 'finished' result");
is(getPermission(testPageURL, "indexedDB-unlimited"),
Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
"Correct permission set");
gBrowser.removeCurrentTab();
unregisterAllPopupEventHandlers();
addMoreTest1Count = seenPopupCount;
executeSoon(finish);
});
executeSoon(function() { dispatchEvent("indexedDB-done"); });
}
else {
++addMoreTest1Count;
executeSoon(function() { dispatchEvent("indexedDB-addMore"); });
}
});
++addMoreTest1Count;
executeSoon(function() { dispatchEvent("indexedDB-addMore"); });
});
registerPopupEventHandler("popupshowing", function () {
ok(true, "prompt showing");
seenPopupCount = addMoreTest1Count - 1;
});
registerPopupEventHandler("popupshown", function () {
ok(true, "prompt shown");
triggerMainCommand(this);
});
registerPopupEventHandler("popuphidden", function () {
ok(true, "prompt hidden");
});
}, true);
info("loading test page: " + testPageURL);
content.location = testPageURL;
}

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

@ -4,7 +4,7 @@
*/
// Make sure this is a unique origin or the tests will randomly fail!
const testPageURL = "http://test2.example.org/browser/" +
const testPageURL = "http://bug704464-2.example.com/browser/" +
"dom/indexedDB/test/browser_quotaPrompt.html";
const notificationID = "indexedDB-quota-prompt";

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

@ -68,7 +68,7 @@ interface nsIDOMWindow;
interface nsIDOMFile;
interface nsIFile;
[scriptable, uuid(c5cf91b3-0b89-4417-b13c-5540ba6ebde8)]
[scriptable, uuid(bf868921-0288-4799-a806-2fa642590197)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -557,7 +557,7 @@ interface nsIDOMWindowUtils : nsISupports {
* Returns the real classname (possibly of the mostly-transparent security
* wrapper) of aObj.
*/
string getClassName(/*in JSObjectPtr aObj*/);
[implicit_jscontext] string getClassName(in jsval aObject);
/**
* Generate a content command event.

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

@ -40,6 +40,7 @@
// FIXME(bug 332648): Give me a real API please!
#include "jscntxt.h"
#include "jsfriendapi.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsJSNPRuntime.h"
@ -1483,7 +1484,7 @@ CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
// the function object.
if (npobj->_class->invoke) {
JSFunction *fun = (JSFunction *)::JS_GetPrivate(cx, funobj);
JSFunction *fun = ::JS_GetObjectFunction(funobj);
JSString *name = ::JS_InternJSString(cx, ::JS_GetFunctionId(fun));
NPIdentifier id = StringToNPIdentifier(cx, name);

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

@ -91,8 +91,8 @@ public:
InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
bool aMainRuntime)
{
JSObject* proto = JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct,
0, sProperties, sFunctions, NULL, NULL);
JSObject* proto = js::InitClassWithReserved(aCx, aObj, aParentProto, &sClass, Construct,
0, sProperties, sFunctions, NULL, NULL);
if (!proto) {
return NULL;
}
@ -102,11 +102,10 @@ public:
parent->AssertIsOnWorkerThread();
JSObject* constructor = JS_GetConstructor(aCx, proto);
if (!constructor ||
!JS_SetReservedSlot(aCx, constructor, CONSTRUCTOR_SLOT_PARENT,
PRIVATE_TO_JSVAL(parent))) {
if (!constructor)
return NULL;
}
js::SetFunctionNativeReserved(constructor, CONSTRUCTOR_SLOT_PARENT,
PRIVATE_TO_JSVAL(parent));
}
return proto;
@ -153,11 +152,8 @@ protected:
return false;
}
jsval priv;
if (!JS_GetReservedSlot(aCx, JSVAL_TO_OBJECT(JS_CALLEE(aCx, aVp)),
CONSTRUCTOR_SLOT_PARENT, &priv)) {
return false;
}
jsval priv = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(JS_CALLEE(aCx, aVp)),
CONSTRUCTOR_SLOT_PARENT);
RuntimeService* runtimeService;
WorkerPrivate* parent;
@ -345,8 +341,8 @@ public:
InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
bool aMainRuntime)
{
JSObject* proto = JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct,
0, NULL, NULL, NULL, NULL);
JSObject* proto = js::InitClassWithReserved(aCx, aObj, aParentProto, &sClass, Construct,
0, NULL, NULL, NULL, NULL);
if (!proto) {
return NULL;
}
@ -356,11 +352,10 @@ public:
parent->AssertIsOnWorkerThread();
JSObject* constructor = JS_GetConstructor(aCx, proto);
if (!constructor ||
!JS_SetReservedSlot(aCx, constructor, CONSTRUCTOR_SLOT_PARENT,
PRIVATE_TO_JSVAL(parent))) {
if (!constructor)
return NULL;
}
js::SetFunctionNativeReserved(constructor, CONSTRUCTOR_SLOT_PARENT,
PRIVATE_TO_JSVAL(parent));
}
return proto;

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

@ -271,11 +271,8 @@ private:
JSObject* wrapper = JSVAL_TO_OBJECT(JS_CALLEE(aCx, aVp));
JS_ASSERT(JS_ObjectIsFunction(aCx, wrapper));
jsval scope, listener;
if (!JS_GetReservedSlot(aCx, wrapper, SLOT_wrappedScope, &scope) ||
!JS_GetReservedSlot(aCx, wrapper, SLOT_wrappedFunction, &listener)) {
return false;
}
jsval scope = js::GetFunctionNativeReserved(wrapper, SLOT_wrappedScope);
jsval listener = js::GetFunctionNativeReserved(wrapper, SLOT_wrappedFunction);
JS_ASSERT(JSVAL_IS_OBJECT(scope));
@ -319,11 +316,8 @@ private:
JS_ASSERT(JSVAL_IS_OBJECT(adaptor));
jsval listener;
if (!JS_GetReservedSlot(aCx, JSVAL_TO_OBJECT(adaptor), SLOT_wrappedFunction,
&listener)) {
return false;
}
jsval listener = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(adaptor),
SLOT_wrappedFunction);
*aVp = listener;
return true;
@ -339,8 +333,8 @@ private:
return false;
}
JSFunction* adaptor = JS_NewFunction(aCx, UnwrapErrorEvent, 1, 0,
JS_GetGlobalObject(aCx), "unwrap");
JSFunction* adaptor = js::NewFunctionWithReserved(aCx, UnwrapErrorEvent, 1, 0,
JS_GetGlobalObject(aCx), "unwrap");
if (!adaptor) {
return false;
}
@ -350,11 +344,9 @@ private:
return false;
}
if (!JS_SetReservedSlot(aCx, listener, SLOT_wrappedScope,
OBJECT_TO_JSVAL(aObj)) ||
!JS_SetReservedSlot(aCx, listener, SLOT_wrappedFunction, *aVp)) {
return false;
}
js::SetFunctionNativeReserved(listener, SLOT_wrappedScope,
OBJECT_TO_JSVAL(aObj));
js::SetFunctionNativeReserved(listener, SLOT_wrappedFunction, *aVp);
jsval val = OBJECT_TO_JSVAL(listener);
return scope->SetEventListenerOnEventTarget(aCx, name + 2, &val);

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

@ -1022,7 +1022,7 @@ nsEditor::GetDocumentIsEmpty(bool *aDocumentIsEmpty)
{
*aDocumentIsEmpty = true;
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
bool hasChildNodes;
@ -1063,7 +1063,7 @@ NS_IMETHODIMP nsEditor::BeginningOfDocument()
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
// get the root element
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
// find first editable thingy
@ -1109,12 +1109,9 @@ nsEditor::EndOfDocument()
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
// get the root element
nsIDOMElement *rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(rootElement);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> child;
NS_ASSERTION(node, "Invalid root element");
do {
node->GetLastChild(getter_AddRefs(child));
@ -1978,18 +1975,14 @@ nsEditor::GetPhonetic(nsAString& aPhonetic)
static nsresult
GetEditorContentWindow(nsIDOMElement *aRoot, nsIWidget **aResult)
GetEditorContentWindow(dom::Element *aRoot, nsIWidget **aResult)
{
NS_ENSURE_TRUE(aRoot && aResult, NS_ERROR_NULL_POINTER);
*aResult = 0;
nsCOMPtr<nsIContent> content = do_QueryInterface(aRoot);
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
// Not ref counted
nsIFrame *frame = content->GetPrimaryFrame();
nsIFrame *frame = aRoot->GetPrimaryFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
@ -2103,8 +2096,8 @@ nsEditor::GetRootElement(nsIDOMElement **aRootElement)
{
NS_ENSURE_ARG_POINTER(aRootElement);
NS_ENSURE_TRUE(mRootElement, NS_ERROR_NOT_AVAILABLE);
*aRootElement = mRootElement;
NS_ADDREF(*aRootElement);
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(mRootElement);
rootElement.forget(aRootElement);
return NS_OK;
}
@ -2175,12 +2168,10 @@ nsEditor::CloneAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
// Use transaction system for undo only if destination
// is already in the document
nsIDOMElement *rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
bool destInBody = true;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
nsCOMPtr<nsIDOMNode> p = aDestNode;
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootNode, NS_ERROR_NULL_POINTER);
bool destInBody = true;
while (p && p != rootNode)
{
nsCOMPtr<nsIDOMNode> tmp;
@ -2292,11 +2283,12 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
if (!mInIMEMode && aStringToInsert.IsEmpty()) return NS_OK;
nsCOMPtr<nsIDOMText> nodeAsText = do_QueryInterface(*aInOutNode);
if (!nodeAsText && IsPlaintextEditor()) {
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(GetRoot());
// In some cases, aInOutNode is the anonymous DIV, and aInOutOffset is 0.
// To avoid injecting unneeded text nodes, we first look to see if we have
// one available. In that case, we'll just adjust aInOutNode and aInOutOffset
// accordingly.
if (*aInOutNode == GetRoot() && *aInOutOffset == 0) {
if (*aInOutNode == rootNode && *aInOutOffset == 0) {
nsCOMPtr<nsIDOMNode> possibleTextNode;
res = (*aInOutNode)->GetFirstChild(getter_AddRefs(possibleTextNode));
if (NS_SUCCEEDED(res)) {
@ -2309,7 +2301,7 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
// In some other cases, aInOutNode is the anonymous DIV, and aInOutOffset points
// to the terminating mozBR. In that case, we'll adjust aInOutNode and aInOutOffset
// to the preceding text node, if any.
if (!nodeAsText && *aInOutNode == GetRoot() && *aInOutOffset > 0) {
if (!nodeAsText && *aInOutNode == rootNode && *aInOutOffset > 0) {
nsCOMPtr<nsIDOMNodeList> children;
res = (*aInOutNode)->GetChildNodes(getter_AddRefs(children));
if (NS_SUCCEEDED(res)) {
@ -2363,7 +2355,7 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
} else {
nsCOMPtr<nsIDOMNode> parent;
(*aInOutNode)->GetParentNode(getter_AddRefs(parent));
if (parent == GetRoot()) {
if (parent == rootNode) {
*aInOutNode = parent;
}
}
@ -2530,7 +2522,7 @@ NS_IMETHODIMP nsEditor::SelectEntireDocument(nsISelection *aSelection)
{
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
if (!rootElement) { return NS_ERROR_NOT_INITIALIZED; }
return aSelection->SelectAllChildren(rootElement);
@ -3546,7 +3538,9 @@ nsEditor::IsRootNode(nsIDOMNode *inNode)
{
NS_ENSURE_TRUE(inNode, false);
return inNode == GetRoot();
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(GetRoot());
return inNode == rootNode;
}
bool
@ -3554,11 +3548,9 @@ nsEditor::IsRootNode(nsINode *inNode)
{
NS_ENSURE_TRUE(inNode, false);
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsINode> rootNode = GetRoot();
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(inNode);
return node == rootElement;
return inNode == rootNode;
}
bool
@ -3572,7 +3564,7 @@ bool
nsEditor::IsDescendantOfBody(nsINode *inNode)
{
NS_ENSURE_TRUE(inNode, false);
nsCOMPtr<nsIContent> root = do_QueryInterface(GetRoot());
nsCOMPtr<nsIContent> root = GetRoot();
NS_ENSURE_TRUE(root, false);
return nsContentUtils::ContentIsDescendantOf(inNode, root);
@ -5149,7 +5141,7 @@ nsEditor::HandleInlineSpellCheck(PRInt32 action,
already_AddRefed<nsIContent>
nsEditor::FindSelectionRoot(nsINode *aNode)
{
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(GetRoot());
nsCOMPtr<nsIContent> rootContent = GetRoot();
return rootContent.forget();
}
@ -5218,7 +5210,7 @@ nsEditor::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
return NS_OK;
}
nsIDOMElement *
dom::Element *
nsEditor::GetRoot()
{
if (!mRootElement)
@ -5236,18 +5228,14 @@ nsresult
nsEditor::DetermineCurrentDirection()
{
// Get the current root direction from its frame
nsIDOMElement *rootElement = GetRoot();
nsresult rv;
dom::Element *rootElement = GetRoot();
// If we don't have an explicit direction, determine our direction
// from the content's direction
if (!(mFlags & (nsIPlaintextEditor::eEditorLeftToRight |
nsIPlaintextEditor::eEditorRightToLeft))) {
nsCOMPtr<nsIContent> content = do_QueryInterface(rootElement, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsIFrame* frame = content->GetPrimaryFrame();
nsIFrame* frame = rootElement->GetPrimaryFrame();
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
// Set the flag here, to enable us to use the same code path below.
@ -5266,8 +5254,7 @@ NS_IMETHODIMP
nsEditor::SwitchTextDirection()
{
// Get the current root direction from its frame
nsIDOMElement *rootElement = GetRoot();
dom::Element *rootElement = GetRoot();
nsresult rv = DetermineCurrentDirection();
NS_ENSURE_SUCCESS(rv, rv);
@ -5277,13 +5264,13 @@ nsEditor::SwitchTextDirection()
"Unexpected mutually exclusive flag");
mFlags &= ~nsIPlaintextEditor::eEditorRightToLeft;
mFlags |= nsIPlaintextEditor::eEditorLeftToRight;
rv = rootElement->SetAttribute(NS_LITERAL_STRING("dir"), NS_LITERAL_STRING("ltr"));
rv = rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("ltr"), true);
} else if (mFlags & nsIPlaintextEditor::eEditorLeftToRight) {
NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorRightToLeft),
"Unexpected mutually exclusive flag");
mFlags |= nsIPlaintextEditor::eEditorRightToLeft;
mFlags &= ~nsIPlaintextEditor::eEditorLeftToRight;
rv = rootElement->SetAttribute(NS_LITERAL_STRING("dir"), NS_LITERAL_STRING("rtl"));
rv = rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("rtl"), true);
}
return rv;
@ -5293,8 +5280,7 @@ void
nsEditor::SwitchTextDirectionTo(PRUint32 aDirection)
{
// Get the current root direction from its frame
nsIDOMElement *rootElement = GetRoot();
dom::Element *rootElement = GetRoot();
nsresult rv = DetermineCurrentDirection();
NS_ENSURE_SUCCESS(rv, );
@ -5305,14 +5291,14 @@ nsEditor::SwitchTextDirectionTo(PRUint32 aDirection)
"Unexpected mutually exclusive flag");
mFlags &= ~nsIPlaintextEditor::eEditorRightToLeft;
mFlags |= nsIPlaintextEditor::eEditorLeftToRight;
rootElement->SetAttribute(NS_LITERAL_STRING("dir"), NS_LITERAL_STRING("ltr"));
rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("ltr"), true);
} else if (aDirection == nsIPlaintextEditor::eEditorRightToLeft &&
(mFlags & nsIPlaintextEditor::eEditorLeftToRight)) {
NS_ASSERTION(!(mFlags & nsIPlaintextEditor::eEditorRightToLeft),
"Unexpected mutually exclusive flag");
mFlags |= nsIPlaintextEditor::eEditorRightToLeft;
mFlags &= ~nsIPlaintextEditor::eEditorLeftToRight;
rootElement->SetAttribute(NS_LITERAL_STRING("dir"), NS_LITERAL_STRING("rtl"));
rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, NS_LITERAL_STRING("rtl"), true);
}
}

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

@ -651,7 +651,7 @@ public:
virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget() = 0;
// Fast non-refcounting editor root element accessor
nsIDOMElement *GetRoot();
mozilla::dom::Element *GetRoot();
// Accessor methods to flags
bool IsPlaintextEditor() const
@ -763,8 +763,8 @@ public:
protected:
PRUint32 mModCount; // number of modifications (for undo/redo stack)
PRUint32 mFlags; // behavior flags. See nsIPlaintextEditor.idl for the flags we use.
PRUint32 mModCount; // number of modifications (for undo/redo stack)
PRUint32 mFlags; // behavior flags. See nsIPlaintextEditor.idl for the flags we use.
nsWeakPtr mSelConWeak; // weak reference to the nsISelectionController
PRInt32 mUpdateCount;
@ -785,7 +785,7 @@ protected:
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset
nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges
nsCOMPtr<nsIDOMElement> mRootElement; // cached root node
nsCOMPtr<mozilla::dom::Element> mRootElement; // cached root node
PRInt32 mAction; // the current editor action
EDirection mDirection; // the current direction of editor action

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

@ -1401,17 +1401,3 @@ nsHTMLCSSUtils::SetCSSPropertyPixels(nsIDOMElement * aElement,
s.AppendInt(aIntValue);
return SetCSSProperty(aElement, aProperty, s + NS_LITERAL_STRING("px"));
}
nsresult
nsHTMLCSSUtils::RemoveCSSProperty(nsIDOMElement * aElement,
const nsAString & aProperty)
{
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
PRUint32 length;
nsresult res = GetInlineStyles(aElement, getter_AddRefs(cssDecl), &length);
if (NS_FAILED(res) || !cssDecl) return res;
nsAutoString returnString;
return cssDecl->RemoveProperty(aProperty, returnString);
}

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

@ -139,8 +139,6 @@ public:
nsresult SetCSSPropertyPixels(nsIDOMElement * aElement,
const nsAString & aProperty,
PRInt32 aIntValue);
nsresult RemoveCSSProperty(nsIDOMElement * aElement,
const nsAString & aProperty);
/** gets the specified/computed style value of a CSS property for a given node (or its element
* ancestor if it is not an element)

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

@ -81,6 +81,7 @@
#include "nsIHTMLDocument.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
@ -256,7 +257,7 @@ nsHTMLEditRules::Init(nsPlaintextEditor *aEditor)
NS_ENSURE_TRUE(mUtilRange, NS_ERROR_NULL_POINTER);
// set up mDocChangeRange to be whole doc
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
nsCOMPtr<nsIDOMElement> rootElem = do_QueryInterface(mHTMLEditor->GetRoot());
if (rootElem)
{
// temporarily turn off rules sniffing
@ -805,7 +806,7 @@ nsHTMLEditRules::GetAlignment(bool *aMixed, nsIHTMLEditor::EAlignment *aAlign)
// get selection location
nsCOMPtr<nsIDOMNode> parent;
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
nsCOMPtr<nsIDOMElement> rootElem = do_QueryInterface(mHTMLEditor->GetRoot());
NS_ENSURE_TRUE(rootElem, NS_ERROR_FAILURE);
PRInt32 offset, rootOffset;
@ -1012,13 +1013,10 @@ nsHTMLEditRules::GetIndentState(bool *aCanIndent, bool *aCanOutdent)
// in the parent hierarchy.
// gather up info we need for test
nsCOMPtr<nsIDOMNode> parent, tmp, root;
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
NS_ENSURE_TRUE(rootElem, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> parent, tmp, root = do_QueryInterface(mHTMLEditor->GetRoot());
NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsISelection> selection;
PRInt32 selOffset;
root = do_QueryInterface(rootElem);
NS_ENSURE_TRUE(root, NS_ERROR_NO_INTERFACE);
res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
@ -1108,7 +1106,7 @@ nsHTMLEditRules::GetParagraphState(bool *aMixed, nsAString &outFormat)
}
// remember root node
nsIDOMElement *rootElem = mHTMLEditor->GetRoot();
nsCOMPtr<nsIDOMElement> rootElem = do_QueryInterface(mHTMLEditor->GetRoot());
NS_ENSURE_TRUE(rootElem, NS_ERROR_NULL_POINTER);
// loop through the nodes in selection and examine their paragraph format
@ -7778,9 +7776,8 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
// check if br can go into the destination node
if (bIsEmptyNode && mHTMLEditor->CanContainTag(selNode, NS_LITERAL_STRING("br")))
{
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(rootElement));
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(mHTMLEditor->GetRoot());
NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
if (selNode == rootNode)
{
// Our root node is completely empty. Don't add a <br> here.
@ -8359,7 +8356,7 @@ nsHTMLEditRules::ConfirmSelectionInBody()
nsresult res = NS_OK;
// get the body
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(mHTMLEditor->GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_UNEXPECTED);
// get the selection

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

@ -381,28 +381,29 @@ nsHTMLEditor::GetRootElement(nsIDOMElement **aRootElement)
// Use the HTML documents body element as the editor root if we didn't
// get a root element during initialization.
nsCOMPtr<nsIDOMElement> rootElement;
nsCOMPtr<nsIDOMHTMLElement> bodyElement;
nsresult rv = GetBodyElement(getter_AddRefs(bodyElement));
NS_ENSURE_SUCCESS(rv, rv);
if (bodyElement) {
mRootElement = bodyElement;
rootElement = bodyElement;
} else {
// If there is no HTML body element,
// we should use the document root element instead.
nsCOMPtr<nsIDOMDocument> doc = do_QueryReferent(mDocWeak);
NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED);
rv = doc->GetDocumentElement(getter_AddRefs(mRootElement));
rv = doc->GetDocumentElement(getter_AddRefs(rootElement));
NS_ENSURE_SUCCESS(rv, rv);
// Document can have no elements
if (!mRootElement) {
if (!rootElement) {
return NS_ERROR_NOT_AVAILABLE;
}
}
*aRootElement = mRootElement;
NS_ADDREF(*aRootElement);
mRootElement = do_QueryInterface(rootElement);
rootElement.forget(aRootElement);
return NS_OK;
}
@ -544,7 +545,7 @@ nsHTMLEditor::BeginningOfDocument()
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
// Get the root element.
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
if (!rootElement) {
NS_WARNING("GetRoot() returned a null pointer (mRootElement is null)");
return NS_OK;
@ -968,155 +969,6 @@ nsHTMLEditor::GetBlockNodeParent(nsIDOMNode *aNode)
return p.forget();
}
///////////////////////////////////////////////////////////////////////////
// GetBlockSection: return leftmost/rightmost nodes in aChild's block
//
nsresult
nsHTMLEditor::GetBlockSection(nsIDOMNode *aChild,
nsIDOMNode **aLeftNode,
nsIDOMNode **aRightNode)
{
nsresult result = NS_OK;
if (!aChild || !aLeftNode || !aRightNode) {return NS_ERROR_NULL_POINTER;}
*aLeftNode = aChild;
*aRightNode = aChild;
nsCOMPtr<nsIDOMNode>sibling;
result = aChild->GetPreviousSibling(getter_AddRefs(sibling));
while ((NS_SUCCEEDED(result)) && sibling)
{
bool isBlock;
NodeIsBlockStatic(sibling, &isBlock);
if (isBlock)
{
nsCOMPtr<nsIDOMCharacterData>nodeAsText = do_QueryInterface(sibling);
if (!nodeAsText) {
break;
}
// XXX: needs some logic to work for other leaf nodes besides text!
}
*aLeftNode = sibling;
result = (*aLeftNode)->GetPreviousSibling(getter_AddRefs(sibling));
}
NS_ADDREF((*aLeftNode));
// now do the right side
result = aChild->GetNextSibling(getter_AddRefs(sibling));
while ((NS_SUCCEEDED(result)) && sibling)
{
bool isBlock;
NodeIsBlockStatic(sibling, &isBlock);
if (isBlock)
{
nsCOMPtr<nsIDOMCharacterData>nodeAsText = do_QueryInterface(sibling);
if (!nodeAsText) {
break;
}
}
*aRightNode = sibling;
result = (*aRightNode)->GetNextSibling(getter_AddRefs(sibling));
}
NS_ADDREF((*aRightNode));
return result;
}
///////////////////////////////////////////////////////////////////////////
// GetBlockSectionsForRange: return list of block sections that intersect
// this range
nsresult
nsHTMLEditor::GetBlockSectionsForRange(nsIDOMRange *aRange,
nsCOMArray<nsIDOMRange>& aSections)
{
if (!aRange) {return NS_ERROR_NULL_POINTER;}
nsresult result;
nsCOMPtr<nsIContentIterator>iter =
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &result);
if (NS_FAILED(result) || !iter) {
return result;
}
nsCOMPtr<nsIDOMRange> lastRange;
iter->Init(aRange);
while (iter->IsDone())
{
nsCOMPtr<nsIContent> currentContent =
do_QueryInterface(iter->GetCurrentNode());
nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(currentContent);
if (currentNode)
{
// <BR> divides block content ranges. We can achieve this by nulling out lastRange
if (currentContent->Tag() == nsEditProperty::br)
{
lastRange = nsnull;
}
else
{
bool isNotInlineOrText;
result = NodeIsBlockStatic(currentNode, &isNotInlineOrText);
if (isNotInlineOrText)
{
PRUint16 nodeType;
currentNode->GetNodeType(&nodeType);
if (nsIDOMNode::TEXT_NODE == nodeType) {
isNotInlineOrText = true;
}
}
if (!isNotInlineOrText) {
nsCOMPtr<nsIDOMNode> leftNode;
nsCOMPtr<nsIDOMNode> rightNode;
result = GetBlockSection(currentNode,
getter_AddRefs(leftNode),
getter_AddRefs(rightNode));
if ((NS_SUCCEEDED(result)) && leftNode && rightNode) {
// Add range to the list if it doesn't overlap with the previous
// range.
bool addRange = true;
if (lastRange)
{
nsCOMPtr<nsIDOMNode> lastStartNode;
lastRange->GetStartContainer(getter_AddRefs(lastStartNode));
nsCOMPtr<nsIDOMNode> blockParentNodeOfLastStartNode =
GetBlockNodeParent(lastStartNode);
nsCOMPtr<nsIDOMElement> blockParentOfLastStartNode =
do_QueryInterface(blockParentNodeOfLastStartNode);
if (blockParentOfLastStartNode)
{
nsCOMPtr<nsIDOMNode> blockParentNodeOfLeftNode =
GetBlockNodeParent(leftNode);
nsCOMPtr<nsIDOMElement> blockParentOfLeftNode =
do_QueryInterface(blockParentNodeOfLeftNode);
if (blockParentOfLeftNode &&
blockParentOfLastStartNode == blockParentOfLeftNode) {
addRange = false;
}
}
}
if (addRange) {
nsCOMPtr<nsIDOMRange> range =
do_CreateInstance("@mozilla.org/content/range;1", &result);
if ((NS_SUCCEEDED(result)) && range) {
// Initialize the range.
range->SetStart(leftNode, 0);
range->SetEnd(rightNode, 0);
aSections.AppendObject(range);
lastRange = do_QueryInterface(range);
}
}
}
}
}
}
/* do not check result here, and especially do not return the result code.
* we rely on iter->IsDone to tell us when the iteration is complete
*/
iter->Next();
}
return result;
}
///////////////////////////////////////////////////////////////////////////
// NextNodeInBlock: gets the next/prev node in the block, if any. Next node
// must be an element or text node, others are ignored
@ -1809,8 +1661,7 @@ nsHTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsIDOMElement *bodyElement = GetRoot();
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsIDOMElement> bodyElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
// Find where the <body> tag starts.
@ -2452,10 +2303,10 @@ nsHTMLEditor::GetHTMLBackgroundColorState(bool *aMixed, nsAString &aOutColor)
}
// If no table or cell found, get page body
element = GetRoot();
NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
mozilla::dom::Element *bodyElement = GetRoot();
NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
return element->GetAttribute(styleName, aOutColor);
return bodyElement->GetAttr(kNameSpaceID_None, nsGkAtoms::bgcolor, aOutColor);
}
NS_IMETHODIMP
@ -3392,7 +3243,7 @@ nsHTMLEditor::SetHTMLBackgroundColor(const nsAString& aColor)
// If we failed to find a cell, fall through to use originally-found element
} else {
// No table element -- set the background color on the body tag
element = GetRoot();
element = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
}
// Use the editor method that goes through the transaction system
@ -3411,8 +3262,7 @@ NS_IMETHODIMP nsHTMLEditor::SetBodyAttribute(const nsAString& aAttribute, const
NS_ASSERTION(mDocWeak, "Missing Editor DOM Document");
// Set the background color attribute on the body tag
nsIDOMElement *bodyElement = GetRoot();
nsCOMPtr<nsIDOMElement> bodyElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
// Use the editor method that goes through the transaction system
@ -3880,7 +3730,7 @@ already_AddRefed<nsIDOMNode>
nsHTMLEditor::FindUserSelectAllNode(nsIDOMNode* aNode)
{
nsCOMPtr<nsIDOMNode> node = aNode;
nsIDOMElement *root = GetRoot();
nsCOMPtr<nsIDOMElement> root = do_QueryInterface(GetRoot());
if (!nsEditorUtils::IsDescendantOf(aNode, root))
return nsnull;
@ -4145,7 +3995,7 @@ nsHTMLEditor::SelectEntireDocument(nsISelection *aSelection)
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
// get editor root node
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
// is doc empty?
bool bDocIsEmpty;
@ -4190,7 +4040,9 @@ nsHTMLEditor::SelectAll()
NS_ENSURE_TRUE(selPriv, NS_ERROR_UNEXPECTED);
rv = selPriv->SetAncestorLimiter(nsnull);
NS_ENSURE_SUCCESS(rv, rv);
return selection->SelectAllChildren(mRootElement);
nsCOMPtr<nsIDOMNode> rootElement = do_QueryInterface(mRootElement, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return selection->SelectAllChildren(rootElement);
}
nsCOMPtr<nsIPresShell> ps = GetPresShell();
@ -4481,7 +4333,7 @@ nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange)
NS_IMETHODIMP
nsHTMLEditor::SetSelectionAtDocumentStart(nsISelection *aSelection)
{
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
return aSelection->Collapse(rootElement,0);

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

@ -277,38 +277,6 @@ public:
/* ------------ Block methods moved from nsEditor -------------- */
static already_AddRefed<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
/** Determines the bounding nodes for the block section containing aNode.
* The calculation is based on some nodes intrinsically being block elements
* acording to HTML. Style sheets are not considered in this calculation.
* <BR> tags separate block content sections. So the HTML markup:
* <PRE>
* <P>text1<BR>text2<B>text3</B></P>
* </PRE>
* contains two block content sections. The first has the text node "text1"
* for both endpoints. The second has "text2" as the left endpoint and
* "text3" as the right endpoint.
* Notice that offsets aren't required, only leaf nodes. Offsets are implicit.
*
* @param aNode the block content returned includes aNode
* @param aLeftNode [OUT] the left endpoint of the block content containing aNode
* @param aRightNode [OUT] the right endpoint of the block content containing aNode
*
*/
static nsresult GetBlockSection(nsIDOMNode *aNode,
nsIDOMNode **aLeftNode,
nsIDOMNode **aRightNode);
/** Compute the set of block sections in a given range.
* A block section is the set of (leftNode, rightNode) pairs given
* by GetBlockSection. The set is computed by computing the
* block section for every leaf node in the range and throwing
* out duplicates.
*
* @param aRange The range to compute block sections for.
* @param aSections Allocated storage for the resulting set, stored as nsIDOMRanges.
*/
static nsresult GetBlockSectionsForRange(nsIDOMRange *aRange,
nsCOMArray<nsIDOMRange>& aSections);
static already_AddRefed<nsIDOMNode> NextNodeInBlock(nsIDOMNode *aNode, IterDirection aDir);
nsresult IsNextCharWhitespace(nsIDOMNode *aParentNode,

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

@ -43,6 +43,7 @@
#include "nsIContent.h"
#include "nsHTMLEditUtils.h"
#include "nsReadableUtils.h"
#include "mozilla/dom/Element.h"
// Uncomment the following line if you want to disable
// table deletion when the only column/row is removed
@ -77,7 +78,7 @@ nsHTMLEditor::ShowInlineTableEditingUI(nsIDOMElement * aCell)
}
// the resizers and the shadow will be anonymous children of the body
nsIDOMElement *bodyElement = GetRoot();
nsCOMPtr<nsIDOMElement> bodyElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
CreateAnonymousElement(NS_LITERAL_STRING("a"), bodyElement,
@ -130,10 +131,7 @@ nsHTMLEditor::HideInlineTableEditingUI()
// UnbindFromTree.
// get the root content node.
nsIDOMElement *bodyElement = GetRoot();
nsCOMPtr<nsIContent> bodyContent( do_QueryInterface(bodyElement) );
nsCOMPtr<nsIContent> bodyContent = GetRoot();
NS_ENSURE_TRUE(bodyContent, NS_ERROR_FAILURE);
DeleteRefToAnonymousNode(mAddColumnBeforeButton, bodyContent, ps);

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

@ -75,6 +75,7 @@
#include "nsGkAtoms.h"
#include "nsDebug.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Element.h"
// Drag & Drop, Clipboard
#include "nsIClipboard.h"
@ -571,7 +572,8 @@ nsPlaintextEditor::GetTextSelectionOffsets(nsISelection *aSelection,
aSelection->GetFocusNode(getter_AddRefs(endNode));
aSelection->GetFocusOffset(&endNodeOffset);
nsIDOMElement* rootNode = GetRoot();
dom::Element *rootElement = GetRoot();
nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootElement);
NS_ENSURE_TRUE(rootNode, NS_ERROR_NULL_POINTER);
PRInt32 startOffset = -1;
@ -585,8 +587,7 @@ nsPlaintextEditor::GetTextSelectionOffsets(nsISelection *aSelection,
PRInt32 nodeCount = 0; // only needed for the assertions below
#endif
PRUint32 totalLength = 0;
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(rootNode);
iter->Init(rootContent);
iter->Init(rootElement);
for (; !iter->IsDone() && (startOffset == -1 || endOffset == -1); iter->Next()) {
nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(iter->GetCurrentNode());
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(currentNode);
@ -1020,16 +1021,15 @@ nsPlaintextEditor::GetTextLength(PRInt32 *aCount)
if (docEmpty)
return NS_OK;
nsIDOMElement* rootNode = GetRoot();
NS_ENSURE_TRUE(rootNode, NS_ERROR_NULL_POINTER);
dom::Element *rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContentIterator> iter =
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 totalLength = 0;
nsCOMPtr<nsIContent> rootContent = do_QueryInterface(rootNode);
iter->Init(rootContent);
iter->Init(rootElement);
for (; !iter->IsDone(); iter->Next()) {
nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(iter->GetCurrentNode());
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(currentNode);
@ -1104,13 +1104,12 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn)
// Ought to set a style sheet here ...
// Probably should keep around an mPlaintextStyleSheet for this purpose.
nsIDOMElement *rootElement = GetRoot();
dom::Element *rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
// Get the current style for this root element:
NS_NAMED_LITERAL_STRING(styleName, "style");
nsAutoString styleValue;
nsresult res = rootElement->GetAttribute(styleName, styleValue);
nsresult res = rootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::style, styleValue);
NS_ENSURE_SUCCESS(res, res);
// We'll replace styles for these values:
@ -1154,7 +1153,7 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn)
else
styleValue.AppendLiteral("white-space: pre;");
return rootElement->SetAttribute(styleName, styleValue);
return rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::style, styleValue, true);
}
NS_IMETHODIMP
@ -1354,7 +1353,7 @@ nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType,
// in which case we set the selection to encompass the root.
else
{
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
if (!nsTextEditUtils::IsBody(rootElement))
{
@ -1684,7 +1683,7 @@ nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection)
if (NS_SUCCEEDED(mRules->DocumentIsEmpty(&bDocIsEmpty)) && bDocIsEmpty)
{
// get root node
nsIDOMElement *rootElement = GetRoot();
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
// if it's empty don't select entire doc - that would select the bogus node

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

@ -68,6 +68,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
@ -460,8 +461,7 @@ nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection)
&parentOffset);
NS_ENSURE_SUCCESS(res, res);
nsIDOMElement *rootElem = mEditor->GetRoot();
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(rootElem);
nsCOMPtr<nsIDOMNode> root = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER);
if (parentNode != root) return NS_OK;
@ -949,7 +949,7 @@ nsTextEditRules::DidUndo(nsISelection *aSelection, nsresult aResult)
}
else
{
nsIDOMElement *theRoot = mEditor->GetRoot();
nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theRoot);
if (node && mEditor->IsMozEditorBogusNode(node))
@ -982,7 +982,7 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
}
else
{
nsIDOMElement *theRoot = mEditor->GetRoot();
nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNodeList> nodeList;
@ -1056,7 +1056,7 @@ nsTextEditRules::RemoveRedundantTrailingBR()
if (IsSingleLineEditor())
return NS_OK;
nsIDOMNode* body = mEditor->GetRoot();
nsCOMPtr<nsIDOMNode> body = do_QueryInterface(mEditor->GetRoot());
if (!body)
return NS_ERROR_NULL_POINTER;
@ -1111,7 +1111,7 @@ nsTextEditRules::CreateTrailingBRIfNeeded()
// but only if we aren't a single line edit field
if (IsSingleLineEditor())
return NS_OK;
nsIDOMNode *body = mEditor->GetRoot();
nsCOMPtr<nsIDOMNode> body = do_QueryInterface(mEditor->GetRoot());
NS_ENSURE_TRUE(body, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> lastChild;
nsresult res = body->GetLastChild(getter_AddRefs(lastChild));
@ -1141,7 +1141,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
// tell rules system to not do any post-processing
nsAutoRules beginRulesSniffing(mEditor, nsEditor::kOpIgnore, nsIEditor::eNone);
nsIDOMNode* body = mEditor->GetRoot();
nsCOMPtr<nsIDOMNode> body = do_QueryInterface(mEditor->GetRoot());
if (!body)
{
// we don't even have a body yet, don't insert any bogus nodes at

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

@ -78,7 +78,7 @@ namespace mozilla {
namespace layers {
class LayerManagerOGL;
class ColorTextureLayerProgram;
};
}
namespace gl {
class GLContext;
@ -542,6 +542,7 @@ public:
#endif
mIsGlobalSharedContext(false),
mHasRobustness(false),
mContextLost(false),
mVendor(-1),
mDebugMode(0),
mCreationFormat(aFormat),
@ -595,6 +596,8 @@ public:
return MakeCurrentImpl(aForce);
}
bool IsContextLost() { return mContextLost; }
virtual bool SetupLookupFunction() = 0;
virtual void WindowDestroyed() {}
@ -1326,6 +1329,7 @@ protected:
bool mIsGLES2;
bool mIsGlobalSharedContext;
bool mHasRobustness;
bool mContextLost;
PRInt32 mVendor;

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

@ -834,6 +834,10 @@ public:
succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
mSurface, mSurface,
mContext);
if (!succeeded && sEGLLibrary.fGetError() == LOCAL_EGL_CONTEXT_LOST) {
mContextLost = true;
NS_WARNING("EGL context has been lost.");
}
NS_ASSERTION(succeeded, "Failed to make GL context current!");
}

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

@ -122,6 +122,13 @@ CreateDummyWindow(HDC *aWindowDC = nsnull)
return win;
}
static inline bool
HasExtension(const char* aExtensions, const char* aRequiredExtension)
{
return GLContext::ListHasExtension(
reinterpret_cast<const GLubyte*>(aExtensions), aRequiredExtension);
}
bool
WGLLibrary::EnsureInitialized()
{
@ -205,9 +212,47 @@ WGLLibrary::EnsureInitialized()
fChoosePixelFormat = nsnull;
}
LibrarySymbolLoader::SymLoadStruct extensionsSymbols[] = {
{ (PRFuncPtr *) &fGetExtensionsString, { "wglGetExtensionsStringARB", NULL} },
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct robustnessSymbols[] = {
{ (PRFuncPtr *) &fCreateContextAttribs, { "wglCreateContextAttribsARB", NULL} },
{ NULL, { NULL } }
};
if (LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress)) {
const char *wglExts = fGetExtensionsString(gSharedWindowDC);
if (wglExts && HasExtension(wglExts, "WGL_ARB_create_context")) {
LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress);
if (HasExtension(wglExts, "WGL_ARB_create_context_robustness")) {
mHasRobustness = true;
}
}
}
// reset back to the previous context, just in case
fMakeCurrent(curDC, curCtx);
if (mHasRobustness) {
fDeleteContext(gSharedWindowGLContext);
int attribs[] = {
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
NULL
};
gSharedWindowGLContext = fCreateContextAttribs(gSharedWindowDC, NULL, attribs);
if (!gSharedWindowGLContext) {
mHasRobustness = false;
gSharedWindowGLContext = fCreateContext(gSharedWindowDC);
}
}
mInitialized = true;
// Call this to create the global GLContext instance,
@ -309,7 +354,7 @@ public:
bool SupportsRobustness()
{
return false;
return sWGLLibrary.HasRobustness();
}
virtual bool SwapBuffers() {
@ -502,16 +547,35 @@ GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
HDC dc = (HDC)aWidget->GetNativeData(NS_NATIVE_GRAPHIC);
SetPixelFormat(dc, gSharedWindowPixelFormat, NULL);
HGLRC context = sWGLLibrary.fCreateContext(dc);
if (!context) {
return nsnull;
}
HGLRC context;
GLContextWGL *shareContext = GetGlobalContextWGL();
if (shareContext &&
!sWGLLibrary.fShareLists(shareContext->Context(), context))
{
shareContext = nsnull;
if (sWGLLibrary.HasRobustness()) {
int attribs[] = {
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
NULL
};
context = sWGLLibrary.fCreateContextAttribs(dc,
shareContext ? shareContext->Context() : nsnull,
attribs);
if (!context && shareContext) {
context = sWGLLibrary.fCreateContextAttribs(dc, nsnull, attribs);
if (context) {
shareContext = nsnull;
}
} else {
context = sWGLLibrary.fCreateContext(dc);
if (context && shareContext && !sWGLLibrary.fShareLists(shareContext->Context(), context)) {
shareContext = nsnull;
}
}
}
if (!context) {
return nsnull;
}
nsRefPtr<GLContextWGL> glContext = new GLContextWGL(ContextFormat(ContextFormat::BasicRGB24),
@ -597,7 +661,19 @@ CreatePBufferOffscreenContext(const gfxIntSize& aSize,
HDC pbdc = sWGLLibrary.fGetPbufferDC(pbuffer);
NS_ASSERTION(pbdc, "expected a dc");
HGLRC context = sWGLLibrary.fCreateContext(pbdc);
HGLRC context;
if (sWGLLibrary.HasRobustness()) {
int attribs[] = {
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
NULL
};
context = sWGLLibrary.fCreateContextAttribs(pbdc, nsnull, attribs);
} else {
context = sWGLLibrary.fCreateContext(pbdc);
}
if (!context) {
sWGLLibrary.fDestroyPbuffer(pbuffer);
return false;
@ -629,15 +705,28 @@ CreateWindowOffscreenContext(const ContextFormat& aFormat)
}
HGLRC context = sWGLLibrary.fCreateContext(dc);
if (!context) {
return nsnull;
if (sWGLLibrary.HasRobustness()) {
int attribs[] = {
LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
NULL
};
context = sWGLLibrary.fCreateContextAttribs(dc, shareContext->Context(), attribs);
} else {
context = sWGLLibrary.fCreateContext(dc);
if (context && shareContext &&
!sWGLLibrary.fShareLists(shareContext->Context(), context))
{
NS_WARNING("wglShareLists failed!");
sWGLLibrary.fDeleteContext(context);
DestroyWindow(win);
return nsnull;
}
}
if (!sWGLLibrary.fShareLists(shareContext->Context(), context)) {
NS_WARNING("wglShareLists failed!");
sWGLLibrary.fDeleteContext(context);
DestroyWindow(win);
if (!context) {
return nsnull;
}

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

@ -3246,4 +3246,5 @@ typedef ptrdiff_t GLintptr;
#define LOCAL_EGL_CORE_NATIVE_ENGINE 0x305B
#define LOCAL_EGL_READ 0x305A
#define LOCAL_EGL_DRAW 0x3059
#define LOCAL_EGL_CONTEXT_LOST 0x300E
#endif

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

@ -1,3 +1,37 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@

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

@ -42,7 +42,8 @@ namespace gl {
class WGLLibrary
{
public:
WGLLibrary() : mInitialized(false), mOGLLibrary(nsnull) {}
WGLLibrary() : mInitialized(false), mOGLLibrary(nsnull),
mHasRobustness(false) {}
typedef HGLRC (GLAPIENTRY * PFNWGLCREATECONTEXTPROC) (HDC);
PFNWGLCREATECONTEXTPROC fCreateContext;
@ -76,11 +77,20 @@ public:
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int* piAttributes, int *piValues);
PFNWGLGETPIXELFORMATATTRIBIVPROC fGetPixelFormatAttribiv;
typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGPROC) (HDC hdc);
PFNWGLGETEXTENSIONSSTRINGPROC fGetExtensionsString;
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSPROC) (HDC hdc, HGLRC hShareContext, const int *attribList);
PFNWGLCREATECONTEXTATTRIBSPROC fCreateContextAttribs;
bool EnsureInitialized();
bool HasRobustness() const { return mHasRobustness; }
private:
bool mInitialized;
PRLibrary *mOGLLibrary;
bool mHasRobustness;
};
// a global WGLLibrary instance

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

@ -1,3 +1,38 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@

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

@ -162,6 +162,10 @@ NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::Value* aRects)
}
JSObject* destArray = JS_NewArrayObject(aCx, numRects * 4, NULL);
if (!destArray) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aRects = OBJECT_TO_JSVAL(destArray);
uint32 n = 0;

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

@ -1,3 +1,37 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@

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

@ -66,7 +66,7 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
{
aBatteryInfo->level() = dom::battery::kDefaultLevel;
aBatteryInfo->charging() = dom::battery::kDefaultCharging;
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
aBatteryInfo->remainingTime() = dom::battery::kDefaultRemainingTime;
}
} // hal_impl

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

@ -66,7 +66,7 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
{
aBatteryInfo->level() = dom::battery::kDefaultLevel;
aBatteryInfo->charging() = dom::battery::kDefaultCharging;
aBatteryInfo->remainingTime() = dom::battery::kUnknownRemainingTime;
aBatteryInfo->remainingTime() = dom::battery::kDefaultRemainingTime;
}
#endif // !MOZ_ENABLE_DBUS

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

@ -747,7 +747,7 @@ jsd_GetValueParent(JSDContext* jsdc, JSDValue* jsdval)
return NULL;
}
parent = JS_GetParent(jsdc->dumbContext,obj);
parent = JS_GetParentOrScopeChain(jsdc->dumbContext,obj);
JS_LeaveCrossCompartmentCall(call);
JS_EndRequest(jsdc->dumbContext);
if(!parent)

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

@ -357,6 +357,7 @@ class HashTable : private AllocPolicy
public:
HashTable(AllocPolicy ap)
: AllocPolicy(ap),
hashShift(sHashBits),
entryCount(0),
gen(0),
removedCount(0),

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

@ -564,6 +564,11 @@ public:
return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
}
ptrdiff_t differenceBetween(DataLabelPtr from, Label to)
{
return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
}
ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
{
return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);

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

@ -334,7 +334,7 @@ public:
return branch32(cond, left, Imm32(right));
}
Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right)
Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right, RegisterID scratch)
{
return branch32(cond, left, Imm32(right));
}

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

@ -431,6 +431,12 @@ public:
return branchPtr(cond, Address(scratchRegister), right);
}
Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right, RegisterID scratch)
{
move(ImmPtr(left.m_ptr), scratch);
return branchPtr(cond, Address(scratch), right);
}
Jump branchPtr(Condition cond, Address left, RegisterID right)
{
m_assembler.cmpq_rm(right, left.offset, left.base);

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

@ -110,9 +110,9 @@ public:
MacroAssembler::repatchInt32(dataLabel32, value);
}
void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value)
void repatch(CodeLocationDataLabelPtr dataLabelPtr, const void* value)
{
MacroAssembler::repatchPointer(dataLabelPtr, value);
MacroAssembler::repatchPointer(dataLabelPtr, (void*) value);
}
void repatchLoadPtrToLEA(CodeLocationInstruction instruction)

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

@ -641,7 +641,7 @@ InitTypeConstructor(JSContext* cx,
JSObject*& typeProto,
JSObject*& dataProto)
{
JSFunction* fun = JS_DefineFunction(cx, parent, spec.name, spec.call,
JSFunction* fun = js::DefineFunctionWithReserved(cx, parent, spec.name, spec.call,
spec.nargs, spec.flags);
if (!fun)
return false;
@ -672,8 +672,7 @@ InitTypeConstructor(JSContext* cx,
// Stash ctypes.{Pointer,Array,Struct}Type.prototype on a reserved slot of
// the type constructor, for faster lookup.
if (!JS_SetReservedSlot(cx, obj, SLOT_FN_CTORPROTO, OBJECT_TO_JSVAL(typeProto)))
return false;
js::SetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO, OBJECT_TO_JSVAL(typeProto));
// Create an object to serve as the common ancestor for all CData objects
// created from the given type constructor. This has ctypes.CData.prototype
@ -725,14 +724,18 @@ InitInt64Class(JSContext* cx,
if (!JS_FreezeObject(cx, ctor))
return NULL;
// Stash ctypes.{Int64,UInt64}.prototype on a reserved slot of the 'join'
// function.
jsval join;
ASSERT_OK(JS_GetProperty(cx, ctor, "join", &join));
if (!JS_SetReservedSlot(cx, JSVAL_TO_OBJECT(join), SLOT_FN_INT64PROTO,
OBJECT_TO_JSVAL(prototype)))
// Redefine the 'join' function as an extended native and stash
// ctypes.{Int64,UInt64}.prototype in a reserved slot of the new function.
JS_ASSERT(clasp == &sInt64ProtoClass || clasp == &sUInt64ProtoClass);
JSNative native = (clasp == &sInt64ProtoClass) ? Int64::Join : UInt64::Join;
JSFunction* fun = js::DefineFunctionWithReserved(cx, ctor, "join", native,
2, CTYPESFN_FLAGS);
if (!fun)
return NULL;
js::SetFunctionNativeReserved(fun, SLOT_FN_INT64PROTO,
OBJECT_TO_JSVAL(prototype));
if (!JS_FreezeObject(cx, prototype))
return NULL;
@ -3045,8 +3048,7 @@ CType::GetProtoFromCtor(JSContext* cx, JSObject* obj, CTypeProtoSlot slot)
{
// Get ctypes.{Pointer,Array,Struct}Type.prototype from a reserved slot
// on the type constructor.
jsval protoslot;
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FN_CTORPROTO, &protoslot));
jsval protoslot = js::GetFunctionNativeReserved(obj, SLOT_FN_CTORPROTO);
JSObject* proto = JSVAL_TO_OBJECT(protoslot);
JS_ASSERT(proto);
JS_ASSERT(CType::IsCTypeProto(cx, proto));
@ -6291,8 +6293,7 @@ Int64::Join(JSContext* cx, uintN argc, jsval* vp)
// Get Int64.prototype from the function's reserved slot.
JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval slot;
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
JSObject* proto = JSVAL_TO_OBJECT(slot);
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sInt64ProtoClass);
@ -6459,8 +6460,7 @@ UInt64::Join(JSContext* cx, uintN argc, jsval* vp)
// Get UInt64.prototype from the function's reserved slot.
JSObject* callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
jsval slot;
ASSERT_OK(JS_GetReservedSlot(cx, callee, SLOT_FN_INT64PROTO, &slot));
jsval slot = js::GetFunctionNativeReserved(callee, SLOT_FN_INT64PROTO);
JSObject* proto = JSVAL_TO_OBJECT(slot);
JS_ASSERT(JS_GET_CLASS(cx, proto) == &sUInt64ProtoClass);

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

@ -93,7 +93,7 @@ DefineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script)
JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0, DNP_SKIP_TYPE);
if (!shape)
return false;
def.knownSlot = shape->slot;
def.knownSlot = shape->slot();
}
Vector<JSScript *, 16> worklist(cx);
@ -123,10 +123,10 @@ DefineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script)
JSObject *obj = arr->vector[i];
if (!obj->isFunction())
continue;
JSFunction *fun = obj->getFunctionPrivate();
JSFunction *fun = obj->toFunction();
JS_ASSERT(fun->isInterpreted());
JSScript *inner = fun->script();
if (outer->isHeavyweightFunction) {
if (outer->function() && outer->function()->isHeavyweight()) {
outer->isOuterFunction = true;
inner->isInnerFunction = true;
}

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

@ -1383,7 +1383,7 @@ frontend::PushBlockScope(TreeContext *tc, StmtInfo *stmt, ObjectBox *blockBox, p
PushStatement(tc, stmt, STMT_BLOCK, top);
stmt->flags |= SIF_SCOPE;
blockBox->parent = tc->blockChainBox;
blockBox->object->setParent(tc->blockChain());
blockBox->object->setStaticBlockScopeChain(tc->blockChain());
stmt->downScope = tc->topScopeStmt;
tc->topScopeStmt = stmt;
tc->blockChainBox = blockBox;
@ -1721,7 +1721,7 @@ frontend::LexicalLookup(TreeContext *tc, JSAtom *atom, jsint *slotp, StmtInfo *s
if (slotp) {
JS_ASSERT(obj->getSlot(JSSLOT_BLOCK_DEPTH).isInt32());
*slotp = obj->getSlot(JSSLOT_BLOCK_DEPTH).toInt32() + shape->shortid;
*slotp = obj->getSlot(JSSLOT_BLOCK_DEPTH).toInt32() + shape->shortid();
}
return stmt;
}
@ -1781,8 +1781,8 @@ LookupCompileTimeConstant(JSContext *cx, BytecodeEmitter *bce, JSAtom *atom, Val
* from our variable object here.
*/
if (!shape->writable() && !shape->configurable() &&
shape->hasDefaultGetter() && obj->containsSlot(shape->slot)) {
*constp = obj->getSlot(shape->slot);
shape->hasDefaultGetter() && obj->containsSlot(shape->slot())) {
*constp = obj->getSlot(shape->slot());
}
}
@ -2020,8 +2020,13 @@ EmitEnterBlock(JSContext *cx, ParseNode *pn, BytecodeEmitter *bce)
* js::Bindings::extensibleParents.
*/
if ((bce->flags & TCF_FUN_EXTENSIBLE_SCOPE) ||
bce->bindings.extensibleParents())
blockObj->setBlockOwnShape(cx);
bce->bindings.extensibleParents()) {
HeapPtrShape shape;
shape.init(blockObj->lastProperty());
if (!Shape::setExtensibleParents(cx, &shape))
return false;
blockObj->setLastPropertyInfallible(shape);
}
return true;
}
@ -2332,7 +2337,6 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
JS_ASSERT(bce->inFunction());
JS_ASSERT_IF(cookie.slot() != UpvarCookie::CALLEE_SLOT, bce->roLexdeps->lookup(atom));
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
JS_ASSERT(bce->fun()->u.i.skipmin <= skip);
/*
* If op is a mutating opcode, this upvar's lookup skips too many levels,
@ -3844,13 +3848,6 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
bce->switchToMain();
}
if (bce->flags & TCF_FUN_UNBRAND_THIS) {
bce->switchToProlog();
if (Emit1(cx, bce, JSOP_UNBRANDTHIS) < 0)
return false;
bce->switchToMain();
}
return EmitTree(cx, bce, body) &&
Emit1(cx, bce, JSOP_STOP) >= 0 &&
JSScript::NewScriptFromEmitter(cx, bce);
@ -4756,7 +4753,7 @@ ParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
case PNK_RC: {
JS_ASSERT(isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST));
gc::AllocKind kind = GuessObjectGCKind(pn_count, false);
gc::AllocKind kind = GuessObjectGCKind(pn_count);
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
if (!obj)
return false;
@ -5447,6 +5444,40 @@ EmitWith(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return PopStatementBCE(cx, bce);
}
static bool
SetMethodFunction(JSContext *cx, FunctionBox *funbox, JSAtom *atom)
{
/*
* Replace a boxed function with a new one with a method atom. Methods
* require a function with the extended size finalize kind, which normal
* functions don't have. We don't eagerly allocate functions with the
* expanded size for boxed functions, as most functions are not methods.
*/
JSFunction *fun = js_NewFunction(cx, NULL, NULL,
funbox->function()->nargs,
funbox->function()->flags,
funbox->function()->getParent(),
funbox->function()->atom,
JSFunction::ExtendedFinalizeKind);
if (!fun)
return false;
JSScript *script = funbox->function()->script();
if (script) {
fun->setScript(script);
if (!script->typeSetFunction(cx, fun))
return false;
}
JS_ASSERT(funbox->function()->joinable());
fun->setJoinable();
fun->setMethodAtom(atom);
funbox->object = fun;
return true;
}
static bool
EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
{
@ -6329,6 +6360,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
pn2->pn_left->isOp(JSOP_SETPROP) &&
pn2->pn_right->isOp(JSOP_LAMBDA) &&
pn2->pn_right->pn_funbox->joinable()) {
if (!SetMethodFunction(cx, pn2->pn_right->pn_funbox, pn2->pn_left->pn_atom))
return JS_FALSE;
pn2->pn_left->setOp(JSOP_SETMETHOD);
}
if (!EmitTree(cx, bce, pn2))
@ -7096,7 +7129,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
*/
JSObject *obj = NULL;
if (!bce->hasSharps() && bce->compileAndGo()) {
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count, false);
gc::AllocKind kind = GuessObjectGCKind(pn->pn_count);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
if (!obj)
return JS_FALSE;
@ -7144,6 +7177,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
obj = NULL;
op = JSOP_INITMETHOD;
pn2->setOp(op);
if (!SetMethodFunction(cx, init->pn_funbox, pn3->pn_atom))
return JS_FALSE;
} else {
/*
* Disable NEWOBJECT on initializers that set __proto__, which has
@ -7171,11 +7206,6 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
}
if (bce->funbox && bce->funbox->shouldUnbrand(methodInits, slowMethodInits)) {
obj = NULL;
if (Emit1(cx, bce, JSOP_UNBRAND) < 0)
return JS_FALSE;
}
if (!EmitEndInit(cx, bce, pn->pn_count))
return JS_FALSE;

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

@ -203,15 +203,6 @@ struct StmtInfo {
/* bits 0x40000 and 0x80000 are unused */
/*
* Flag signifying that the current function seems to be a constructor that
* sets this.foo to define "methods", at least one of which can't be a null
* closure, so we should avoid over-specializing property cache entries and
* trace inlining guards to method function object identity, which will vary
* per instance.
*/
#define TCF_FUN_UNBRAND_THIS 0x100000
/*
* "Module pattern", i.e., a lambda that is immediately applied and the whole
* of an expression statement.

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

@ -133,20 +133,6 @@ FunctionBox::scopeIsExtensible() const
return tcflags & TCF_FUN_EXTENSIBLE_SCOPE;
}
bool
FunctionBox::shouldUnbrand(uintN methods, uintN slowMethods) const
{
if (slowMethods != 0) {
for (const FunctionBox *funbox = this; funbox; funbox = funbox->parent) {
if (!(funbox->tcflags & TCF_FUN_MODULE_PATTERN))
return true;
if (funbox->inLoop)
return true;
}
}
return false;
}
/* Add |node| to |parser|'s free node list. */
void
ParseNodeAllocator::freeNode(ParseNode *pn)

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

@ -1271,18 +1271,6 @@ struct FunctionBox : public ObjectBox
* ancestor?
*/
bool scopeIsExtensible() const;
/*
* Unbrand an object being initialized or constructed if any method cannot
* be joined to one compiler-created null closure shared among N different
* closure environments.
*
* We despecialize from caching function objects, caching slots or shapes
* instead, because an unbranded object may still have joined methods (for
* which shape->isMethod), since PropertyCache::fill gives precedence to
* joined methods over branded methods.
*/
bool shouldUnbrand(uintN methods, uintN slowMethods) const;
};
struct FunctionBoxQueue {

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

@ -533,7 +533,7 @@ js::CheckStrictParameters(JSContext *cx, TreeContext *tc)
/* Start with lastVariable(), not lastArgument(), for destructuring. */
for (Shape::Range r = tc->bindings.lastVariable(); !r.empty(); r.popFront()) {
jsid id = r.front().propid;
jsid id = r.front().propid();
if (!JSID_IS_ATOM(id))
continue;
@ -932,8 +932,11 @@ Parser::newFunction(TreeContext *tc, JSAtom *atom, FunctionSyntaxKind kind)
JSFUN_INTERPRETED | (kind == Expression ? JSFUN_LAMBDA : 0),
parent, atom);
if (fun && !tc->compileAndGo()) {
fun->clearParent();
fun->clearType();
if (!fun->clearParent(context))
return NULL;
if (!fun->clearType(context))
return NULL;
fun->setEnvironment(NULL);
}
return fun;
}
@ -1169,7 +1172,7 @@ LeaveFunction(ParseNode *fn, TreeContext *funtc, PropertyName *funName = NULL,
* we create it eagerly whenever parameters are (or might, in the case of
* calls to eval) be assigned.
*/
if (funtc->inStrictMode() && funbox->object->getFunctionPrivate()->nargs > 0) {
if (funtc->inStrictMode() && funbox->object->toFunction()->nargs > 0) {
AtomDeclsIter iter(&funtc->decls);
Definition *dn;
@ -1951,7 +1954,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
* BytecodeEmitter.cpp:EmitEnterBlock so they don't tie up unused space
* in the so-called "static" prototype Block.
*/
blockObj->setSlot(shape->slot, PrivateValue(pn));
blockObj->setSlot(shape->slot(), PrivateValue(pn));
return true;
}
@ -1965,7 +1968,7 @@ PopStatement(TreeContext *tc)
JS_ASSERT(!obj->isClonedBlock());
for (Shape::Range r = obj->lastProperty()->all(); !r.empty(); r.popFront()) {
JSAtom *atom = JSID_TO_ATOM(r.front().propid);
JSAtom *atom = JSID_TO_ATOM(r.front().propid());
/* Beware the empty destructuring dummy. */
if (atom == tc->parser->context->runtime->atomState.emptyAtom)
@ -1973,14 +1976,7 @@ PopStatement(TreeContext *tc)
tc->decls.remove(atom);
}
/*
* js_CloneBlockObject requires obj's shape to be frozen. Compare
* Bindings::makeImmutable.
*
* (This is a second pass over the shapes, if obj has a dictionary, but
* that is rare.)
*/
obj->lastProp->freezeIfDictionary();
JS_ASSERT(!obj->inDictionaryMode());
}
PopStatementTC(tc);
}
@ -2051,7 +2047,7 @@ DefineGlobal(ParseNode *pn, BytecodeEmitter *bce, PropertyName *name)
return true;
}
def = GlobalScope::GlobalDef(shape->slot);
def = GlobalScope::GlobalDef(shape->slot());
} else {
def = GlobalScope::GlobalDef(name, funbox);
}
@ -3687,7 +3683,7 @@ Parser::letStatement()
stmt->downScope = tc->topScopeStmt;
tc->topScopeStmt = stmt;
obj->setParent(tc->blockChain());
obj->setStaticBlockScopeChain(tc->blockChain());
blockbox->parent = tc->blockChainBox;
tc->blockChainBox = blockbox;
stmt->blockBox = blockbox;
@ -7156,8 +7152,10 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
return NULL;
if (!tc->compileAndGo()) {
reobj->clearParent();
reobj->clearType();
if (!reobj->clearParent(context))
return NULL;
if (!reobj->clearType(context))
return NULL;
}
pn->pn_objbox = tc->parser->newObjectBox(reobj);

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

@ -164,7 +164,6 @@ FindFunArgs(FunctionBox *funbox, int level, FunctionBoxQueue *queue)
do {
ParseNode *fn = funbox->node;
JS_ASSERT(fn->isArity(PN_FUNC));
JSFunction *fun = funbox->function();
int fnlevel = level;
/*
@ -245,12 +244,10 @@ FindFunArgs(FunctionBox *funbox, int level, FunctionBoxQueue *queue)
/*
* Finally, after we've traversed all of the current function's kids,
* minimize fun's skipmin against our accumulated skipmin. Do likewise
* with allskipmin, but minimize across funbox and all of its siblings,
* to compute our return value.
* minimize allskipmin against our accumulated skipmin. Minimize across
* funbox and all of its siblings, to compute our return value.
*/
if (skipmin != UpvarCookie::FREE_LEVEL) {
fun->u.i.skipmin = skipmin;
if (skipmin < allskipmin)
allskipmin = skipmin;
}
@ -512,46 +509,6 @@ FlagHeavyweights(Definition *dn, FunctionBox *funbox, uint32 *tcflags)
*tcflags |= TCF_FUN_HEAVYWEIGHT;
}
static void
ConsiderUnbranding(FunctionBox *funbox)
{
/*
* We've already recursively set our kids' kinds, which also classifies
* enclosing functions holding upvars referenced in those descendants'
* bodies. So now we can check our "methods".
*
* Despecialize from branded method-identity-based shape to shape- or
* slot-based shape if this function smells like a constructor and too many
* of its methods are *not* joinable null closures (i.e., they have one or
* more upvars fetched via the display).
*/
bool returnsExpr = !!(funbox->tcflags & TCF_RETURN_EXPR);
#if JS_HAS_EXPR_CLOSURES
{
ParseNode *pn2 = funbox->node->pn_body;
if (pn2->isKind(PNK_UPVARS))
pn2 = pn2->pn_tree;
if (pn2->isKind(PNK_ARGSBODY))
pn2 = pn2->last();
if (!pn2->isKind(PNK_STATEMENTLIST))
returnsExpr = true;
}
#endif
if (!returnsExpr) {
uintN methodSets = 0, slowMethodSets = 0;
for (ParseNode *method = funbox->methods; method; method = method->pn_link) {
JS_ASSERT(method->isOp(JSOP_LAMBDA) || method->isOp(JSOP_LAMBDA_FC));
++methodSets;
if (!method->pn_funbox->joinable())
++slowMethodSets;
}
if (funbox->shouldUnbrand(methodSets, slowMethodSets))
funbox->tcflags |= TCF_FUN_UNBRAND_THIS;
}
}
static void
SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
{
@ -559,10 +516,8 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
ParseNode *fn = funbox->node;
ParseNode *pn = fn->pn_body;
if (funbox->kids) {
if (funbox->kids)
SetFunctionKinds(funbox->kids, tcflags, isDirectEval);
ConsiderUnbranding(funbox);
}
JSFunction *fun = funbox->function();
@ -674,8 +629,8 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
* must have their OWN_SHAPE flags set; the comments for
* js::Bindings::extensibleParents explain why.
*/
static void
MarkExtensibleScopeDescendants(FunctionBox *funbox, bool hasExtensibleParent)
static bool
MarkExtensibleScopeDescendants(JSContext *context, FunctionBox *funbox, bool hasExtensibleParent)
{
for (; funbox; funbox = funbox->siblings) {
/*
@ -685,14 +640,20 @@ MarkExtensibleScopeDescendants(FunctionBox *funbox, bool hasExtensibleParent)
*/
JS_ASSERT(!funbox->bindings.extensibleParents());
if (hasExtensibleParent)
funbox->bindings.setExtensibleParents();
if (hasExtensibleParent) {
if (!funbox->bindings.setExtensibleParents(context))
return false;
}
if (funbox->kids) {
MarkExtensibleScopeDescendants(funbox->kids,
hasExtensibleParent || funbox->scopeIsExtensible());
if (!MarkExtensibleScopeDescendants(context, funbox->kids,
hasExtensibleParent || funbox->scopeIsExtensible())) {
return false;
}
}
}
return true;
}
bool
@ -703,7 +664,8 @@ frontend::AnalyzeFunctions(TreeContext *tc)
return true;
if (!MarkFunArgs(tc->parser->context, tc->functionList, tc->parser->functionCount))
return false;
MarkExtensibleScopeDescendants(tc->functionList, false);
if (!MarkExtensibleScopeDescendants(tc->parser->context, tc->functionList, false))
return false;
bool isDirectEval = !!tc->parser->callerFrame;
SetFunctionKinds(tc->functionList, &tc->flags, isDirectEval);
return true;

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

@ -271,7 +271,8 @@ typedef HeapPtr<JSFunction> HeapPtrFunction;
typedef HeapPtr<JSString> HeapPtrString;
typedef HeapPtr<JSScript> HeapPtrScript;
typedef HeapPtr<Shape> HeapPtrShape;
typedef HeapPtr<const Shape> HeapPtrConstShape;
typedef HeapPtr<BaseShape> HeapPtrBaseShape;
typedef HeapPtr<types::TypeObject> HeapPtrTypeObject;
typedef HeapPtr<JSXML> HeapPtrXML;
/* Useful for hashtables with a HeapPtr as key. */

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

@ -192,7 +192,6 @@ Statistics::beginGC(JSCompartment *comp, Reason reason)
Probes::GCStart(compartment);
GCCrashData crashData;
crashData.isRegen = runtime->shapeGen & SHAPE_OVERFLOW_BIT;
crashData.isCompartment = !!compartment;
crash::SaveCrashData(crash::JS_CRASH_TAG_GC, &crashData, sizeof(crashData));
}
@ -277,8 +276,7 @@ Statistics::endGC()
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
(*cb)(JS_TELEMETRY_GC_REASON, triggerReason);
(*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, compartment ? 1 : 0);
(*cb)(JS_TELEMETRY_GC_IS_SHAPE_REGEN,
runtime->shapeGen & SHAPE_OVERFLOW_BIT ? 1 : 0);
(*cb)(JS_TELEMETRY_GC_IS_SHAPE_REGEN, 0);
(*cb)(JS_TELEMETRY_GC_MS, t(PHASE_GC));
(*cb)(JS_TELEMETRY_GC_MARK_MS, t(PHASE_MARK));
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(PHASE_SWEEP));

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

@ -0,0 +1,4 @@
var o4 = Object.freeze({
set: function(summary) {}
});

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

@ -0,0 +1,7 @@
a = "".__proto__
b = uneval().__proto__
for (var i = 0; i < 2; i++) {
a.__defineSetter__("valueOf", function() {})
a + ""
delete b.valueOf
}

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

@ -0,0 +1,4 @@
for (let j = 0; j < (20); ++(__lookupSetter__)) {
function g() { j; }
j++;
}

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

@ -0,0 +1,13 @@
Function.prototype.__proto__["p"] = 3
c = [].__proto__
c[5] = 3
Namespace.prototype.__proto__[4] = function() {}
gc()
Function("\
{\
function f(d) {}\
for each(let z in[0]) {\
f(z)\
}\
}\
")()

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

@ -0,0 +1 @@
for (let x in [<y/>.(let(x) function() {})]) {}

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

@ -0,0 +1,3 @@
Object.defineProperty(Namespace.prototype, "toString", {
enumerable: true
})

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

@ -0,0 +1,12 @@
function f(s) {
eval(s);
return function() {
with({}) {};
return b;
};
}
var b = 1;
var g1 = f("");
var g2 = f("var b = 2;");
g1('');
assertEq(g2(''), 2);

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

@ -0,0 +1,11 @@
c = (0).__proto__
function f(o) {
o.__proto__ = null
for (x in o) {}
}
for (i = 0; i < 9; i++) {
f(c)
Function.prototype.__proto__.__proto__ = c
for (x in Function.prototype.__proto__) {}
f(Math.__proto__)
}

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

@ -0,0 +1,13 @@
// |jit-test| error: TypeError
function f(o) {
for (j = 0; j < 9; j++) {
if (j) {
o.__proto__ = null
}
for (v in o) {}
}
}
for (i = 0; i < 9; i++) {
(new Boolean).__proto__.__defineGetter__("toString", function() {})
f(Boolean.prototype)
}

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

@ -0,0 +1,9 @@
// Check that an onExceptionUnwind hook can force a frame to return a value early.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
dbg.onExceptionUnwind = function (frame, exc) {
return { return:"sproon" };
};
g.eval("function f() { throw 'ksnife'; }");
assertEq(g.f(), "sproon");

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

@ -0,0 +1,10 @@
// Check that if an onExceptionUnwind hook forces a constructor frame to
// return a primitive value, it still gets wrapped up in an object.
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
dbg.onExceptionUnwind = function (frame, exc) {
return { return:"sproon" };
};
g.eval("function f() { throw 'ksnife'; }");
assertEq(typeof new g.f, "object");

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

@ -0,0 +1,11 @@
// Check that an onExceptionUnwind hook can force a frame to throw a different exception.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = Debugger(g);
dbg.onExceptionUnwind = function (frame, exc) {
return { throw:"sproon" };
};
g.eval("function f() { throw 'ksnife'; }");
assertThrowsValue(g.f, "sproon");

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше