merge mozilla-central to devtools

This commit is contained in:
Rob Campbell 2011-03-29 09:53:45 -03:00
Родитель c6f80bc19d 948f195dc1
Коммит 754165375c
191 изменённых файлов: 5601 добавлений и 12819 удалений

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

@ -1272,6 +1272,27 @@ nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
g_signal_emit(atkObj, id, 0);
} break;
case nsIAccessibleEvent::EVENT_WINDOW_MAXIMIZE:
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_MAXIMIZE\n"));
guint id = g_signal_lookup ("maximize", MAI_TYPE_ATK_OBJECT);
g_signal_emit(atkObj, id, 0);
} break;
case nsIAccessibleEvent::EVENT_WINDOW_MINIMIZE:
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_MINIMIZE\n"));
guint id = g_signal_lookup ("minimize", MAI_TYPE_ATK_OBJECT);
g_signal_emit(atkObj, id, 0);
} break;
case nsIAccessibleEvent::EVENT_WINDOW_RESTORE:
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_RESTORE\n"));
guint id = g_signal_lookup ("restore", MAI_TYPE_ATK_OBJECT);
g_signal_emit(atkObj, id, 0);
} break;
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
{
MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));

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

@ -218,6 +218,24 @@ mai_util_get_type(void)
return type;
}
static void
window_added (AtkObject *atk_obj,
guint index,
AtkObject *child)
{
guint id = g_signal_lookup ("create", MAI_TYPE_ATK_OBJECT);
g_signal_emit (child, id, 0);
}
static void
window_removed (AtkObject *atk_obj,
guint index,
AtkObject *child)
{
guint id = g_signal_lookup ("destroy", MAI_TYPE_ATK_OBJECT);
g_signal_emit (child, id, 0);
}
/* intialize the the atk interface (function pointers) with MAI implementation.
* When atk bridge get loaded, these interface can be used.
*/
@ -248,6 +266,10 @@ mai_util_class_init(MaiUtilClass *klass)
listener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
_listener_info_destroy);
// Keep track of added/removed windows.
AtkObject *root = atk_get_root ();
g_signal_connect (root, "children-changed::add", (GCallback) window_added, NULL);
g_signal_connect (root, "children-changed::remove", (GCallback) window_removed, NULL);
}
static guint

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

@ -304,10 +304,10 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
if (accEvent->mEventRule != AccEvent::eDoNotEmit) {
mDocument->ProcessPendingEvent(accEvent);
AccMutationEvent* showOrhideEvent = downcast_accEvent(accEvent);
if (showOrhideEvent) {
if (showOrhideEvent->mTextChangeEvent)
mDocument->ProcessPendingEvent(showOrhideEvent->mTextChangeEvent);
AccMutationEvent* showOrHideEvent = downcast_accEvent(accEvent);
if (showOrHideEvent) {
if (showOrHideEvent->mTextChangeEvent)
mDocument->ProcessPendingEvent(showOrHideEvent->mTextChangeEvent);
}
}
if (!mDocument)

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

@ -70,7 +70,10 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
PRUint32 aSkipStart)
{
nsAccessible* parent = mTextLeaf->GetParent();
NS_ASSERTION(parent, "No parent for text leaf!");
if (!parent) {
NS_ERROR("No parent for text leaf!");
return;
}
mHyperText = parent->AsHyperText();
if (!mHyperText) {

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

@ -537,6 +537,22 @@ nsAccessibilityService::UpdateText(nsIPresShell* aPresShell,
document->UpdateText(aContent);
}
void
nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
nsIContent* aHTMLListItemContent,
bool aHasBullet)
{
nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
if (document) {
nsAccessible* accessible = document->GetAccessible(aHTMLListItemContent);
if (accessible) {
nsHTMLLIAccessible* listItem = accessible->AsHTMLListItem();
if (listItem)
listItem->UpdateBullet(aHasBullet);
}
}
}
void
nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
{

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

@ -120,6 +120,13 @@ public:
virtual void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent);
/**
* Update list bullet accessible.
*/
virtual void UpdateListBullet(nsIPresShell* aPresShell,
nsIContent* aHTMLListItemContent,
bool aHasBullet);
virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget);
virtual void PresShellDestroyed(nsIPresShell* aPresShell);

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

@ -3228,15 +3228,37 @@ nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
nsAccessible *
nsAccessible::GetFirstAvailableAccessible(nsINode *aStartNode) const
{
nsAccessible *accessible =
nsAccessible* accessible =
GetAccService()->GetAccessibleInWeakShell(aStartNode, mWeakShell);
if (accessible)
return accessible;
nsIContent *content = nsCoreUtils::GetRoleContent(aStartNode);
nsAccTreeWalker walker(mWeakShell, content, PR_FALSE);
nsRefPtr<nsAccessible> childAccessible = walker.GetNextChild();
return childAccessible;
nsCOMPtr<nsIDOMDocumentTraversal> trav =
do_QueryInterface(aStartNode->GetOwnerDoc());
NS_ENSURE_TRUE(trav, nsnull);
nsCOMPtr<nsIDOMNode> currentNode = do_QueryInterface(aStartNode);
nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(GetNode()));
nsCOMPtr<nsIDOMTreeWalker> walker;
trav->CreateTreeWalker(rootNode,
nsIDOMNodeFilter::SHOW_ELEMENT | nsIDOMNodeFilter::SHOW_TEXT,
nsnull, PR_FALSE, getter_AddRefs(walker));
NS_ENSURE_TRUE(walker, nsnull);
walker->SetCurrentNode(currentNode);
while (true) {
walker->NextNode(getter_AddRefs(currentNode));
if (!currentNode)
return nsnull;
nsCOMPtr<nsINode> node(do_QueryInterface(currentNode));
nsAccessible* accessible =
GetAccService()->GetAccessibleInWeakShell(node, mWeakShell);
if (accessible)
return accessible;
}
return nsnull;
}
PRBool nsAccessible::CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView)

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

@ -58,6 +58,7 @@ class AccGroupInfo;
class EmbeddedObjCollector;
class nsAccessible;
class nsHyperTextAccessible;
class nsHTMLLIAccessible;
struct nsRoleMapEntry;
class nsTextAccessible;
@ -364,6 +365,9 @@ public:
inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
nsHyperTextAccessible* AsHyperText();
inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
nsHTMLLIAccessible* AsHTMLListItem();
inline bool IsRoot() const { return mFlags & eRootAccessible; }
nsRootAccessible* AsRoot();
@ -512,8 +516,9 @@ protected:
enum AccessibleTypes {
eApplicationAccessible = 1 << 2,
eHyperTextAccessible = 1 << 3,
eRootAccessible = 1 << 4,
eTextLeafAccessible = 1 << 5
eHTMLListItemAccessible = 1 << 4,
eRootAccessible = 1 << 5,
eTextLeafAccessible = 1 << 6
};
//////////////////////////////////////////////////////////////////////////////

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

@ -650,6 +650,11 @@ nsDocAccessible::Shutdown()
RemoveEventListeners();
// Mark the document as shutdown before AT is notified about the document
// removal from its container (valid for root documents on ATK).
nsCOMPtr<nsIDocument> kungFuDeathGripDoc = mDocument;
mDocument = nsnull;
if (mParent) {
nsDocAccessible* parentDocument = mParent->GetDocAccessible();
if (parentDocument)
@ -672,9 +677,6 @@ nsDocAccessible::Shutdown()
mNodeToAccessibleMap.Clear();
ClearCache(mAccessibleCache);
nsCOMPtr<nsIDocument> kungFuDeathGripDoc = mDocument;
mDocument = nsnull;
nsHyperTextAccessibleWrap::Shutdown();
GetAccService()->NotifyOfDocumentShutdown(kungFuDeathGripDoc);
@ -1472,7 +1474,10 @@ nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible)
// Make sure we keep children updated. While we're inside of caching
// loop then we must exist it with cached children.
nsAccessible* container = GetContainerAccessible(content);
container->UpdateChildren();
NS_ASSERTION(container,
"Got a referenced element that is not in document!");
if (container)
container->UpdateChildren();
}
}
mInvalidationList.Clear();
@ -1950,8 +1955,9 @@ nsDocAccessible::CacheChildrenInSubtree(nsAccessible* aRoot)
PRUint32 count = aRoot->GetChildCount();
for (PRUint32 idx = 0; idx < count; idx++) {
nsAccessible* child = aRoot->GetChildAt(idx);
NS_ASSERTION(child, "Illicit tree change while tree is created!");
// Don't cross document boundaries.
if (child->IsContent())
if (child && child->IsContent())
CacheChildrenInSubtree(child);
}
}

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

