Fix document.dir getters and setters to (a) work and (b) conform to HTML5. Bug 151407, r=ehsan

This commit is contained in:
Simon Montagu 2013-04-14 05:37:48 -07:00
parent ff817875bc
commit 30a9b6835f
26 changed files with 340 additions and 78 deletions

View File

@ -6139,7 +6139,12 @@ function AddKeywordForSearchField() {
}
function SwitchDocumentDirection(aWindow) {
aWindow.document.dir = (aWindow.document.dir == "ltr" ? "rtl" : "ltr");
// document.dir can also be "auto", in which case it won't change
if (aWindow.document.dir == "ltr" || aWindow.document.dir == "") {
aWindow.document.dir = "rtl";
} else if (aWindow.document.dir == "rtl") {
aWindow.document.dir = "ltr";
}
for (var run = 0; run < aWindow.frames.length; run++)
SwitchDocumentDirection(aWindow.frames[run]);
}

View File

@ -23,7 +23,6 @@
#include "nsPIDOMWindow.h" // for use in inline functions
#include "nsPropertyTable.h" // for member
#include "nsTHashtable.h" // for member
#include "mozilla/dom/DirectionalityUtils.h"
#include "mozilla/dom/DocumentBinding.h"
class imgIRequest;
@ -523,10 +522,6 @@ public:
mSandboxFlags = sandboxFlags;
}
inline mozilla::Directionality GetDocumentDirectionality() {
return mDirectionality;
}
/**
* Access HTTP header data (this may also get set from other
* sources, like HTML META tags).
@ -641,7 +636,7 @@ protected:
public:
// Get the root <html> element, or return null if there isn't one (e.g.
// if the root isn't <html>)
Element* GetHtmlElement();
Element* GetHtmlElement() const;
// Returns the first child of GetHtmlContent which has the given tag,
// or nullptr if that doesn't exist.
Element* GetHtmlChildElement(nsIAtom* aTag);
@ -2001,7 +1996,7 @@ public:
virtual void GetTitle(nsString& aTitle) = 0;
virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv) = 0;
void GetDir(nsAString& aDirection) const;
void SetDir(const nsAString& aDirection, mozilla::ErrorResult& rv);
void SetDir(const nsAString& aDirection);
nsIDOMWindow* GetDefaultView() const
{
return GetWindow();
@ -2150,12 +2145,6 @@ protected:
return mContentType;
}
inline void
SetDocumentDirectionality(mozilla::Directionality aDir)
{
mDirectionality = aDir;
}
// All document WrapNode implementations MUST call this method. A
// false return value means an exception was thrown.
bool PostCreateWrapper(JSContext* aCx, JSObject *aNewObject);
@ -2335,9 +2324,6 @@ protected:
// are immutable - see nsSandboxFlags.h for the possible flags.
uint32_t mSandboxFlags;
// The root directionality of this document.
mozilla::Directionality mDirectionality;
nsCString mContentLanguage;
private:
nsCString mContentType;

View File

@ -600,13 +600,9 @@ RecomputeDirectionality(Element* aElement, bool aNotify)
dir = parentDir;
}
} else {
// If there is no parent element, the directionality is the same as the
// document direction.
Directionality documentDir =
aElement->OwnerDoc()->GetDocumentDirectionality();
if (documentDir != eDir_NotSet) {
dir = documentDir;
}
// If there is no parent element and no dir attribute, the directionality
// is LTR.
dir = eDir_LTR;
}
aElement->SetDirectionality(dir, aNotify);

View File

@ -94,7 +94,6 @@
#include "nsIFormControl.h"
#include "nsBidiUtils.h"
#include "mozilla/dom/DirectionalityUtils.h"
#include "nsIDOMUserDataHandler.h"
#include "nsIDOMXPathEvaluator.h"
@ -1323,7 +1322,6 @@ nsIDocument::nsIDocument()
mAllowDNSPrefetch(true),
mIsBeingUsedAsImage(false),
mHasLinksToUpdate(false),
mDirectionality(eDir_LTR),
mPartID(0)
{
SetInDocument();
@ -5782,7 +5780,7 @@ nsIDocument::GetLocation() const
}
Element*
nsIDocument::GetHtmlElement()
nsIDocument::GetHtmlElement() const
{
Element* rootElement = GetRootElement();
if (rootElement && rootElement->IsHTML(nsGkAtoms::html))
@ -6241,16 +6239,7 @@ nsDocument::GetAnimationController()
return mAnimationController;
}
struct DirTable {
const char* mName;
uint8_t mValue;
};
static const DirTable dirAttributes[] = {
{"ltr", IBMBIDI_TEXTDIRECTION_LTR},
{"rtl", IBMBIDI_TEXTDIRECTION_RTL},
{0}
};
static const char* dirAttributes[] = { "ltr", "rtl", "auto", 0 };
/**
* Retrieve the "direction" property of the document.
@ -6267,11 +6256,16 @@ nsDocument::GetDir(nsAString& aDirection)
void
nsIDocument::GetDir(nsAString& aDirection) const
{
uint32_t options = GetBidiOptions();
for (const DirTable* elt = dirAttributes; elt->mName; elt++) {
if (GET_BIDI_OPTION_DIRECTION(options) == elt->mValue) {
CopyASCIItoUTF16(elt->mName, aDirection);
return;
aDirection.Truncate();
Element* rootElement = GetHtmlElement();
if (rootElement) {
nsAutoString dir;
rootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::dir, dir);
for (uint32_t i = 0; dirAttributes[i]; ++i) {
if (dir.LowerCaseEqualsASCII(dirAttributes[i])) {
aDirection.AssignASCII(dirAttributes[i]);
return;
}
}
}
}
@ -6284,45 +6278,17 @@ nsIDocument::GetDir(nsAString& aDirection) const
NS_IMETHODIMP
nsDocument::SetDir(const nsAString& aDirection)
{
ErrorResult rv;
nsIDocument::SetDir(aDirection, rv);
return rv.ErrorCode();
nsIDocument::SetDir(aDirection);
return NS_OK;
}
void
nsIDocument::SetDir(const nsAString& aDirection, ErrorResult& rv)
nsIDocument::SetDir(const nsAString& aDirection)
{
uint32_t options = GetBidiOptions();
for (const DirTable* elt = dirAttributes; elt->mName; elt++) {
if (aDirection == NS_ConvertASCIItoUTF16(elt->mName)) {
if (GET_BIDI_OPTION_DIRECTION(options) != elt->mValue) {
SET_BIDI_OPTION_DIRECTION(options, elt->mValue);
nsIPresShell *shell = GetShell();
if (shell) {
nsPresContext *context = shell->GetPresContext();
if (!context) {
rv.Throw(NS_ERROR_UNEXPECTED);
return;
}
context->SetBidi(options, true);
} else {
// No presentation; just set it on ourselves
SetBidiOptions(options);
}
Directionality dir = elt->mValue == IBMBIDI_TEXTDIRECTION_RTL ?
eDir_RTL : eDir_LTR;
SetDocumentDirectionality(dir);
// Set the directionality of the root element and its descendants, if any
Element* rootElement = GetRootElement();
if (rootElement) {
rootElement->SetDirectionality(dir, true);
SetDirectionalityOnDescendants(rootElement, dir);
}
}
break;
}
Element* rootElement = GetHtmlElement();
if (rootElement) {
rootElement->SetAttr(kNameSpaceID_None, nsGkAtoms::dir,
aDirection, true);
}
}

View File

@ -100,7 +100,6 @@ partial interface Document {
//(Not proxy yet)getter object (DOMString name);
[SetterThrows]
attribute DOMString title;
[SetterThrows]
attribute DOMString dir;
//(HTML only) attribute HTMLElement? body;
//(HTML only)readonly attribute HTMLHeadElement? head;

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for elements</title>
</head>
<body>
<div dir="">dir="", getDir returns ""</div>
<div dir="ltr">dir="ltr", getDir returns "ltr"</div>
<div dir="rtl">dir="rtl", getDir returns "rtl"</div>
<div dir="auto">dir="auto", getDir returns "auto"</div>
<div dir="foopy">dir="foopy", getDir returns ""</div>
<div>no dir attribute, getDir returns ""</div>
</body>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for elements</title>
<script type="text/javascript">
function fill() {
for (var i = 0; ; ++i) {
div = document.getElementById("div" + i);
if (!div) break;
span = document.getElementById("span" + i);
span.innerHTML = div.dir;
}
}
</script>
</head>
<body onLoad="fill()">
<div id="div0" dir="">dir="", getDir returns "<span id="span0"></span>"</div>
<div id="div1" dir="ltr">dir="ltr", getDir returns "<span id="span1"></span>"</div>
<div id="div2" dir="rtl">dir="rtl", getDir returns "<span id="span2"></span>"</div>
<div id="div3" dir="auto">dir="auto", getDir returns "<span id="span3"></span>"</div>
<div id="div4" dir="foopy">dir="foopy", getDir returns "<span id="span4"></span>"</div>
<div id="div5">no dir attribute, getDir returns "<span id="span5"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for elements</title>
<script type="text/javascript">
function fill() {
div0.dir = "";
div1.dir = "ltr";
div2.dir = "rtl";
div3.dir = "auto";
div4.dir = "foopy";
for (var i = 0; ; ++i) {
div = document.getElementById("div" + i);
if (!div) break;
span = document.getElementById("span" + i);
span.innerHTML = div.dir;
}
}
</script>
</head>
<body onLoad="fill()">
<div id="div0">dir="", getDir returns "<span id="span0"></span>"</div>
<div id="div1">dir="ltr", getDir returns "<span id="span1"></span>"</div>
<div id="div2">dir="rtl", getDir returns "<span id="span2"></span>"</div>
<div id="div3">dir="auto", getDir returns "<span id="span3"></span>"</div>
<div id="div4">dir="foopy", getDir returns "<span id="span4"></span>"</div>
<div id="div5">no dir attribute, getDir returns "<span id="span5"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html dir="auto">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
</head>
<body>
<div>getDir on document returns "auto"</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html dir="auto">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
<script type="text/javascript">
function fill() {
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
</head>
<body>
<div>getDir on document returns ""</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
<script type="text/javascript">
function fill() {
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html dir="foopy">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
<script type="text/javascript">
function fill() {
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
</head>
<body>
<div>getDir on document returns "ltr"</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
<script type="text/javascript">
function fill() {
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
</head>
<body>
<div>getDir on document returns "rtl"</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test GetDir() for documents</title>
<script type="text/javascript">
function fill() {
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
</head>
<body>
<div>getDir on document after setDir returns "auto"</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
<script type="text/javascript">
function fill() {
document.dir = "auto"
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document after setDir returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
</head>
<body>
<div>getDir on document after setDir returns ""</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
<script type="text/javascript">
function fill() {
document.dir = "foopy"
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document after setDir returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
</head>
<body>
<div>getDir on document after setDir returns "ltr"</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
<script type="text/javascript">
function fill() {
document.dir = "ltr"
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document after setDir returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html dir="rtl">
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
</head>
<body>
<div>getDir on document after setDir returns "rtl"</div>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="utf-8">
<title>Test SetDir() for documents</title>
<script type="text/javascript">
function fill() {
document.dir = "rtl"
span = document.getElementById("span0");
span.innerHTML = document.dir;
}
</script>
</head>
<body onLoad="fill()">
<div>getDir on document after setDir returns "<span id="span0"></span>"</div>
</body>
</html>

View File

@ -54,6 +54,17 @@ fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azur
fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,111,7) == 83958-2c.html 83958-2-ref.html
== 115921-1.html 115921-1-ref.html
== 115921-2.html 115921-2-ref.html
== 151407-1.html 151407-1-ref.html
== 151407-1a.html 151407-1-ref.html
== 151407-2-ltr.html 151407-2-ltr-ref.html
== 151407-2-rtl.html 151407-2-rtl-ref.html
== 151407-2-auto.html 151407-2-auto-ref.html
== 151407-2-empty.html 151407-2-empty-ref.html
== 151407-2-foopy.html 151407-2-empty-ref.html
== 151407-3-ltr.html 151407-3-ltr-ref.html
== 151407-3-rtl.html 151407-3-rtl-ref.html
== 151407-3-auto.html 151407-3-auto-ref.html
== 151407-3-foopy.html 151407-3-empty-ref.html
== 229367-1.html 229367-1-ref.html
== 229367-2.html 229367-2-ref.html
== 229367-3.html 229367-3-ref.html