@ -254,12 +254,15 @@ nsHTMLOutputAccessible::GetAttributesInternal(nsIPersistentProperties* aAttribut
nsHTMLLIAccessible::
nsHTMLLIAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
nsHyperTextAccessibleWrap(aContent, aShell)
nsHyperTextAccessibleWrap(aContent, aShell), mBullet(nsnull)
{
mFlags |= eHTMLListItemAccessible;
nsBlockFrame* blockFrame = do_QueryFrame(GetFrame());
if (blockFrame && !blockFrame->BulletIsEmptyExternal()) {
mBulletAccessible = new nsHTMLListBulletAccessible(mContent, mWeakShell);
GetDocAccessible()->BindToDocument(mBulletAccessible, nsnull);
if (blockFrame && blockFrame->HasBullet()) {
mBullet = new nsHTMLListBulletAccessible(mContent, mWeakShell);
if (!GetDocAccessible()->BindToDocument(mBullet, nsnull))
mBullet = nsnull;
}
}
@ -268,13 +271,9 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLIAccessible, nsHyperTextAccessible)
void
nsHTMLLIAccessible::Shutdown()
{
if (mBulletAccessible) {
// Ensure that pointer to this is nulled out.
mBulletAccessible->Shutdown();
}
mBullet = nsnull;
nsHyperTextAccessibleWrap::Shutdown();
mBulletAccessible = nsnull;
}
PRUint32
@ -297,12 +296,11 @@ nsHTMLLIAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
{
nsresult rv = nsAccessibleWrap::GetBounds(x, y, width, height);
if (NS_FAILED(rv) || !mBulletAccessible) {
if (NS_FAILED(rv) || !mBullet)
return rv;
}
PRInt32 bulletX, bulletY, bulletWidth, bulletHeight;
rv = mBulletAccessible->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
NS_ENSURE_SUCCESS(rv, rv);
*x = bulletX; // Move x coordinate of list item over to cover bullet as well
@ -310,14 +308,41 @@ NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *wid
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLLIAccessible: public
void
nsHTMLLIAccessible::UpdateBullet(bool aHasBullet)
{
if (aHasBullet == !!mBullet) {
NS_NOTREACHED("Bullet and accessible are in sync already!");
return;
}
nsDocAccessible* document = GetDocAccessible();
if (aHasBullet) {
mBullet = new nsHTMLListBulletAccessible(mContent, mWeakShell);
if (document->BindToDocument(mBullet, nsnull)) {
InsertChildAt(0, mBullet);
}
} else {
RemoveChild(mBullet);
document->UnbindFromDocument(mBullet);
mBullet = nsnull;
}
// XXXtodo: fire show/hide and reorder events. That's hard to make it
// right now because coalescence happens by DOM node.
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLLIAccessible: nsAccessible protected
void
nsHTMLLIAccessible::CacheChildren()
{
if (mBulletAccessible)
AppendChild(mBulletAccessible);
if (mBullet)
AppendChild(mBullet);
// Cache children from subtree.
nsAccessibleWrap::CacheChildren();
@ -331,19 +356,11 @@ nsHTMLListBulletAccessible::
nsHTMLListBulletAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
nsLeafAccessible(aContent, aShell)
{
mBulletText += ' '; // Otherwise bullets are jammed up against list text
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLListBulletAccessible: nsAccessNode
void
nsHTMLListBulletAccessible::Shutdown()
{
mBulletText.Truncate();
nsLeafAccessible::Shutdown();
}
bool
nsHTMLListBulletAccessible::IsPrimaryForNode() const
{
@ -363,6 +380,7 @@ nsHTMLListBulletAccessible::GetName(nsAString &aName)
// Native anonymous content, ARIA can't be used. Get list bullet text.
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
NS_ASSERTION(blockFrame, "No frame for list item!");
if (blockFrame) {
blockFrame->GetBulletText(aName);
@ -394,17 +412,13 @@ void
nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength)
{
nsAutoString bulletText;
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
if (blockFrame) {
nsAutoString bulletText;
NS_ASSERTION(blockFrame, "No frame for list item!");
if (blockFrame)
blockFrame->GetBulletText(bulletText);
PRUint32 maxLength = bulletText.Length() - aStartOffset;
if (aLength > maxLength)
aLength = maxLength;
aText += Substring(bulletText, aStartOffset, aLength);
}
aText.Append(Substring(bulletText, aStartOffset, aLength));
}
////////////////////////////////////////////////////////////////////////////////

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

@ -136,7 +136,6 @@ public:
NS_IMETHOD GetName(nsAString& aName);
// nsAccessNode
virtual void Shutdown();
virtual bool IsPrimaryForNode() const;
// nsAccessible
@ -144,15 +143,6 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
PRUint32 aLength = PR_UINT32_MAX);
protected:
// XXX: Ideally we'd get the bullet text directly from the bullet frame via
// nsBulletFrame::GetListItemText(), but we'd need an interface for getting
// text from contentless anonymous frames. Perhaps something like
// nsIAnonymousFrame::GetText() ? However, in practice storing the bullet text
// here should not be a problem if we invalidate the right parts of
// the accessibility cache when mutation events occur.
nsString mBulletText;
};
/**
@ -182,22 +172,32 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
// nsAccessNode
virtual void Shutdown();
// nsIAccessible
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
// nsAccessible
virtual PRUint32 NativeRole();
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// nsHTMLLIAccessible
void UpdateBullet(bool aHasBullet);
protected:
// nsAccessible
virtual void CacheChildren();
private:
nsRefPtr<nsHTMLListBulletAccessible> mBulletAccessible;
nsRefPtr<nsHTMLListBulletAccessible> mBullet;
};
#endif
inline nsHTMLLIAccessible*
nsAccessible::AsHTMLListItem()
{
return mFlags & eHTMLListItemAccessible ?
static_cast<nsHTMLLIAccessible*>(this) : nsnull;
}
#endif

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

@ -308,7 +308,7 @@ STDMETHODIMP nsAccessNodeWrap::get_attributesForNames(
/* [length_is][size_is][retval] */ BSTR __RPC_FAR *aAttribValues)
{
__try {
if (IsDefunct() || IsDocument())
if (IsDefunct() || !IsElement())
return E_FAIL;
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mContent));
@ -616,12 +616,7 @@ void nsAccessNodeWrap::InitAccessibility()
DoATSpecificProcessing();
// Register window class that'll be used for document accessibles associated
// with tabs.
if (nsWinUtils::IsWindowEmulationEnabled()) {
nsWinUtils::RegisterNativeWindow(kClassNameTabContent);
sHWNDCache.Init(4);
}
nsWinUtils::MaybeStartWindowEmulation();
nsAccessNode::InitXPAccessibility();
}
@ -631,10 +626,7 @@ void nsAccessNodeWrap::ShutdownAccessibility()
NS_IF_RELEASE(gTextEvent);
::DestroyCaret();
// Unregister window call that's used for document accessibles associated
// with tabs.
if (nsWinUtils::IsWindowEmulationEnabled())
::UnregisterClassW(kClassNameTabContent, GetModuleHandle(NULL));
nsWinUtils::ShutdownWindowEmulation();
nsAccessNode::ShutdownXPAccessibility();
}

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

@ -203,7 +203,7 @@ __try {
// Return window system accessible object for root document and tab document
// accessibles.
if (!doc->ParentDocument() ||
nsWinUtils::IsWindowEmulationEnabled() &&
nsWinUtils::IsWindowEmulationStarted() &&
nsWinUtils::IsTabDocument(doc->GetDocumentNode())) {
HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,

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

@ -255,10 +255,11 @@ STDMETHODIMP nsDocAccessibleWrap::get_accValue(
void
nsDocAccessibleWrap::Shutdown()
{
if (nsWinUtils::IsWindowEmulationEnabled()) {
// Do window emulation specific shutdown if emulation was started.
if (nsWinUtils::IsWindowEmulationStarted()) {
// Destroy window created for root document.
if (nsWinUtils::IsTabDocument(mDocument)) {
nsAccessibleWrap::sHWNDCache.Remove(mHWND);
sHWNDCache.Remove(mHWND);
::DestroyWindow(static_cast<HWND>(mHWND));
}
@ -285,14 +286,14 @@ nsDocAccessibleWrap::NotifyOfInitialUpdate()
{
nsDocAccessible::NotifyOfInitialUpdate();
if (nsWinUtils::IsWindowEmulationEnabled()) {
if (nsWinUtils::IsWindowEmulationStarted()) {
// Create window for tab document.
if (nsWinUtils::IsTabDocument(mDocument)) {
nsRootAccessible* rootDocument = RootAccessible();
PRBool isActive = PR_TRUE;
PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
if (nsWinUtils::IsWindowEmulationEnabled(kDolphinModuleHandle)) {
if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle)) {
GetBounds(&x, &y, &width, &height);
PRInt32 rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0;
rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight);
@ -308,7 +309,7 @@ nsDocAccessibleWrap::NotifyOfInitialUpdate()
mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
x, y, width, height, isActive);
nsAccessibleWrap::sHWNDCache.Put(mHWND, this);
sHWNDCache.Put(mHWND, this);
} else {
nsDocAccessible* parentDocument = ParentDocument();

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

@ -63,7 +63,7 @@ nsRootAccessibleWrap::~nsRootAccessibleWrap()
void
nsRootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
{
if (nsWinUtils::IsWindowEmulationEnabled(kDolphinModuleHandle) &&
if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle) &&
nsWinUtils::IsTabDocument(aDocument->GetDocumentNode())) {
PRUint32 count = mChildDocuments.Length();
for (PRUint32 idx = 0; idx < count; idx++) {

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

@ -99,6 +99,34 @@ nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
return S_OK;
}
bool
nsWinUtils::MaybeStartWindowEmulation()
{
// Register window class that'll be used for document accessibles associated
// with tabs.
if (IsWindowEmulationFor(0)) {
RegisterNativeWindow(kClassNameTabContent);
nsAccessNodeWrap::sHWNDCache.Init(4);
return true;
}
return false;
}
void
nsWinUtils::ShutdownWindowEmulation()
{
// Unregister window call that's used for document accessibles associated
// with tabs.
if (IsWindowEmulationFor(0))
::UnregisterClassW(kClassNameTabContent, GetModuleHandle(NULL));
}
bool
nsWinUtils::IsWindowEmulationStarted()
{
return nsAccessNodeWrap::sHWNDCache.IsInitialized();
}
void
nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass)
{
@ -146,7 +174,7 @@ nsWinUtils::HideNativeWindow(HWND aWnd)
}
bool
nsWinUtils::IsWindowEmulationEnabled(LPCWSTR kModuleHandle)
nsWinUtils::IsWindowEmulationFor(LPCWSTR kModuleHandle)
{
return kModuleHandle ? ::GetModuleHandleW(kModuleHandle) :
::GetModuleHandleW(kJAWSModuleHandle) ||

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

@ -63,6 +63,21 @@ public:
static HRESULT ConvertToIA2Array(nsIArray *aCollection,
IUnknown ***aAccessibles, long *aCount);
/**
* Start window emulation if presence of specific AT is detected.
*/
static bool MaybeStartWindowEmulation();
/**
* Free resources used for window emulation.
*/
static void ShutdownWindowEmulation();
/**
* Return true if window emulation is started.
*/
static bool IsWindowEmulationStarted();
/**
* Helper to register window class.
*/
@ -88,7 +103,7 @@ public:
/**
* Return true if window emulation is enabled.
*/
static bool IsWindowEmulationEnabled(LPCWSTR kModuleHandle = 0);
static bool IsWindowEmulationFor(LPCWSTR kModuleHandle);
/**
* Return true if the given document node is for tab document accessible.

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

@ -64,6 +64,10 @@ const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
const kEmbedChar = String.fromCharCode(0xfffc);
const kDiscBulletText = String.fromCharCode(0x2022) + " ";
const kCircleBulletText = String.fromCharCode(0x25e6) + " ";
const kSquareBulletText = String.fromCharCode(0x25aa) + " ";
/**
* nsIAccessibleRetrieval, initialized when test is loaded.
*/

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

@ -54,6 +54,7 @@ _TEST_FILES =\
test_general.html \
test_general.xul \
test_link.html \
test_list.html \
test_markup.html \
test_nsRootAcc.xul \
markuprules.xml \

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

@ -0,0 +1,91 @@
<html>
<head>
<title>nsIAccessible::name calculation for HTML li</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../name.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
/**
* Alter list item numbering and change list style type.
*/
function bulletUpdate()
{
this.eventSeq = [
new invokerChecker(EVENT_REORDER, getNode("list"))
];
this.invoke = function bulletUpdate_invoke()
{
testName("li_end", "1. list end");
var li = document.createElement("li");
li.setAttribute("id", "li_start");
li.textContent = "list start";
getNode("list").insertBefore(li, getNode("li_end"));
}
this.finalCheck = function bulletUpdate_finalCheck()
{
testName("li_start", "1. list start");
testName("li_end", "2. list end");
// change list style type
var list = getNode("list");
list.setAttribute("style", "list-style-type: disc;");
getComputedStyle(list, "").color; // make style processing sync
testName("li_start", kDiscBulletText + "list start");
testName("li_end", kDiscBulletText + "list end");
}
this.getID = function bulletUpdate_getID()
{
return "Update bullet of list items";
}
}
var gQueue = null;
function doTest()
{
gQueue = new eventQueue();
gQueue.push(new bulletUpdate());
gQueue.invoke(); // SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=634200"
title="crash [@ nsIFrame::GetStyleVisibility() ]">
Mozilla Bug 634200
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<ol id="list">
<li id="li_end">list end</li>
</ol>
</body>
</html>

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

@ -5,6 +5,12 @@
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
h6.gencontent:before {
content: "aga"
}
</style>
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
@ -40,6 +46,16 @@
testText(IDs, 10, 13, "e " + kEmbedChar);
testText(IDs, 0, 13, "hello " + kEmbedChar + " see " + kEmbedChar);
////////////////////////////////////////////////////////////////////////
// getTextAtOffset line boundary
testTextAtOffset(0, BOUNDARY_LINE_START, "line ", 0, 5,
"hypertext3", kOk, kOk, kOk);
// XXX: see bug 638684.
testTextAtOffset(0, BOUNDARY_LINE_START, "line ", 0, 5,
"hypertext4", kTodo, kOk, kTodo);
//////////////////////////////////////////////////////////////////////////
// list
//////////////////////////////////////////////////////////////////////////
@ -63,7 +79,14 @@
<a target="_blank"
title="Fix getText"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630001">Mozilla Bug 630001, part3</a>
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630001">
Bug 630001, part3
</a>
<a target="_blank"
title="getTextAtOffset line boundary may return more than one line"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=638326">
Bug 638326
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -73,5 +96,17 @@
<div id="hypertext2">hello <a>friend</a> see <input></div>
<ol id="list"><li id="listitem">foo</li></ol>
<div id="hypertext3">line
<!-- haha -->
<!-- hahaha -->
<h6>heading</h6>
</div>
<div id="hypertext4">line
<!-- haha -->
<!-- hahaha -->
<h6 role="presentation" class="gencontent">heading</h6>
</div>
</body>
</html>

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

@ -40,17 +40,13 @@
function doTest()
{
const discBulletText = String.fromCharCode(0x2022) + " ";
const circleBulletText = String.fromCharCode(0x25e6) + " ";
const squareBulletText = String.fromCharCode(0x25aa) + " ";
// list1
var discAccTree = {
role: ROLE_LIST,
children: [
new listItemTree(discBulletText, "Oranges"),
new listItemTree(discBulletText, "Apples"),
new listItemTree(discBulletText, "Bananas")
new listItemTree(kDiscBulletText, "Oranges"),
new listItemTree(kDiscBulletText, "Apples"),
new listItemTree(kDiscBulletText, "Bananas")
]
};
@ -60,9 +56,9 @@
var circleAccTree = {
role: ROLE_LIST,
children: [
new listItemTree(circleBulletText, "Oranges"),
new listItemTree(circleBulletText, "Apples"),
new listItemTree(circleBulletText, "Bananas")
new listItemTree(kCircleBulletText, "Oranges"),
new listItemTree(kCircleBulletText, "Apples"),
new listItemTree(kCircleBulletText, "Bananas")
]
};
@ -72,9 +68,9 @@
var squareAccTree = {
role: ROLE_LIST,
children: [
new listItemTree(squareBulletText, "Oranges"),
new listItemTree(squareBulletText, "Apples"),
new listItemTree(squareBulletText, "Bananas")
new listItemTree(kSquareBulletText, "Oranges"),
new listItemTree(kSquareBulletText, "Apples"),
new listItemTree(kSquareBulletText, "Bananas")
]
};
@ -92,6 +88,43 @@
testAccessibleTree("list4", nestedAccTree);
// dl list
var tree =
{ LIST: [ // dl
{ LISTITEM: [ // dt
{ TEXT_LEAF: [] },
] },
{ PARAGRAPH: [ // dd
{ TEXT_LEAF: [] }
] },
{ LISTITEM: [ // dt
{ TEXT_LEAF: [] }
] },
{ PARAGRAPH: [ // dd
{ TEXT_LEAF: [] }
] }
] };
testAccessibleTree("list5", tree);
// dl list inside ordered list
tree =
{ LIST: [ // ol
{ LISTITEM: [ // li
{ STATICTEXT: [ ] },
{ LIST: [ // dl
{ LISTITEM: [ // dt
{ TEXT_LEAF: [] }
] },
{ PARAGRAPH: [ // dd
{ TEXT_LEAF: [] }
] }
] }
] }
] };
testAccessibleTree("list6", tree);
SimpleTest.finish();
}
@ -111,6 +144,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=604587">
Mozilla Bug 604587
</a>
<a target="_blank"
title="Fix list bullets for DL list (crash [@ nsBulletFrame::GetListItemText])"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=629114">
Mozilla Bug 629114
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -144,5 +182,18 @@
</ul>
</li>
</ol>
<dl id="list5">
<dt>item1</dt><dd>description</dd>
<dt>item2</td><dd>description</dd>
</dl>
<ol id="list6">
<li>
<dl id="dl">
<dt>item1</dt><dd>description</dd>
</dl>
</li>
</ol>
</body>
</html>

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

@ -48,8 +48,6 @@
#endif
#endif
pref("general.startup.browser", true);
pref("browser.chromeURL","chrome://browser/content/");
pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
@ -536,11 +534,6 @@ pref("mousewheel.withcontrolkey.action",3);
pref("mousewheel.withcontrolkey.sysnumlines",false);
pref("mousewheel.withcontrolkey.numlines",1);
pref("profile.allow_automigration", false); // setting to false bypasses automigration in the profile code
// Customizable toolbar stuff
pref("custtoolbar.personal_toolbar_folder", "");
// pref to control the alert notification
pref("alerts.slideIncrement", 1);
pref("alerts.slideIncrementTime", 10);

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

@ -5068,23 +5068,19 @@ var TabsInTitlebar = {
let titlebar = $("titlebar");
if (allowed) {
let availTop = screen.availTop;
function top(ele) ele.boxObject.screenY - availTop;
function bottom(ele) top(ele) + rect(ele).height;
function rect(ele) ele.getBoundingClientRect();
let tabsToolbar = $("TabsToolbar");
let appmenuButtonBox = $("appmenu-button-container");
let captionButtonsBox = $("titlebar-buttonbox");
this._sizePlaceholder("appmenu-button", rect(appmenuButtonBox).width);
this._sizePlaceholder("caption-buttons", rect(captionButtonsBox).width);
let maxMargin = top(gNavToolbox);
let tabsBottom = maxMargin + rect(tabsToolbar).height;
let titlebarBottom = Math.max(bottom(appmenuButtonBox), bottom(captionButtonsBox));
let distance = tabsBottom - titlebarBottom;
titlebar.style.marginBottom = - Math.min(distance, maxMargin) + "px";
let tabsToolbarRect = rect(tabsToolbar);
let titlebarTop = rect($("titlebar-content")).top;
titlebar.style.marginBottom = - Math.min(tabsToolbarRect.top - titlebarTop,
tabsToolbarRect.height) + "px";
docElement.setAttribute("tabsintitlebar", "true");

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

@ -84,6 +84,7 @@ function GroupItem(listOfEls, options) {
this.fadeAwayUndoButtonDuration = 300;
this.keepProportional = false;
this._frozenItemSizeData = {};
// Double click tracker
this._lastClick = 0;
@ -194,6 +195,7 @@ function GroupItem(listOfEls, options) {
gTabView.firstUseExperienced = true;
})
.focus(function() {
self._unfreezeItemSize();
if (!self._titleFocused) {
(self.$title)[0].select();
self._titleFocused = true;
@ -644,6 +646,9 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.removeAll({dontClose: true});
GroupItems.unregister(this);
// remove unfreeze event handlers, if item size is frozen
this._unfreezeItemSize({dontArrange: true});
let self = this;
let destroyGroup = function () {
iQ(self.container).remove();
@ -677,6 +682,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Closes the groupItem and all of its children.
closeAll: function GroupItem_closeAll() {
if (this._children.length > 0) {
this._unfreezeItemSize();
this._children.forEach(function(child) {
iQ(child.container).hide();
});
@ -878,8 +884,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.$undoContainer = iQ("<div/>")
.addClass("undo")
.attr("type", "button")
.text(tabviewString("groupItem.undoCloseGroup"))
.appendTo("body");
iQ("<span/>")
.text(tabviewString("groupItem.undoCloseGroup"))
.appendTo(this.$undoContainer);
let undoClose = iQ("<span/>")
.addClass("close")
.appendTo(this.$undoContainer);
@ -1007,8 +1015,13 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
item.groupItemData = {};
item.addSubscriber(this, "close", function() {
let count = self._children.length;
let dontArrange = self.expanded || !self.shouldStack(count);
let dontClose = !item.closedManually && gBrowser._numPinnedTabs > 0;
self.remove(item, { dontClose: dontClose });
self.remove(item, {dontArrange: dontArrange, dontClose: dontClose});
if (dontArrange)
self._freezeItemSize(count);
if (self._children.length > 0 && self._activeTab) {
GroupItems.setActiveGroupItem(self);
@ -1035,6 +1048,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
if (!options.dontArrange)
this.arrange({animate: !options.immediately});
this._unfreezeItemSize({dontArrange: true});
this._sendToSubscribers("childAdded",{ groupItemId: this.id, item: item });
UI.setReorderTabsOnHide(this);
@ -1105,8 +1119,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
let closed = options.dontClose ? false : this.closeIfEmpty();
if (closed)
this._makeClosestTabActive();
else if (!options.dontArrange)
else if (!options.dontArrange) {
this.arrange({animate: !options.immediately});
this._unfreezeItemSize({dontArrange: true});
}
this._sendToSubscribers("childRemoved",{ groupItemId: this.id, item: item });
} catch(e) {
@ -1237,6 +1253,66 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
return shouldStack;
},
// ----------
// Function: _freezeItemSize
// Freezes current item size (when removing a child).
//
// Parameters:
// itemCount - the number of children before the last one was removed
_freezeItemSize: function GroupItem__freezeItemSize(itemCount) {
let data = this._frozenItemSizeData;
if (!data.lastItemCount) {
let self = this;
data.lastItemCount = itemCount;
// unfreeze item size when tabview is hidden
data.onTabViewHidden = function () self._unfreezeItemSize();
window.addEventListener('tabviewhidden', data.onTabViewHidden, false);
// we don't need to observe mouse movement when expanded because the
// tray is closed when we leave it and collapse causes unfreezing
if (self.expanded)
return;
// unfreeze item size when cursor is moved out of group bounds
data.onMouseMove = function (e) {
let cursor = new Point(e.pageX, e.pageY);
if (!self.bounds.contains(cursor))
self._unfreezeItemSize();
}
iQ(window).mousemove(data.onMouseMove);
}
this.arrange({animate: true, count: data.lastItemCount});
},
// ----------
// Function: _unfreezeItemSize
// Unfreezes and updates item size.
//
// Parameters:
// options - various options (see below)
//
// Possible options:
// dontArrange - do not arrange items when unfreezing
_unfreezeItemSize: function GroupItem__unfreezeItemSize(options) {
let data = this._frozenItemSizeData;
if (!data.lastItemCount)
return;
if (!options || !options.dontArrange)
this.arrange({animate: true});
// unbind event listeners
window.removeEventListener('tabviewhidden', data.onTabViewHidden, false);
if (data.onMouseMove)
iQ(window).unbind('mousemove', data.onMouseMove);
// reset freeze status
this._frozenItemSizeData = {};
},
// ----------
// Function: arrange
// Lays out all of the children.
@ -1561,6 +1637,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
this.arrange({z: z + 2});
this._unfreezeItemSize({dontArrange: true});
}
},
@ -1688,8 +1765,11 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Function: setResizable
// Sets whether the groupItem is resizable and updates the UI accordingly.
setResizable: function GroupItem_setResizable(value, immediately) {
var self = this;
this.resizeOptions.minWidth = GroupItems.minGroupWidth;
this.resizeOptions.minHeight = GroupItems.minGroupHeight;
this.resizeOptions.start = function () self._unfreezeItemSize();
if (value) {
immediately ? this.$resizer.show() : this.$resizer.fadeIn();

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

@ -23,6 +23,7 @@
* Aza Raskin <aza@mozilla.com>
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Sean Dunn <seanedunn@yahoo.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -169,8 +170,10 @@ Item.prototype = {
this.dragOptions = {
cancelClass: 'close stackExpander',
start: function(e, ui) {
if (this.isAGroupItem)
if (this.isAGroupItem) {
GroupItems.setActiveGroupItem(this);
this._unfreezeItemSize();
}
// if we start dragging a tab within a group, start with dropSpace on.
else if (this.parent != null)
this.parent._dropSpaceActive = true;
@ -598,6 +601,35 @@ Item.prototype = {
var droppables;
var dropTarget;
// determine the best drop target based on the current mouse coordinates
let determineBestDropTarget = function (e, box) {
// drop events
var best = {
dropTarget: null,
score: 0
};
droppables.forEach(function(droppable) {
var intersection = box.intersection(droppable.bounds);
if (intersection && intersection.area() > best.score) {
var possibleDropTarget = droppable.item;
var accept = true;
if (possibleDropTarget != dropTarget) {
var dropOptions = possibleDropTarget.dropOptions;
if (dropOptions && typeof dropOptions.accept == "function")
accept = dropOptions.accept.apply(possibleDropTarget, [self]);
}
if (accept) {
best.dropTarget = possibleDropTarget;
best.score = intersection.area();
}
}
});
return best.dropTarget;
}
// ___ mousemove
var handleMouseMove = function(e) {
// global drag tracking
@ -624,31 +656,9 @@ Item.prototype = {
if (typeof self.dragOptions.drag == "function")
self.dragOptions.drag.apply(self, [e]);
// drop events
var best = {
dropTarget: null,
score: 0
};
let bestDropTarget = determineBestDropTarget(e, box);
droppables.forEach(function(droppable) {
var intersection = box.intersection(droppable.bounds);
if (intersection && intersection.area() > best.score) {
var possibleDropTarget = droppable.item;
var accept = true;
if (possibleDropTarget != dropTarget) {
var dropOptions = possibleDropTarget.dropOptions;
if (dropOptions && typeof dropOptions.accept == "function")
accept = dropOptions.accept.apply(possibleDropTarget, [self]);
}
if (accept) {
best.dropTarget = possibleDropTarget;
best.score = intersection.area();
}
}
});
if (best.dropTarget != dropTarget) {
if (bestDropTarget != dropTarget) {
var dropOptions;
if (dropTarget) {
dropOptions = dropTarget.dropOptions;
@ -656,7 +666,7 @@ Item.prototype = {
dropOptions.out.apply(dropTarget, [e]);
}
dropTarget = best.dropTarget;
dropTarget = bestDropTarget;
if (dropTarget) {
dropOptions = dropTarget.dropOptions;
@ -710,10 +720,10 @@ Item.prototype = {
}
startMouse = new Point(e.pageX, e.pageY);
startPos = self.getBounds().position();
let bounds = self.getBounds();
startPos = bounds.position();
startEvent = e;
startSent = false;
dropTarget = null;
droppables = [];
iQ('.iq-droppable').each(function(elem) {
@ -726,6 +736,8 @@ Item.prototype = {
}
});
dropTarget = determineBestDropTarget(e, bounds);
iQ(gWindow)
.mousemove(handleMouseMove)
.mouseup(handleMouseUp);

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

@ -21,6 +21,7 @@
* Aza Raskin <aza@mozilla.com>
* Ian Gilman <ian@iangilman.com>
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* This file incorporates work from:
* jQuery JavaScript Library v1.4.2: http://code.jquery.com/jquery-1.4.2.js
@ -170,16 +171,22 @@ Rect.prototype = {
// ----------
// Function: contains
// Returns a boolean denoting if the given <Rect> is contained within
// Returns a boolean denoting if the <Rect> or <Point> is contained inside
// this rectangle.
//
// Paramaters
// - A <Rect>
contains: function Rect_contains(rect) {
return (rect.left >= this.left &&
rect.right <= this.right &&
rect.top >= this.top &&
rect.bottom <= this.bottom);
// Parameters
// - A <Rect> or a <Point>
contains: function Rect_contains(a) {
if (Utils.isPoint(a))
return (a.x > this.left &&
a.x < this.right &&
a.y > this.top &&
a.y < this.bottom);
return (a.left >= this.left &&
a.right <= this.right &&
a.top >= this.top &&
a.bottom <= this.bottom);
},
// ----------

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

@ -721,6 +721,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
complete();
};
UI.setActiveTab(this);
TabItems._update(this.tab, {force: true});
$tab.addClass("front");

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

@ -112,11 +112,6 @@ body {
position: absolute;
}
.undo .close {
display: inline-block;
position: relative;
}
.info-item {
position: absolute;
}

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

@ -4,7 +4,7 @@ function test() {
waitForExplicitFinish();
is(getTopWin(), window, "got top window");
is(getBoolPref("general.startup.browser", false), true, "getBoolPref");
is(getBoolPref("browser.search.openintab", false), false, "getBoolPref");
is(getBoolPref("this.pref.doesnt.exist", true), true, "getBoolPref fallback");
is(getBoolPref("this.pref.doesnt.exist", false), false, "getBoolPref fallback #2");

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

@ -85,6 +85,7 @@ _BROWSER_FILES = \
browser_tabview_bug608184.js \
browser_tabview_bug608158.js \
browser_tabview_bug608405.js \
browser_tabview_bug610208.js \
browser_tabview_bug610242.js \
browser_tabview_bug612470.js \
browser_tabview_bug613541.js \

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

@ -4,10 +4,12 @@
function test() {
waitForExplicitFinish();
newWindowWithTabView(onTabViewShown);
newWindowWithTabView(part1);
}
function onTabViewShown(win) {
function part1(win) {
registerCleanupFunction(function() win.close());
let contentWindow = win.document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1, "Has only one group");
@ -52,8 +54,32 @@ function onTabViewShown(win) {
checkActive(function() {
checkActive(function() {
win.close();
finish();
newWindowWithTabView(part2);
});
}, 490);
}, 10)
}
function part2(win) {
registerCleanupFunction(function() win.close());
let newTab = win.gBrowser.loadOneTab("about:blank", {inBackground: true});
hideTabView(function() {
let selectedTab = win.gBrowser.selectedTab;
isnot(selectedTab, newTab, "They are different tabs");
// switch the selected tab to new tab
win.gBrowser.selectedTab = newTab;
win.addEventListener("tabviewhidden", function () {
win.removeEventListener("tabviewhidden", arguments.callee, false);
is(win.gBrowser.selectedTab, newTab, "The seleted tab should be the same as before (new tab)");
win.close();
finish();
}, false);
// show tabview
EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
// hide tabview
EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
})
}

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

@ -15,8 +15,8 @@ function test() {
}
let testVeryQuickDragAndDrop = function () {
let sourceGroup = cw.GroupItems.groupItems[0];
let targetGroup = createGroupItem();
let sourceGroup = createGroupItem();
let targetGroup = cw.GroupItems.groupItems[0];
sourceGroup.pushAway(true);
targetGroup.pushAway(true);

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

@ -0,0 +1,231 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let win;
let groupItem;
let next = function () {
let test = tests.shift();
if (test) {
test();
return;
}
win.close();
finish();
}
let prepareTest = function (testName) {
let originalBounds = groupItem.getChild(0).getBounds();
let tabItem = groupItem.getChild(1);
let bounds = tabItem.getBounds();
tabItem.close();
ok(originalBounds.equals(groupItem.getChild(0).getBounds()), testName + ': tabs did not change their size');
ok(bounds.equals(groupItem.getChild(1).getBounds()), testName + ': third tab is now on second tab\'s previous position');
return originalBounds;
}
let cleanUpTest = function (testName, originalBounds, callback) {
// Use setTimeout here because the groupItem.arrange() call uses
// animation to re-arrange the tabItems.
win.setTimeout(function () {
ok(!originalBounds.equals(groupItem.getChild(0).getBounds()), testName + ': tabs changed their size');
// cleanup
cw.GroupItems.setActiveGroupItem(groupItem);
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
afterAllTabsLoaded(callback, win);
}, 500);
}
let tests = [];
// focus group title's input field to cause item arrange
let testFocusTitle = function () {
let originalBounds = prepareTest('testFocusTitle');
let target = groupItem.$titleShield[0];
EventUtils.synthesizeMouseAtCenter(target, {}, cw);
cleanUpTest('testFocusTitle', originalBounds, next);
}
// hide tabview to cause item arrange
let testHideTabView = function () {
let originalBounds = prepareTest('testHideTabView');
hideTabView(function () {
cleanUpTest('testHideTabView', originalBounds, function () {
showTabView(next, win);
});
}, win);
}
// (undo) close a group to cause item arrange
let testCloseGroupUndo = function () {
let originalBounds = prepareTest('testCloseGroupUndo');
hideGroupItem(groupItem, function () {
unhideGroupItem(groupItem, function () {
cleanUpTest('testCloseGroupUndo', originalBounds, next);
});
});
}
// leave the group's container with the mouse to cause item arrange
let testMouseOut = function () {
let originalBounds = prepareTest('testMouseOut');
let doc = cw.document.documentElement;
let bounds = groupItem.getBounds();
EventUtils.synthesizeMouse(doc, bounds.right - 5, bounds.bottom - 5, {type: 'mousemove'}, cw);
ok(originalBounds.equals(groupItem.getChild(0).getBounds()), 'testMouseOut: tabs did not change their size');
EventUtils.synthesizeMouse(doc, bounds.right + 1, bounds.bottom + 1, {type: 'mousemove'}, cw);
cleanUpTest('testMouseOut', originalBounds, next);
}
// sort item (drag it around) in its group to cause item arrange
let testSortInGroup = function () {
let originalBounds = prepareTest('testSortInGroup');
let target = groupItem.getChild(0).container;
// simulate drag/drop sorting
EventUtils.synthesizeMouse(target, 20, 20, {type: 'mousedown'}, cw);
EventUtils.synthesizeMouse(target, 40, 20, {type: 'mousemove'}, cw);
EventUtils.synthesizeMouse(target, 20, 20, {type: 'mouseup'}, cw);
cleanUpTest('testSortInGroup', originalBounds, next);
}
// arrange items when the containing group is resized
let testResizeGroup = function () {
let originalBounds = prepareTest('testResizeGroup');
let oldBounds = groupItem.getBounds();
let resizer = groupItem.$resizer[0];
// simulate drag/drop resizing
EventUtils.synthesizeMouse(resizer, 5, 5, {type: 'mousedown'}, cw);
EventUtils.synthesizeMouse(resizer, 40, 20, {type: 'mousemove'}, cw);
EventUtils.synthesizeMouse(resizer, 20, 20, {type: 'mouseup'}, cw);
// reset group size
groupItem.setBounds(oldBounds);
groupItem.setUserSize();
cleanUpTest('testResizeGroup', originalBounds, next);
}
// make sure we don't freeze item size when removing an item from a stack
let testRemoveWhileStacked = function () {
let oldBounds = groupItem.getBounds();
groupItem.setSize(150, 200, true);
groupItem.setUserSize();
let originalBounds = groupItem.getChild(0).getBounds();
ok(!groupItem._isStacked, 'testRemoveWhileStacked: group is not stacked');
// add a new tab to let the group stack
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
ok(groupItem._isStacked, 'testRemoveWhileStacked: group is now stacked');
afterAllTabsLoaded(function () {
groupItem.getChild(0).close();
let bounds = groupItem.getChild(0).getBounds();
ok(originalBounds.equals(bounds), 'testRemoveWhileStacked: tabs did not change their size');
// reset group size
groupItem.setBounds(oldBounds);
groupItem.setUserSize();
next();
}, win);
}
// 1) make sure item size is frozen when removing an item in expanded mode
// 2) make sure item size stays frozen while moving the mouse in the expanded
// layer
let testExpandedMode = function () {
let oldBounds = groupItem.getBounds();
groupItem.setSize(100, 100, true);
groupItem.setUserSize();
ok(groupItem._isStacked, 'testExpandedMode: group is stacked');
groupItem.addSubscriber(groupItem, 'expanded', function () {
groupItem.removeSubscriber(groupItem, 'expanded');
onExpanded();
});
groupItem.addSubscriber(groupItem, 'collapsed', function () {
groupItem.removeSubscriber(groupItem, 'collapsed');
onCollapsed();
});
let onExpanded = function () {
let originalBounds = groupItem.getChild(0).getBounds();
let tabItem = groupItem.getChild(1);
let bounds = tabItem.getBounds();
for (let i=0; i<3; i++)
groupItem.getChild(1).close();
ok(originalBounds.equals(groupItem.getChild(0).getBounds()), 'testExpandedMode: tabs did not change their size');
// move the mouse over the expanded layer
let trayBounds = groupItem.expanded.bounds;
let target = groupItem.expanded.$tray[0];
EventUtils.synthesizeMouse(target, trayBounds.right - 5, trayBounds.bottom -5, {type: 'mousemove'}, cw);
ok(originalBounds.equals(groupItem.getChild(0).getBounds()), 'testExpandedMode: tabs did not change their size');
groupItem.collapse();
}
let onCollapsed = function () {
// reset group size
groupItem.setBounds(oldBounds);
groupItem.setUserSize();
next();
}
groupItem.expand();
}
tests.push(testFocusTitle);
tests.push(testHideTabView);
tests.push(testCloseGroupUndo);
tests.push(testMouseOut);
tests.push(testSortInGroup);
tests.push(testResizeGroup);
tests.push(testRemoveWhileStacked);
tests.push(testExpandedMode);
waitForExplicitFinish();
newWindowWithTabView(function (tvwin) {
win = tvwin;
registerCleanupFunction(function () {
if (!win.closed)
win.close();
});
cw = win.TabView.getContentWindow();
groupItem = cw.GroupItems.groupItems[0];
groupItem.setSize(400, 200, true);
groupItem.setUserSize();
for (let i=0; i<3; i++)
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
afterAllTabsLoaded(next, win);
});
}

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

@ -81,8 +81,7 @@
<stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
<!-- addons, forgery (phishing) UI -->
<groupbox id="addonsPhishingGroup"
xmlns:aaa="http://www.w3.org/2005/07/aaa">
<groupbox id="addonsPhishingGroup">
<hbox id="addonInstallBox">
<checkbox id="warnAddonInstall" flex="1"
label="&warnAddonInstall.label;"

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

@ -299,9 +299,12 @@ html[dir=rtl] .appTabTrayContainer {
.undo {
background-color: rgba(0,0,0,.2);
width: 150px;
height: 30px;
line-height: 30px;
padding-top: 3px;
padding-bottom: 3px;
-moz-padding-start: 5px;
-moz-padding-end: 20px;
width: 135px;
line-height: 25px;
box-shadow: 0 1px 0 rgba(255,255,255,.4), 0 1px 0 rgba(0,0,0,.3) inset;
text-shadow: 0 1px 0 rgba(255,255,255,.2);
color: WindowText;
@ -316,14 +319,14 @@ html[dir=rtl] .appTabTrayContainer {
}
.undo .close {
top: 4px;
left: 4px;
top: 7px;
right: 7px;
opacity: 0.5;
}
html[dir=rtl] .undo .close {
left: auto;
right: 4px;
right: auto;
left: 7px;
}
.undo .close:hover{

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

@ -293,9 +293,12 @@ html[dir=rtl] .appTabTrayContainer {
.undo {
background-color: #A0A0A0;
width: 150px;
height: 30px;
line-height: 30px;
padding-top: 3px;
padding-bottom: 3px;
-moz-padding-start: 5px;
-moz-padding-end: 20px;
width: 135px;
line-height: 25px;
box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.24);
text-shadow: 0px -1px 0px rgba(255,255,255,.2);
color: rgba( 0,0,0, .8);
@ -310,14 +313,14 @@ html[dir=rtl] .appTabTrayContainer {
}
.undo .close {
top: 4px;
left: 4px;
top: 7px;
right: 7px;
opacity: 0.5;
}
html[dir=rtl] .undo .close {
left: auto;
right: 4px;
right: auto;
left: 7px;
}
.undo .close:hover{

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

@ -318,9 +318,12 @@ html[dir=rtl] .appTabTrayContainer {
.undo {
background-color: #A0A0A0;
width: 150px;
height: 30px;
line-height: 30px;
padding-top: 3px;
padding-bottom: 3px;
-moz-padding-start: 5px;
-moz-padding-end: 20px;
width: 135px;
line-height: 25px;
box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.24);
text-shadow: 0px -1px 0px rgba(255,255,255,.2);
color: rgba( 0,0,0, .8);
@ -335,14 +338,14 @@ html[dir=rtl] .appTabTrayContainer {
}
.undo .close {
top: 4px;
left: 4px;
top: 7px;
right: 7px;
opacity: 0.5;
}
html[dir=rtl] .undo .close {
left: auto;
right: 4px;
right: auto;
left: 7px;
}
.undo .close:hover{

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

@ -57,7 +57,7 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
/**
* Check that the script currently running in context "cx" can load "uri".
*
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* should be denied.
*
* @param cx the JSContext of the script causing the load
@ -105,7 +105,7 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
/**
* Check that content with principal aPrincipal can load "uri".
*
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* should be denied.
*
* @param aPrincipal the principal identifying the actor causing the load
@ -113,13 +113,13 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
* @param flags the permission set, see above
*/
void checkLoadURIWithPrincipal(in nsIPrincipal aPrincipal,
in nsIURI uri,
in nsIURI uri,
in unsigned long flags);
/**
* Check that content from "from" can load "uri".
*
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* should be denied.
*
* @param from the URI causing the load
@ -128,8 +128,8 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
*
* @deprecated Use checkLoadURIWithPrincipal instead of this function.
*/
void checkLoadURI(in nsIURI from, in nsIURI uri,
in unsigned long flags);
[deprecated] void checkLoadURI(in nsIURI from, in nsIURI uri,
in unsigned long flags);
/**
* Similar to checkLoadURIWithPrincipal but there are two differences:
@ -141,17 +141,17 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
* function will return error code NS_ERROR_DOM_BAD_URI.
*/
void checkLoadURIStrWithPrincipal(in nsIPrincipal aPrincipal,
in AUTF8String uri,
in unsigned long flags);
in AUTF8String uri,
in unsigned long flags);
/**
* Same as CheckLoadURI but takes string arguments for ease of use
* by scripts
*
* @deprecated Use checkLoadURIStrWithPrincipal instead of this function.
*/
void checkLoadURIStr(in AUTF8String from, in AUTF8String uri,
in unsigned long flags);
[deprecated] void checkLoadURIStr(in AUTF8String from, in AUTF8String uri,
in unsigned long flags);
/**
* Check that the function 'funObj' is allowed to run on 'targetObj'
@ -173,10 +173,10 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
[noscript] boolean canExecuteScripts(in JSContextPtr cx,
in nsIPrincipal principal);
///////////////// Principals ///////////////////////
///////////////// Principals ///////////////////////
/**
* Return the principal of the innermost frame of the currently
* executing script. Will return null if there is no script
* Return the principal of the innermost frame of the currently
* executing script. Will return null if there is no script
* currently executing.
*/
[noscript] nsIPrincipal getSubjectPrincipal();
@ -215,12 +215,12 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
*/
[noscript] short requestCapability(in nsIPrincipal principal,
in string capability);
/**
* Return true if the currently executing script has 'capability' enabled.
*/
boolean isCapabilityEnabled(in string capability);
/**
* Enable 'capability' in the innermost frame of the currently executing
* script.
@ -249,7 +249,7 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
// XXXbz ideally we'd pass a subjectName here too, and the nsISupports
// cert we're enabling for...
void setCanEnableCapability(in AUTF8String certificateFingerprint,
in string capability,
in string capability,
in short canEnable);
///////////////////////

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

@ -385,6 +385,7 @@ GNU_LD = @GNU_LD@
GNU_CC = @GNU_CC@
GNU_CXX = @GNU_CXX@
HAVE_GCC3_ABI = @HAVE_GCC3_ABI@
HAVE_OLD_CLANG = @HAVE_OLD_CLANG@
INTEL_CC = @INTEL_CC@
INTEL_CXX = @INTEL_CXX@

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

@ -1167,6 +1167,28 @@ fi
fi # COMPILE_ENVIRONMENT
dnl clang prior to 2.9 (including Xcode 4) does not support all the
dnl constructs required by the libtheora inline asm. This is used to
dnl detect and disable it
AC_LANG_SAVE
AC_LANG_C
AC_TRY_COMPILE([
#if defined(__clang__)
# if __clang_major__<2 || (__clang_major__==2 && __clang_minor__<9)
# error "clang older than 2.9 detected"
# endif
#endif
],
[],
result="yes",
result="no")
if test "$result" = "no"; then
AC_DEFINE(HAVE_OLD_CLANG)
HAVE_OLD_CLANG=1
fi
AC_LANG_RESTORE
AC_SUBST(HAVE_OLD_CLANG)
if test -n "$MAKE"; then
if test `echo $MAKE | grep -c make.py` != 1; then
NOT_PYMAKE=$MAKE
@ -5052,13 +5074,18 @@ if test -z "$XULRUNNER_STUB_NAME"; then
fi
AC_SUBST(XULRUNNER_STUB_NAME)
AC_MSG_CHECKING([for application to build])
if test -z "$MOZ_BUILD_APP"; then
AC_MSG_ERROR([--enable-application=APP was not specified and is required.])
AC_MSG_RESULT([browser])
MOZ_BUILD_APP=browser
else
# We have a valid application only if it has a build.mk file in its top
# directory.
if test ! -f "${srcdir}/${MOZ_BUILD_APP}/build.mk" ; then
AC_MSG_RESULT([none])
AC_MSG_ERROR([--enable-application value not recognized (${MOZ_BUILD_APP}/build.mk does not exist).])
else
AC_MSG_RESULT([$MOZ_BUILD_APP])
fi
fi

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

@ -109,7 +109,7 @@ interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
* you're aware of all the security implications. And then think twice about
* it.
*/
[scriptable, uuid(6bb91106-85f0-4d93-8cb4-e57b3d0624f2)]
[scriptable, uuid(af62a870-820c-4981-96a3-28ab17b779e1)]
interface nsIXMLHttpRequest : nsISupports
{
/**
@ -187,42 +187,19 @@ interface nsIXMLHttpRequest : nsISupports
*/
ACString getResponseHeader(in AUTF8String header);
/**
* Native (non-script) method to initialize a request. Note that
* the request is not sent until the <code>send</code> method
* is invoked.
*
* If there is an "active" request (that is, if open() or openRequest() has
* been called already), this is equivalent to calling abort().
*
* @param method The HTTP method, for example "POST" or "GET". Ignored
* if the URL is not a HTTP(S) URL.
* @param url The URL to which to send the request.
* @param async Whether the request is synchronous or asynchronous
* i.e. whether send returns only after the response
* is received or if it returns immediately after
* sending the request. In the latter case, notification
* of completion is sent through the event listeners.
* This argument must be true if the multipart
* attribute has been set to true, or an exception will
* be thrown.
* @param user A username for authentication if necessary.
* @param password A password for authentication if necessary.
*/
[noscript] void openRequest(in AUTF8String method,
in AUTF8String url,
in boolean async,
in AString user,
in AString password);
%{C++
// note this is NOT virtual so this won't muck with the vtable!
inline nsresult Open(const nsACString& method, const nsACString& url,
PRBool async, const nsAString& user,
const nsAString& password) {
return Open(method, url, async, user, password, 3);
}
%}
/**
* Meant to be a script-only method for initializing a request.
* The parameters are similar to the ones detailed in the
* description of <code>openRequest</code>, but the last
* 3 are optional.
*
* If there is an "active" request (that is, if open() or openRequest() has
* been called already), this is equivalent to calling abort().
* If there is an "active" request (that is, if open() has been called
* already), this is equivalent to calling abort() and then open().
*
* @param method The HTTP method - either "POST" or "GET". Ignored
* if the URL is not a HTTP URL.

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

@ -448,6 +448,14 @@ nsContentList::nsContentList(nsINode* aRootNode,
{
NS_ASSERTION(mRootNode, "Must have root");
mRootNode->AddMutationObserver(this);
// We only need to flush if we're in an non-HTML document, since the
// HTML5 parser doesn't need flushing. Further, if we're not in a
// document at all right now (in the GetCurrentDoc() sense), we're
// not parser-created and don't need to be flushing stuff under us
// to get our kids right.
nsIDocument* doc = mRootNode->GetCurrentDoc();
mFlushesNeeded = doc && !doc->IsHTML();
}
nsContentList::~nsContentList()

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

@ -54,52 +54,337 @@
#include "nsIChannelEventSink.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsXMLHttpRequest.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "prclist.h"
#include "prtime.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#define PREFLIGHT_CACHE_SIZE 100
static PRBool gDisableCORS = PR_FALSE;
static PRBool gDisableCORSPrivateData = PR_FALSE;
class nsChannelCanceller
//////////////////////////////////////////////////////////////////////////
// Preflight cache
class nsPreflightCache
{
public:
nsChannelCanceller(nsIChannel* aChannel)
: mChannel(aChannel)
struct TokenTime
{
nsCString token;
PRTime expirationTime;
};
struct CacheEntry : public PRCList
{
CacheEntry(nsCString& aKey)
: mKey(aKey)
{
MOZ_COUNT_CTOR(nsPreflightCache::CacheEntry);
}
~CacheEntry()
{
MOZ_COUNT_DTOR(nsPreflightCache::CacheEntry);
}
void PurgeExpired(PRTime now);
PRBool CheckRequest(const nsCString& aMethod,
const nsTArray<nsCString>& aCustomHeaders);
nsCString mKey;
nsTArray<TokenTime> mMethods;
nsTArray<TokenTime> mHeaders;
};
nsPreflightCache()
{
MOZ_COUNT_CTOR(nsPreflightCache);
PR_INIT_CLIST(&mList);
}
~nsChannelCanceller()
~nsPreflightCache()
{
if (mChannel) {
mChannel->Cancel(NS_ERROR_DOM_BAD_URI);
Clear();
MOZ_COUNT_DTOR(nsPreflightCache);
}
PRBool Initialize()
{
return mTable.Init();
}
CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRBool aWithCredentials, PRBool aCreate);
void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal);
void Clear();
private:
static PLDHashOperator
RemoveExpiredEntries(const nsACString& aKey, nsAutoPtr<CacheEntry>& aValue,
void* aUserData);
static PRBool GetCacheKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRBool aWithCredentials, nsACString& _retval);
nsClassHashtable<nsCStringHashKey, CacheEntry> mTable;
PRCList mList;
};
// Will be initialized in EnsurePreflightCache.
static nsPreflightCache* sPreflightCache = nsnull;
static PRBool EnsurePreflightCache()
{
if (sPreflightCache)
return PR_TRUE;
nsAutoPtr<nsPreflightCache> newCache(new nsPreflightCache());
if (newCache->Initialize()) {
sPreflightCache = newCache.forget();
return PR_TRUE;
}
return PR_FALSE;
}
void
nsPreflightCache::CacheEntry::PurgeExpired(PRTime now)
{
PRUint32 i;
for (i = 0; i < mMethods.Length(); ++i) {
if (now >= mMethods[i].expirationTime) {
mMethods.RemoveElementAt(i--);
}
}
for (i = 0; i < mHeaders.Length(); ++i) {
if (now >= mHeaders[i].expirationTime) {
mHeaders.RemoveElementAt(i--);
}
}
}
PRBool
nsPreflightCache::CacheEntry::CheckRequest(const nsCString& aMethod,
const nsTArray<nsCString>& aHeaders)
{
PurgeExpired(PR_Now());
if (!aMethod.EqualsLiteral("GET") && !aMethod.EqualsLiteral("POST")) {
PRUint32 i;
for (i = 0; i < mMethods.Length(); ++i) {
if (aMethod.Equals(mMethods[i].token))
break;
}
if (i == mMethods.Length()) {
return PR_FALSE;
}
}
void DontCancel()
{
mChannel = nsnull;
for (PRUint32 i = 0; i < aHeaders.Length(); ++i) {
PRUint32 j;
for (j = 0; j < mHeaders.Length(); ++j) {
if (aHeaders[i].Equals(mHeaders[j].token,
nsCaseInsensitiveCStringComparator())) {
break;
}
}
if (j == mHeaders.Length()) {
return PR_FALSE;
}
}
private:
nsIChannel* mChannel;
};
return PR_TRUE;
}
NS_IMPL_ISUPPORTS5(nsCrossSiteListenerProxy, nsIStreamListener,
nsPreflightCache::CacheEntry*
nsPreflightCache::GetEntry(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
PRBool aCreate)
{
nsCString key;
if (!GetCacheKey(aURI, aPrincipal, aWithCredentials, key)) {
NS_WARNING("Invalid cache key!");
return nsnull;
}
CacheEntry* entry;
if (mTable.Get(key, &entry)) {
// Entry already existed so just return it. Also update the LRU list.
// Move to the head of the list.
PR_REMOVE_LINK(entry);
PR_INSERT_LINK(entry, &mList);
return entry;
}
if (!aCreate) {
return nsnull;
}
// This is a new entry, allocate and insert into the table now so that any
// failures don't cause items to be removed from a full cache.
entry = new CacheEntry(key);
if (!entry) {
NS_WARNING("Failed to allocate new cache entry!");
return nsnull;
}
NS_ASSERTION(mTable.Count() <= PREFLIGHT_CACHE_SIZE,
"Something is borked, too many entries in the cache!");
// Now enforce the max count.
if (mTable.Count() == PREFLIGHT_CACHE_SIZE) {
// Try to kick out all the expired entries.
PRTime now = PR_Now();
mTable.Enumerate(RemoveExpiredEntries, &now);
// If that didn't remove anything then kick out the least recently used
// entry.
if (mTable.Count() == PREFLIGHT_CACHE_SIZE) {
CacheEntry* lruEntry = static_cast<CacheEntry*>(PR_LIST_TAIL(&mList));
PR_REMOVE_LINK(lruEntry);
// This will delete 'lruEntry'.
mTable.Remove(lruEntry->mKey);
NS_ASSERTION(mTable.Count() == PREFLIGHT_CACHE_SIZE - 1,
"Somehow tried to remove an entry that was never added!");
}
}
if (!mTable.Put(key, entry)) {
// Failed, clean up the new entry.
delete entry;
NS_WARNING("Failed to add entry to the CORS preflight cache!");
return nsnull;
}
PR_INSERT_LINK(entry, &mList);
return entry;
}
void
nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
{
CacheEntry* entry;
nsCString key;
if (GetCacheKey(aURI, aPrincipal, PR_TRUE, key) &&
mTable.Get(key, &entry)) {
PR_REMOVE_LINK(entry);
mTable.Remove(key);
}
if (GetCacheKey(aURI, aPrincipal, PR_FALSE, key) &&
mTable.Get(key, &entry)) {
PR_REMOVE_LINK(entry);
mTable.Remove(key);
}
}
void
nsPreflightCache::Clear()
{
PR_INIT_CLIST(&mList);
mTable.Clear();
}
/* static */ PLDHashOperator
nsPreflightCache::RemoveExpiredEntries(const nsACString& aKey,
nsAutoPtr<CacheEntry>& aValue,
void* aUserData)
{
PRTime* now = static_cast<PRTime*>(aUserData);
aValue->PurgeExpired(*now);
if (aValue->mHeaders.IsEmpty() &&
aValue->mMethods.IsEmpty()) {
// Expired, remove from the list as well as the hash table.
PR_REMOVE_LINK(aValue);
return PL_DHASH_REMOVE;
}
return PL_DHASH_NEXT;
}
/* static */ PRBool
nsPreflightCache::GetCacheKey(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
nsACString& _retval)
{
NS_ASSERTION(aURI, "Null uri!");
NS_ASSERTION(aPrincipal, "Null principal!");
NS_NAMED_LITERAL_CSTRING(space, " ");
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCAutoString scheme, host, port;
if (uri) {
uri->GetScheme(scheme);
uri->GetHost(host);
port.AppendInt(NS_GetRealPort(uri));
}
nsCAutoString cred;
if (aWithCredentials) {
_retval.AssignLiteral("cred");
}
else {
_retval.AssignLiteral("nocred");
}
nsCAutoString spec;
rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
_retval.Assign(cred + space + scheme + space + host + space + port + space +
spec);
return PR_TRUE;
}
//////////////////////////////////////////////////////////////////////////
// nsCORSListenerProxy
NS_IMPL_ISUPPORTS5(nsCORSListenerProxy, nsIStreamListener,
nsIRequestObserver, nsIChannelEventSink,
nsIInterfaceRequestor, nsIAsyncVerifyRedirectCallback)
/* static */
void
nsCrossSiteListenerProxy::Startup()
nsCORSListenerProxy::Startup()
{
nsContentUtils::AddBoolPrefVarCache("content.cors.disable", &gDisableCORS);
nsContentUtils::AddBoolPrefVarCache("content.cors.no_private_data", &gDisableCORSPrivateData);
}
nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
nsresult* aResult)
/* static */
void
nsCORSListenerProxy::Shutdown()
{
delete sPreflightCache;
sPreflightCache = nsnull;
}
nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
nsresult* aResult)
: mOuterListener(aOuter),
mRequestingPrincipal(aRequestingPrincipal),
mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
@ -118,14 +403,13 @@ nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
}
}
nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
const nsCString& aPreflightMethod,
const nsTArray<nsCString>& aPreflightHeaders,
nsresult* aResult)
nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
const nsCString& aPreflightMethod,
const nsTArray<nsCString>& aPreflightHeaders,
nsresult* aResult)
: mOuterListener(aOuter),
mRequestingPrincipal(aRequestingPrincipal),
mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
@ -152,19 +436,18 @@ nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(aRequest));
if (!mRequestApproved) {
if (nsXMLHttpRequest::sAccessControlCache) {
if (sPreflightCache) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel) {
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIURI> uri;
NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
if (uri) {
nsXMLHttpRequest::sAccessControlCache->
RemoveEntries(uri, mRequestingPrincipal);
sPreflightCache->RemoveEntries(uri, mRequestingPrincipal);
}
}
}
@ -219,7 +502,7 @@ IsValidHTTPToken(const nsCSubstring& aToken)
}
nsresult
nsCrossSiteListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
{
// Check if this was actually a cross domain request
if (!mHasBeenCrossSite) {
@ -326,19 +609,19 @@ nsCrossSiteListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatusCode)
nsCORSListenerProxy::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatusCode)
{
return mOuterListener->OnStopRequest(aRequest, aContext, aStatusCode);
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aInputStream,
PRUint32 aOffset,
PRUint32 aCount)
nsCORSListenerProxy::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aInputStream,
PRUint32 aOffset,
PRUint32 aCount)
{
if (!mRequestApproved) {
return NS_ERROR_DOM_BAD_URI;
@ -348,7 +631,7 @@ nsCrossSiteListenerProxy::OnDataAvailable(nsIRequest* aRequest,
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
nsCORSListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
{
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
*aResult = static_cast<nsIChannelEventSink*>(this);
@ -363,21 +646,20 @@ nsCrossSiteListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *cb)
nsCORSListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *cb)
{
nsresult rv;
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
rv = CheckRequestApproved(aOldChannel);
if (NS_FAILED(rv)) {
if (nsXMLHttpRequest::sAccessControlCache) {
if (sPreflightCache) {
nsCOMPtr<nsIURI> oldURI;
NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
if (oldURI) {
nsXMLHttpRequest::sAccessControlCache->
RemoveEntries(oldURI, mRequestingPrincipal);
sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal);
}
}
aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
@ -408,7 +690,7 @@ nsCrossSiteListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnRedirectVerifyCallback(nsresult result)
nsCORSListenerProxy::OnRedirectVerifyCallback(nsresult result)
{
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
NS_ASSERTION(mOldRedirectChannel, "mOldRedirectChannel not set in callback");
@ -417,7 +699,7 @@ nsCrossSiteListenerProxy::OnRedirectVerifyCallback(nsresult result)
if (NS_SUCCEEDED(result)) {
nsresult rv = UpdateChannel(mNewRedirectChannel);
if (NS_FAILED(rv)) {
NS_WARNING("nsCrossSiteListenerProxy::OnRedirectVerifyCallback: "
NS_WARNING("nsCORSListenerProxy::OnRedirectVerifyCallback: "
"UpdateChannel() returned failure");
}
result = rv;
@ -435,7 +717,7 @@ nsCrossSiteListenerProxy::OnRedirectVerifyCallback(nsresult result)
}
nsresult
nsCrossSiteListenerProxy::UpdateChannel(nsIChannel* aChannel)
nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel)
{
nsCOMPtr<nsIURI> uri, originalURI;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
@ -517,3 +799,304 @@ nsCrossSiteListenerProxy::UpdateChannel(nsIChannel* aChannel)
return NS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Preflight proxy
// Class used as streamlistener and notification callback when
// doing the initial OPTIONS request for a CORS check
class nsCORSPreflightListener : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink
{
public:
nsCORSPreflightListener(nsIChannel* aOuterChannel,
nsIStreamListener* aOuterListener,
nsISupports* aOuterContext,
nsIPrincipal* aReferrerPrincipal,
const nsACString& aRequestMethod,
PRBool aWithCredentials)
: mOuterChannel(aOuterChannel), mOuterListener(aOuterListener),
mOuterContext(aOuterContext), mReferrerPrincipal(aReferrerPrincipal),
mRequestMethod(aRequestMethod), mWithCredentials(aWithCredentials)
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
private:
void AddResultToCache(nsIRequest* aRequest);
nsCOMPtr<nsIChannel> mOuterChannel;
nsCOMPtr<nsIStreamListener> mOuterListener;
nsCOMPtr<nsISupports> mOuterContext;
nsCOMPtr<nsIPrincipal> mReferrerPrincipal;
nsCString mRequestMethod;
PRBool mWithCredentials;
};
NS_IMPL_ISUPPORTS4(nsCORSPreflightListener, nsIStreamListener,
nsIRequestObserver, nsIInterfaceRequestor,
nsIChannelEventSink)
void
nsCORSPreflightListener::AddResultToCache(nsIRequest *aRequest)
{
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest);
NS_ASSERTION(http, "Request was not http");
// The "Access-Control-Max-Age" header should return an age in seconds.
nsCAutoString headerVal;
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Max-Age"),
headerVal);
if (headerVal.IsEmpty()) {
return;
}
// Sanitize the string. We only allow 'delta-seconds' as specified by
// http://dev.w3.org/2006/waf/access-control (digits 0-9 with no leading or
// trailing non-whitespace characters).
PRUint32 age = 0;
nsCSubstring::const_char_iterator iter, end;
headerVal.BeginReading(iter);
headerVal.EndReading(end);
while (iter != end) {
if (*iter < '0' || *iter > '9') {
return;
}
age = age * 10 + (*iter - '0');
// Cap at 24 hours. This also avoids overflow
age = NS_MIN(age, 86400U);
++iter;
}
if (!age || !EnsurePreflightCache()) {
return;
}
// String seems fine, go ahead and cache.
// Note that we have already checked that these headers follow the correct
// syntax.
nsCOMPtr<nsIURI> uri;
NS_GetFinalChannelURI(http, getter_AddRefs(uri));
// PR_Now gives microseconds
PRTime expirationTime = PR_Now() + (PRUint64)age * PR_USEC_PER_SEC;
nsPreflightCache::CacheEntry* entry =
sPreflightCache->GetEntry(uri, mReferrerPrincipal, mWithCredentials,
PR_TRUE);
if (!entry) {
return;
}
// The "Access-Control-Allow-Methods" header contains a comma separated
// list of method names.
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
headerVal);
nsCCharSeparatedTokenizer methods(headerVal, ',');
while(methods.hasMoreTokens()) {
const nsDependentCSubstring& method = methods.nextToken();
if (method.IsEmpty()) {
continue;
}
PRUint32 i;
for (i = 0; i < entry->mMethods.Length(); ++i) {
if (entry->mMethods[i].token.Equals(method)) {
entry->mMethods[i].expirationTime = expirationTime;
break;
}
}
if (i == entry->mMethods.Length()) {
nsPreflightCache::TokenTime* newMethod =
entry->mMethods.AppendElement();
if (!newMethod) {
return;
}
newMethod->token = method;
newMethod->expirationTime = expirationTime;
}
}
// The "Access-Control-Allow-Headers" header contains a comma separated
// list of method names.
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
headerVal);
nsCCharSeparatedTokenizer headers(headerVal, ',');
while(headers.hasMoreTokens()) {
const nsDependentCSubstring& header = headers.nextToken();
if (header.IsEmpty()) {
continue;
}
PRUint32 i;
for (i = 0; i < entry->mHeaders.Length(); ++i) {
if (entry->mHeaders[i].token.Equals(header)) {
entry->mHeaders[i].expirationTime = expirationTime;
break;
}
}
if (i == entry->mHeaders.Length()) {
nsPreflightCache::TokenTime* newHeader =
entry->mHeaders.AppendElement();
if (!newHeader) {
return;
}
newHeader->token = header;
newHeader->expirationTime = expirationTime;
}
}
}
NS_IMETHODIMP
nsCORSPreflightListener::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
nsresult status;
nsresult rv = aRequest->GetStatus(&status);
if (NS_SUCCEEDED(rv)) {
rv = status;
}
if (NS_SUCCEEDED(rv)) {
// Everything worked, try to cache and then fire off the actual request.
AddResultToCache(aRequest);
rv = mOuterChannel->AsyncOpen(mOuterListener, mOuterContext);
}
if (NS_FAILED(rv)) {
mOuterChannel->Cancel(rv);
mOuterListener->OnStartRequest(mOuterChannel, mOuterContext);
mOuterListener->OnStopRequest(mOuterChannel, mOuterContext, rv);
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
nsCORSPreflightListener::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatus)
{
return NS_OK;
}
/** nsIStreamListener methods **/
NS_IMETHODIMP
nsCORSPreflightListener::OnDataAvailable(nsIRequest *aRequest,
nsISupports *ctxt,
nsIInputStream *inStr,
PRUint32 sourceOffset,
PRUint32 count)
{
return NS_OK;
}
NS_IMETHODIMP
nsCORSPreflightListener::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *callback)
{
// Only internal redirects allowed for now.
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags))
return NS_ERROR_DOM_BAD_URI;
callback->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
NS_IMETHODIMP
nsCORSPreflightListener::GetInterface(const nsIID & aIID, void **aResult)
{
return QueryInterface(aIID, aResult);
}
nsresult
NS_StartCORSPreflight(nsIChannel* aRequestChannel,
nsIStreamListener* aListener,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
nsTArray<nsCString>& aUnsafeHeaders,
nsIChannel** aPreflightChannel)
{
*aPreflightChannel = nsnull;
nsCAutoString method;
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequestChannel));
NS_ENSURE_TRUE(httpChannel, NS_ERROR_UNEXPECTED);
httpChannel->GetRequestMethod(method);
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aRequestChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsPreflightCache::CacheEntry* entry =
sPreflightCache ?
sPreflightCache->GetEntry(uri, aPrincipal, aWithCredentials, PR_FALSE) :
nsnull;
if (entry && entry->CheckRequest(method, aUnsafeHeaders)) {
// We have a cached preflight result, just start the original channel
return aRequestChannel->AsyncOpen(aListener, nsnull);
}
// Either it wasn't cached or the cached result has expired. Build a
// channel for the OPTIONS request.
nsCOMPtr<nsILoadGroup> loadGroup;
rv = aRequestChannel->GetLoadGroup(getter_AddRefs(loadGroup));
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags;
rv = aRequestChannel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> preflightChannel;
rv = NS_NewChannel(getter_AddRefs(preflightChannel), uri, nsnull,
loadGroup, nsnull, loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannel> preHttp = do_QueryInterface(preflightChannel);
NS_ASSERTION(preHttp, "Failed to QI to nsIHttpChannel!");
rv = preHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
NS_ENSURE_SUCCESS(rv, rv);
// Set up listener which will start the original channel
nsCOMPtr<nsIStreamListener> preflightListener =
new nsCORSPreflightListener(aRequestChannel, aListener, nsnull, aPrincipal,
method, aWithCredentials);
NS_ENSURE_TRUE(preflightListener, NS_ERROR_OUT_OF_MEMORY);
preflightListener =
new nsCORSListenerProxy(preflightListener, aPrincipal,
preflightChannel, aWithCredentials,
method, aUnsafeHeaders, &rv);
NS_ENSURE_TRUE(preflightListener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
// Start preflight
rv = preflightChannel->AsyncOpen(preflightListener, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
// Return newly created preflight channel
preflightChannel.forget(aPreflightChannel);
return NS_OK;
}

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

@ -35,8 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsCrossSiteListenerProxy_h__
#define nsCrossSiteListenerProxy_h__
#ifndef nsCORSListenerProxy_h__
#define nsCORSListenerProxy_h__
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
@ -55,24 +55,32 @@ class nsIPrincipal;
extern PRBool
IsValidHTTPToken(const nsCSubstring& aToken);
class nsCrossSiteListenerProxy : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink,
public nsIAsyncVerifyRedirectCallback
nsresult
NS_StartCORSPreflight(nsIChannel* aRequestChannel,
nsIStreamListener* aListener,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
nsTArray<nsCString>& aACUnsafeHeaders,
nsIChannel** aPreflightChannel);
class nsCORSListenerProxy : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink,
public nsIAsyncVerifyRedirectCallback
{
public:
nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
nsresult* aResult);
nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
const nsCString& aPreflightMethod,
const nsTArray<nsCString>& aPreflightHeaders,
nsresult* aResult);
nsCORSListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
nsresult* aResult);
nsCORSListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
PRBool aWithCredentials,
const nsCString& aPreflightMethod,
const nsTArray<nsCString>& aPreflightHeaders,
nsresult* aResult);
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
@ -84,6 +92,8 @@ public:
// Must be called at startup.
static void Startup();
static void Shutdown();
private:
nsresult UpdateChannel(nsIChannel* aChannel);
nsresult CheckRequestApproved(nsIRequest* aRequest);

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

@ -42,7 +42,7 @@
#include "nsDOMAttributeMap.h"
#include "nsDOMAttribute.h"
#include "nsIDOM3Document.h"
#include "nsIDOMDocument.h"
#include "nsGenericElement.h"
#include "nsIContent.h"
#include "nsIDocument.h"
@ -298,7 +298,7 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMNode *aNode,
}
if (!mContent->HasSameOwnerDoc(iAttribute)) {
nsCOMPtr<nsIDOM3Document> domDoc =
nsCOMPtr<nsIDOMDocument> domDoc =
do_QueryInterface(mContent->GetOwnerDoc(), &rv);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -52,7 +52,6 @@
#include "nsTArray.h"
#include "nsHashSets.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMDocumentXBL.h"
#include "nsIDOMNSDocument.h"
@ -509,7 +508,6 @@ class nsDocument : public nsIDocument,
public nsIDOMDocumentRange,
public nsIDOMDocumentTraversal,
public nsIDOMDocumentXBL,
public nsIDOM3Document,
public nsSupportsWeakReference,
public nsIDOMEventTarget,
public nsIDOM3EventTarget,
@ -805,9 +803,6 @@ public:
// nsIDOMDocument
NS_DECL_NSIDOMDOCUMENT
// nsIDOM3Document
NS_DECL_NSIDOM3DOCUMENT
// nsIDOMXMLDocument
NS_DECL_NSIDOMXMLDOCUMENT
@ -1279,7 +1274,6 @@ protected:
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocumentTraversal, \
nsDocument) \
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMEventTarget, nsDocument) \
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMNode, nsDocument) \
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOM3Document, nsDocument)
NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMNode, nsDocument)
#endif /* nsDocument_h___ */

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

@ -3564,7 +3564,7 @@ nsINode::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
rv = kid->GetNodeType(&nodeType);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOM3Document> domDoc = do_QueryInterface(GetOwnerDoc());
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(GetOwnerDoc());
// DocumentType nodes are the only nodes that can have a null
// ownerDocument according to the DOM spec, and we need to allow
@ -4075,7 +4075,7 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
if (!HasSameOwnerDoc(newContent) &&
(nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE ||
newContent->GetOwnerDoc())) {
nsCOMPtr<nsIDOM3Document> domDoc = do_QueryInterface(doc);
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
if (domDoc) {
nsresult rv;

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

@ -220,8 +220,8 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
}
if (aLoaderPrincipal) {
listener = new nsCrossSiteListenerProxy(listener, aLoaderPrincipal,
mChannel, PR_FALSE, &rv);
listener = new nsCORSListenerProxy(listener, aLoaderPrincipal,
mChannel, PR_FALSE, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -227,9 +227,7 @@ nsTextFragment::SetTo(const PRUnichar* aBuffer, PRInt32 aLength)
}
// Copy data
// Use the same copying code we use elsewhere; it's likely to be
// carefully tuned.
LossyConvertEncoding<PRUnichar, char> converter(buff);
LossyConvertEncoding16to8 converter(buff);
copy_string(aBuffer, aBuffer+aLength, converter);
m1b = buff;
}
@ -260,9 +258,8 @@ nsTextFragment::CopyTo(PRUnichar *aDest, PRInt32 aOffset, PRInt32 aCount)
} else {
const char *cp = m1b + aOffset;
const char *end = cp + aCount;
while (cp < end) {
*aDest++ = (unsigned char)(*cp++);
}
LossyConvertEncoding8to16 converter(aDest);
copy_string(cp, end, converter);
}
}
}
@ -316,11 +313,10 @@ nsTextFragment::Append(const PRUnichar* aBuffer, PRUint32 aLength)
return;
}
// Copy data
for (PRUint32 i = 0; i < mState.mLength; ++i) {
buff[i] = (unsigned char)m1b[i];
}
// Copy data into buff
LossyConvertEncoding8to16 converter(buff);
copy_string(m1b, m1b+mState.mLength, converter);
memcpy(buff + mState.mLength, aBuffer, aLength * sizeof(PRUnichar));
mState.mLength += aLength;
@ -354,10 +350,10 @@ nsTextFragment::Append(const PRUnichar* aBuffer, PRUint32 aLength)
memcpy(buff, m1b, mState.mLength);
mState.mInHeap = PR_TRUE;
}
for (PRUint32 i = 0; i < aLength; ++i) {
buff[mState.mLength + i] = (char)aBuffer[i];
}
// Copy aBuffer into buff.
LossyConvertEncoding16to8 converter(buff + mState.mLength);
copy_string(aBuffer, aBuffer + aLength, converter);
m1b = buff;
mState.mLength += aLength;

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

@ -87,7 +87,6 @@
#include "nsCrossSiteListenerProxy.h"
#include "nsDOMError.h"
#include "nsIHTMLDocument.h"
#include "nsIDOM3Document.h"
#include "nsIMultiPartChannel.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIStorageStream.h"
@ -146,8 +145,6 @@
XML_HTTP_REQUEST_SENT | \
XML_HTTP_REQUEST_STOPPED)
#define ACCESS_CONTROL_CACHE_SIZE 100
#define NS_BADCERTHANDLER_CONTRACTID \
"@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
@ -286,225 +283,6 @@ nsMultipartProxyListener::OnDataAvailable(nsIRequest *aRequest,
count);
}
// Class used as streamlistener and notification callback when
// doing the initial GET request for an access-control check
class nsACProxyListener : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink
{
public:
nsACProxyListener(nsIChannel* aOuterChannel,
nsIStreamListener* aOuterListener,
nsISupports* aOuterContext,
nsIPrincipal* aReferrerPrincipal,
const nsACString& aRequestMethod,
PRBool aWithCredentials)
: mOuterChannel(aOuterChannel), mOuterListener(aOuterListener),
mOuterContext(aOuterContext), mReferrerPrincipal(aReferrerPrincipal),
mRequestMethod(aRequestMethod), mWithCredentials(aWithCredentials)
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
private:
void AddResultToCache(nsIRequest* aRequest);
nsCOMPtr<nsIChannel> mOuterChannel;
nsCOMPtr<nsIStreamListener> mOuterListener;
nsCOMPtr<nsISupports> mOuterContext;
nsCOMPtr<nsIPrincipal> mReferrerPrincipal;
nsCString mRequestMethod;
PRBool mWithCredentials;
};
NS_IMPL_ISUPPORTS4(nsACProxyListener, nsIStreamListener, nsIRequestObserver,
nsIInterfaceRequestor, nsIChannelEventSink)
void
nsACProxyListener::AddResultToCache(nsIRequest *aRequest)
{
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest);
NS_ASSERTION(http, "Request was not http");
// The "Access-Control-Max-Age" header should return an age in seconds.
nsCAutoString headerVal;
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Max-Age"),
headerVal);
if (headerVal.IsEmpty()) {
return;
}
// Sanitize the string. We only allow 'delta-seconds' as specified by
// http://dev.w3.org/2006/waf/access-control (digits 0-9 with no leading or
// trailing non-whitespace characters).
PRUint32 age = 0;
nsCSubstring::const_char_iterator iter, end;
headerVal.BeginReading(iter);
headerVal.EndReading(end);
while (iter != end) {
if (*iter < '0' || *iter > '9') {
return;
}
age = age * 10 + (*iter - '0');
// Cap at 24 hours. This also avoids overflow
age = NS_MIN(age, 86400U);
++iter;
}
if (!age || !nsXMLHttpRequest::EnsureACCache()) {
return;
}
// String seems fine, go ahead and cache.
// Note that we have already checked that these headers follow the correct
// syntax.
nsCOMPtr<nsIURI> uri;
NS_GetFinalChannelURI(http, getter_AddRefs(uri));
// PR_Now gives microseconds
PRTime expirationTime = PR_Now() + (PRUint64)age * PR_USEC_PER_SEC;
nsAccessControlLRUCache::CacheEntry* entry =
nsXMLHttpRequest::sAccessControlCache->
GetEntry(uri, mReferrerPrincipal, mWithCredentials, PR_TRUE);
if (!entry) {
return;
}
// The "Access-Control-Allow-Methods" header contains a comma separated
// list of method names.
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
headerVal);
nsCCharSeparatedTokenizer methods(headerVal, ',');
while(methods.hasMoreTokens()) {
const nsDependentCSubstring& method = methods.nextToken();
if (method.IsEmpty()) {
continue;
}
PRUint32 i;
for (i = 0; i < entry->mMethods.Length(); ++i) {
if (entry->mMethods[i].token.Equals(method)) {
entry->mMethods[i].expirationTime = expirationTime;
break;
}
}
if (i == entry->mMethods.Length()) {
nsAccessControlLRUCache::TokenTime* newMethod =
entry->mMethods.AppendElement();
if (!newMethod) {
return;
}
newMethod->token = method;
newMethod->expirationTime = expirationTime;
}
}
// The "Access-Control-Allow-Headers" header contains a comma separated
// list of method names.
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
headerVal);
nsCCharSeparatedTokenizer headers(headerVal, ',');
while(headers.hasMoreTokens()) {
const nsDependentCSubstring& header = headers.nextToken();
if (header.IsEmpty()) {
continue;
}
PRUint32 i;
for (i = 0; i < entry->mHeaders.Length(); ++i) {
if (entry->mHeaders[i].token.Equals(header)) {
entry->mHeaders[i].expirationTime = expirationTime;
break;
}
}
if (i == entry->mHeaders.Length()) {
nsAccessControlLRUCache::TokenTime* newHeader =
entry->mHeaders.AppendElement();
if (!newHeader) {
return;
}
newHeader->token = header;
newHeader->expirationTime = expirationTime;
}
}
}
NS_IMETHODIMP
nsACProxyListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
{
nsresult status;
nsresult rv = aRequest->GetStatus(&status);
if (NS_SUCCEEDED(rv)) {
rv = status;
}
if (NS_SUCCEEDED(rv)) {
// Everything worked, try to cache and then fire off the actual request.
AddResultToCache(aRequest);
rv = mOuterChannel->AsyncOpen(mOuterListener, mOuterContext);
}
if (NS_FAILED(rv)) {
mOuterChannel->Cancel(rv);
mOuterListener->OnStartRequest(mOuterChannel, mOuterContext);
mOuterListener->OnStopRequest(mOuterChannel, mOuterContext, rv);
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
nsACProxyListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatus)
{
return NS_OK;
}
/** nsIStreamListener methods **/
NS_IMETHODIMP
nsACProxyListener::OnDataAvailable(nsIRequest *aRequest,
nsISupports *ctxt,
nsIInputStream *inStr,
PRUint32 sourceOffset,
PRUint32 count)
{
return NS_OK;
}
NS_IMETHODIMP
nsACProxyListener::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *callback)
{
// Only internal redirects allowed for now.
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags))
return NS_ERROR_DOM_BAD_URI;
callback->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
NS_IMETHODIMP
nsACProxyListener::GetInterface(const nsIID & aIID, void **aResult)
{
return QueryInterface(aIID, aResult);
}
/////////////////////////////////////////////
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
@ -633,219 +411,11 @@ NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
void
nsAccessControlLRUCache::CacheEntry::PurgeExpired(PRTime now)
{
PRUint32 i;
for (i = 0; i < mMethods.Length(); ++i) {
if (now >= mMethods[i].expirationTime) {
mMethods.RemoveElementAt(i--);
}
}
for (i = 0; i < mHeaders.Length(); ++i) {
if (now >= mHeaders[i].expirationTime) {
mHeaders.RemoveElementAt(i--);
}
}
}
PRBool
nsAccessControlLRUCache::CacheEntry::CheckRequest(const nsCString& aMethod,
const nsTArray<nsCString>& aHeaders)
{
PurgeExpired(PR_Now());
if (!aMethod.EqualsLiteral("GET") && !aMethod.EqualsLiteral("POST")) {
PRUint32 i;
for (i = 0; i < mMethods.Length(); ++i) {
if (aMethod.Equals(mMethods[i].token))
break;
}
if (i == mMethods.Length()) {
return PR_FALSE;
}
}
for (PRUint32 i = 0; i < aHeaders.Length(); ++i) {
PRUint32 j;
for (j = 0; j < mHeaders.Length(); ++j) {
if (aHeaders[i].Equals(mHeaders[j].token,
nsCaseInsensitiveCStringComparator())) {
break;
}
}
if (j == mHeaders.Length()) {
return PR_FALSE;
}
}
return PR_TRUE;
}
nsAccessControlLRUCache::CacheEntry*
nsAccessControlLRUCache::GetEntry(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
PRBool aCreate)
{
nsCString key;
if (!GetCacheKey(aURI, aPrincipal, aWithCredentials, key)) {
NS_WARNING("Invalid cache key!");
return nsnull;
}
CacheEntry* entry;
if (mTable.Get(key, &entry)) {
// Entry already existed so just return it. Also update the LRU list.
// Move to the head of the list.
PR_REMOVE_LINK(entry);
PR_INSERT_LINK(entry, &mList);
return entry;
}
if (!aCreate) {
return nsnull;
}
// This is a new entry, allocate and insert into the table now so that any
// failures don't cause items to be removed from a full cache.
entry = new CacheEntry(key);
if (!entry) {
NS_WARNING("Failed to allocate new cache entry!");
return nsnull;
}
if (!mTable.Put(key, entry)) {
// Failed, clean up the new entry.
delete entry;
NS_WARNING("Failed to add entry to the access control cache!");
return nsnull;
}
PR_INSERT_LINK(entry, &mList);
NS_ASSERTION(mTable.Count() <= ACCESS_CONTROL_CACHE_SIZE + 1,
"Something is borked, too many entries in the cache!");
// Now enforce the max count.
if (mTable.Count() > ACCESS_CONTROL_CACHE_SIZE) {
// Try to kick out all the expired entries.
PRTime now = PR_Now();
mTable.Enumerate(RemoveExpiredEntries, &now);
// If that didn't remove anything then kick out the least recently used
// entry.
if (mTable.Count() > ACCESS_CONTROL_CACHE_SIZE) {
CacheEntry* lruEntry = static_cast<CacheEntry*>(PR_LIST_TAIL(&mList));
PR_REMOVE_LINK(lruEntry);
// This will delete 'lruEntry'.
mTable.Remove(lruEntry->mKey);
NS_ASSERTION(mTable.Count() == ACCESS_CONTROL_CACHE_SIZE,
"Somehow tried to remove an entry that was never added!");
}
}
return entry;
}
void
nsAccessControlLRUCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
{
CacheEntry* entry;
nsCString key;
if (GetCacheKey(aURI, aPrincipal, PR_TRUE, key) &&
mTable.Get(key, &entry)) {
PR_REMOVE_LINK(entry);
mTable.Remove(key);
}
if (GetCacheKey(aURI, aPrincipal, PR_FALSE, key) &&
mTable.Get(key, &entry)) {
PR_REMOVE_LINK(entry);
mTable.Remove(key);
}
}
void
nsAccessControlLRUCache::Clear()
{
PR_INIT_CLIST(&mList);
mTable.Clear();
}
/* static */ PLDHashOperator
nsAccessControlLRUCache::RemoveExpiredEntries(const nsACString& aKey,
nsAutoPtr<CacheEntry>& aValue,
void* aUserData)
{
PRTime* now = static_cast<PRTime*>(aUserData);
aValue->PurgeExpired(*now);
if (aValue->mHeaders.IsEmpty() &&
aValue->mHeaders.IsEmpty()) {
// Expired, remove from the list as well as the hash table.
PR_REMOVE_LINK(aValue);
return PL_DHASH_REMOVE;
}
return PL_DHASH_NEXT;
}
/* static */ PRBool
nsAccessControlLRUCache::GetCacheKey(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRBool aWithCredentials,
nsACString& _retval)
{
NS_ASSERTION(aURI, "Null uri!");
NS_ASSERTION(aPrincipal, "Null principal!");
NS_NAMED_LITERAL_CSTRING(space, " ");
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCAutoString scheme, host, port;
if (uri) {
uri->GetScheme(scheme);
uri->GetHost(host);
port.AppendInt(NS_GetRealPort(uri));
}
nsCAutoString cred;
if (aWithCredentials) {
_retval.AssignLiteral("cred");
}
else {
_retval.AssignLiteral("nocred");
}
nsCAutoString spec;
rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
_retval.Assign(cred + space + scheme + space + host + space + port + space +
spec);
return PR_TRUE;
}
/////////////////////////////////////////////
//
//
/////////////////////////////////////////////
// Will be initialized in nsXMLHttpRequest::EnsureACCache.
nsAccessControlLRUCache* nsXMLHttpRequest::sAccessControlCache = nsnull;
nsXMLHttpRequest::nsXMLHttpRequest()
: mRequestObserver(nsnull), mState(XML_HTTP_REQUEST_UNINITIALIZED),
mUploadTransferred(0), mUploadTotal(0), mUploadComplete(PR_TRUE),
@ -985,7 +555,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mResponseXML)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mACGetChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCORSPreflightChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnReadystatechangeListener)
@ -1006,7 +576,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResponseXML)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mACGetChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCORSPreflightChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
@ -1363,8 +933,8 @@ nsXMLHttpRequest::Abort()
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
if (mACGetChannel) {
mACGetChannel->Cancel(NS_BINDING_ABORTED);
if (mCORSPreflightChannel) {
mCORSPreflightChannel->Cancel(NS_BINDING_ABORTED);
}
mResponseXML = nsnull;
PRUint32 responseLength = mResponseBody.Length();
@ -1390,7 +960,7 @@ nsXMLHttpRequest::Abort()
}
// The ChangeState call above calls onreadystatechange handlers which
// if they load a new url will cause nsXMLHttpRequest::OpenRequest to clear
// if they load a new url will cause nsXMLHttpRequest::Open to clear
// the abort state bit. If this occurs we're not uninitialized (bug 361773).
if (mState & XML_HTTP_REQUEST_ABORTED) {
ChangeState(XML_HTTP_REQUEST_UNINITIALIZED, PR_FALSE); // IE seems to do it
@ -1655,7 +1225,7 @@ nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
nsCAutoString method;
httpChannel->GetRequestMethod(method);
if (!mACUnsafeHeaders.IsEmpty() ||
if (!mCORSUnsafeHeaders.IsEmpty() ||
HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
(mUpload && mUpload->HasListeners()) ||
(!method.LowerCaseEqualsLiteral("get") &&
@ -1667,16 +1237,18 @@ nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
return NS_OK;
}
/* noscript void openRequest (in AUTF8String method, in AUTF8String url, in boolean async, in AString user, in AString password); */
NS_IMETHODIMP
nsXMLHttpRequest::OpenRequest(const nsACString& method,
const nsACString& url,
PRBool async,
const nsAString& user,
const nsAString& password)
nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
PRBool async, const nsAString& user,
const nsAString& password, PRUint8 optional_argc)
{
NS_ENSURE_ARG(!method.IsEmpty());
if (!optional_argc) {
// No optional arguments were passed in. Default async to true.
async = PR_TRUE;
}
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
// Disallow HTTP/1.1 TRACE method (see bug 302489)
@ -1806,20 +1378,6 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
return rv;
}
/* void open (in AUTF8String method, in AUTF8String url); */
NS_IMETHODIMP
nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
PRBool async, const nsAString& user,
const nsAString& password, PRUint8 optional_argc)
{
if (!optional_argc) {
// No optional arguments were passed in. Default async to true.
async = PR_TRUE;
}
return OpenRequest(method, url, async, user, password);
}
/*
* "Copy" from a stream.
*/
@ -2279,13 +1837,10 @@ GetRequestBody(nsIVariant* aBody, nsIInputStream** aResult,
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(supports);
if (doc) {
aContentType.AssignLiteral("application/xml");
nsCOMPtr<nsIDOM3Document> dom3doc = do_QueryInterface(doc);
if (dom3doc) {
nsAutoString inputEncoding;
dom3doc->GetInputEncoding(inputEncoding);
if (!DOMStringIsNull(inputEncoding)) {
CopyUTF16toUTF8(inputEncoding, aCharset);
}
nsAutoString inputEncoding;
doc->GetInputEncoding(inputEncoding);
if (!DOMStringIsNull(inputEncoding)) {
CopyUTF16toUTF8(inputEncoding, aCharset);
}
// Serialize to a stream so that the encoding used will
@ -2571,7 +2126,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
if (!contentType.LowerCaseEqualsLiteral("text/plain") &&
!contentType.LowerCaseEqualsLiteral("application/x-www-form-urlencoded") &&
!contentType.LowerCaseEqualsLiteral("multipart/form-data")) {
mACUnsafeHeaders.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
mCORSUnsafeHeaders.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
}
}
}
@ -2588,41 +2143,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
PRBool withCredentials = !!(mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS);
// If so, set up the preflight
if (mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT) {
// Check to see if this initial OPTIONS request has already been cached
// in our special Access Control Cache.
nsCOMPtr<nsIURI> uri;
rv = NS_GetFinalChannelURI(mChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsAccessControlLRUCache::CacheEntry* entry =
sAccessControlCache ?
sAccessControlCache->GetEntry(uri, mPrincipal, withCredentials, PR_FALSE) :
nsnull;
if (!entry || !entry->CheckRequest(method, mACUnsafeHeaders)) {
// Either it wasn't cached or the cached result has expired. Build a
// channel for the OPTIONS request.
nsCOMPtr<nsILoadGroup> loadGroup;
GetLoadGroup(getter_AddRefs(loadGroup));
nsLoadFlags loadFlags;
rv = mChannel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewChannel(getter_AddRefs(mACGetChannel), uri, nsnull,
loadGroup, nsnull, loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannel> acHttp = do_QueryInterface(mACGetChannel);
NS_ASSERTION(acHttp, "Failed to QI to nsIHttpChannel!");
rv = acHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
NS_ENSURE_SUCCESS(rv, rv);
}
}
// Hook us up to listen to redirects and the like
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
@ -2637,10 +2157,10 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
}
if (!IsSystemXHR()) {
// Always create a nsCrossSiteListenerProxy here even if it's
// Always create a nsCORSListenerProxy here even if it's
// a same-origin request right now, since it could be redirected.
listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
withCredentials, &rv);
listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
withCredentials, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -2661,10 +2181,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
else if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
AddLoadFlags(mChannel,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
if (mACGetChannel) {
AddLoadFlags(mACGetChannel,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
}
}
// Since we expect XML data, set the type hint accordingly
@ -2672,22 +2188,16 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
// ignoring return value, as this is not critical
mChannel->SetContentType(NS_LITERAL_CSTRING("application/xml"));
// If we're doing a cross-site non-GET request we need to first do
// a GET request to the same URI. Set that up if needed
if (mACGetChannel) {
nsCOMPtr<nsIStreamListener> acProxyListener =
new nsACProxyListener(mChannel, listener, nsnull, mPrincipal, method,
withCredentials);
NS_ENSURE_TRUE(acProxyListener, NS_ERROR_OUT_OF_MEMORY);
// Set up the preflight if needed
if (mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT) {
// Check to see if this initial OPTIONS request has already been cached
// in our special Access Control Cache.
acProxyListener =
new nsCrossSiteListenerProxy(acProxyListener, mPrincipal, mACGetChannel,
withCredentials, method, mACUnsafeHeaders,
&rv);
NS_ENSURE_TRUE(acProxyListener, NS_ERROR_OUT_OF_MEMORY);
rv = NS_StartCORSPreflight(mChannel, listener,
mPrincipal, withCredentials,
mCORSUnsafeHeaders,
getter_AddRefs(mCORSPreflightChannel));
NS_ENSURE_SUCCESS(rv, rv);
rv = mACGetChannel->AsyncOpen(acProxyListener, nsnull);
}
else {
// Start reading from the channel
@ -2697,7 +2207,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
if (NS_FAILED(rv)) {
// Drop our ref to the channel to avoid cycles
mChannel = nsnull;
mACGetChannel = nsnull;
mCORSPreflightChannel = nsnull;
return rv;
}
@ -2774,17 +2284,17 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
{
nsresult rv;
// Make sure we don't store an invalid header name in mACUnsafeHeaders
// Make sure we don't store an invalid header name in mCORSUnsafeHeaders
if (!IsValidHTTPToken(header)) {
return NS_ERROR_FAILURE;
}
// Check that we haven't already opened the channel. We can't rely on
// the channel throwing from mChannel->SetRequestHeader since we might
// still be waiting for mACGetChannel to actually open mChannel
if (mACGetChannel) {
// still be waiting for mCORSPreflightChannel to actually open mChannel
if (mCORSPreflightChannel) {
PRBool pending;
rv = mACGetChannel->IsPending(&pending);
rv = mCORSPreflightChannel->IsPending(&pending);
NS_ENSURE_SUCCESS(rv, rv);
if (pending) {
@ -2849,7 +2359,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
}
if (!safeHeader) {
mACUnsafeHeaders.AppendElement(header);
mCORSUnsafeHeaders.AppendElement(header);
}
}

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

@ -60,10 +60,6 @@
#include "nsTArray.h"
#include "nsIJSNativeInitializer.h"
#include "nsIDOMLSProgressEvent.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "prclist.h"
#include "prtime.h"
#include "nsIDOMNSEvent.h"
#include "nsITimer.h"
#include "nsIPrivateDOMEvent.h"
@ -74,72 +70,6 @@
class nsILoadGroup;
class AsyncVerifyRedirectCallbackForwarder;
class nsAccessControlLRUCache
{
public:
struct TokenTime
{
nsCString token;
PRTime expirationTime;
};
struct CacheEntry : public PRCList
{
CacheEntry(nsCString& aKey)
: mKey(aKey)
{
MOZ_COUNT_CTOR(nsAccessControlLRUCache::CacheEntry);
}
~CacheEntry()
{
MOZ_COUNT_DTOR(nsAccessControlLRUCache::CacheEntry);
}
void PurgeExpired(PRTime now);
PRBool CheckRequest(const nsCString& aMethod,
const nsTArray<nsCString>& aCustomHeaders);
nsCString mKey;
nsTArray<TokenTime> mMethods;
nsTArray<TokenTime> mHeaders;
};
nsAccessControlLRUCache()
{
MOZ_COUNT_CTOR(nsAccessControlLRUCache);
PR_INIT_CLIST(&mList);
}
~nsAccessControlLRUCache()
{
Clear();
MOZ_COUNT_DTOR(nsAccessControlLRUCache);
}
PRBool Initialize()
{
return mTable.Init();
}
CacheEntry* GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRBool aWithCredentials, PRBool aCreate);
void RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal);
void Clear();
private:
static PLDHashOperator
RemoveExpiredEntries(const nsACString& aKey, nsAutoPtr<CacheEntry>& aValue,
void* aUserData);
static PRBool GetCacheKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRBool aWithCredentials, nsACString& _retval);
nsClassHashtable<nsCStringHashKey, CacheEntry> mTable;
PRCList mList;
};
class nsXHREventTarget : public nsDOMEventTargetWrapperCache,
public nsIXMLHttpRequestEventTarget
{
@ -281,32 +211,8 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequest,
nsXHREventTarget)
static PRBool EnsureACCache()
{
if (sAccessControlCache)
return PR_TRUE;
nsAutoPtr<nsAccessControlLRUCache> newCache(new nsAccessControlLRUCache());
NS_ENSURE_TRUE(newCache, PR_FALSE);
if (newCache->Initialize()) {
sAccessControlCache = newCache.forget();
return PR_TRUE;
}
return PR_FALSE;
}
static void ShutdownACCache()
{
delete sAccessControlCache;
sAccessControlCache = nsnull;
}
PRBool AllowUploadProgress();
static nsAccessControlLRUCache* sAccessControlCache;
protected:
friend class nsMultipartProxyListener;
@ -357,8 +263,8 @@ protected:
// mReadRequest is different from mChannel for multipart requests
nsCOMPtr<nsIRequest> mReadRequest;
nsCOMPtr<nsIDOMDocument> mResponseXML;
nsCOMPtr<nsIChannel> mACGetChannel;
nsTArray<nsCString> mACUnsafeHeaders;
nsCOMPtr<nsIChannel> mCORSPreflightChannel;
nsTArray<nsCString> mCORSUnsafeHeaders;
nsRefPtr<nsDOMEventListenerWrapper> mOnUploadProgressListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnReadystatechangeListener;

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

@ -76,7 +76,7 @@ nsresult TestGetURL(const nsCString& aURL)
rv = xhr->Init(systemPrincipal, nsnull, nsnull, nsnull);
TEST_ENSURE_SUCCESS(rv, "Couldn't initialize the XHR!");
rv = xhr->OpenRequest(getString, aURL, PR_FALSE, empty, empty);
rv = xhr->Open(getString, aURL, PR_FALSE, empty, empty);
TEST_ENSURE_SUCCESS(rv, "OpenRequest failed!");
rv = xhr->Send(nsnull);

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

@ -77,9 +77,9 @@ nsresult TestNativeXMLHttpRequest()
const nsAString& empty = EmptyString();
printf("*** About to see an expected warning about mPrincipal:\n");
rv = xhr->OpenRequest(getString, testURL, PR_FALSE, empty, empty);
rv = xhr->Open(getString, testURL, PR_FALSE, empty, empty);
printf("*** End of expected warning output.\n");
TEST_ENSURE_FAILED(rv, "OpenRequest should have failed!");
TEST_ENSURE_FAILED(rv, "Open should have failed!");
nsCOMPtr<nsIScriptSecurityManager> secman =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
@ -92,8 +92,8 @@ nsresult TestNativeXMLHttpRequest()
rv = xhr->Init(systemPrincipal, nsnull, nsnull, nsnull);
TEST_ENSURE_SUCCESS(rv, "Couldn't initialize the XHR!");
rv = xhr->OpenRequest(getString, testURL, PR_FALSE, empty, empty);
TEST_ENSURE_SUCCESS(rv, "OpenRequest failed!");
rv = xhr->Open(getString, testURL, PR_FALSE, empty, empty);
TEST_ENSURE_SUCCESS(rv, "Open failed!");
rv = xhr->Send(nsnull);
TEST_ENSURE_SUCCESS(rv, "Send failed!");

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

@ -25,7 +25,7 @@ window.addEventListener("message", function(e) {
};
var xhr = new XMLHttpRequest();
for each(type in ["load", "abort", "error", "loadstart"]) {
for each(type in ["load", "abort", "error", "loadstart", "loadend"]) {
xhr.addEventListener(type, function(e) {
res.events.push(e.type);
}, false);
@ -48,10 +48,10 @@ window.addEventListener("message", function(e) {
}, false);
}
}
xhr.onload = xhr.onerror = function (event) {
if (event.type == "error") {
res.didFail = true;
}
xhr.onerror = function(e) {
res.didFail = true;
};
xhr.onloadend = function (event) {
res.status = xhr.status;
try {
res.statusText = xhr.statusText;

Двоичные данные
content/base/test/file_CrossSiteXHR_inner.jar

Двоичный файл не отображается.

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

@ -14,7 +14,7 @@ window.addEventListener("message", function(e) {\n\
};\n\
\n\
var xhr = new XMLHttpRequest();\n\
for each(type in ["load", "abort", "error", "loadstart"]) {\n\
for each(type in ["load", "abort", "error", "loadstart", "loadend"]) {\n\
xhr.addEventListener(type, function(e) {\n\
res.events.push(e.type);\n\
}, false);\n\
@ -37,26 +37,27 @@ window.addEventListener("message", function(e) {\n\
}, false);\n\
}\n\
}\n\
xhr.onload = function () {\n\
res.status = xhr.status;\n\
res.statusText = xhr.statusText;\n\
res.responseXML = xhr.responseXML ?\n\
(new XMLSerializer()).serializeToString(xhr.responseXML) :\n\
null;\n\
res.responseText = xhr.responseText;\n\
post(e, res);\n\
};\n\
xhr.onerror = function () {\n\
xhr.onerror = function(e) {\n\
res.didFail = true;\n\
};\n\
xhr.onloadend = function (event) {\n\
res.status = xhr.status;\n\
try {\n\
res.statusText = xhr.statusText;\n\
} catch (e) {\n\
delete(res.statusText);\n\
}\n\
res.responseXML = xhr.responseXML ?\n\
(new XMLSerializer()).serializeToString(xhr.responseXML) :\n\
null;\n\
res.responseText = xhr.responseText;\n\
\n\
res.responseHeaders = {};\n\
for (responseHeader in req.responseHeaders) {\n\
res.responseHeaders[responseHeader] =\n\
xhr.getResponseHeader(responseHeader);\n\
}\n\
\n\
post(e, res);\n\
}\n\
\n\

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

@ -656,7 +656,7 @@ function runTest() {
is(res.responseText, "<res>hello pass</res>\n",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load,loadend",
"wrong responseText in test for " + test.toSource());
}
else {
@ -665,7 +665,7 @@ function runTest() {
is(res.responseText, "",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,load,loadend",
"wrong responseText in test for " + test.toSource());
}
if (test.responseHeaders) {
@ -694,7 +694,7 @@ function runTest() {
"wrong responseText in test for " + test.toSource());
if (!res.sendThrew) {
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend",
"wrong events in test for " + test.toSource());
}
is(res.progressEvents, 0,
@ -822,7 +822,7 @@ function runTest() {
is(res.responseText, "<res>hello pass</res>\n",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load,loadend",
"wrong responseText in test for " + test.toSource());
}
else {
@ -835,7 +835,7 @@ function runTest() {
is(res.responseText, "",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend",
"wrong events in test for " + test.toSource());
is(res.progressEvents, 0,
"wrong events in test for " + test.toSource());
@ -1091,7 +1091,7 @@ function runTest() {
is(res.responseText, "<res>hello pass</res>\n",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load,loadend",
"wrong responseText in test for " + test.toSource());
}
else {
@ -1104,7 +1104,7 @@ function runTest() {
is(res.responseText, "",
"wrong responseText in test for " + test.toSource());
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend",
"wrong events in test for " + test.toSource());
is(res.progressEvents, 0,
"wrong progressevents in test for " + test.toSource());

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

@ -464,7 +464,7 @@ function runTest() {
is(res.responseText, "<res>hello pass</res>\n",
"wrong responseText in test for " + testName);
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load,loadend",
"wrong events in test for " + testName);
}
else {
@ -476,15 +476,13 @@ function runTest() {
is(res.responseText, "",
"wrong responseText in test for " + testName);
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend",
"wrong events in test for " + testName);
is(res.progressEvents, 0,
"wrong events in test for " + testName);
}
}
SimpleTest.finish();
yield;

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

@ -133,7 +133,7 @@ function runTest() {
is(res.responseText, "<res>hello pass</res>\n",
"wrong responseText in test for " + allowOrigin);
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load",
"opening,rs1,sending,rs1,loadstart,rs2,rs3,rs4,load,loadend",
"wrong responseText in test for " + allowOrigin);
}
@ -151,7 +151,7 @@ function runTest() {
is(res.statusText, "", "wrong status text for " + allowOrigin);
is(res.responseXML, null, "should have no XML for " + allowOrigin);
is(res.events.join(","),
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error",
"opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend",
"wrong events in test for " + allowOrigin);
is(res.progressEvents, 0,
"wrong events in test for " + allowOrigin);

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

@ -42,7 +42,6 @@
#include "nsIAtom.h"
#include "nsIContentViewer.h"
#include "mozilla/css/StyleRule.h"
#include "nsCSSStruct.h"
#include "nsIDocument.h"
#include "nsIDocumentEncoder.h"
#include "nsIDOMHTMLBodyElement.h"

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

@ -43,7 +43,6 @@
#include "nsStyleConsts.h"
#include "nsPresContext.h"
#include "nsMappedAttributes.h"
#include "nsCSSStruct.h"
#include "nsRuleData.h"
#include "nsIDocument.h"

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

@ -974,11 +974,11 @@ nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
nsCOMPtr<nsIStreamListener> listener;
if (ShouldCheckAllowOrigin()) {
listener =
new nsCrossSiteListenerProxy(loadListener,
NodePrincipal(),
channel,
PR_FALSE,
&rv);
new nsCORSListenerProxy(loadListener,
NodePrincipal(),
channel,
PR_FALSE,
&rv);
} else {
rv = nsContentUtils::GetSecurityManager()->
CheckLoadURIWithPrincipal(NodePrincipal(),

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

@ -41,7 +41,6 @@
#include "nsStyleConsts.h"
#include "nsMappedAttributes.h"
#include "nsRuleData.h"
#include "nsCSSStruct.h"
class nsHTMLPreElement : public nsGenericHTMLElement,
public nsIDOMHTMLPreElement

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

@ -1320,7 +1320,12 @@ nsHTMLDocument::GetElementsByTagName(const nsAString& aTagname,
return nsDocument::GetElementsByTagName(aTagname, aReturn);
}
// nsIDOM3Document interface implementation
NS_IMETHODIMP
nsHTMLDocument::GetInputEncoding(nsAString& aInputEncoding)
{
return nsDocument::GetInputEncoding(aInputEncoding);
}
NS_IMETHODIMP
nsHTMLDocument::GetXmlEncoding(nsAString& aXmlEncoding)
{
@ -1334,7 +1339,7 @@ nsHTMLDocument::GetXmlEncoding(nsAString& aXmlEncoding)
}
NS_IMETHODIMP
nsHTMLDocument::GetXmlStandalone(PRBool *aXmlStandalone)
nsHTMLDocument::GetXmlStandalone(PRBool* aXmlStandalone)
{
if (!IsHTML()) {
return nsDocument::GetXmlStandalone(aXmlStandalone);
@ -1355,7 +1360,6 @@ nsHTMLDocument::SetXmlStandalone(PRBool aXmlStandalone)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
NS_IMETHODIMP
nsHTMLDocument::GetXmlVersion(nsAString& aXmlVersion)
{
@ -1378,6 +1382,57 @@ nsHTMLDocument::SetXmlVersion(const nsAString& aXmlVersion)
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
NS_IMETHODIMP
nsHTMLDocument::GetStrictErrorChecking(PRBool* aStrictErrorChecking)
{
return nsDocument::GetStrictErrorChecking(aStrictErrorChecking);
}
NS_IMETHODIMP
nsHTMLDocument::SetStrictErrorChecking(PRBool aStrictErrorChecking)
{
return nsDocument::SetStrictErrorChecking(aStrictErrorChecking);
}
NS_IMETHODIMP
nsHTMLDocument::GetDocumentURI(nsAString& aDocumentURI)
{
return nsDocument::GetDocumentURI(aDocumentURI);
}
NS_IMETHODIMP
nsHTMLDocument::SetDocumentURI(const nsAString& aDocumentURI)
{
return nsDocument::SetDocumentURI(aDocumentURI);
}
NS_IMETHODIMP
nsHTMLDocument::AdoptNode(nsIDOMNode* aSource, nsIDOMNode** aRetval)
{
return nsDocument::AdoptNode(aSource, aRetval);
}
NS_IMETHODIMP
nsHTMLDocument::GetDomConfig(nsIDOMDOMConfiguration** aDomConfig)
{
return nsDocument::GetDomConfig(aDomConfig);
}
NS_IMETHODIMP
nsHTMLDocument::NormalizeDocument()
{
return nsDocument::NormalizeDocument();
}
NS_IMETHODIMP
nsHTMLDocument::RenameNode(nsIDOMNode* aNode,
const nsAString& aNamespaceURI,
const nsAString& aQualifiedName,
nsIDOMNode** aRetval)
{
return nsDocument::RenameNode(aNode, aNamespaceURI, aQualifiedName, aRetval);
}
//
// nsIDOMHTMLDocument interface implementation
//

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

@ -74,6 +74,8 @@ class nsHTMLDocument : public nsDocument,
public nsIDOMNSHTMLDocument
{
public:
using nsDocument::SetDocumentURI;
nsHTMLDocument();
virtual nsresult Init();
@ -123,13 +125,6 @@ public:
// nsIDOMDocument interface
NS_DECL_NSIDOMDOCUMENT
// nsIDOM3Document interface
NS_IMETHOD GetXmlEncoding(nsAString& aXmlVersion);
NS_IMETHOD GetXmlStandalone(PRBool *aXmlStandalone);
NS_IMETHOD SetXmlStandalone(PRBool aXmlStandalone);
NS_IMETHOD GetXmlVersion(nsAString& aXmlVersion);
NS_IMETHOD SetXmlVersion(const nsAString& aXmlVersion);
// nsIDOMNode interface
NS_FORWARD_NSIDOMNODE(nsDocument::)

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

@ -161,8 +161,8 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest)
NS_ENSURE_SUCCESS(rv, rv);
if (element->ShouldCheckAllowOrigin()) {
// If the request was cancelled by nsCrossSiteListenerProxy due to failing
// the Access Control check, send an error through to the media element.
// If the request was cancelled by nsCORSListenerProxy due to failing
// the CORS security check, send an error through to the media element.
if (status == NS_ERROR_DOM_BAD_URI) {
mDecoder->NetworkError();
return NS_ERROR_DOM_BAD_URI;
@ -457,12 +457,12 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener)
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
if (element->ShouldCheckAllowOrigin()) {
nsresult rv;
nsCrossSiteListenerProxy* crossSiteListener =
new nsCrossSiteListenerProxy(mListener,
element->NodePrincipal(),
mChannel,
PR_FALSE,
&rv);
nsCORSListenerProxy* crossSiteListener =
new nsCORSListenerProxy(mListener,
element->NodePrincipal(),
mChannel,
PR_FALSE,
&rv);
listener = crossSiteListener;
NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -79,7 +79,10 @@ nsOggCodecState::nsOggCodecState(ogg_page* aBosPage) :
nsOggCodecState::~nsOggCodecState() {
MOZ_COUNT_DTOR(nsOggCodecState);
int ret = ogg_stream_clear(&mState);
#ifdef DEBUG
int ret =
#endif
ogg_stream_clear(&mState);
NS_ASSERTION(ret == 0, "ogg_stream_clear failed");
}

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

@ -204,7 +204,11 @@ nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
if (ogg_page_bos(&page)) {
NS_ASSERTION(!readAllBOS, "We shouldn't encounter another BOS page");
codecState = nsOggCodecState::Create(&page);
PRBool r = mCodecStates.Put(serial, codecState);
#ifdef DEBUG
PRBool r =
#endif
mCodecStates.Put(serial, codecState);
NS_ASSERTION(r, "Failed to insert into mCodecStates");
bitstreams.AppendElement(codecState);
mKnownStreams.AppendElement(serial);

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

@ -511,8 +511,7 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, PRBool aEndOnly)
case STATE_STARTUP:
{
nsSMILInterval firstInterval;
mElementState =
NS_SUCCEEDED(GetNextInterval(nsnull, nsnull, firstInterval))
mElementState = GetNextInterval(nsnull, nsnull, firstInterval)
? STATE_WAITING
: STATE_POSTACTIVE;
stateChanged = PR_TRUE;
@ -556,8 +555,7 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, PRBool aEndOnly)
if (mCurrentInterval->End()->Time() <= sampleTime) {
nsSMILInterval newInterval;
mElementState =
NS_SUCCEEDED(GetNextInterval(mCurrentInterval, nsnull, newInterval))
mElementState = GetNextInterval(mCurrentInterval, nsnull, newInterval)
? STATE_WAITING
: STATE_POSTACTIVE;
if (mClient) {
@ -1483,17 +1481,17 @@ nsSMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList)
// See:
// http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LC-Start
//
nsresult
PRBool
nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
const nsSMILInstanceTime* aFixedBeginTime,
nsSMILInterval& aResult) const
{
NS_ABORT_IF_FALSE(!aFixedBeginTime || aFixedBeginTime->Time().IsResolved(),
"Unresolved begin time specified for interval start");
static nsSMILTimeValue zeroTime(0L);
static const nsSMILTimeValue zeroTime(0L);
if (mRestartMode == RESTART_NEVER && aPrevInterval)
return NS_ERROR_FAILURE;
return PR_FALSE;
// Calc starting point
nsSMILTimeValue beginAfter;
@ -1516,8 +1514,9 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
while (PR_TRUE) {
// Calculate begin time
if (aFixedBeginTime) {
if (aFixedBeginTime->Time() < beginAfter)
return NS_ERROR_FAILURE;
if (aFixedBeginTime->Time() < beginAfter) {
return PR_FALSE;
}
// our ref-counting is not const-correct
tempBegin = const_cast<nsSMILInstanceTime*>(aFixedBeginTime);
} else if ((!mAnimationElement ||
@ -1527,8 +1526,9 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
} else {
PRInt32 beginPos = 0;
tempBegin = GetNextGreaterOrEqual(mBeginInstances, beginAfter, beginPos);
if (!tempBegin || !tempBegin->Time().IsResolved())
return NS_ERROR_FAILURE;
if (!tempBegin || !tempBegin->Time().IsResolved()) {
return PR_FALSE;
}
}
NS_ABORT_IF_FALSE(tempBegin && tempBegin->Time().IsResolved() &&
tempBegin->Time() >= beginAfter,
@ -1560,7 +1560,7 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
mEndInstances.IsEmpty() ||
EndHasEventConditions();
if (!tempEnd && !openEndedIntervalOk)
return NS_ERROR_FAILURE; // Bad interval
return PR_FALSE; // Bad interval
nsSMILTimeValue intervalEnd = tempEnd
? tempEnd->Time() : nsSMILTimeValue();
@ -1588,19 +1588,19 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval,
if (tempEnd->Time() > zeroTime ||
(tempBegin->Time() == zeroTime && tempEnd->Time() == zeroTime)) {
aResult.Set(*tempBegin, *tempEnd);
return NS_OK;
return PR_TRUE;
}
if (mRestartMode == RESTART_NEVER) {
// tempEnd <= 0 so we're going to loop which effectively means restarting
return NS_ERROR_FAILURE;
return PR_FALSE;
}
beginAfter = tempEnd->Time();
}
NS_NOTREACHED("Hmm... we really shouldn't be here");
return NS_ERROR_FAILURE;
return PR_FALSE;
}
nsSMILInstanceTime*
@ -1803,10 +1803,7 @@ nsSMILTimedElement::UpdateCurrentInterval(PRBool aForceChangeNotice)
? mCurrentInterval->Begin()
: nsnull;
nsSMILInterval updatedInterval;
nsresult rv =
GetNextInterval(GetPreviousInterval(), beginTime, updatedInterval);
if (NS_SUCCEEDED(rv)) {
if (GetNextInterval(GetPreviousInterval(), beginTime, updatedInterval)) {
if (mElementState == STATE_POSTACTIVE) {

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

@ -475,12 +475,11 @@ protected:
* should be updated such as when the animation is in
* the ACTIVE state. May be nsnull.
* @param[out] aResult The next interval. Will be unchanged if no suitable
* interval was found (in which case NS_ERROR_FAILURE
* will be returned).
* @return NS_OK if a suitable interval was found, NS_ERROR_FAILURE
* otherwise.
* interval was found (in which case PR_FALSE will be
* returned).
* @return PR_TRUE if a suitable interval was found, PR_FALSE otherwise.
*/
nsresult GetNextInterval(const nsSMILInterval* aPrevInterval,
PRBool GetNextInterval(const nsSMILInterval* aPrevInterval,
const nsSMILInstanceTime* aFixedBeginTime,
nsSMILInterval& aResult) const;
nsSMILInstanceTime* GetNextGreater(const InstanceTimeList& aList,

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

@ -45,7 +45,9 @@
class nsSVGDocument : public nsXMLDocument,
public nsIDOMSVGDocument
{
public:
public:
using nsDocument::GetElementById;
using nsDocument::SetDocumentURI;
nsSVGDocument();
virtual ~nsSVGDocument();

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

@ -522,8 +522,8 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
// Always install in case of redirects
nsCOMPtr<nsIStreamListener> listener =
new nsCrossSiteListenerProxy(sink, aReferrerPrincipal, channel,
PR_FALSE, &rv);
new nsCORSListenerProxy(sink, aReferrerPrincipal, channel,
PR_FALSE, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -217,8 +217,8 @@ nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(scriptObject);
req->Init(docPrincipal, context, owner, nsnull);
rv = req->OpenRequest(NS_LITERAL_CSTRING("GET"), uriStr, PR_TRUE,
EmptyString(), EmptyString());
rv = req->Open(NS_LITERAL_CSTRING("GET"), uriStr, PR_TRUE,
EmptyString(), EmptyString());
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(req));

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

@ -53,7 +53,6 @@
#include "mozilla/dom/Element.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMStorageObsolete.h"

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

@ -80,7 +80,6 @@
#include "nsIAttribute.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMEvent.h"
@ -2194,7 +2193,6 @@ nsDOMClassInfo::WrapNativeParent(JSContext *cx, JSObject *scope,
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentXBL) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Document) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathEvaluator) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)

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

@ -108,7 +108,6 @@
#include "nsIDOMCrypto.h"
#endif
#include "nsIDOMDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMElement.h"
@ -4408,19 +4407,8 @@ nsGlobalWindow::SetFullScreen(PRBool aFullScreen)
mFullScreen = aFullScreen;
nsCOMPtr<nsIWidget> widget = GetMainWidget();
if (widget) {
PRBool visible;
widget->IsVisible(visible);
if (visible && aFullScreen)
widget->Show(PR_FALSE);
if (widget)
widget->MakeFullScreen(aFullScreen);
if (visible && aFullScreen) {
widget->Show(PR_TRUE);
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm)
fm->SetActiveWindow(this);
}
}
return NS_OK;
}
@ -7967,9 +7955,7 @@ nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
*aSessionStorage = nsnull;
nsString documentURI;
nsCOMPtr<nsIDOM3Document> document3 = do_QueryInterface(mDoc);
if (document3)
document3->GetDocumentURI(documentURI);
mDocument->GetDocumentURI(documentURI);
nsresult rv = docShell->GetSessionStorageForPrincipal(principal,
documentURI,
@ -8053,9 +8039,7 @@ nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
NS_ENSURE_SUCCESS(rv, rv);
nsString documentURI;
nsCOMPtr<nsIDOM3Document> document3 = do_QueryInterface(mDoc);
if (document3)
document3->GetDocumentURI(documentURI);
mDocument->GetDocumentURI(documentURI);
rv = storageManager->GetLocalStorageForPrincipal(principal,
documentURI,

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

@ -67,7 +67,6 @@ SDK_XPIDLSRCS = \
nsIDOMText.idl \
$(NULL)
XPIDLSRCS = \
nsIDOM3Document.idl \
nsIDOM3Node.idl \
nsIDOM3Text.idl \
nsIDOM3TypeInfo.idl \

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

@ -1,75 +0,0 @@
/* ***** 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
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christopher A. Aillon <christopher@aillon.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#include "domstubs.idl"
interface nsIDOMDOMConfiguration;
/**
* For more information on this interface, please see
* http://www.w3.org/TR/DOM-Level-3-Core/
*/
[scriptable, uuid(c0568f22-b9d5-427a-9642-b6a797edc5cd)]
interface nsIDOM3Document : nsISupports
{
// Introduced in DOM Level 3:
readonly attribute DOMString inputEncoding;
// Introduced in DOM Level 3:
readonly attribute DOMString xmlEncoding;
// Introduced in DOM Level 3:
attribute boolean xmlStandalone;
// raises(DOMException) on setting
// Introduced in DOM Level 3:
attribute DOMString xmlVersion;
// raises(DOMException) on setting
// Introduced in DOM Level 3:
attribute boolean strictErrorChecking;
// Introduced in DOM Level 3:
attribute DOMString documentURI;
// Introduced in DOM Level 3:
nsIDOMNode adoptNode(in nsIDOMNode source)
raises(DOMException);
// Introduced in DOM Level 3:
readonly attribute nsIDOMDOMConfiguration domConfig;
// Introduced in DOM Level 3:
void normalizeDocument();
// Introduced in DOM Level 3:
nsIDOMNode renameNode(in nsIDOMNode node,
in DOMString namespaceURI,
in DOMString qualifiedName)
raises(DOMException);
};

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

@ -39,6 +39,8 @@
#include "nsIDOMNode.idl"
interface nsIDOMDOMConfiguration;
/**
* The nsIDOMDocument interface represents the entire HTML or XML document.
* Conceptually, it is the root of the document tree, and provides the
@ -49,10 +51,10 @@
* objects.
*
* For more information on this interface please see
* http://www.w3.org/TR/DOM-Level-2-Core/
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
*/
[scriptable, uuid(a6cf9075-15b3-11d2-932e-00805f8add32)]
[scriptable, uuid(fde1a53b-cf60-4997-a0b2-1aa1dc55492e)]
interface nsIDOMDocument : nsIDOMNode
{
readonly attribute nsIDOMDocumentType doctype;
@ -91,4 +93,30 @@ interface nsIDOMDocument : nsIDOMNode
in DOMString localName);
// Introduced in DOM Level 2:
nsIDOMElement getElementById(in DOMString elementId);
// Introduced in DOM Level 3:
readonly attribute DOMString inputEncoding;
// Introduced in DOM Level 3:
readonly attribute DOMString xmlEncoding;
// Introduced in DOM Level 3:
attribute boolean xmlStandalone;
// raises(DOMException) on setting
// Introduced in DOM Level 3:
attribute DOMString xmlVersion;
// raises(DOMException) on setting
// Introduced in DOM Level 3:
attribute boolean strictErrorChecking;
// Introduced in DOM Level 3:
attribute DOMString documentURI;
// Introduced in DOM Level 3:
nsIDOMNode adoptNode(in nsIDOMNode source)
raises(DOMException);
// Introduced in DOM Level 3:
readonly attribute nsIDOMDOMConfiguration domConfig;
// Introduced in DOM Level 3:
void normalizeDocument();
// Introduced in DOM Level 3:
nsIDOMNode renameNode(in nsIDOMNode node,
in DOMString namespaceURI,
in DOMString qualifiedName)
raises(DOMException);
};

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

@ -639,25 +639,6 @@ nsDOMWorkerXHR::GetResponseHeader(const nsACString& aHeader,
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerXHR::OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword)
{
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
if (mCanceled) {
return NS_ERROR_ABORT;
}
nsresult rv = mXHRProxy->OpenRequest(aMethod, aUrl, aAsync, aUser, aPassword);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWorkerXHR::Open(const nsACString& aMethod, const nsACString& aUrl,
PRBool aAsync, const nsAString& aUser,
@ -673,7 +654,10 @@ nsDOMWorkerXHR::Open(const nsACString& aMethod, const nsACString& aUrl,
aAsync = PR_TRUE;
}
return OpenRequest(aMethod, aUrl, aAsync, aUser, aPassword);
nsresult rv = mXHRProxy->Open(aMethod, aUrl, aAsync, aUser, aPassword);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP

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

@ -136,17 +136,17 @@ namespace nsDOMWorkerProxiedXHRFunctions
}
};
class OpenRequest : public SyncEventCapturingRunnable
class Open : public SyncEventCapturingRunnable
{
public:
OpenRequest(const nsACString& aMethod, const nsACString& aUrl,
PRBool aAsync, const nsAString& aUser,
const nsAString& aPassword)
Open(const nsACString& aMethod, const nsACString& aUrl,
PRBool aAsync, const nsAString& aUser,
const nsAString& aPassword)
: mMethod(aMethod), mUrl(aUrl), mAsync(aAsync), mUser(aUser),
mPassword(aPassword) { }
virtual nsresult RunInternal() {
return mXHR->OpenRequest(mMethod, mUrl, mAsync, mUser, mPassword);
return mXHR->Open(mMethod, mUrl, mAsync, mUser, mPassword);
}
private:

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

@ -683,7 +683,7 @@ nsDOMWorkerXHRProxy::DispatchPrematureAbortEvents(PRUint32 aType,
}
nsresult
nsDOMWorkerXHRProxy::MaybeDispatchPrematureAbortEvents(PRBool aFromOpenRequest)
nsDOMWorkerXHRProxy::MaybeDispatchPrematureAbortEvents(PRBool aFromOpen)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -698,7 +698,7 @@ nsDOMWorkerXHRProxy::MaybeDispatchPrematureAbortEvents(PRBool aFromOpenRequest)
nsnull);
NS_ENSURE_SUCCESS(rv, rv);
if (aFromOpenRequest) {
if (aFromOpen) {
rv = DispatchPrematureAbortEvents(LISTENER_TYPE_ABORT, target,
mDownloadProgressInfo);
NS_ENSURE_SUCCESS(rv, rv);
@ -866,17 +866,17 @@ nsDOMWorkerXHRProxy::HandleEventRunnable(nsIRunnable* aRunnable)
}
nsresult
nsDOMWorkerXHRProxy::OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword)
nsDOMWorkerXHRProxy::Open(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword)
{
if (!NS_IsMainThread()) {
mSyncRequest = !aAsync;
// Always do async behind the scenes!
RUN_PROXIED_FUNCTION(OpenRequest,
RUN_PROXIED_FUNCTION(Open,
(aMethod, aUrl, PR_TRUE, aUser, aPassword));
return NS_OK;
}
@ -888,12 +888,12 @@ nsDOMWorkerXHRProxy::OpenRequest(const nsACString& aMethod,
nsresult rv = MaybeDispatchPrematureAbortEvents(PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
rv = mXHR->OpenRequest(aMethod, aUrl, aAsync, aUser, aPassword);
rv = mXHR->Open(aMethod, aUrl, aAsync, aUser, aPassword);
NS_ENSURE_SUCCESS(rv, rv);
// Do this after OpenRequest is called so that we will continue to run events
// from the old channel if OpenRequest fails. Any events generated by the
// OpenRequest method will always run regardless of channel ID.
// Do this after Open is called so that we will continue to run events
// from the old channel if Open fails. Any events generated by the
// Open method will always run regardless of channel ID.
mChannelID++;
return NS_OK;

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

@ -92,11 +92,11 @@ public:
nsIXMLHttpRequest* GetXMLHttpRequest();
nsresult OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword);
nsresult Open(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword);
nsresult Abort();

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

@ -178,13 +178,8 @@ GPSDProvider.prototype = {
watch: function(c) {
LOG("watch called\n");
try {
// Turn GPSD buffer on, results in smoother data points which I think we want.
// Required due to the way that different data arrives in different NMEA sentences.
var bufferOption = "J=1\n";
this.outputStream.write(bufferOption, bufferOption.length);
// Go into "watcher" mode
var mode = "w\n";
var mode = '?WATCH={"enable":true,"json":true}';
this.outputStream.write(mode, mode.length);
} catch (e) { return; }
@ -196,54 +191,57 @@ GPSDProvider.prototype = {
var sInputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
sInputStream.init(inputStream);
var s = sInputStream.read(count);
var responseSentence = sInputStream.read(count);
var response = s.split('=');
var response = null;
try {
response = JSON.parse(responseSentence);
} catch (e) { return; }
var header = response[0];
var info = response[1];
// is this location information?
if (header != 'GPSD,O') {
// don't do anything
// is the right kind of sentence?
if (response.class != 'TPV') {
//don't do anything
return;
}
// is there a fix?
if (info == '?') {
if (response.mode == '1') {
// don't do anything
return;
}
// get the info from the string
var fields = info.split(' ');
// we'll only use RMC data as it seems to make sense
if (fields[0] != 'RMC') {
return;
}
LOG("Got info: " + info);
for (var i = 0; i < fields.length; i++) {
if (fields[i] == '?') {
fields[i] = null;
}
}
LOG("Got info: " + responseSentence);
// The API requires these values, if one is missing
// we return without updating the position.
if (response.time && response.lat && response.lon
&& response.epx && response.epy) {
var timestamp = response.time; // UTC
var latitude = response.lat; // degrees
var longitude = response.lon; // degrees
var horizontalError = Math.max(response.epx,response.epy); } // meters
else { return; }
var timestamp = fields[1]; // UTC
var timeError = fields[2]; // seconds
var latitude = fields[3]; // degrees
var longitude = fields[4]; // degrees
var altitude = fields[5]; // meters
var horizontalError = fields[6]; // meters
var verticalError = fields[7]; // meters
var course = fields[8]; // degrees;
var speed = fields[9]; // meters/sec maybe knots depending on GPSD version TODO: figure this out
// Altitude is optional, but if it's present, so must be vertical precision.
var altitude = null;
var verticalError = null;
if (response.alt && response.epv) {
altitude = response.alt; // meters
verticalError = response.epv; // meters
}
var speed = null;
if (response.speed) { var speed = response.speed; } // meters/sec
var course = null;
if (response.track) { var course = response.track; } // degrees
var geoPos = new GeoPositionObject(latitude, longitude, altitude, horizontalError, verticalError, course, speed, timestamp);
c.update(geoPos);
LOG("Position updated:" + timestamp + "," + latitude + "," + longitude + ","
+ horizontalError + "," + altitude + "," + verticalError + "," + course
+ "," + speed);
}

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

@ -39,333 +39,6 @@
#include "nsIServiceManager.h"
#include "windows.h"
#ifdef WINCE_WINDOWS_MOBILE
////////////////////////////
// HTC
////////////////////////////
typedef struct _SENSORDATA
{
SHORT TiltX; // From -1000 to 1000 (about), 0 is flat
SHORT TiltY; // From -1000 to 1000 (about), 0 is flat
SHORT Orientation; // From -1000 to 1000 (about)
WORD Unknown1; // Always zero
DWORD AngleY; // From 0 to 359
DWORD AngleX; // From 0 to 359
DWORD Unknown2; // Bit field?
} SENSORDATA, *PSENSORDATA;
typedef HANDLE (WINAPI * HTCSensorOpen)(DWORD);
typedef void (WINAPI * HTCSensorClose)(HANDLE);
typedef DWORD (WINAPI * HTCSensorGetDataOutput)(HANDLE, PSENSORDATA);
HTCSensorOpen gHTCSensorOpen = nsnull;
HTCSensorClose gHTCSensorClose = nsnull;
HTCSensorGetDataOutput gHTCSensorGetDataOutput = nsnull;
class HTCSensor : public Sensor
{
public:
HTCSensor();
~HTCSensor();
PRBool Startup();
void Shutdown();
void GetValues(double *x, double *y, double *z);
private:
HMODULE mLibrary;
HANDLE mHTCHandle;
};
HTCSensor::HTCSensor()
{
}
HTCSensor::~HTCSensor()
{
}
PRBool
HTCSensor::Startup()
{
HMODULE hSensorLib = LoadLibraryW(L"HTCSensorSDK.dll");
if (!hSensorLib)
return PR_FALSE;
gHTCSensorOpen = (HTCSensorOpen) GetProcAddressW(hSensorLib, L"HTCSensorOpen");
gHTCSensorClose = (HTCSensorClose) GetProcAddressW(hSensorLib, L"HTCSensorClose");
gHTCSensorGetDataOutput = (HTCSensorGetDataOutput) GetProcAddressW(hSensorLib,
L"HTCSensorGetDataOutput");
if (gHTCSensorOpen != nsnull && gHTCSensorClose != nsnull &&
gHTCSensorGetDataOutput != nsnull) {
mHTCHandle = gHTCSensorOpen(1);
if (mHTCHandle)
return PR_TRUE;
}
FreeLibrary(hSensorLib);
mLibrary = nsnull;
gHTCSensorOpen = nsnull;
gHTCSensorClose = nsnull;
gHTCSensorGetDataOutput = nsnull;
return PR_FALSE;
}
void
HTCSensor::Shutdown()
{
NS_ASSERTION(mHTCHandle, "mHTCHandle should not be null at shutdown!");
gHTCSensorClose(mHTCHandle);
NS_ASSERTION(mLibrary, "Shutdown called when mLibrary is null?");
FreeLibrary(mLibrary);
mLibrary = nsnull;
gHTCSensorOpen = nsnull;
gHTCSensorClose = nsnull;
gHTCSensorGetDataOutput = nsnull;
}
void
HTCSensor::GetValues(double *x, double *y, double *z)
{
if (!mHTCHandle)
return;
static const double htcScalingFactor = 1.0 / 1000.0 * 9.8;
SENSORDATA sd;
gHTCSensorGetDataOutput(mHTCHandle, &sd);
*x = ((double)sd.TiltX) / 980 ;
*y = ((double)sd.TiltY) / 980 ;
*z = ((double)sd.Orientation) / 1000;
}
////////////////////////////
// Samsung
////////////////////////////
/**
* The result of an SMI SDK function call.
*/
typedef UINT SMI_RESULT;
/**
* Common result codes.
*/
typedef enum
{
SMI_SUCCESS = 0x00000000,
SMI_ERROR_UNKNOWN = 0x00000001,
SMI_ERROR_DEVICE_NOT_FOUND = 0x00000002,
SMI_ERROR_DEVICE_DISABLED = 0x00000003,
SMI_ERROR_PERMISSION_DENIED = 0x00000004,
SMI_ERROR_INVALID_PARAMETER = 0x00000005,
SMI_ERROR_CANNOT_ACTIVATE_SERVER= 0x00000006,
SMI_ACCELEROMETER_RESULT_BASE = 0x10010000,
SMI_HAPTICS_RESULT_BASE = 0x10020000,
SMI_LED_RESULT_BASE = 0x10030000
} SmiResultCode;
/**
* Accelerometer vector data.
*
*/
typedef struct
{
FLOAT x; /**< X-direction value */
FLOAT y; /**< Y-direction value */
FLOAT z; /**< Z-direction value */
} SmiAccelerometerVector;
/**
* Specifies the capabilities of the Accelerometer device.
*/
typedef struct
{
UINT callbackPeriod; /**<The unit of the vector sampling time, in milliseconds. */
} SmiAccelerometerCapabilities;
typedef SMI_RESULT (WINAPI * SmiAccelerometerGetVector)(SmiAccelerometerVector *);
typedef void (*SmiAccelerometerHandler)(SmiAccelerometerVector accel);
SmiAccelerometerGetVector gSmiAccelerometerGetVector = nsnull;
class SMISensor : public Sensor
{
public:
SMISensor();
~SMISensor();
PRBool Startup();
void Shutdown();
void GetValues(double *x, double *y, double *z);
private:
HMODULE mLibrary;
};
SMISensor::SMISensor()
:mLibrary(nsnull)
{
}
SMISensor::~SMISensor()
{
}
PRBool
SMISensor::Startup()
{
HMODULE hSensorLib = LoadLibraryW(L"SamsungMobileSDK_1.dll");
if (!hSensorLib)
return PR_FALSE;
gSmiAccelerometerGetVector = (SmiAccelerometerGetVector)
GetProcAddressW(hSensorLib, L"SmiAccelerometerGetVector");
if (gSmiAccelerometerGetVector == nsnull) {
FreeLibrary(hSensorLib);
mLibrary = nsnull;
gSmiAccelerometerGetVector = nsnull;
return PR_FALSE;
}
mLibrary = hSensorLib;
return PR_TRUE;
}
void
SMISensor::Shutdown()
{
NS_ASSERTION(mLibrary, "Shutdown called when mLibrary is null?");
FreeLibrary(mLibrary);
mLibrary = nsnull;
gSmiAccelerometerGetVector = nsnull;
}
void
SMISensor::GetValues(double *x, double *y, double *z)
{
NS_ASSERTION(mLibrary, "mLibrary should not be null when GetValues is called");
SmiAccelerometerVector vector;
vector.x = vector.y = vector.z = 0;
SMI_RESULT result = gSmiAccelerometerGetVector(&vector);
// don't we have to adjust
*x = vector.x;
*y = vector.y;
*z = vector.z;
}
////////////////////////////
// Toshiba TG01 / T-01A
////////////////////////////
typedef struct _TS_ACCELERATION
{
SHORT x;
SHORT y;
SHORT z;
FILETIME time;
} TS_ACCELERATION;
typedef DWORD (WINAPI *TSRegisterAcceleration)(HANDLE,DWORD,DWORD*);
typedef DWORD (WINAPI *TSDeregisterAcceleration)(DWORD);
typedef DWORD (WINAPI *TSGetAcceleration)(DWORD,TS_ACCELERATION*);
TSRegisterAcceleration gTSRegisterAcceleration = nsnull;
TSDeregisterAcceleration gTSDeregisterAcceleration = nsnull;
TSGetAcceleration gTSGetAcceleration = nsnull;
class TsSensor : public Sensor
{
public:
TsSensor();
~TsSensor();
PRBool Startup();
void Shutdown();
void GetValues(double *x, double *y, double *z);
private:
HMODULE mLibrary;
DWORD mId;
};
TsSensor::TsSensor() : mLibrary(nsnull), mId(0)
{
}
TsSensor::~TsSensor()
{
}
PRBool
TsSensor::Startup()
{
HMODULE hSensorLib = LoadLibraryW(L"axcon.dll");
if (!hSensorLib)
return PR_FALSE;
gTSRegisterAcceleration = (TSRegisterAcceleration) GetProcAddressW(hSensorLib, L"TSRegisterAcceleration");
gTSDeregisterAcceleration = (TSDeregisterAcceleration) GetProcAddressW(hSensorLib, L"TSDeregisterAcceleration");
gTSGetAcceleration = (TSGetAcceleration) GetProcAddressW(hSensorLib, L"TSGetAcceleration");
if (gTSRegisterAcceleration && gTSDeregisterAcceleration && gTSGetAcceleration) {
if (!gTSRegisterAcceleration(GetModuleHandle(NULL), 100, &mId)) {
mLibrary = hSensorLib;
return PR_TRUE;
}
}
FreeLibrary(hSensorLib);
mLibrary = nsnull;
mId = 0;
gTSRegisterAcceleration = nsnull;
gTSDeregisterAcceleration = nsnull;
gTSGetAcceleration = nsnull;
return PR_FALSE;
}
void
TsSensor::Shutdown()
{
NS_ASSERTION(mLibrary, "Shutdown called when mLibrary is null?");
gTSDeregisterAcceleration(mId);
FreeLibrary(mLibrary);
mLibrary = nsnull;
mId = 0;
gTSRegisterAcceleration = nsnull;
gTSDeregisterAcceleration = nsnull;
gTSGetAcceleration = nsnull;
}
void
TsSensor::GetValues(double *x, double *y, double *z)
{
NS_ASSERTION(mLibrary, "mLibrary should not be null when GetValues is called");
TS_ACCELERATION data;
gTSGetAcceleration(mId, &data);
// Value for TG-01 is landscaped
*x = ((double)data.y) / 1000;
*y = ((double)data.x) / 1000;
*z = ((double)data.z) / 1000;
}
#endif // WINCE_WINDOWS_MOBILE
#if !defined(WINCE) && !defined(WINCE_WINDOWS_MOBILE) // normal windows.
////////////////////////////
@ -472,26 +145,6 @@ void nsAccelerometerSystem::Startup()
PRBool started = PR_FALSE;
#ifdef WINCE_WINDOWS_MOBILE
mSensor = new SMISensor();
if (mSensor)
started = mSensor->Startup();
if (!started) {
mSensor = new HTCSensor();
if (mSensor)
started = mSensor->Startup();
}
if (!started) {
mSensor = new TsSensor();
if (mSensor)
started = mSensor->Startup();
}
#endif
#if !defined(WINCE) && !defined(WINCE_WINDOWS_MOBILE) // normal windows.
mSensor = new ThinkPadSensor();

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

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var f = document.getElementById("f");
var fw = f.contentWindow;
fw.document.designMode = 'on';
f.style.content = "'m'";
fw.document.removeChild(fw.document.documentElement)
}
</script>
</head>
<body onload="boom();"><iframe id="f" src="data:text/html,"></iframe></body>
</html>

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

@ -21,3 +21,4 @@ load 582138-1.xhtml
load 612565-1.html
asserts(6) load 615015-1.html # Bug 439258
load 615450-1.html
load 643786-1.html

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

@ -9205,6 +9205,10 @@ nsHTMLEditRules::DocumentModifiedWorker()
if (!mHTMLEditor) {
return;
}
// DeleteNode below may cause a flush, which could destroy the editor
nsAutoRemovableScriptBlocker scriptBlocker;
nsCOMPtr<nsIHTMLEditor> kungFuDeathGrip(mHTMLEditor);
nsCOMPtr<nsISelection> selection;
nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection));

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

@ -1,7 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 tw=80 et cindent: */
/*
* ***** BEGIN LICENSE BLOCK *****
/* ***** 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
@ -61,7 +60,6 @@
#include "nsIDOMWindow.h"
#include "nsIDOMWindowCollection.h"
#include "nsIWebBrowser.h"
#include "nsIDOM3Document.h"
#include "nsIContent.h"
#include "nsIPresShell.h"
#include "nsIFormControl.h"
@ -555,8 +553,7 @@ EmbedContextMenuInfo::UpdateContextData(nsIDOMEvent *aDOMEvent)
if (NS_SUCCEEDED(rv) && domDoc && mCtxDocument != domDoc) {
mCtxDocument = domDoc;
mNSHHTMLElementSc = nsnull;
nsCOMPtr<nsIDOM3Document> docuri = do_QueryInterface(mCtxDocument);
docuri->GetDocumentURI(mCtxURI);
mCtxDocument->GetDocumentURI(mCtxURI);
NS_ENSURE_ARG_POINTER(mOwner);
nsCOMPtr<nsIWebBrowser> webBrowser;
mOwner->mWindow->GetWebBrowser(getter_AddRefs(webBrowser));

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

@ -1,6 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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
@ -49,7 +48,6 @@
#include "nsIComponentManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOM3Document.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMElement.h"
@ -1747,10 +1745,7 @@ nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
#if defined(DEBUG_smaug)
nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(browser->mDocShell);
nsAutoString documentURI;
if (domDocument) {
nsCOMPtr<nsIDOM3Document> d3 = do_QueryInterface(domDocument);
d3->GetDocumentURI(documentURI);
}
domDocument->GetDocumentURI(documentURI);
printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)browser,
NS_ConvertUTF16toUTF8(documentURI).get());
#endif
@ -1762,10 +1757,7 @@ nsEventStatus nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
#if defined(DEBUG_smaug)
nsCOMPtr<nsIDOMDocument> domDocument = do_GetInterface(browser->mDocShell);
nsAutoString documentURI;
if (domDocument) {
nsCOMPtr<nsIDOM3Document> d3 = do_QueryInterface(domDocument);
d3->GetDocumentURI(documentURI);
}
domDocument->GetDocumentURI(documentURI);
printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)browser,
NS_ConvertUTF16toUTF8(documentURI).get());
#endif

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

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

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

@ -68,8 +68,10 @@ class OTSStream {
}
while (length >= 4) {
chksum_ += ntohl(*reinterpret_cast<const uint32_t*>(
reinterpret_cast<const uint8_t*>(data) + offset));
uint32_t tmp;
std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset,
sizeof(uint32_t));
chksum_ += ntohl(tmp);
length -= 4;
offset += 4;
}

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

@ -1011,7 +1011,7 @@ gfxDWriteFontList::GetFontSubstitutes()
for (i = 0, rv = ERROR_SUCCESS; rv != ERROR_NO_MORE_ITEMS; i++) {
aliasName[0] = 0;
lenAlias = sizeof(aliasName);
lenAlias = NS_ARRAY_LENGTH(aliasName);
actualName[0] = 0;
lenActual = sizeof(actualName);
rv = RegEnumValueW(hKey, i, aliasName, &lenAlias, NULL, &valueType,

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

@ -626,7 +626,7 @@ gfxGDIFontList::GetFontSubstitutes()
for (i = 0, rv = ERROR_SUCCESS; rv != ERROR_NO_MORE_ITEMS; i++) {
aliasName[0] = 0;
lenAlias = sizeof(aliasName);
lenAlias = NS_ARRAY_LENGTH(aliasName);
actualName[0] = 0;
lenActual = sizeof(actualName);
rv = RegEnumValueW(hKey, i, aliasName, &lenAlias, NULL, &valueType,

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

@ -57,7 +57,10 @@ nsCollationMacUC::nsCollationMacUC()
nsCollationMacUC::~nsCollationMacUC()
{
if (mHasCollator) {
OSStatus err = ::UCDisposeCollator(&mCollator);
#ifdef DEBUG
OSStatus err =
#endif
::UCDisposeCollator(&mCollator);
mHasCollator = PR_FALSE;
NS_ASSERTION((err == noErr), "UCDisposeCollator failed");
}

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

@ -147,7 +147,6 @@ geostd8=GEOSTD8
armscii-8=armscii-8
x-viet-tcvn5712=x-viet-tcvn5712
x-viet-vps=x-viet-vps
x-viet-vni=x-viet-vni
iso-10646-ucs-2=UTF-16BE
x-iso-10646-ucs-2-be=UTF-16BE
x-iso-10646-ucs-2-le=UTF-16LE
@ -474,10 +473,6 @@ csiso2022kr=ISO-2022-KR
#
csviscii=VISCII
#
# Aliases for VIQR
#
csviqr=VIQR
#
# Aliases for x-euc-tw
#
zh_tw-euc=x-euc-tw

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

@ -279,9 +279,6 @@
#include "nsUnicodeToISO2022CN.h"
#include "gbku.h"
#define DECODER_NAME_BASE "Unicode Decoder-"
#define ENCODER_NAME_BASE "Unicode Encoder-"
NS_CONVERTER_REGISTRY_START
NS_UCONV_REG_UNREG("ISO-8859-1", NS_ISO88591TOUNICODE_CID, NS_UNICODETOISO88591_CID)
NS_UCONV_REG_UNREG("windows-1252", NS_CP1252TOUNICODE_CID, NS_UNICODETOCP1252_CID)
@ -460,9 +457,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsISO2022CNToUnicode)
//----------------------------------------------------------------------------
// Global functions and data [declaration]
#define DECODER_NAME_BASE "Unicode Decoder-"
#define ENCODER_NAME_BASE "Unicode Encoder-"
// ucvja
const PRUint16 g_uf0201Mapping[] = {
#include "jis0201.uf"
@ -480,10 +474,6 @@ const PRUint16 g_uf0208extMapping[] = {
#include "jis0208ext.uf"
};
const PRUint16 g_uf0212Mapping[] = {
#include "jis0212.uf"
};
// ucvtw2
const PRUint16 g_ufCNS1MappingTable[] = {
#include "cns_1.uf"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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