Merge mozilla-central to Places

This commit is contained in:
Shawn Wilsher 2010-11-10 09:38:08 -08:00
commit 06f60f7a34
1177 changed files with 52618 additions and 19322 deletions

View File

@ -82,7 +82,6 @@ nsIStringBundle *nsAccessNode::gStringBundle = 0;
nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
nsINode *nsAccessNode::gLastFocusedNode = nsnull;
PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
@ -217,7 +216,6 @@ void nsAccessNode::InitXPAccessibility()
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefBranch) {
prefBranch->GetBoolPref("accessibility.disablecache", &gIsCacheDisabled);
prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
}

View File

@ -156,7 +156,7 @@ public:
*/
virtual nsINode* GetNode() const { return mContent; }
nsIContent* GetContent() const { return mContent; }
nsIDocument* GetDocumentNode() const
virtual nsIDocument* GetDocumentNode() const
{ return mContent ? mContent->GetOwnerDoc() : nsnull; }
/**
@ -212,7 +212,6 @@ protected:
static nsIStringBundle *gStringBundle;
static nsIStringBundle *gKeyStringBundle;
static PRBool gIsCacheDisabled;
static PRBool gIsFormFillEnabled;
private:

View File

@ -100,6 +100,7 @@ ACCESSIBILITY_ATOM(a, "a")
ACCESSIBILITY_ATOM(abbr, "abbr")
ACCESSIBILITY_ATOM(acronym, "acronym")
ACCESSIBILITY_ATOM(area, "area")
ACCESSIBILITY_ATOM(article, "article") // HTML landmark
ACCESSIBILITY_ATOM(autocomplete, "autocomplete")
ACCESSIBILITY_ATOM(blockquote, "blockquote")
ACCESSIBILITY_ATOM(br, "br")
@ -111,7 +112,9 @@ ACCESSIBILITY_ATOM(dd, "dd")
ACCESSIBILITY_ATOM(div, "div")
ACCESSIBILITY_ATOM(dl, "dl")
ACCESSIBILITY_ATOM(dt, "dt")
ACCESSIBILITY_ATOM(footer, "footer") // HTML landmark
ACCESSIBILITY_ATOM(form, "form")
ACCESSIBILITY_ATOM(header, "header") // HTML landmark
ACCESSIBILITY_ATOM(h1, "h1")
ACCESSIBILITY_ATOM(h2, "h2")
ACCESSIBILITY_ATOM(h3, "h3")
@ -135,6 +138,7 @@ ACCESSIBILITY_ATOM(map, "map")
ACCESSIBILITY_ATOM(math, "math")
ACCESSIBILITY_ATOM(menupopup, "menupopup") // XUL
ACCESSIBILITY_ATOM(object, "object")
ACCESSIBILITY_ATOM(nav, "nav") // HTML landmark
ACCESSIBILITY_ATOM(ol, "ol")
ACCESSIBILITY_ATOM(optgroup, "optgroup")
ACCESSIBILITY_ATOM(option, "option")
@ -196,6 +200,7 @@ ACCESSIBILITY_ATOM(multiline, "multiline") // XUL
ACCESSIBILITY_ATOM(name, "name")
ACCESSIBILITY_ATOM(onclick, "onclick")
ACCESSIBILITY_ATOM(popup, "popup")
ACCESSIBILITY_ATOM(placeholder, "placeholder")
ACCESSIBILITY_ATOM(readonly, "readonly")
ACCESSIBILITY_ATOM(scope, "scope") // HTML table
ACCESSIBILITY_ATOM(seltype, "seltype") // XUL listbox
@ -289,3 +294,4 @@ ACCESSIBILITY_ATOM(live, "live")
ACCESSIBILITY_ATOM(lineNumber, "line-number")
ACCESSIBILITY_ATOM(posinset, "posinset")
ACCESSIBILITY_ATOM(setsize, "setsize")
ACCESSIBILITY_ATOM(xmlroles, "xml-roles")

View File

@ -477,32 +477,33 @@ nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
nsIContent* aStartChild,
nsIContent* aEndChild)
{
#ifdef DEBUG_A11Y
#ifdef DEBUG_CONTENTMUTATION
nsAutoString tag;
aStartChild->Tag()->ToString(tag);
nsIAtom* id = aStartChild->GetID();
nsCAutoString strid;
if (id)
id->ToUTF8String(strid);
nsIAtom* atomid = aStartChild->GetID();
nsCAutoString id;
if (atomid)
atomid->ToUTF8String(id);
nsAutoString ctag;
aContainer->Tag()->ToString(ctag);
nsIAtom* cid = aContainer->GetID();
nsCAutoString strcid;
if (cid)
cid->ToUTF8String(strcid);
nsCAutoString cid;
nsIAtom* catomid = nsnull;
if (aContainer) {
aContainer->Tag()->ToString(ctag);
catomid = aContainer->GetID();
if (catomid)
catomid->ToUTF8String(cid);
}
printf("\ncontent inserted: %s@id='%s', container: %s@id='%s', end node: %p\n\n",
NS_ConvertUTF16toUTF8(tag).get(), strid.get(),
NS_ConvertUTF16toUTF8(ctag).get(), strcid.get(), aEndChild);
NS_ConvertUTF16toUTF8(tag).get(), id.get(),
NS_ConvertUTF16toUTF8(ctag).get(), cid.get(), aEndChild);
#endif
// XXX: bug 606082. aContainer is null when root element is inserted into
// document, we need to handle this and update the tree, also we need to
// update a content node of the document accessible.
if (aContainer) {
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
if (docAccessible)
docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
}
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
if (docAccessible)
docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
}
void
@ -510,21 +511,34 @@ nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
nsIContent* aContainer,
nsIContent* aChild)
{
#ifdef DEBUG_A11Y
nsAutoString id;
aChild->Tag()->ToString(id);
printf("\ncontent removed: %s\n", NS_ConvertUTF16toUTF8(id).get());
#ifdef DEBUG_CONTENTMUTATION
nsAutoString tag;
aChild->Tag()->ToString(tag);
nsIAtom* atomid = aChild->GetID();
nsCAutoString id;
if (atomid)
atomid->ToUTF8String(id);
nsAutoString ctag;
nsCAutoString cid;
nsIAtom* catomid = nsnull;
if (aContainer) {
aContainer->Tag()->ToString(ctag);
catomid = aContainer->GetID();
if (catomid)
catomid->ToUTF8String(cid);
}
printf("\ncontent removed: %s@id='%s', container: %s@id='%s'\n\n",
NS_ConvertUTF16toUTF8(tag).get(), id.get(),
NS_ConvertUTF16toUTF8(ctag).get(), cid.get());
#endif
// XXX: bug 606082. aContainer is null when root element is inserted into
// document, we need to handle this and update the tree, perhaps destroy
// the document accessible.
if (aContainer) {
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
if (docAccessible)
docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
PR_FALSE);
}
nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
if (docAccessible)
docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
PR_FALSE);
}
void

View File

@ -467,9 +467,6 @@ nsAccessible::GetFirstChild(nsIAccessible **aFirstChild)
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
if (gIsCacheDisabled)
InvalidateChildren();
PRInt32 childCount = GetChildCount();
NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE);
@ -2733,6 +2730,9 @@ nsAccessible::InvalidateChildren()
PRBool
nsAccessible::AppendChild(nsAccessible* aChild)
{
if (!aChild)
return PR_FALSE;
if (!mChildren.AppendElement(aChild))
return PR_FALSE;
@ -2746,11 +2746,16 @@ nsAccessible::AppendChild(nsAccessible* aChild)
PRBool
nsAccessible::InsertChildAt(PRUint32 aIndex, nsAccessible* aChild)
{
if (!aChild)
return PR_FALSE;
if (!mChildren.InsertElementAt(aIndex, aChild))
return PR_FALSE;
for (PRUint32 idx = aIndex + 1; idx < mChildren.Length(); idx++)
mChildren[idx]->mIndexInParent++;
for (PRUint32 idx = aIndex + 1; idx < mChildren.Length(); idx++) {
NS_ASSERTION(mChildren[idx]->mIndexInParent == idx - 1, "Accessible child index doesn't match");
mChildren[idx]->mIndexInParent = idx;
}
if (nsAccUtils::IsText(aChild))
mChildrenFlags = eMixedChildren;
@ -2764,23 +2769,28 @@ nsAccessible::InsertChildAt(PRUint32 aIndex, nsAccessible* aChild)
PRBool
nsAccessible::RemoveChild(nsAccessible* aChild)
{
if (aChild->mParent != this || aChild->mIndexInParent == -1)
if (!aChild)
return PR_FALSE;
if (aChild->mIndexInParent >= mChildren.Length() ||
mChildren[aChild->mIndexInParent] != aChild) {
PRInt32 index = aChild->mIndexInParent;
if (aChild->mParent != this || index == -1)
return PR_FALSE;
if (index >= mChildren.Length() || mChildren[index] != aChild) {
NS_ERROR("Child is bound to parent but parent hasn't this child at its index!");
aChild->UnbindFromParent();
return PR_FALSE;
}
for (PRUint32 idx = aChild->mIndexInParent + 1; idx < mChildren.Length(); idx++)
mChildren[idx]->mIndexInParent--;
mChildren.RemoveElementAt(aChild->mIndexInParent);
mEmbeddedObjCollector = nsnull;
for (PRUint32 idx = index + 1; idx < mChildren.Length(); idx++) {
NS_ASSERTION(mChildren[idx]->mIndexInParent == idx, "Accessible child index doesn't match");
mChildren[idx]->mIndexInParent = idx - 1;
}
aChild->UnbindFromParent();
mChildren.RemoveElementAt(index);
mEmbeddedObjCollector = nsnull;
return PR_TRUE;
}

View File

@ -285,8 +285,12 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK_DEFUNCT_OBJECT;
}
if (aExtraState)
*aExtraState = 0;
if (aExtraState) {
// The root content of the document might be removed so that mContent is
// out of date.
*aExtraState = (mContent->GetCurrentDoc() == mDocument) ?
0 : nsIAccessibleStates::EXT_STATE_STALE;
}
#ifdef MOZ_XUL
nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
@ -675,8 +679,10 @@ nsDocAccessible::Shutdown()
mParent->RemoveChild(this);
}
PRUint32 childDocCount = mChildDocuments.Length();
for (PRUint32 idx = 0; idx < childDocCount; idx++)
// Walk the array backwards because child documents remove themselves from the
// array as they are shutdown.
PRInt32 childDocCount = mChildDocuments.Length();
for (PRInt32 idx = childDocCount - 1; idx >= 0; idx--)
mChildDocuments[idx]->Shutdown();
mChildDocuments.Clear();
@ -1239,12 +1245,17 @@ void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent2,
nsEventStates aStateMask)
{
if (!aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
return;
if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent1);
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2);
}
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent1);
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2);
if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
nsRefPtr<AccEvent> event =
new AccStateChangeEvent(aContent1, nsIAccessibleStates::STATE_INVALID,
PR_FALSE, PR_TRUE);
FireDelayedAccessibleEvent(event);
}
}
void nsDocAccessible::DocumentStatesChanged(nsIDocument* aDocument,
@ -1346,22 +1357,49 @@ nsDocAccessible::UpdateTree(nsIContent* aContainerNode,
// Since this information may be not correct then we need to fire some events
// regardless the document loading state.
// Update the whole tree of this document accessible when the container is
// null (document element is inserted or removed).
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
nsIEventStateManager* esm = presShell->GetPresContext()->EventStateManager();
PRBool fireAllEvents = PR_TRUE;//IsContentLoaded() || esm->IsHandlingUserInputExternal();
// We don't create new accessibles on content removal.
nsAccessible* container = aIsInsert ?
GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
GetAccService()->GetCachedAccessibleOrContainer(aContainerNode);
// XXX: bug 608887 reconsider accessible tree update logic because
// 1) elements appended outside the HTML body don't get accessibles;
// 2) the document having elements that should be accessible may function
// without body.
nsAccessible* container = nsnull;
if (aIsInsert) {
container = aContainerNode ?
GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
this;
// The document children were changed; the root content might be affected.
if (container == this) {
nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocument);
// No root content (for example HTML document element was inserted but no
// body). Nothing to update.
if (!rootContent)
return;
// New root content has been inserted, update it and update the tree.
if (rootContent != mContent)
mContent = rootContent;
}
// XXX: Invalidate parent-child relations for container accessible and its
// children because there's no good way to find insertion point of new child
// accessibles into accessible tree. We need to invalidate children even
// there's no inserted accessibles in the end because accessible children
// are created while parent recaches child accessibles.
container->InvalidateChildren();
} else {
// Don't create new accessibles on content removal.
container = aContainerNode ?
GetAccService()->GetCachedAccessibleOrContainer(aContainerNode) :
this;
}
EIsFromUserInput fromUserInput = esm->IsHandlingUserInputExternal() ?

View File

@ -108,6 +108,7 @@ public:
virtual nsIFrame* GetFrame();
virtual PRBool IsDefunct();
virtual nsINode* GetNode() const { return mDocument; }
virtual nsIDocument* GetDocumentNode() const { return mDocument; }
// nsAccessible
virtual PRUint32 NativeRole();

View File

@ -196,8 +196,13 @@ nsOuterDocAccessible::InvalidateChildren()
PRBool
nsOuterDocAccessible::AppendChild(nsAccessible *aAccessible)
{
NS_ASSERTION(!mChildren.Length(),
"Previous child document of outerdoc accessible wasn't removed!");
// We keep showing the old document for a bit after creating the new one,
// and while building the new DOM and frame tree. That's done on purpose
// to avoid weird flashes of default background color.
// The old viewer will be destroyed after the new one is created.
// For a11y, it should be safe to shut down the old document now.
if (mChildren.Length())
mChildren[0]->Shutdown();
if (!nsAccessible::AppendChild(aAccessible))
return PR_FALSE;

View File

@ -412,16 +412,24 @@ nsHTMLTextFieldAccessible::GetNameInternal(nsAString& aName)
if (!aName.IsEmpty())
return NS_OK;
if (!mContent->GetBindingParent())
if (mContent->GetBindingParent())
{
// XXX: bug 459640
// There's a binding parent.
// This means we're part of another control, so use parent accessible for name.
// This ensures that a textbox inside of a XUL widget gets
// an accessible name.
nsAccessible* parent = GetParent();
parent->GetName(aName);
}
if (!aName.IsEmpty())
return NS_OK;
// XXX: bug 459640
// There's a binding parent.
// This means we're part of another control, so use parent accessible for name.
// This ensures that a textbox inside of a XUL widget gets
// an accessible name.
nsAccessible* parent = GetParent();
return parent ? parent->GetName(aName) : NS_OK;
// text inputs and textareas might have useful placeholder text
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::placeholder, aName);
return NS_OK;
}
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval)

View File

@ -134,8 +134,10 @@ nsHyperTextAccessible::NativeRole()
if (tag == nsAccessibilityAtoms::form)
return nsIAccessibleRole::ROLE_FORM;
if (tag == nsAccessibilityAtoms::div ||
tag == nsAccessibilityAtoms::blockquote)
if (tag == nsAccessibilityAtoms::article ||
tag == nsAccessibilityAtoms::blockquote ||
tag == nsAccessibilityAtoms::div ||
tag == nsAccessibilityAtoms::nav)
return nsIAccessibleRole::ROLE_SECTION;
if (tag == nsAccessibilityAtoms::h1 ||
@ -146,6 +148,14 @@ nsHyperTextAccessible::NativeRole()
tag == nsAccessibilityAtoms::h6)
return nsIAccessibleRole::ROLE_HEADING;
// Deal with html landmark elements
if (tag == nsAccessibilityAtoms::header)
return nsIAccessibleRole::ROLE_HEADER;
if (tag == nsAccessibilityAtoms::footer)
return nsIAccessibleRole::ROLE_FOOTER;
// Treat block frames as paragraphs
nsIFrame *frame = GetFrame();
if (frame && frame->GetType() == nsAccessibilityAtoms::blockFrame &&
frame->GetContent()->Tag() != nsAccessibilityAtoms::input) {
@ -1197,6 +1207,21 @@ nsHyperTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttribute
}
}
// For the html landmark elements we expose them like we do aria landmarks to
// make AT navigation schemes "just work".
if (mContent->Tag() == nsAccessibilityAtoms::nav)
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
NS_LITERAL_STRING("navigation"));
else if (mContent->Tag() == nsAccessibilityAtoms::header)
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
NS_LITERAL_STRING("banner"));
else if (mContent->Tag() == nsAccessibilityAtoms::footer)
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
NS_LITERAL_STRING("contentinfo"));
else if (mContent->Tag() == nsAccessibilityAtoms::article)
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
NS_LITERAL_STRING("main"));
return NS_OK;
}

View File

@ -95,6 +95,7 @@ _TEST_FILES =\
test_descr.html \
test_editabletext_1.html \
test_editabletext_2.html \
test_elm_landmarks.html \
test_elm_listbox.xul \
$(warning test_elm_media.html temporarily disabled) \
test_elm_nsApplicationAcc.html \

View File

@ -26,10 +26,6 @@
{
this.DOMNode = aDocNode;
this.eventSeq = [
new invokerChecker(EVENT_STATE_CHANGE, getAccessible(this.DOMNode))
];
this.invoke = function editabledoc_invoke() {
// Note: this should fire an EVENT_STATE_CHANGE
this.DOMNode.designMode = 'on';
@ -58,6 +54,24 @@
};
}
function invalidInput(aNodeOrID)
{
this.DOMNode = getNode(aNodeOrID);
this.invoke = function invalidInput_invoke() {
// Note: this should fire an EVENT_STATE_CHANGE
this.DOMNode.value = "I am too long";
};
this.check = function invalidInput_check() {
testStates(aNodeOrID, STATE_INVALID);
};
this.getID = function invalidInput_getID() {
return prettyName(aNodeOrID) + " became invalid";
};
}
////////////////////////////////////////////////////////////////////////////
// Do tests
@ -67,12 +81,15 @@
function doTests()
{
gQueue = new eventQueue();
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
// Test delayed editable state change
var doc = document.getElementById("iframe").contentDocument;
gQueue.push(new makeEditableDoc(doc));
// invalid state change
gQueue.push(new invalidInput("maxlength"));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -87,6 +104,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=564471"
title="Make state change events async">
Mozilla Bug 564471
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=555728"
title="Fire a11y event based on HTML5 constraint validation">
Mozilla Bug 555728
</a>
<p id="display"></p>
@ -97,6 +119,9 @@
<div id="testContainer">
<iframe id="iframe"></iframe>
</div>
<input id="maxlength" maxlength="1">
<div id="eventdump"></div>
</body>
</html>

View File

@ -19,11 +19,13 @@ const ROLE_DIALOG = nsIAccessibleRole.ROLE_DIALOG;
const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
const ROLE_FOOTER = nsIAccessibleRole.ROLE_FOOTER;
const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION;
const ROLE_FORM = nsIAccessibleRole.ROLE_FORM;
const ROLE_GRAPHIC = nsIAccessibleRole.ROLE_GRAPHIC;
const ROLE_GRID_CELL = nsIAccessibleRole.ROLE_GRID_CELL;
const ROLE_GROUPING = nsIAccessibleRole.ROLE_GROUPING;
const ROLE_HEADER = nsIAccessibleRole.ROLE_HEADER;
const ROLE_HEADING = nsIAccessibleRole.ROLE_HEADING;
const ROLE_IMAGE_MAP = nsIAccessibleRole.ROLE_IMAGE_MAP;
const ROLE_INTERNAL_FRAME = nsIAccessibleRole.ROLE_INTERNAL_FRAME;

View File

@ -38,6 +38,7 @@ const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE;
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;

View File

@ -17,7 +17,7 @@
<script type="application/javascript">
function doTest()
{
{
var docAcc = getAccessible(document, [nsIAccessibleDocument]);
if (docAcc) {
testStates(docAcc, STATE_READONLY);
@ -28,6 +28,7 @@
testStates(docAcc, 0, EXT_STATE_EDITABLE);
testStates("article", 0, EXT_STATE_EDITABLE);
testStates("article", 0, EXT_STATE_EDITABLE);
testStates("editable_article", 0, EXT_STATE_EDITABLE);
document.designMode = "off";

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<title>HTML landmark tests</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="role.js"></script>
<script type="application/javascript"
src="attributes.js"></script>
<script type="application/javascript">
function doTest()
{
testRole("nav", ROLE_SECTION);
testRole("header", ROLE_HEADER);
testRole("footer", ROLE_FOOTER);
testRole("article", ROLE_SECTION);
// Some AT may look for this
testAttrs("nav", {"xml-roles" : "navigation"}, true);
testAttrs("header", {"xml-roles" : "banner"}, true);
testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
testAttrs("article", {"xml-roles" : "main"}, true);
testAttrs("document", {"xml-roles" : "document"}, true); // ARIA override
// And some AT may look for this
testAttrs("nav", {"tag" : "NAV"}, true);
testAttrs("header", {"tag" : "HEADER"}, true);
testAttrs("footer", {"tag" : "FOOTER"}, true);
testAttrs("article", {"tag" : "ARTICLE"}, true);
testAttrs("document", {"tag" : "ARTICLE"}, true); // no override expected
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Provide mappings for html5 <nav> <header> <footer> <article>"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=593368">Bug 593368</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<nav id="nav">a nav</nav>
<header id="header">a header</header>
<footer id="footer">a footer</footer>
<article id="article">an article</article>
<article id="document" role="document">a document</article>
</body>
</html>

View File

@ -176,6 +176,14 @@
testName("textboxinend", "This day was sunny");
testName("textbox2", "This day was");
// placeholder
testName("ph_password", "a placeholder");
testName("ph_text", "a placeholder");
testName("ph_textarea", "a placeholder");
testName("ph_text2", "a label");
testName("ph_textarea2", "a label");
testName("ph_text3", "a label");
SimpleTest.finish();
}
@ -196,6 +204,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=530081"
title="Clean up our tree walker ">
Mozilla Bug 530081
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=604391"
title="Use placeholder as name if name is otherwise empty">
Mozilla Bug 604391
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -421,5 +434,18 @@
</label>
</form>
<!-- placeholder -->
<input id="ph_password" type="password" value="" placeholder="a placeholder" />
<input id="ph_text" type="text" placeholder="a placeholder" />
<textarea id="ph_textarea" cols="5" placeholder="a placeholder"></textarea>
<!-- placeholder does not win -->
<input id="ph_text2" type="text" aria-label="a label" placeholder="meh" />
<textarea id="ph_textarea2" cols="5" aria-labelledby="ph_text2"
placeholder="meh"></textarea>
<label for="ph_text3">a label</label>
<input id="ph_text3" placeholder="meh" />
</body>
</html>

View File

@ -46,6 +46,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_doc.html \
test_list_editabledoc.html \
test_list.html \
test_recreation.html \

View File

@ -0,0 +1,370 @@
<!DOCTYPE html>
<html>
<head>
<title>Test document root content mutations</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="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
////////////////////////////////////////////////////////////////////////////
// Helpers
function getDocNode(aID)
{
return getNode(aID).contentDocument;
}
function getDocChildNode(aID)
{
return getDocNode(aID).body.firstChild;
}
function rootContentReplaced(aID, aTextName)
{
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
new invokerChecker(EVENT_REORDER, getDocNode, aID)
];
this.finalCheck = function rootContentReplaced_finalCheck()
{
var tree = {
role: ROLE_DOCUMENT,
children: [
{
role: ROLE_TEXT_LEAF,
name: aTextName
}
]
};
testAccessibleTree(getDocNode(aID), tree);
}
}
function rootContentRemoved(aID)
{
this.eventSeq = [
new invokerChecker(EVENT_HIDE, null),
new invokerChecker(EVENT_REORDER, getDocNode, aID)
];
this.preinvoke = function rootContentRemoved_preinvoke()
{
// Set up target for hide event before we invoke.
var text = getAccessible(getAccessible(getDocNode(aID)).firstChild,
[nsIAccessNode]).DOMNode;
this.eventSeq[0].target = text;
}
this.finalCheck = function rootContentRemoved_finalCheck()
{
var tree = {
role: ROLE_DOCUMENT,
states: {
// Out of date root content involves stale state presence.
states: 0,
extraStates: EXT_STATE_STALE
},
children: [ ]
};
testAccessibleTree(getDocNode(aID), tree);
}
}
function rootContentInserted(aID, aTextName)
{
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
new invokerChecker(EVENT_REORDER, getDocNode, aID)
];
this.finalCheck = function rootContentInserted_finalCheck()
{
var tree = {
role: ROLE_DOCUMENT,
states: {
states: 0,
extraStates: 0,
absentStates: 0,
absentExtraStates: EXT_STATE_STALE
},
children: [
{
role: ROLE_TEXT_LEAF,
name: aTextName
}
]
};
testAccessibleTree(getDocNode(aID), tree);
}
}
////////////////////////////////////////////////////////////////////////////
// Invokers
function writeIFrameDoc(aID)
{
this.__proto__ = new rootContentReplaced(aID, "hello");
this.invoke = function writeIFrameDoc_invoke()
{
var docNode = getDocNode(aID);
// We can't use open/write/close outside of iframe document because of
// security error.
var script = docNode.createElement("script");
script.textContent = "document.open(); document.write('hello'); document.close();";
docNode.body.appendChild(script);
}
this.getID = function writeIFrameDoc_getID()
{
return "write document";
}
}
/**
* Replace HTML element.
*/
function replaceIFrameHTMLElm(aID)
{
this.__proto__ = new rootContentReplaced(aID, "New Wave");
this.invoke = function replaceIFrameHTMLElm_invoke()
{
var docNode = getDocNode(aID);
var newHTMLNode = docNode.createElement("html");
var newBodyNode = docNode.createElement("body");
var newTextNode = docNode.createTextNode("New Wave");
newBodyNode.appendChild(newTextNode);
newHTMLNode.appendChild(newBodyNode);
docNode.replaceChild(newHTMLNode, docNode.documentElement);
}
this.getID = function replaceIFrameBody_getID()
{
return "replace HTML element";
}
}
/**
* Replace HTML body.
*/
function replaceIFrameBody(aID)
{
this.__proto__ = new rootContentReplaced(aID, "New Hello");
this.invoke = function replaceIFrameBody_invoke()
{
var docNode = getDocNode(aID);
var newBodyNode = docNode.createElement("body");
var newTextNode = docNode.createTextNode("New Hello");
newBodyNode.appendChild(newTextNode);
docNode.documentElement.replaceChild(newBodyNode, docNode.body);
}
this.finalCheck = function replaceIFrameBody_finalCheck()
{
var tree = {
role: ROLE_DOCUMENT,
children: [
{
role: ROLE_TEXT_LEAF,
name: "New Hello"
}
]
};
testAccessibleTree(getDocNode(aID), tree);
}
this.getID = function replaceIFrameBody_getID()
{
return "replace body";
}
}
/**
* Open/close document pair.
*/
function openIFrameDoc(aID)
{
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function openIFrameDoc_invoke()
{
this.preinvoke();
// Open document.
var docNode = getDocNode(aID);
var script = docNode.createElement("script");
script.textContent = "function closeMe() { document.write('Works?'); document.close(); } window.closeMe = closeMe; document.open();";
docNode.body.appendChild(script);
}
this.getID = function openIFrameDoc_getID()
{
return "open document";
}
}
function closeIFrameDoc(aID)
{
this.__proto__ = new rootContentInserted(aID, "Works?");
this.invoke = function closeIFrameDoc_invoke()
{
// Write and close document.
getDocNode(aID).write('Works?'); getDocNode(aID).close();
}
this.getID = function closeIFrameDoc_getID()
{
return "close document";
}
}
/**
* Remove/insert HTML element pair.
*/
function removeHTMLFromIFrameDoc(aID)
{
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function removeHTMLFromIFrameDoc_invoke()
{
this.preinvoke();
// Remove HTML element.
var docNode = getDocNode(aID);
docNode.removeChild(docNode.firstChild);
}
this.getID = function removeHTMLFromIFrameDoc_getID()
{
return "remove HTML element";
}
}
function insertHTMLToIFrameDoc(aID)
{
this.__proto__ = new rootContentInserted(aID, "Haha");
this.invoke = function insertHTMLToIFrameDoc_invoke()
{
// Insert HTML element.
var docNode = getDocNode(aID);
var html = docNode.createElement("html");
var body = docNode.createElement("body");
var text = docNode.createTextNode("Haha");
body.appendChild(text);
html.appendChild(body);
docNode.appendChild(html);
}
this.getID = function insertHTMLToIFrameDoc_getID()
{
return "insert HTML element document";
}
}
/**
* Remove/insert HTML body pair.
*/
function removeBodyFromIFrameDoc(aID)
{
this.__proto__ = new rootContentRemoved(aID);
this.invoke = function removeBodyFromIFrameDoc_invoke()
{
this.preinvoke();
// Remove body element.
var docNode = getDocNode(aID);
docNode.documentElement.removeChild(docNode.body);
}
this.getID = function removeBodyFromIFrameDoc_getID()
{
return "remove body element";
}
}
function insertBodyToIFrameDoc(aID)
{
this.__proto__ = new rootContentInserted(aID, "Yo ho ho i butylka roma!");
this.invoke = function insertBodyToIFrameDoc_invoke()
{
// Insert body element.
var docNode = getDocNode(aID);
var body = docNode.createElement("body");
var text = docNode.createTextNode("Yo ho ho i butylka roma!");
body.appendChild(text);
docNode.documentElement.appendChild(body);
}
this.getID = function insertBodyToIFrameDoc_getID()
{
return "insert body element";
}
}
////////////////////////////////////////////////////////////////////////////
// Test
//gA11yEventDumpID = "eventdump"; // debug stuff
var gQueue = null;
function doTest()
{
gQueue = new eventQueue();
gQueue.push(new writeIFrameDoc("iframe"));
gQueue.push(new replaceIFrameHTMLElm("iframe"));
gQueue.push(new replaceIFrameBody("iframe"));
gQueue.push(new openIFrameDoc("iframe"));
gQueue.push(new closeIFrameDoc("iframe"));
gQueue.push(new removeHTMLFromIFrameDoc("iframe"));
gQueue.push(new insertHTMLToIFrameDoc("iframe"));
gQueue.push(new removeBodyFromIFrameDoc("iframe"));
gQueue.push(new insertBodyToIFrameDoc("iframe"));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Update accessible tree when root element is changed"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<iframe id="iframe"></iframe>
<div id="eventdump"></div>
</body>
</html>

View File

@ -59,9 +59,9 @@ pref("extensions.logging.enabled", false);
// Preferences for AMO integration
pref("extensions.getAddons.cache.enabled", true);
pref("extensions.getAddons.maxResults", 15);
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%");
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=firefox");
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/%VERSION%/%OS%");
// Blocklist preferences
@ -239,6 +239,8 @@ pref("browser.shell.checkDefaultBrowser", true);
pref("browser.startup.page", 1);
pref("browser.startup.homepage", "chrome://branding/locale/browserconfig.properties");
pref("browser.aboutHomeSnippets.updateUrl", "http://snippets.mozilla.com/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
pref("browser.enable_automatic_image_resizing", true);
pref("browser.chrome.site_icons", true);
pref("browser.chrome.favicons", true);

View File

@ -82,6 +82,7 @@ endif
endif
ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
endif

View File

@ -139,6 +139,10 @@ function loadSnippets()
let updateURL = localStorage["snippets-update-url"];
if (updateURL && (!lastUpdate ||
Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS)) {
// Even if fetching should fail we don't want to spam the server, thus
// set the last update time regardless its results. Will retry tomorrow.
localStorage["snippets-last-update"] = Date.now();
// Try to update from network.
let xhr = new XMLHttpRequest();
xhr.open('GET', updateURL, true);
@ -149,7 +153,6 @@ function loadSnippets()
{
if (xhr.status == 200) {
localStorage["snippets"] = xhr.responseText;
localStorage["snippets-last-update"] = Date.now();
}
showSnippets();
};
@ -162,32 +165,39 @@ function loadSnippets()
function showSnippets()
{
let snippets = localStorage["snippets"];
// If there are remotely fetched snippets, try to to show them.
if (snippets) {
let snippetsElt = document.getElementById("snippets");
snippetsElt.innerHTML = snippets;
// Scripts injected by innerHTML are inactive, so we have to relocate them
// through DOM manipulation to activate their contents.
Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
let relocatedScript = document.createElement("script");
relocatedScript.type = "text/javascript;version=1.8";
relocatedScript.text = elt.text;
elt.parentNode.replaceChild(relocatedScript, elt);
});
snippetsElt.hidden = false;
} else {
// If there are no saved snippets, show one of the default ones.
let defaultSnippetsElt = document.getElementById("defaultSnippets");
let entries = defaultSnippetsElt.querySelectorAll("span");
// Choose a random snippet. Assume there is always at least one.
let randIndex = Math.round(Math.random() * (entries.length - 1));
let entry = entries[randIndex];
// Inject url in the eventual link.
if (DEFAULT_SNIPPETS_URLS[randIndex]) {
let links = entry.getElementsByTagName("a");
if (links.length != 1)
return; // Something is messed up in this entry, we support just 1 link.
links[0].href = DEFAULT_SNIPPETS_URLS[randIndex];
// Injecting snippets can throw if they're invalid XML.
try {
snippetsElt.innerHTML = snippets;
// Scripts injected by innerHTML are inactive, so we have to relocate them
// through DOM manipulation to activate their contents.
Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
let relocatedScript = document.createElement("script");
relocatedScript.type = "text/javascript;version=1.8";
relocatedScript.text = elt.text;
elt.parentNode.replaceChild(relocatedScript, elt);
});
snippetsElt.hidden = false;
return;
} catch (ex) {
// Bad content, continue to show default snippets.
}
entry.hidden = false;
}
// Show default snippets otherwise.
let defaultSnippetsElt = document.getElementById("defaultSnippets");
let entries = defaultSnippetsElt.querySelectorAll("span");
// Choose a random snippet. Assume there is always at least one.
let randIndex = Math.round(Math.random() * (entries.length - 1));
let entry = entries[randIndex];
// Inject url in the eventual link.
if (DEFAULT_SNIPPETS_URLS[randIndex]) {
let links = entry.getElementsByTagName("a");
if (links.length != 1)
return; // Something is messed up in this entry, we support just 1 link.
links[0].href = DEFAULT_SNIPPETS_URLS[randIndex];
}
entry.hidden = false;
}

View File

@ -113,15 +113,6 @@
label="&helpSafeMode.label;"
oncommand="safeModeRestart();"/>
<menuseparator/>
<menuseparator id="updateSeparator"/>
#ifdef XP_MACOSX
#ifdef MOZ_UPDATER
<menuitem id="checkForUpdates"
label="&updateCmd.label;"
class="menuitem-iconic"
oncommand="checkForUpdates();"/>
#endif
#endif
<menuseparator id="aboutSeparator"/>
<menuitem id="aboutName"
accesskey="&aboutProduct.accesskey;"

View File

@ -439,11 +439,17 @@
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="subscribeToPageMenuitem"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="subscribeToPageMenupopup"
#ifndef XP_MACOSX
class="menu-iconic"
#endif
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="subscribeToPageSubmenuMenupopup"

View File

@ -51,7 +51,7 @@ tabbrowser {
-moz-transition: opacity .25s;
}
.tabbrowser-tab[pinned] {
.tabbrowser-tabs:not([pinnedonly]) > .tabbrowser-tab[pinned] {
position: fixed;
display: block; /* position:fixed already does this (bug 579776), but let's be explicit */
}
@ -80,7 +80,7 @@ toolbar[printpreview="true"] {
-moz-box-ordinal-group: 10;
}
%ifdef MENUBAR_CAN_AUTOHIDE
%ifdef CAN_DRAW_IN_TITLEBAR
#main-window[inFullscreen] > #titlebar {
display: none;
}

View File

@ -1913,12 +1913,7 @@ function BrowserReloadSkipCache() {
BrowserReloadWithFlags(reloadFlags);
}
function BrowserHome()
{
var homePage = gHomeButton.getHomePage();
loadOneOrMoreURIs(homePage);
}
var BrowserHome = BrowserGoHome;
function BrowserGoHome(aEvent) {
if (aEvent && "button" in aEvent &&
aEvent.button == 2) // right-click: do nothing
@ -1928,6 +1923,11 @@ function BrowserGoHome(aEvent) {
var where = whereToOpenLink(aEvent, false, true);
var urls;
// Home page should open in a new tab when current tab is an app tab
if (where == "current" &&
gBrowser.selectedTab.pinned)
where = "tab";
// openUILinkIn in utilityOverlay.js doesn't handle loading multiple pages
switch (where) {
case "current":
@ -3489,9 +3489,10 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
PlacesToolbarHelper.customizeDone();
BookmarksMenuButton.customizeDone();
UpdateUrlbarSearchSplitterState();
// The url bar splitter state is dependent on whether stop/reload
// and the location bar are combined, so we need this ordering
CombinedStopReload.init();
UpdateUrlbarSearchSplitterState();
// Update the urlbar
if (gURLBar) {
@ -4723,14 +4724,18 @@ function updateAppButtonDisplay() {
window.menubar.visible &&
document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
#ifdef CAN_DRAW_IN_TITLEBAR
document.getElementById("titlebar").hidden = !displayAppButton;
if (displayAppButton)
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
else
document.documentElement.removeAttribute("chromemargin");
#endif
}
#endif
#ifdef CAN_DRAW_IN_TITLEBAR
function onTitlebarMaxClick() {
if (window.windowState == window.STATE_MAXIMIZED)
window.restore();
@ -4983,134 +4988,159 @@ function asyncOpenWebPanel(event)
* - gatherTextUnder
*/
// Called whenever the user clicks in the content area,
// except when left-clicking on links (special case)
// should always return true for click to go through
function contentAreaClick(event, fieldNormalClicks)
{
if (!event.isTrusted || event.getPreventDefault()) {
return true;
}
/**
* Extracts linkNode and href for the current click target.
*
* @param event
* The click event.
* @return [href, linkNode].
*
* @note linkNode will be null if the click wasn't on an anchor
* element (or XLink).
*/
function hrefAndLinkNodeForClickEvent(event)
{
function isHTMLLink(aNode)
{
return aNode instanceof HTMLAnchorElement ||
aNode instanceof HTMLAreaElement ||
aNode instanceof HTMLLinkElement;
}
var target = event.target;
var linkNode;
let linkNode;
if (isHTMLLink(event.target)) {
// This is a hack to work around Gecko bug 266932.
// Walk up the DOM looking for a parent link node, to match the existing
// behaviour for left click.
// TODO: this is no more needed and should be removed in bug 325652.
let node = event.target;
while (node) {
if (isHTMLLink(node) && node.hasAttribute("href"))
linkNode = node;
node = node.parentNode;
}
}
else {
let node = event.originalTarget;
while (node && !(node instanceof HTMLAnchorElement)) {
node = node.parentNode;
}
// <a> cannot be nested. So if we find an anchor without an
// href, there is no useful <a> around the target.
if (node && node.hasAttribute("href"))
linkNode = node;
}
if (target instanceof HTMLAnchorElement ||
target instanceof HTMLAreaElement ||
target instanceof HTMLLinkElement) {
if (target.hasAttribute("href"))
linkNode = target;
if (linkNode)
return [linkNode.href, linkNode];
// xxxmpc: this is kind of a hack to work around a Gecko bug (see bug 266932)
// we're going to walk up the DOM looking for a parent link node,
// this shouldn't be necessary, but we're matching the existing behaviour for left click
var parent = target.parentNode;
while (parent) {
if (parent instanceof HTMLAnchorElement ||
parent instanceof HTMLAreaElement ||
parent instanceof HTMLLinkElement) {
if (parent.hasAttribute("href"))
linkNode = parent;
}
parent = parent.parentNode;
}
}
else {
linkNode = event.originalTarget;
while (linkNode && !(linkNode instanceof HTMLAnchorElement))
linkNode = linkNode.parentNode;
// <a> cannot be nested. So if we find an anchor without an
// href, there is no useful <a> around the target
if (linkNode && !linkNode.hasAttribute("href"))
linkNode = null;
}
var wrapper = null;
if (linkNode) {
wrapper = linkNode;
if (event.button == 0 && !event.ctrlKey && !event.shiftKey &&
!event.altKey && !event.metaKey) {
// A Web panel's links should target the main content area. Do this
// if no modifier keys are down and if there's no target or the target equals
// _main (the IE convention) or _content (the Mozilla convention).
// XXX Now that markLinkVisited is gone, we may not need to field _main and
// _content here.
target = wrapper.getAttribute("target");
if (fieldNormalClicks &&
(!target || target == "_content" || target == "_main"))
// IE uses _main, SeaMonkey uses _content, we support both
{
if (!wrapper.href)
return true;
if (wrapper.getAttribute("onclick"))
return true;
// javascript links should be executed in the current browser
if (wrapper.href.substr(0, 11) === "javascript:")
return true;
// data links should be executed in the current browser
if (wrapper.href.substr(0, 5) === "data:")
return true;
// If there is no linkNode, try simple XLink.
let href, baseURI;
let node = event.target;
while (node) {
if (node.nodeType == Node.ELEMENT_NODE) {
href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
if (href)
baseURI = node.baseURI;
}
node = node.parentNode;
}
try {
urlSecurityCheck(wrapper.href, wrapper.ownerDocument.nodePrincipal);
}
catch(ex) {
return false;
}
// In case of XLink, we don't return the node we got href from since
// callers expect <a>-like elements.
return [href ? makeURLAbsolute(baseURI, href) : null, null];
}
var postData = { };
var url = getShortcutOrURI(wrapper.href, postData);
if (!url)
return true;
loadURI(url, null, postData.value, false);
event.preventDefault();
return false;
}
else if (linkNode.getAttribute("rel") == "sidebar") {
// This is the Opera convention for a special link that - when clicked - allows
// you to add a sidebar panel. We support the Opera convention here. The link's
// title attribute contains the title that should be used for the sidebar panel.
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href),
wrapper.getAttribute("title"),
null, null, true, true);
event.preventDefault();
return false;
}
}
else {
handleLinkClick(event, wrapper.href, linkNode);
}
/**
* Called whenever the user clicks in the content area.
*
* @param event
* The click event.
* @param isPanelClick
* Whether the event comes from a web panel.
* @note default event is prevented if the click is handled.
*/
function contentAreaClick(event, isPanelClick)
{
if (!event.isTrusted || event.getPreventDefault() || event.button == 2)
return true;
return true;
} else {
// Try simple XLink
var href, realHref, baseURI;
linkNode = target;
while (linkNode) {
if (linkNode.nodeType == Node.ELEMENT_NODE) {
wrapper = linkNode;
let [href, linkNode] = hrefAndLinkNodeForClickEvent(event);
if (!href) {
// Not a link, handle middle mouse navigation.
if (event.button == 1 &&
gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
!gPrefService.getBoolPref("general.autoScroll")) {
middleMousePaste(event);
event.preventDefault();
}
return true;
}
realHref = wrapper.getAttributeNS("http://www.w3.org/1999/xlink", "href");
if (realHref) {
href = realHref;
baseURI = wrapper.baseURI
}
}
linkNode = linkNode.parentNode;
}
if (href) {
href = makeURLAbsolute(baseURI, href);
handleLinkClick(event, href, null);
return true;
}
}
if (event.button == 1 &&
gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
!gPrefService.getBoolPref("general.autoScroll")) {
middleMousePaste(event);
}
return true;
}
// This code only applies if we have a linkNode (i.e. clicks on real anchor
// elements, as opposed to XLink).
if (linkNode && event.button == 0 &&
!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
// A Web panel's links should target the main content area. Do this
// if no modifier keys are down and if there's no target or the target
// equals _main (the IE convention) or _content (the Mozilla convention).
let target = linkNode.target;
let mainTarget = !target || target == "_content" || target == "_main";
if (isPanelClick && mainTarget) {
// javascript and data links should be executed in the current browser.
if (linkNode.getAttribute("onclick") ||
href.substr(0, 11) === "javascript:" ||
href.substr(0, 5) === "data:")
return true;
try {
urlSecurityCheck(href, linkNode.ownerDocument.nodePrincipal);
}
catch(ex) {
// Prevent loading unsecure destinations.
event.preventDefault();
return true;
}
let postData = {};
let url = getShortcutOrURI(href, postData);
if (!url)
return true;
loadURI(url, null, postData.value, false);
event.preventDefault();
return true;
}
if (linkNode.getAttribute("rel") == "sidebar") {
// This is the Opera convention for a special link that, when clicked,
// allows to add a sidebar panel. The link's title attribute contains
// the title that should be used for the sidebar panel.
PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(href),
linkNode.getAttribute("title"),
null, null, true, true);
event.preventDefault();
return true;
}
}
handleLinkClick(event, href, linkNode);
// Mark the page as a user followed link. This is done so that history can
// distinguish automatic embed visits from user activated ones. For example
// pages loaded in frames are embed visits and lost with the session, while
// visits across frames should be preserved.
try {
PlacesUIUtils.markPageAsFollowedLink(href);
} catch (ex) { /* Skip invalid URIs. */ }
return true;
}
/**
* Handles clicks on links.
*
* @return true if the click event was handled, false otherwise.
*/
function handleLinkClick(event, href, linkNode) {
if (event.button == 2) // right click
return false;
@ -5124,6 +5154,7 @@ function handleLinkClick(event, href, linkNode) {
if (where == "save") {
saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, true,
true, doc.documentURIObject);
event.preventDefault();
return true;
}
@ -5131,7 +5162,7 @@ function handleLinkClick(event, href, linkNode) {
openLinkIn(href, where, { fromContent: true,
referrerURI: doc.documentURIObject,
charset: doc.characterSet });
event.stopPropagation();
event.preventDefault();
return true;
}
@ -7835,17 +7866,11 @@ function switchToTabHavingURI(aURI, aOpenNew, aCallback) {
for (let i = 0; i < browsers.length; i++) {
let browser = browsers[i];
if (browser.currentURI.equals(aURI)) {
gURLBar.handleRevert();
// We need the current tab so we can check if we should close it
let prevTab = gBrowser.selectedTab;
// Focus the matching window & tab
aWindow.focus();
aWindow.gBrowser.tabContainer.selectedIndex = i;
if (aCallback)
aCallback(browser);
// Close the previously selected tab if it was empty
if (isTabEmpty(prevTab))
gBrowser.removeTab(prevTab);
return true;
}
}

View File

@ -429,29 +429,25 @@
<tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
</popupset>
#ifdef MENUBAR_CAN_AUTOHIDE
<vbox id="titlebar">
#ifdef CAN_DRAW_IN_TITLEBAR
<vbox id="titlebar">
<hbox id="titlebar-content">
<hbox id="appmenu-button-container" align="start">
<button id="appmenu-button"
type="menu"
#ifdef XP_WIN
label="&brandShortName;"
#else
label="&appMenuButton.label;"
#endif
style="-moz-user-focus: ignore;">
<hbox id="appmenu-button-container" align="start">
<button id="appmenu-button"
type="menu"
label="&brandShortName;"
style="-moz-user-focus: ignore;">
#include browser-appmenu.inc
</button>
</button>
</hbox>
<spacer id="titlebar-spacer" flex="1"/>
<hbox id="titlebar-buttonbox">
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
</hbox>
</hbox>
<spacer id="titlebar-spacer" flex="1"/>
<hbox id="titlebar-buttonbox">
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
</hbox>
</hbox>
</vbox>
</vbox>
#endif
<deck flex="1" id="tab-view-deck">
@ -580,13 +576,16 @@
onclick="gURLBar.handleCommand(event);"/>
</hbox>
<toolbarbutton id="urlbar-go-button"
class="chromeclass-toolbar-additional"
onclick="gURLBar.handleCommand(event);"
tooltiptext="&goEndCap.tooltip;"/>
<toolbarbutton id="urlbar-reload-button"
class="chromeclass-toolbar-additional"
command="Browser:ReloadOrDuplicate"
onclick="checkForMiddleClick(this, event);"
tooltiptext="&reloadButton.tooltip;"/>
<toolbarbutton id="urlbar-stop-button"
class="chromeclass-toolbar-additional"
command="Browser:Stop"
tooltiptext="&stopButton.tooltip;"/>
</textbox>
@ -652,11 +651,17 @@
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="BMB_subscribeToPageMenuitem"
#ifndef XP_MACOSX
class="menuitem-iconic"
#endif
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="BMB_subscribeToPageMenupopup"
#ifndef XP_MACOSX
class="menu-iconic"
#endif
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="BMB_subscribeToPageSubmenuMenupopup"

View File

@ -524,8 +524,10 @@
browserHistory.unregisterOpenPage(this.mBrowser.registeredOpenURI);
delete this.mBrowser.registeredOpenURI;
}
browserHistory.registerOpenPage(aLocation);
this.mBrowser.registeredOpenURI = aLocation;
if (aLocation.spec != "about:blank") {
browserHistory.registerOpenPage(aLocation);
this.mBrowser.registeredOpenURI = aLocation;
}
}
if (!this.mBlank) {
@ -830,31 +832,48 @@
// Focus is suppressed in the event that the main browser window is minimized - focusing a tab would restore the window
if (!this._previewMode) {
// We've selected the new tab, so go ahead and notify listeners.
var event = document.createEvent("Events");
let event = document.createEvent("Events");
event.initEvent("TabSelect", true, false);
this.mCurrentTab.dispatchEvent(event);
this._tabAttrModified(oldTab);
this._tabAttrModified(this.mCurrentTab);
// Change focus to the new browser unless the findbar is focused.
if (!gFindBarInitialized ||
gFindBar.hidden ||
gFindBar.getElement("findbar-textbox").getAttribute("focused") != "true") {
// Adjust focus
do {
// Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible
// if the tab is a blank one.
oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
if (newBrowser._urlbarFocused && gURLBar) {
if (!window.fullScreen) {
gURLBar.focus();
break;
} else if (isTabEmpty(this.mCurrentTab)) {
focusAndSelectUrlBar();
break;
}
}
var fm = Components.classes["@mozilla.org/focus-manager;1"].
getService(Components.interfaces.nsIFocusManager);
var newFocusedElement = fm.getFocusedElementForWindow(window.content, true, {});
// If the find bar is focused, keep it focused.
if (gFindBarInitialized &&
!gFindBar.hidden &&
gFindBar.getElement("findbar-textbox").getAttribute("focused") == "true")
break;
// Otherwise, focus the content area.
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
let newFocusedElement = fm.getFocusedElementForWindow(window.content, true, {});
// for anchors, use FLAG_SHOWRING so that it is clear what link was
// last clicked when switching back to that tab
var focusFlags = fm.FLAG_NOSCROLL;
let focusFlags = fm.FLAG_NOSCROLL;
if (newFocusedElement &&
(newFocusedElement instanceof HTMLAnchorElement ||
newFocusedElement.getAttributeNS("http://www.w3.org/1999/xlink", "type") == "simple"))
focusFlags |= fm.FLAG_SHOWRING;
fm.setFocus(newBrowser, focusFlags);
}
} while (false);
}
]]>
</body>
@ -1900,15 +1919,11 @@
<parameter name="aTab"/>
<body>
<![CDATA[
if (this.visibleTabs.length == 1)
if (this.tabs.length == 1)
return null;
// tell a new window to take the "dropped" tab
return Services.ww.openWindow(window,
getBrowserURL(),
null,
"chrome,dialog=no,all",
aTab);
return window.openDialog(getBrowserURL(), "_blank", "dialog=no,all", aTab);
]]>
</body>
</method>
@ -2706,11 +2721,18 @@
<method name="_positionPinnedTabs">
<body><![CDATA[
var width = 0;
var scrollButtonWidth = this.getAttribute("overflow") != "true" ? 0 :
var pinnedOnly = (this.tabbrowser._numPinnedTabs == this.tabbrowser.visibleTabs.length);
if (pinnedOnly)
this.tabbrowser.tabContainer.setAttribute("pinnedonly", "true");
else
this.tabbrowser.tabContainer.removeAttribute("pinnedonly");
var scrollButtonWidth = (this.getAttribute("overflow") != "true" || pinnedOnly) ? 0 :
this.mTabstrip._scrollButtonDown.scrollWidth;
for (var i = this.tabbrowser._numPinnedTabs - 1; i >= 0; i--) {
let tab = this.childNodes[i];
width += tab.scrollWidth;
width += pinnedOnly ? 0 : tab.scrollWidth;
tab.style.MozMarginStart = - (width + scrollButtonWidth) + "px";
}
this.style.MozMarginStart = width + "px";

View File

@ -81,6 +81,8 @@ function GroupItem(listOfEls, options) {
this.locked = (options.locked ? Utils.copy(options.locked) : {});
this.topChild = null;
this.hidden = false;
this.fadeAwayUndoButtonDelay = 15000;
this.fadeAwayUndoButtonDuration = 300;
this.keepProportional = false;
@ -277,6 +279,7 @@ function GroupItem(listOfEls, options) {
// ___ Undo Close
this.$undoContainer = null;
this._undoButtonTimeoutId = null;
// ___ Superclass initialization
this._init($container[0]);
@ -637,28 +640,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
}, 50);
let remove = function() {
// close all children
let toClose = self._children.concat();
toClose.forEach(function(child) {
child.removeSubscriber(self, "close");
child.close();
});
// remove all children
self.removeAll();
GroupItems.unregister(self);
self._sendToSubscribers("close");
self.removeTrenches();
iQ(self.container).remove();
self.$undoContainer.remove();
self.$undoContainer = null;
Items.unsquish();
self.deleteData();
};
this.$undoContainer.click(function(e) {
// Only do this for clicks on this actual element.
if (e.target.nodeName != self.$undoContainer[0].nodeName)
@ -667,6 +648,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
self.$undoContainer.fadeOut(function() {
iQ(this).remove();
self.hidden = false;
self._cancelFadeAwayUndoButtonTimer();
self.$undoContainer = null;
iQ(self.container).show().animate({
@ -686,31 +668,92 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
undoClose.click(function() {
self.$undoContainer.fadeOut(remove);
self._cancelFadeAwayUndoButtonTimer();
self.$undoContainer.fadeOut(function() { self._removeHiddenGroupItem(); });
});
// After 15 seconds, fade away.
const WAIT = 15000;
const FADE = 300;
this.setupFadeAwayUndoButtonTimer();
// Cancel the fadeaway if you move the mouse over the undo
// button, and restart the countdown once you move out of it.
this.$undoContainer.mouseover(function() {
self._cancelFadeAwayUndoButtonTimer();
});
this.$undoContainer.mouseout(function() {
self.setupFadeAwayUndoButtonTimer();
});
},
let fadeaway = function() {
if (self.$undoContainer)
// ----------
// Sets up fade away undo button timeout.
setupFadeAwayUndoButtonTimer: function() {
let self = this;
if (!this._undoButtonTimeoutId) {
this._undoButtonTimeoutId = setTimeout(function() {
self._fadeAwayUndoButton();
}, this.fadeAwayUndoButtonDelay);
}
},
// ----------
// Cancels the fade away undo button timeout.
_cancelFadeAwayUndoButtonTimer: function() {
clearTimeout(this._undoButtonTimeoutId);
this._undoButtonTimeoutId = null;
},
// ----------
// Fades away the undo button
_fadeAwayUndoButton: function() {
let self = this;
if (this.$undoContainer) {
// if there is one or more orphan tabs or there is more than one group
// and other groupS are not empty, fade away the undo button.
let shouldFadeAway = GroupItems.getOrphanedTabs().length > 0;
if (!shouldFadeAway && GroupItems.groupItems.length > 1) {
shouldFadeAway =
GroupItems.groupItems.some(function(groupItem) {
return (groupItem != self && groupItem.getChildren().length > 0);
});
}
if (shouldFadeAway) {
self.$undoContainer.animate({
color: "transparent",
opacity: 0
}, {
duration: FADE,
complete: remove
duration: this.fadeAwayUndoButtonDuration,
complete: function() { self._removeHiddenGroupItem(); }
});
};
}
}
},
let timeoutId = setTimeout(fadeaway, WAIT);
// Cancel the fadeaway if you move the mouse over the undo
// button, and restart the countdown once you move out of it.
this.$undoContainer.mouseover(function() clearTimeout(timeoutId));
this.$undoContainer.mouseout(function() {
timeoutId = setTimeout(fadeaway, WAIT);
// ----------
// Removes the group item, its children and its container.
_removeHiddenGroupItem: function() {
let self = this;
// close all children
let toClose = this._children.concat();
toClose.forEach(function(child) {
child.removeSubscriber(self, "close");
child.close();
});
// remove all children
this.removeAll();
GroupItems.unregister(this);
this._sendToSubscribers("close");
this.removeTrenches();
iQ(this.container).remove();
this.$undoContainer.remove();
this.$undoContainer = null;
Items.unsquish();
this.deleteData();
},
// ----------
@ -977,19 +1020,22 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: shouldStack
// Returns true if the groupItem, given "count", should stack (instead of grid).
// Returns true if the groupItem should stack (instead of grid).
shouldStack: function GroupItem_shouldStack(count) {
if (count <= 1)
return false;
var bb = this.getContentBounds();
var options = {
pretend: true,
count: count
return: 'widthAndColumns',
count: count || this._children.length
};
let {childWidth, columns} = Items.arrange(null, bb, options);
var rects = Items.arrange(null, bb, options);
return (rects[0].width < 55);
let shouldStack = childWidth < TabItems.minTabWidth * 1.35;
this._columns = shouldStack ? null : columns;
return shouldStack;
},
// ----------
@ -1006,35 +1052,30 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
Items.arrange(this._children, box, Utils.extend({}, options, {z: 99999}));
} else {
var bb = this.getContentBounds();
var count = this._children.length;
if (!this.shouldStack(count)) {
if (!this.shouldStack()) {
if (!options)
options = {};
var animate;
if (typeof options.animate == 'undefined')
animate = true;
else
animate = options.animate;
this._children.forEach(function(child) {
child.removeClass("stacked")
});
this.topChild = null;
var arrangeOptions = Utils.copy(options);
Utils.extend(arrangeOptions, {
pretend: true,
count: count
});
if (!count) {
if (!this._children.length) {
this.xDensity = 0;
this.yDensity = 0;
return;
}
var arrangeOptions = Utils.copy(options);
Utils.extend(arrangeOptions, {
columns: this._columns
});
// Items.arrange will rearrange the children, but also return an array
// of the Rect's used.
var rects = Items.arrange(this._children, bb, arrangeOptions);
// yDensity = (the distance of the bottom of the last tab to the top of the content area)
@ -1055,15 +1096,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
}
this.xDensity = (rightMostRight - bb.left) / (bb.width);
this._children.forEach(function(child, index) {
if (!child.locked.bounds) {
child.setBounds(rects[index], !animate);
child.setRotation(0);
if (options.z)
child.setZ(options.z);
}
});
this._isStacked = false;
} else
this._stackArrange(bb, options);

View File

@ -1,252 +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 infoitems.js.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ian Gilman <ian@iangilman.com>
* Aza Raskin <aza@mozilla.com>
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Ehsan Akhgari <ehsan@mozilla.com>
*
* 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 ***** */
// **********
// Title: infoitems.js
// ##########
// Class: InfoItem
// An <Item> in TabView used for displaying information, such as the welcome video.
// Note that it implements the <Subscribable> interface.
//
// ----------
// Constructor: InfoItem
//
// Parameters:
// bounds - a <Rect> for where the item should be located
// options - various options for this infoItem (see below)
//
// Possible options:
// locked - see <Item.locked>; default is {}
// dontPush - true if this infoItem shouldn't push away on creation; default is false
// immediately - place the item immediately, without animation
function InfoItem(bounds, options) {
try {
Utils.assertThrow(Utils.isRect(bounds), 'bounds');
if (typeof options == 'undefined')
options = {};
this._inited = false;
this.isAnInfoItem = true;
this.defaultSize = bounds.size();
this.locked = (options.locked ? Utils.copy(options.locked) : {});
this.bounds = new Rect(bounds);
this.isDragging = false;
var self = this;
var $container = iQ('<div>')
.addClass('info-item')
.css(this.bounds)
.appendTo('body');
this.$contents = iQ('<div>')
.appendTo($container);
var $close = iQ('<div>')
.addClass('close')
.click(function() {
self.close();
})
.appendTo($container);
// ___ locking
if (this.locked.bounds)
$container.css({cursor: 'default'});
if (this.locked.close)
$close.hide();
// ___ Superclass initialization
this._init($container[0]);
if (this.$debug)
this.$debug.css({zIndex: -1000});
// ___ Finish Up
if (!this.locked.bounds)
this.draggable();
// ___ Position
if (!options.dontPush)
this.snap(options.immediately);
this._inited = true;
this.save();
} catch(e) {
Utils.log(e);
}
};
// ----------
InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: getStorageData
// Returns all of the info worth storing about this item.
getStorageData: function InfoItem_getStorageData() {
var data = null;
try {
data = {
bounds: this.getBounds(),
locked: Utils.copy(this.locked)
};
} catch(e) {
Utils.log(e);
}
return data;
},
// ----------
// Function: save
// Saves this item to persistent storage.
save: function InfoItem_save() {
try {
if (!this._inited) // too soon to save now
return;
var data = this.getStorageData();
} catch(e) {
Utils.log(e);
}
},
// ----------
// Function: setBounds
// Sets the bounds with the given <Rect>, animating unless "immediately" is false.
setBounds: function InfoItem_setBounds(rect, immediately) {
try {
Utils.assertThrow(Utils.isRect(rect), 'InfoItem.setBounds: rect must be a real rectangle!');
// ___ Determine what has changed
var css = {};
if (rect.left != this.bounds.left)
css.left = rect.left;
if (rect.top != this.bounds.top)
css.top = rect.top;
if (rect.width != this.bounds.width)
css.width = rect.width;
if (rect.height != this.bounds.height)
css.height = rect.height;
if (Utils.isEmptyObject(css))
return;
this.bounds = new Rect(rect);
Utils.assertThrow(Utils.isRect(this.bounds),
'InfoItem.setBounds: this.bounds must be a real rectangle!');
// ___ Update our representation
if (immediately) {
iQ(this.container).css(css);
} else {
TabItems.pausePainting();
iQ(this.container).animate(css, {
duration: 350,
easing: "tabviewBounce",
complete: function() {
TabItems.resumePainting();
}
});
}
this._updateDebugBounds();
this.setTrenches(rect);
this.save();
} catch(e) {
Utils.log(e);
}
},
// ----------
// Function: setZ
// Set the Z order for the item's container.
setZ: function InfoItem_setZ(value) {
try {
Utils.assertThrow(typeof value == 'number', 'value must be a number');
this.zIndex = value;
iQ(this.container).css({zIndex: value});
if (this.$debug)
this.$debug.css({zIndex: value + 1});
} catch(e) {
Utils.log(e);
}
},
// ----------
// Function: close
// Closes the item.
close: function InfoItem_close() {
try {
this._sendToSubscribers("close");
this.removeTrenches();
iQ(this.container).fadeOut(function() {
iQ(this).remove();
Items.unsquish();
});
} catch(e) {
Utils.log(e);
}
},
// ----------
// Function: html
// Sets the item's container's html to the specified value.
html: function InfoItem_html(value) {
try {
Utils.assertThrow(typeof value == 'string', 'value must be a string');
this.$contents.html(value);
} catch(e) {
Utils.log(e);
}
}
});

View File

@ -601,7 +601,7 @@ Item.prototype = {
// ___ mousemove
var handleMouseMove = function(e) {
// positioning
var mouse = new Point(e.pageX, e.pageY);
var mouse = new Point(e.pageX, e.pageY);
if (!startSent) {
if(Math.abs(mouse.x - startMouse.x) > self.dragOptions.minDragDistance ||
Math.abs(mouse.y - startMouse.y) > self.dragOptions.minDragDistance) {
@ -892,39 +892,41 @@ let Items = {
// maximizing item size but maintaining standard tab aspect ratio for each
//
// Parameters:
// items - an array of <Item>s. Can be null if the pretend and count options are set.
// items - an array of <Item>s. Can be null, in which case we won't
// actually move anything.
// bounds - a <Rect> defining the space to arrange within
// options - an object with various properites (see below)
//
// Possible "options" properties:
// animate - whether to animate; default: true.
// z - the z index to set all the items; default: don't change z.
// pretend - whether to collect and return the rectangle rather than moving the items; default: false
// count - overrides the item count for layout purposes; default: the actual item count
// return - if set to 'widthAndColumns', it'll return an object with the
// width of children and the columns.
// count - overrides the item count for layout purposes;
// default: the actual item count
// padding - pixels between each item
// columns - (int) a preset number of columns to use
//
// Returns:
// the list of rectangles if the pretend option is set; otherwise null
// an object with the width value of the child items and the number of columns,
// if the return option is set to 'widthAndColumns'; otherwise the list of <Rect>s
arrange: function Items_arrange(items, bounds, options) {
var animate;
if (!options || typeof options.animate == 'undefined')
animate = true;
else
animate = options.animate;
if (typeof options == 'undefined')
options = {};
var rects = null;
if (options.pretend)
rects = [];
var animate = true;
if (typeof options.animate != 'undefined')
animate = options.animate;
var immediately = !animate;
var rects = [];
var tabAspect = TabItems.tabHeight / TabItems.tabWidth;
var count = options.count || (items ? items.length : 0);
if (!count)
return rects;
var columns = 1;
var columns = options.columns || 1;
// We'll assume for the time being that all the items have the same styling
// and that the margin is the same width around.
var itemMargin = items && items.length ?
@ -954,20 +956,17 @@ let Items = {
tabWidth = Math.min(tabWidth, (bounds.height - 2 * itemMargin) / tabAspect);
tabHeight = tabWidth * tabAspect;
}
if (options.return == 'widthAndColumns')
return {childWidth: tabWidth, columns: columns};
var box = new Rect(bounds.left, bounds.top, tabWidth, tabHeight);
var row = 0;
var column = 0;
var immediately;
var a;
for (a = 0; a < count; a++) {
immediately = !animate;
if (rects)
rects.push(new Rect(box));
else if (items && a < items.length) {
var item = items[a];
for (let a = 0; a < count; a++) {
rects.push(new Rect(box));
if (items && a < items.length) {
let item = items[a];
if (!item.locked.bounds) {
item.setBounds(box, immediately);
item.setRotation(0);
@ -982,7 +981,6 @@ let Items = {
box.left = bounds.left;
box.top += (box.height * yScale) + padding;
column = 0;
row++;
}
}

View File

@ -52,8 +52,5 @@ XPCOMUtils.defineLazyGetter(this, "gPrivateBrowsing", function() {
#include tabitems.js
#include drag.js
#include trench.js
#include infoitems.js
#include ui.js
#include search.js

View File

@ -249,16 +249,19 @@ let UI = {
// Resets the Panorama view to have just one group with all tabs
// and, if firstTime == true, add the welcome video/tab
reset: function UI_reset(firstTime) {
let padding = 10;
let infoWidth = 350;
let infoHeight = 232;
let padding = Trenches.defaultRadius;
let welcomeWidth = 300;
let pageBounds = Items.getPageBounds();
pageBounds.inset(padding, padding);
let $actions = iQ("#actions");
if ($actions)
pageBounds.width -= $actions.width();
// ___ make a fresh groupItem
let box = new Rect(pageBounds);
box.width =
Math.min(box.width * 0.667, pageBounds.width - (infoWidth + padding));
box.width = Math.min(box.width * 0.667,
pageBounds.width - (welcomeWidth + padding));
box.height = box.height * 0.667;
GroupItems.groupItems.forEach(function(group) {
@ -280,17 +283,18 @@ let UI = {
if (firstTime) {
gPrefBranch.setBoolPref("experienced_first_run", true);
// ___ make info item
let video =
"http://videos-cdn.mozilla.net/firefox4beta/tabcandy_howto.webm";
let html =
"<div class='intro'>"
+ "<video src='" + video + "' width='100%' preload controls>"
+ "</div>";
let infoBox = new Rect(box.right + padding, box.top,
infoWidth, infoHeight);
let infoItem = new InfoItem(infoBox);
infoItem.html(html);
let url = gPrefBranch.getCharPref("welcome_url");
let newTab = gBrowser.loadOneTab(url, {inBackground: true});
let newTabItem = newTab.tabItem;
let parent = newTabItem.parent;
Utils.assert(parent, "should have a parent");
newTabItem.parent.remove(newTabItem);
let aspect = TabItems.tabHeight / TabItems.tabWidth;
let welcomeBounds = new Rect(box.right + padding, box.top,
welcomeWidth, welcomeWidth * aspect);
newTabItem.setBounds(welcomeBounds, true);
GroupItems.setActiveGroupItem(groupItem);
}
},

View File

@ -145,6 +145,7 @@ _BROWSER_FILES = \
browser_bug561636.js \
browser_bug562649.js \
browser_bug563588.js \
browser_bug565575.js \
browser_bug575561.js \
browser_bug577121.js \
browser_bug579872.js \
@ -159,6 +160,7 @@ _BROWSER_FILES = \
browser_bug595507.js \
browser_bug596687.js \
browser_bug597218.js \
browser_bug609700.js \
browser_contextSearchTabPosition.js \
browser_ctrlTab.js \
browser_discovery.js \
@ -221,6 +223,7 @@ _BROWSER_FILES = \
browser_aboutHome.js \
app_bug575561.html \
app_subframe_bug575561.html \
browser_contentAreaClick.js \
$(NULL)
# compartment-disabled

View File

@ -94,6 +94,32 @@ let gTests = [
}
},
{
desc: "Check default snippets are shown if snippets are invalid xml",
setup: function ()
{
let storage = getStorage();
// This must be some incorrect xhtml code.
storage.setItem("snippets", "<p><b></p></b>");
},
run: function ()
{
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let snippetsElt = doc.getElementById("snippets");
ok(snippetsElt, "Found snippets element");
ok(snippetsElt.hidden, "Snippets element is hidden");
let defaultsElt = doc.getElementById("defaultSnippets");
ok(defaultsElt, "Found default snippets element")
ok(Array.some(defaultsElt.getElementsByTagName("span"), function(elt) {
return !elt.hidden;
}), "A default snippet is visible.");
executeSoon(runNextTest);
}
},
];
function test()

View File

@ -0,0 +1,13 @@
function test() {
gBrowser.selectedBrowser.focus();
BrowserOpenTab();
ok(gURLBar.focused, "location bar is focused for a new tab");
gBrowser.selectedTab = gBrowser.tabs[0];
ok(!gURLBar.focused, "location bar isn't focused for the previously selected tab");
gBrowser.selectedTab = gBrowser.tabs[1];
ok(gURLBar.focused, "location bar is re-focused when selecting the new tab");
gBrowser.removeCurrentTab();
}

View File

@ -0,0 +1,20 @@
function test() {
waitForExplicitFinish();
Services.ww.registerNotification(function (aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
Services.ww.unregisterNotification(arguments.callee);
ok(true, "duplicateTabIn opened a new window");
aSubject.addEventListener("load", function () {
executeSoon(function () {
aSubject.close();
finish();
});
}, false);
}
});
duplicateTabIn(gBrowser.selectedTab, "window");
}

View File

@ -0,0 +1,296 @@
/* ***** 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 Firefox Browser Test Code.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net>
*
* 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 ***** */
/**
* Test for bug 549340.
* Test for browser.js::contentAreaClick() util.
*
* The test opens a new browser window, then replaces browser.js methods invoked
* by contentAreaClick with a mock function that tracks which methods have been
* called.
* Each sub-test synthesizes a mouse click event on links injected in content,
* the event is collected by a click handler that ensures that contentAreaClick
* correctly prevent default events, and follows the correct code path.
*/
let gTests = [
{
desc: "Simple left click",
setup: function() {},
clean: function() {},
event: {},
target: "commonlink",
expectedInvokedMethods: [],
preventDefault: false,
},
{
desc: "Ctrl/Cmd left click",
setup: function() {},
clean: function() {},
event: { ctrlKey: true,
metaKey: true },
target: "commonlink",
expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
preventDefault: true,
},
// The next test was once handling feedService.forcePreview(). Now it should
// just be like Alt click.
{
desc: "Shift+Alt left click",
setup: function() {},
clean: function() {},
event: { shiftKey: true,
altKey: true },
target: "commonlink",
expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
preventDefault: true,
},
{
desc: "Shift click",
setup: function() {},
clean: function() {},
event: { shiftKey: true },
target: "commonlink",
expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
preventDefault: true,
},
{
desc: "Alt click",
setup: function() {},
clean: function() {},
event: { altKey: true },
target: "commonlink",
expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
preventDefault: true,
},
{
desc: "Panel click",
setup: function() {},
clean: function() {},
event: {},
target: "panellink",
expectedInvokedMethods: [ "urlSecurityCheck", "getShortcutOrURI", "loadURI" ],
preventDefault: true,
},
{
desc: "Simple middle click opentab",
setup: function() {},
clean: function() {},
event: { button: 1 },
target: "commonlink",
expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
preventDefault: true,
},
{
desc: "Simple middle click openwin",
setup: function() {
gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
},
clean: function() {
try {
gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
} catch(ex) {}
},
event: { button: 1 },
target: "commonlink",
expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
preventDefault: true,
},
{
desc: "Middle mouse paste",
setup: function() {
gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
gPrefService.setBoolPref("general.autoScroll", false);
},
clean: function() {
try {
gPrefService.clearUserPref("middlemouse.contentLoadURL");
} catch(ex) {}
try {
gPrefService.clearUserPref("general.autoScroll");
} catch(ex) {}
},
event: { button: 1 },
target: "emptylink",
expectedInvokedMethods: [ "middleMousePaste" ],
preventDefault: true,
},
];
// Array of method names that will be replaced in the new window.
let gReplacedMethods = [
"middleMousePaste",
"urlSecurityCheck",
"loadURI",
"gatherTextUnder",
"saveURL",
"openLinkIn",
"getShortcutOrURI",
];
// Reference to the new window.
let gTestWin = null;
// List of methods invoked by a specific call to contentAreaClick.
let gInvokedMethods = [];
// The test currently running.
let gCurrentTest = null;
function test() {
waitForExplicitFinish();
gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
gTestWin.addEventListener("load", function (event) {
info("Window loaded.");
gTestWin.removeEventListener("load", arguments.callee, false);
waitForFocus(function() {
info("Setting up browser...");
setupTestBrowserWindow();
info("Running tests...");
executeSoon(runNextTest);
}, gTestWin.content, true);
}, false);
}
// Click handler used to steal click events.
let gClickHandler = {
handleEvent: function (event) {
let linkId = event.target.id;
is(event.type, "click",
gCurrentTest.desc + ":Handler received a click event on " + linkId);
let isPanelClick = linkId == "panellink";
let returnValue = gTestWin.contentAreaClick(event, isPanelClick);
let prevent = event.getPreventDefault();
is(prevent, gCurrentTest.preventDefault,
gCurrentTest.desc + ": event.getPreventDefault() is correct (" + prevent + ")")
// Check that all required methods have been called.
gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
});
if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
is(false, "More than the expected methods have been called");
gInvokedMethods.forEach(function (method) info(method + " was invoked"));
}
event.preventDefault();
event.stopPropagation();
executeSoon(runNextTest);
}
}
// Wraps around the methods' replacement mock function.
function wrapperMethod(aInvokedMethods, aMethodName) {
return function () {
aInvokedMethods.push(aMethodName);
// At least getShortcutOrURI requires to return url that is the first param.
return arguments[0];
}
}
function setupTestBrowserWindow() {
// Steal click events and don't propagate them.
gTestWin.addEventListener("click", gClickHandler, true);
// Replace methods.
gReplacedMethods.forEach(function (aMethodName) {
gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
});
// Inject links in content.
let doc = gTestWin.content.document;
let mainDiv = doc.createElement("div");
mainDiv.innerHTML =
'<a id="commonlink" href="http://mochi.test/moz/">Common link</a>' +
'<a id="panellink" href="http://mochi.test/moz/">Panel link</a>' +
'<a id="emptylink">Empty link</a>';
doc.body.appendChild(mainDiv);
}
function runNextTest() {
if (gCurrentTest) {
info(gCurrentTest.desc + ": cleaning up...")
gCurrentTest.clean();
gInvokedMethods.length = 0;
}
if (gTests.length > 0) {
gCurrentTest = gTests.shift();
info(gCurrentTest.desc + ": starting...");
// Prepare for test.
gCurrentTest.setup();
// Fire click event.
let target = gTestWin.content.document.getElementById(gCurrentTest.target);
ok(target, gCurrentTest.desc + ": target is valid (" + target.id + ")");
EventUtils.synthesizeMouse(target, 2, 2, gCurrentTest.event, gTestWin.content);
}
else {
// No more tests to run.
finishTest()
}
}
function finishTest() {
info("Restoring browser...");
gTestWin.removeEventListener("click", gClickHandler, true);
// Restore original methods.
gReplacedMethods.forEach(function (aMethodName) {
gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
delete gTestWin["old_" + aMethodName];
});
gTestWin.close();
finish();
}

View File

@ -121,7 +121,7 @@ var gTestSteps = [
},
function() {
info("Running step 7 - remove tab immediately");
let tab = gBrowser.addTab("about:blank");
let tab = gBrowser.addTab("about:logo");
gBrowser.removeTab(tab);
ensure_opentabs_match_db();
nextStep();
@ -208,6 +208,8 @@ function ensure_opentabs_match_db() {
for (let i = 0; i < browserWin.gBrowser.tabContainer.childElementCount; i++) {
let browser = browserWin.gBrowser.getBrowserAtIndex(i);
let url = browser.currentURI.spec;
if (url == "about:blank")
continue;
if (!(url in tabs))
tabs[url] = 1;
else
@ -247,6 +249,10 @@ function ensure_opentabs_match_db() {
ok(dbtabs.indexOf(url) > -1,
"tab is open (" + tabs[url] + " times) and should recorded in db: " + url);
}
dbtabs.forEach(function (url) {
ok(url in tabs,
"db-recorded tab should actually exist: " + url);
});
}
/**

View File

@ -44,11 +44,8 @@ function test() {
browser2.contentWindow, null, true,
"focusedElement after tab change, focus in new tab");
// switching tabs when the urlbar is focused and nothing in the new tab is focused
// switching tabs when nothing in the new tab is focused
// should focus the browser
expectFocusShift(function () gURLBar.focus(),
window, gURLBar.inputField, true,
"url field focused");
expectFocusShift(function () gBrowser.selectedTab = tab1,
browser1.contentWindow, null, true,
"focusedElement after tab change, focus in new tab");
@ -89,6 +86,9 @@ function test() {
window, gURLBar.inputField, true,
"focusedWindow after url field focused");
is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "url field focused, button in tab");
expectFocusShift(function () gURLBar.blur(),
window, null, true,
"focusedWindow after browser focused");
// when a chrome element is focused, switching tabs to a tab with a button
// with the current focus should focus the button

View File

@ -53,6 +53,7 @@ _BROWSER_FILES = \
browser_tabview_bug594176.js \
browser_tabview_bug595191.js \
browser_tabview_bug595518.js \
browser_tabview_bug595521.js \
browser_tabview_bug595804.js \
browser_tabview_bug595930.js \
browser_tabview_bug595943.js \

View File

@ -0,0 +1,101 @@
/* ***** 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 a test for bug 595521.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Raymond Lee <raymond@appcoast.com>
*
* 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 ***** */
let fadeAwayUndoButtonDelay;
let fadeAwayUndoButtonDuration;
function test() {
waitForExplicitFinish();
window.addEventListener("tabviewshown", testCloseLastGroup, false);
TabView.toggle();
}
function testCloseLastGroup() {
window.removeEventListener("tabviewshown", testCloseLastGroup, false);
ok(TabView.isVisible(), "Tab View is visible");
let contentWindow = document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1, "Has one group only");
let groupItem = contentWindow.GroupItems.groupItems[0];
let checkExistence = function() {
is(contentWindow.GroupItems.groupItems.length, 1,
"Still has one group after delay");
EventUtils.sendMouseEvent(
{ type: "click" }, groupItem.$undoContainer[0], contentWindow);
};
groupItem.addSubscriber(groupItem, "groupHidden", function() {
groupItem.removeSubscriber(groupItem, "groupHidden");
// it should still stay after 3 ms.
setTimeout(checkExistence, 3);
});
groupItem.addSubscriber(groupItem, "groupShown", function() {
groupItem.removeSubscriber(groupItem, "groupShown");
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
ok(!TabView.isVisible(), "Tab View is hidden");
groupItem.fadeAwayUndoButtonDelay = fadeAwayUndoButtonDelay;
groupItem.fadeAwayUndoButtonDuration = fadeAwayUndoButtonDuration;
finish();
};
window.addEventListener("tabviewhidden", endGame, false);
TabView.toggle();
});
let closeButton = groupItem.container.getElementsByClassName("close");
ok(closeButton, "Group item close button exists");
// store the original values
fadeAwayUndoButtonDelay = groupItem.fadeAwayUndoButtonDelay;
fadeAwayUndoButtonDuration = groupItem.fadeAwayUndoButtonDuration;
// set both fade away delay and duration to 1ms
groupItem.fadeAwayUndoButtonDelay = 1;
groupItem.fadeAwayUndoButtonDuration = 1;
EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow);
}

View File

@ -35,15 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
let newWin;
let prefService;
function test() {
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
prefService =
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
getBranch("browser.panorama.");
// make sure we don't trigger the 'first run' behavior
prefService.setBoolPref("experienced_first_run", true);
waitForExplicitFinish();
@ -104,7 +97,6 @@ function test() {
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
// clean up and finish
prefService.setBoolPref("experienced_first_run", false);
newWin.close();
finish();

View File

@ -44,8 +44,10 @@ function test() {
ok(!TabView.isVisible(), "Main window TabView is hidden");
ok(experienced(), "should start as experienced");
prefsBranch.setBoolPref("experienced_first_run", false);
ok(!experienced(), "not experienced");
ok(!experienced(), "set to not experienced");
newWindowWithTabView(checkFirstRun, part2);
}
@ -58,11 +60,14 @@ function experienced() {
function checkFirstRun(win) {
let contentWindow = win.document.getElementById("tab-view").contentWindow;
let infoItems = contentWindow.iQ(".info-item");
is(infoItems.length, 1, "There should be an info item");
is(win.gBrowser.tabs.length, 2, "There should be two tabs");
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There should be one group");
is(groupItems[0].getChildren().length, 1, "...with one child");
let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
is(orphanTabCount, 1, "There should also be an orphaned tab");
ok(experienced(), "we're now experienced");
}
@ -74,12 +79,19 @@ function part2() {
function checkNotFirstRun(win) {
let contentWindow = win.document.getElementById("tab-view").contentWindow;
let infoItems = contentWindow.iQ(".info-item");
is(infoItems.length, 0, "There should be no info items");
is(win.gBrowser.tabs.length, 1, "There should be one tab");
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There should be one group");
is(groupItems[0].getChildren().length, 1, "...with one child");
let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
is(orphanTabCount, 0, "There should also be no orphaned tabs");
}
function endGame() {
ok(!TabView.isVisible(), "Main window TabView is still hidden");
ok(experienced(), "should finish as experienced");
finish();
}

View File

@ -161,7 +161,7 @@
pasteAndGo.setAttribute("label", label);
pasteAndGo.setAttribute("anonid", "paste-and-go");
pasteAndGo.setAttribute("oncommand",
"gURLBar.value = ''; goDoCommand('cmd_paste'); gURLBar.handleCommand();");
"gURLBar.select(); goDoCommand('cmd_paste'); gURLBar.handleCommand();");
cxmenu.insertBefore(pasteAndGo, insertLocation.nextSibling);
}
]]></constructor>
@ -248,8 +248,13 @@
if (action) {
url = action.param;
if (!(aTriggeringEvent && aTriggeringEvent.altKey)) {
if (action.type == "switchtab")
switchToTabHavingURI(url);
if (action.type == "switchtab") {
this.handleRevert();
let prevTab = gBrowser.selectedTab;
if (switchToTabHavingURI(url) &&
isTabEmpty(prevTab))
gBrowser.removeTab(prevTab);
}
return;
}
}
@ -272,8 +277,13 @@
if (aTriggeringEvent instanceof MouseEvent) {
// We have a mouse event (from the go button), so use the standard
// UI link behaviors
openUILink(url, aTriggeringEvent, false, false,
true /* allow third party fixup */, postData);
let where = whereToOpenLink(aTriggeringEvent, false, false);
if (where != "current") {
this.handleRevert();
content.focus();
}
openUILinkIn(url, where,
{ allowThirdPartyFixup: true, postData: postData });
return;
}

View File

@ -412,9 +412,8 @@ function isBidiEnabled() {
function openAboutDialog() {
var enumerator = Services.wm.getEnumerator("Browser:About");
while (enumerator.hasMoreElements()) {
// Only open one about window (Bug 599573)
let win = enumerator.getNext();
if (win.opener != window)
continue;
win.focus();
return;
}
@ -486,107 +485,12 @@ function openFeedbackPage()
openUILinkIn("http://input.mozilla.com/feedback", "tab");
}
#ifdef MOZ_UPDATER
/**
* Opens the update manager and checks for updates to the application.
*/
function checkForUpdates()
{
var um =
Components.classes["@mozilla.org/updates/update-manager;1"].
getService(Components.interfaces.nsIUpdateManager);
var prompter =
Components.classes["@mozilla.org/updates/update-prompt;1"].
createInstance(Components.interfaces.nsIUpdatePrompt);
// If there's an update ready to be applied, show the "Update Downloaded"
// UI instead and let the user know they have to restart the browser for
// the changes to be applied.
if (um.activeUpdate && um.activeUpdate.state == "pending")
prompter.showUpdateDownloaded(um.activeUpdate);
else
prompter.checkForUpdates();
}
#endif
#ifdef MOZ_UPDATER
/**
* Updates an element to reflect the state of available update services.
*/
function setupCheckForUpdates(checkForUpdates, aStringBundle)
{
var updates =
Components.classes["@mozilla.org/updates/update-service;1"].
getService(Components.interfaces.nsIApplicationUpdateService);
var um =
Components.classes["@mozilla.org/updates/update-manager;1"].
getService(Components.interfaces.nsIUpdateManager);
// Disable the UI if the update enabled pref has been locked by the
// administrator or if we cannot update for some other reason
var canCheckForUpdates = updates.canCheckForUpdates;
checkForUpdates.setAttribute("disabled", !canCheckForUpdates);
if (!canCheckForUpdates)
return;
var activeUpdate = um.activeUpdate;
// If there's an active update, substitute its name into the label
// we show for this item, otherwise display a generic label.
function getStringWithUpdateName(key) {
if (activeUpdate && activeUpdate.name)
return aStringBundle.formatStringFromName(key, [activeUpdate.name], 1);
return aStringBundle.GetStringFromName(key + "Fallback");
}
// By default, show "Check for Updates..."
var key = "default";
if (activeUpdate) {
switch (activeUpdate.state) {
case "downloading":
// If we're downloading an update at present, show the text:
// "Downloading Firefox x.x..." otherwise we're paused, and show
// "Resume Downloading Firefox x.x..."
key = updates.isDownloading ? "downloading" : "resume";
break;
case "pending":
// If we're waiting for the user to restart, show: "Apply Downloaded
// Updates Now..."
key = "pending";
break;
}
}
checkForUpdates.label = getStringWithUpdateName("updatesItem_" + key);
checkForUpdates.accessKey = aStringBundle.
GetStringFromName("updatesItem_" + key + ".accesskey");
if (um.activeUpdate && updates.isDownloading)
checkForUpdates.setAttribute("loading", "true");
else
checkForUpdates.removeAttribute("loading");
}
#endif
function buildHelpMenu()
{
// Enable/disable the "Report Web Forgery" menu item. safebrowsing object
// may not exist in OSX
if (typeof safebrowsing != "undefined")
safebrowsing.setReportPhishingMenu();
#ifdef XP_MACOSX
#ifdef MOZ_UPDATER
var checkForUpdates = document.getElementById("checkForUpdates");
var browserBundle = document.getElementById("bundle_browser").stringBundle;
setupCheckForUpdates(checkForUpdates, browserBundle);
#else
// Needed by safebrowsing for inserting its menuitem so just hide it
document.getElementById("updateSeparator").hidden = true;
#endif
#else
// Needed by safebrowsing for inserting its menuitem so just hide it
document.getElementById("updateSeparator").hidden = true;
#endif
}
function isElementVisible(aElement)

View File

@ -1,5 +1,6 @@
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
// The time interval between checks for a new version (in seconds)
// nightly=8 hours, official=24 hours
pref("app.update.interval", 28800);

View File

@ -1,5 +1,6 @@
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
// The time interval between checks for a new version (in seconds)
// nightly=8 hours, official=24 hours
pref("app.update.interval", 28800);

View File

@ -37,6 +37,8 @@
const kIMig = Components.interfaces.nsIBrowserProfileMigrator;
const kIPStartup = Components.interfaces.nsIProfileStartup;
const kProfileMigratorContractIDPrefix = "@mozilla.org/profile/migrator;1?app=browser&type=";
const Cc = Components.classes;
const Ci = Components.interfaces;
var MigrationWizard = {
_source: "", // Source Profile Migrator ContractID suffix
@ -54,6 +56,7 @@ var MigrationWizard = {
os.addObserver(this, "Migration:Started", false);
os.addObserver(this, "Migration:ItemBeforeMigrate", false);
os.addObserver(this, "Migration:ItemAfterMigrate", false);
os.addObserver(this, "Migration:ItemError", false);
os.addObserver(this, "Migration:Ended", false);
this._wiz = document.documentElement;
@ -81,6 +84,7 @@ var MigrationWizard = {
os.removeObserver(this, "Migration:Started");
os.removeObserver(this, "Migration:ItemBeforeMigrate");
os.removeObserver(this, "Migration:ItemAfterMigrate");
os.removeObserver(this, "Migration:ItemError");
os.removeObserver(this, "Migration:Ended");
},
@ -489,6 +493,35 @@ var MigrationWizard = {
nextButton.click();
}
break;
case "Migration:ItemError":
var type = "undefined";
switch (parseInt(aData)) {
case Ci.nsIBrowserProfileMigrator.SETTINGS:
type = "settings";
break;
case Ci.nsIBrowserProfileMigrator.COOKIES:
type = "cookies";
break;
case Ci.nsIBrowserProfileMigrator.HISTORY:
type = "history";
break;
case Ci.nsIBrowserProfileMigrator.FORMDATA:
type = "form data";
break;
case Ci.nsIBrowserProfileMigrator.PASSWORDS:
type = "passwords";
break;
case Ci.nsIBrowserProfileMigrator.BOOKMARKS:
type = "bookmarks";
break;
case Ci.nsIBrowserProfileMigrator.OTHERDATA:
type = "misc. data";
break;
}
Cc["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService)
.logStringMessage("some " + type + " did not successfully migrate.");
break;
}
},

View File

@ -39,6 +39,7 @@
#define browserprofilemigratorutils___h___
#define MIGRATION_ITEMBEFOREMIGRATE "Migration:ItemBeforeMigrate"
#define MIGRATION_ITEMMIGRATEERROR "Migration:ItemError"
#define MIGRATION_ITEMAFTERMIGRATE "Migration:ItemAfterMigrate"
#define MIGRATION_STARTED "Migration:Started"
#define MIGRATION_ENDED "Migration:Ended"
@ -47,11 +48,12 @@
mObserverService->NotifyObservers(nsnull, message, item)
#define COPY_DATA(func, replace, itemIndex) \
if (NS_SUCCEEDED(rv) && (aItems & itemIndex || !aItems)) { \
if ((aItems & itemIndex || !aItems)) { \
nsAutoString index; \
index.AppendInt(itemIndex); \
NOTIFY_OBSERVERS(MIGRATION_ITEMBEFOREMIGRATE, index.get()); \
rv = func(replace); \
if (NS_FAILED(func(replace))) \
NOTIFY_OBSERVERS(MIGRATION_ITEMMIGRATEERROR, index.get()); \
NOTIFY_OBSERVERS(MIGRATION_ITEMAFTERMIGRATE, index.get()); \
}

View File

@ -70,6 +70,8 @@
#include "nsILocalFileWin.h"
#include "nsAutoPtr.h"
#include "prnetdb.h"
#include <objbase.h>
#include <shlguid.h>
#include <urlhist.h>
@ -1919,14 +1921,20 @@ nsIEProfileMigrator::CopyCookiesFromBuffer(char *aBuffer,
nsDependentCString stringName(name),
stringPath(path);
// delete any possible extant matching host cookie
if (hostCopy[0] == '.')
// delete any possible extant matching host cookie and
// check if we're dealing with an IPv4/IPv6 hostname.
PRBool isIPAddress = PR_FALSE;
if (hostCopy[0] == '.') {
aCookieManager->Remove(nsDependentCString(hostCopy+1),
stringName, stringPath, PR_FALSE);
PRNetAddr addr;
if (PR_StringToNetAddr(hostCopy+1, &addr) == PR_SUCCESS)
isIPAddress = PR_TRUE;
}
nsresult onerv;
// Add() makes a new domain cookie
onerv = aCookieManager->Add(nsDependentCString(hostCopy),
onerv = aCookieManager->Add(nsDependentCString(hostCopy + (isIPAddress ? 1 : 0)),
stringPath,
stringName,
nsDependentCString(value),

View File

@ -574,8 +574,6 @@ nsBrowserContentHandler.prototype = {
get defaultArgs() {
var prefb = Components.classes["@mozilla.org/preferences-service;1"]
.getService(nsIPrefBranch);
var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
.getService(Components.interfaces.nsIURLFormatter);
var overridePage = "";
var haveUpdateSession = false;
@ -589,7 +587,7 @@ nsBrowserContentHandler.prototype = {
switch (override) {
case OVERRIDE_NEW_PROFILE:
// New profile.
overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
overridePage = Services.urlFormatter.formatURLPref("startup.homepage_welcome_url");
break;
case OVERRIDE_NEW_MSTONE:
// Existing profile, new milestone build.
@ -600,12 +598,19 @@ nsBrowserContentHandler.prototype = {
var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
.getService(Components.interfaces.nsISessionStartup);
haveUpdateSession = ss.doRestore();
overridePage = formatter.formatURLPref("startup.homepage_override_url");
overridePage = Services.urlFormatter.formatURLPref("startup.homepage_override_url");
if (prefb.prefHasUserValue("app.update.postupdate"))
overridePage = getPostUpdateOverridePage(overridePage);
break;
}
}
else {
// No need to override homepage, but update snippets url if the pref has
// been manually changed.
if (Services.prefs.prefHasUserValue(AboutHomeUtils.SNIPPETS_URL_PREF)) {
AboutHomeUtils.loadSnippetsURL();
}
}
} catch (ex) {}
// formatURLPref might return "about:blank" if getting the pref fails
@ -882,6 +887,7 @@ nsDefaultCommandLineHandler.prototype = {
};
let AboutHomeUtils = {
SNIPPETS_URL_PREF: "browser.aboutHomeSnippets.updateUrl",
get _storage() {
let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
@ -908,10 +914,10 @@ let AboutHomeUtils = {
loadSnippetsURL: function AHU_loadSnippetsURL()
{
const STARTPAGE_VERSION = 1;
const SNIPPETS_URL = "http://snippets.mozilla.com/" + STARTPAGE_VERSION + "/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/";
let updateURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"].
getService(Components.interfaces.nsIURLFormatter).
formatURL(SNIPPETS_URL);
let updateURL = Services.prefs
.getCharPref(this.SNIPPETS_URL_PREF)
.replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION);
updateURL = Services.urlFormatter.formatURL(updateURL);
this._storage.setItem("snippets-update-url", updateURL);
},
};

View File

@ -499,10 +499,10 @@ PlacesViewBase.prototype = {
// Many users consider toolbars as shortcuts containers, so explicitly
// allow empty labels on toolbarbuttons. For any other element try to be
// smarter, guessing a title from the uri.
elt.label = PlacesUIUtils.getBestTitle(aPlacesNode);
elt.setAttribute("label", PlacesUIUtils.getBestTitle(aPlacesNode));
}
else {
elt.label = aNewTitle;
elt.setAttribute("label", aNewTitle);
}
},

View File

@ -720,7 +720,7 @@ var PlacesUIUtils = {
* This is actually used to distinguish user-initiated visits in frames
* so automatic visits can be correctly ignored.
*/
markPageAsFollowedLink: function PUIU_markPageAsUserClicked(aURL) {
markPageAsFollowedLink: function PUIU_markPageAsFollowedLink(aURL) {
PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory)
.markPageAsFollowedLink(this.createFixedURI(aURL));
},

View File

@ -66,6 +66,10 @@ _BROWSER_TEST_FILES = \
browser_sidebarpanels_click.js \
sidebarpanels_click_test_page.html \
browser_library_infoBox.js \
browser_markPageAsFollowedLink.js \
framedPage.html \
frameLeft.html \
frameRight.html \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

View File

@ -0,0 +1,89 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Tests that visits across frames are correctly represented in the database.
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
const BASE_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser";
const PAGE_URL = BASE_URL + "/framedPage.html";
const LEFT_URL = BASE_URL + "/frameLeft.html";
const RIGHT_URL = BASE_URL + "/frameRight.html";
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
let gTabLoaded = false;
let gLeftFrameVisited = false;
let observer = {
observe: function(aSubject, aTopic, aData)
{
let url = aSubject.QueryInterface(Ci.nsIURI).spec;
if (url == LEFT_URL ) {
is(getTransitionForUrl(url), PlacesUtils.history.TRANSITION_EMBED,
"Frames should get a EMBED transition.");
gLeftFrameVisited = true;
maybeClickLink();
}
else if (url == RIGHT_URL ) {
is(getTransitionForUrl(url), PlacesUtils.history.TRANSITION_FRAMED_LINK,
"User activated visits should get a FRAMED_LINK transition.");
finish();
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
};
Services.obs.addObserver(observer, "uri-visit-saved", false);
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab(PAGE_URL);
let frameCount = 0;
gBrowser.selectedTab.linkedBrowser.addEventListener("DOMContentLoaded",
function (event)
{
// Wait for all the frames.
if (frameCount++ < 2)
return;
gBrowser.selectedTab.linkedBrowser.removeEventListener("DOMContentLoaded", arguments.callee, false)
gTabLoaded = true;
maybeClickLink();
}, false
);
}
function maybeClickLink() {
if (gTabLoaded && gLeftFrameVisited) {
// Click on the link in the left frame to cause a page load in the
// right frame.
EventUtils.sendMouseEvent({type: "click"}, "clickme", content.frames[0]);
}
}
function getTransitionForUrl(aUrl)
{
let dbConn = PlacesUtils.history
.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
let stmt = dbConn.createStatement(
"SELECT visit_type FROM moz_historyvisits_view WHERE place_id = " +
"(SELECT id FROM moz_places_view WHERE url = :page_url)");
stmt.params.page_url = aUrl;
try {
ok(stmt.executeStep(), "Found the visit in the database");
return stmt.row.visit_type;
}
finally {
stmt.finalize();
}
}
registerCleanupFunction(function ()
{
gBrowser.removeTab(gBrowser.selectedTab);
Services.obs.removeObserver(observer, "uri-visit-saved");
})

View File

@ -291,8 +291,8 @@ var bookmarksObserver = {
}
else {
if (!aNewValue && aElementOrTreeIndex.localName != "toolbarbutton")
return aElementOrTreeIndex.label == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
return aElementOrTreeIndex.label == aNewValue;
return aElementOrTreeIndex.getAttribute("label") == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
return aElementOrTreeIndex.getAttribute("label") == aNewValue;
}
};

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>Left frame</title>
</head>
<body>
<a id="clickme" href="frameRight.html" target="right">Open page in the right frame.</a>
</body>
</html>

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>Right Frame</title>
</head>
<body>
This is the right frame.
</body>
</html>

View File

@ -0,0 +1,9 @@
<html>
<head>
<title>Framed page</title>
</head>
<frameset cols="*,*">
<frame name="left" src="frameLeft.html">
<frame name="right" src="about:robots">
</frameset>
</html>

View File

@ -45,12 +45,10 @@
%globalDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
#ifdef XP_WIN
<!ENTITY basePBMenu.label "<span class='appMenuButton'>&brandShortName;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
#elifdef XP_MACOSX
#ifdef XP_MACOSX
<!ENTITY basePBMenu.label "&toolsMenu.label;">
#else
<!ENTITY basePBMenu.label "<span class='appMenuButton'>&appMenuButton.label;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
<!ENTITY basePBMenu.label "<span class='appMenuButton'>&brandShortName;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
#endif
<!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
%privatebrowsingpageDTD;

View File

@ -469,8 +469,10 @@ PrivateBrowsingService.prototype = {
if (aCmdLine.handleFlag("private", false))
; // It has already been handled
else if (aCmdLine.handleFlag("private-toggle", false)) {
if (this._autoStarted) {
throw Cr.NS_ERROR_ABORT;
}
this.privateBrowsingEnabled = !this.privateBrowsingEnabled;
this._autoStarted = false;
this._lastChangedByCommandLine = true;
}
},

View File

@ -52,14 +52,14 @@
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
label="&reportPhishSiteMenu.title2;"
accesskey="&reportPhishSiteMenu.accesskey;"
insertbefore="updateSeparator"
insertbefore="aboutSeparator"
observes="reportPhishingBroadcaster"
oncommand="openUILink(safebrowsing.getReportURL('Phish'), event);"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu"
label="&safeb.palm.notforgery.label2;"
accesskey="&reportPhishSiteMenu.accesskey;"
insertbefore="updateSeparator"
insertbefore="aboutSeparator"
observes="reportPhishingErrorBroadcaster"
oncommand="openUILinkIn(safebrowsing.getReportURL('Error'), 'tab');"
onclick="checkForMiddleClick(this, event);"/>

View File

@ -605,7 +605,7 @@
element.setAttribute("label", label);
element.setAttribute("anonid", "paste-and-search");
element.setAttribute("oncommand",
"BrowserSearch.searchBar.value = ''; goDoCommand('cmd_paste'); BrowserSearch.searchBar.handleSearchCommand();");
"BrowserSearch.searchBar.select(); goDoCommand('cmd_paste'); BrowserSearch.searchBar.handleSearchCommand();");
cxmenu.insertBefore(element, insertLocation.nextSibling);
pasteAndSearch = element;
}

View File

@ -745,24 +745,59 @@ SessionStoreService.prototype = {
!this._inPrivateBrowsing) {
// default to the most-recently closed window
// don't use popup windows
let state = null;
let newClosedWindows = this._closedWindows.filter(function(aWinState) {
if (!state && !aWinState.isPopup) {
state = aWinState;
return false;
let closedWindowState = null;
let closedWindowIndex;
for (let i = 0; i < this._closedWindows.length; i++) {
// Take the first non-popup, point our object at it, and break out.
if (!this._closedWindows[i].isPopup) {
closedWindowState = this._closedWindows[i];
closedWindowIndex = i;
break;
}
return true;
});
if (state) {
delete state.hidden;
}
if (closedWindowState) {
let newWindowState;
#ifndef XP_MACOSX
if (!this._doResumeSession())
if (!this._doResumeSession()) {
#endif
state.tabs = state.tabs.filter(function (tab) tab.pinned);
if (state.tabs.length > 0) {
this._closedWindows = newClosedWindows;
// We want to split the window up into pinned tabs and unpinned tabs.
// Pinned tabs should be restored. If there are any remaining tabs,
// they should be added back to _closedWindows.
// We'll cheat a little bit and reuse _prepDataForDeferredRestore
// even though it wasn't built exactly for this.
let [appTabsState, normalTabsState] =
this._prepDataForDeferredRestore(JSON.stringify({ windows: [closedWindowState] }));
// These are our pinned tabs, which we should restore
if (appTabsState.windows.length) {
newWindowState = appTabsState.windows[0];
delete newWindowState.__lastSessionWindowID;
}
// In case there were no unpinned tabs, remove the window from _closedWindows
if (!normalTabsState.windows.length) {
this._closedWindows.splice(closedWindowIndex, 1);
}
// Or update _closedWindows with the modified state
else {
delete normalTabsState.windows[0].__lastSessionWindowID;
this._closedWindows[closedWindowIndex] = normalTabsState.windows[0];
}
#ifndef XP_MACOSX
}
else {
// If we're just restoring the window, make sure it gets removed from
// _closedWindows.
this._closedWindows.splice(closedWindowIndex, 1);
newWindowState = closedWindowState;
delete newWindowState.hidden;
}
#endif
if (newWindowState) {
// Ensure that the window state isn't hidden
this._restoreCount = 1;
state = { windows: [state] };
let state = { windows: [newWindowState] };
this.restoreWindow(aWindow, state, this._isCmdLineEmpty(aWindow, state));
}
}

View File

@ -120,6 +120,7 @@ _BROWSER_TEST_FILES = \
browser_581593.js \
browser_586147.js \
browser_586068-cascaded_restore.js \
browser_589246.js \
browser_590268.js \
browser_600545.js \
$(NULL)

View File

@ -0,0 +1,276 @@
/* ***** 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 sessionstore test code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Paul OShannessy <paul@oshannessy.com>
*
* 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 ***** */
// Mirrors WINDOW_ATTRIBUTES IN nsSessionStore.js
const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
Cu.import("resource://gre/modules/Services.jsm");
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
let stateBackup = ss.getBrowserState();
let originalWarnOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
let originalStartupPage = gPrefService.getIntPref("browser.startup.page");
let originalWindowType = document.documentElement.getAttribute("windowtype");
let gotLastWindowClosedTopic = false;
let shouldPinTab = false;
let shouldOpenTabs = false;
let shouldCloseTab = false;
let testNum = 0;
let afterTestCallback;
// Set state so we know the closed windows content
let testState = {
windows: [
{ tabs: [{ entries: [{ url: "http://example.org" }] }] }
],
_closedWindows: []
};
// We'll push a set of conditions and callbacks into this array
// Ideally we would also test win/linux under a complete set of conditions, but
// the tests for osx mirror the other set of conditions possible on win/linux.
let tests = [];
// the third & fourth test share a condition check, keep it DRY
function checkOSX34Generator(num) {
return function(aPreviousState, aCurState) {
// In here, we should have restored the pinned tab, so only the unpinned tab
// should be in aCurState. So let's shape our expectations.
let expectedState = JSON.parse(aPreviousState);
expectedState[0].tabs.shift();
// size attributes are stripped out in _prepDataForDeferredRestore in nsSessionStore.
// This isn't the best approach, but neither is comparing JSON strings
WINDOW_ATTRIBUTES.forEach(function (attr) delete expectedState[0][attr]);
is(aCurState, JSON.stringify(expectedState),
"test #" + num + ": closedWindowState is as expected");
};
}
function checkNoWindowsGenerator(num) {
return function(aPreviousState, aCurState) {
is(aCurState, "[]", "test #" + num + ": there should be no closedWindowsLeft");
};
}
// The first test has 0 pinned tabs and 1 unpinned tab
tests.push({
pinned: false,
extra: false,
close: false,
checkWinLin: checkNoWindowsGenerator(1),
checkOSX: function(aPreviousState, aCurState) {
is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
}
});
// The second test has 1 pinned tab and 0 unpinned tabs.
tests.push({
pinned: true,
extra: false,
close: false,
checkWinLin: checkNoWindowsGenerator(2),
checkOSX: checkNoWindowsGenerator(2)
});
// The third test has 1 pinned tab and 2 unpinned tabs.
tests.push({
pinned: true,
extra: true,
close: false,
checkWinLin: checkNoWindowsGenerator(3),
checkOSX: checkOSX34Generator(3)
});
// The fourth test has 1 pinned tab, 2 unpinned tabs, and closes one unpinned tab.
tests.push({
pinned: true,
extra: true,
close: "one",
checkWinLin: checkNoWindowsGenerator(4),
checkOSX: checkOSX34Generator(4)
});
// The fifth test has 1 pinned tab, 2 unpinned tabs, and closes both unpinned tabs.
tests.push({
pinned: true,
extra: true,
close: "both",
checkWinLin: checkNoWindowsGenerator(5),
checkOSX: checkNoWindowsGenerator(5)
});
function test() {
/** Test for Bug 589246 - Closed window state getting corrupted when closing
and reopening last browser window without exiting browser **/
waitForExplicitFinish();
// windows opening & closing, so extending the timeout
requestLongerTimeout(2);
// We don't want the quit dialog pref
gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
// Ensure that we would restore the session (important for Windows)
gPrefService.setIntPref("browser.startup.page", 3);
runNextTestOrFinish();
}
function runNextTestOrFinish() {
if (tests.length) {
setupForTest(tests.shift())
}
else {
// some state is cleaned up at the end of each test, but not all
["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
if (gPrefService.prefHasUserValue(p))
gPrefService.clearUserPref(p);
});
ss.setBrowserState(stateBackup);
executeSoon(finish);
}
}
function setupForTest(aConditions) {
// reset some checks
gotLastWindowClosedTopic = false;
shouldPinTab = aConditions.pinned;
shouldOpenTabs = aConditions.extra;
shouldCloseTab = aConditions.close;
testNum++;
// set our test callback
afterTestCallback = /Mac/.test(navigator.platform) ? aConditions.checkOSX
: aConditions.checkWinLin;
// Add observers
Services.obs.addObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
// Set the state
Services.obs.addObserver(onStateRestored, "sessionstore-browser-state-restored", false);
ss.setBrowserState(JSON.stringify(testState));
}
function onStateRestored(aSubject, aTopic, aData) {
info("test #" + testNum + ": onStateRestored");
Services.obs.removeObserver(onStateRestored, "sessionstore-browser-state-restored", false);
// change this window's windowtype so that closing a new window will trigger
// browser-lastwindow-close-granted.
document.documentElement.setAttribute("windowtype", "navigator:testrunner");
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
newWin.addEventListener("load", function(aEvent) {
newWin.removeEventListener("load", arguments.callee, false);
newWin.gBrowser.selectedBrowser.addEventListener("load", function() {
newWin.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
// pin this tab
if (shouldPinTab)
newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
newWin.addEventListener("unload", onWindowUnloaded, false);
// Open a new tab as well. On Windows/Linux this will be restored when the
// new window is opened below (in onWindowUnloaded). On OS X we'll just
// restore the pinned tabs, leaving the unpinned tab in the closedWindowsData.
if (shouldOpenTabs) {
let newTab = newWin.gBrowser.addTab("about:config");
let newTab2 = newWin.gBrowser.addTab("about:buildconfig");
newTab.linkedBrowser.addEventListener("load", function() {
newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
if (shouldCloseTab == "one") {
newWin.gBrowser.removeTab(newTab2);
}
else if (shouldCloseTab == "both") {
newWin.gBrowser.removeTab(newTab);
newWin.gBrowser.removeTab(newTab2);
}
newWin.BrowserTryToCloseWindow();
}, true);
}
else {
newWin.BrowserTryToCloseWindow();
}
}, true);
}, false);
}
// This will be called before the window is actually closed
function onLastWindowClosed(aSubject, aTopic, aData) {
info("test #" + testNum + ": onLastWindowClosed");
Services.obs.removeObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
gotLastWindowClosedTopic = true;
}
// This is the unload event listener on the new window (from onStateRestored).
// Unload is fired after the window is closed, so sessionstore has already
// updated _closedWindows (which is important). We'll open a new window here
// which should actually trigger the bug.
function onWindowUnloaded() {
info("test #" + testNum + ": onWindowClosed");
ok(gotLastWindowClosedTopic, "test #" + testNum + ": browser-lastwindow-close-granted was notified prior");
let previousClosedWindowData = ss.getClosedWindowData();
// Now we want to open a new window
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:robots");
newWin.addEventListener("load", function(aEvent) {
newWin.removeEventListener("load", arguments.callee, false);
newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
// Good enough for checking the state
afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
afterTestCleanup(newWin);
}, true);
}, false);
}
function afterTestCleanup(aNewWin) {
executeSoon(function() {
aNewWin.close();
document.documentElement.setAttribute("windowtype", originalWindowType);
runNextTestOrFinish();
});
}

View File

@ -260,10 +260,7 @@ var WinTaskbarJumpList =
_pendingStatements: {},
_hasPendingStatements: function WTBJL__hasPendingStatements() {
for (let listType in this._pendingStatements) {
return true;
}
return false;
return Object.keys(this._pendingStatements).length > 0;
},
_buildList: function WTBJL__buildList() {
@ -344,6 +341,11 @@ var WinTaskbarJumpList =
},
_buildFrequent: function WTBJL__buildFrequent() {
// If history is empty, just bail out.
if (!PlacesUtils.history.hasHistoryEntries) {
return;
}
// Windows supports default frequent and recent lists,
// but those depend on internal windows visit tracking
// which we don't populate. So we build our own custom
@ -377,6 +379,11 @@ var WinTaskbarJumpList =
},
_buildRecent: function WTBJL__buildRecent() {
// If history is empty, just bail out.
if (!PlacesUtils.history.hasHistoryEntries) {
return;
}
var items = Cc["@mozilla.org/array;1"].
createInstance(Ci.nsIMutableArray);
// Frequent items will be skipped, so we select a double amount of

View File

@ -213,6 +213,7 @@
@BINPATH@/components/necko_strconv.xpt
@BINPATH@/components/necko_viewsource.xpt
@BINPATH@/components/necko_wifi.xpt
@BINPATH@/components/necko_wyciwyg.xpt
@BINPATH@/components/necko.xpt
@BINPATH@/components/loginmgr.xpt
@BINPATH@/components/parentalcontrols.xpt
@ -383,8 +384,6 @@
#ifdef MOZ_SERVICES_SYNC
@BINPATH@/components/SyncComponents.manifest
@BINPATH@/components/Weave.js
@BINPATH@/components/WeaveCrypto.manifest
@BINPATH@/components/WeaveCrypto.js
#endif
; Modules

View File

@ -67,6 +67,8 @@ components/nsUrlClassifierTable.js
components/nsXmlRpcClient.js
components/pluginGlue.js
components/sidebar.xpt
components/WeaveCrypto.js
components/WeaveCrypto.manifest
components/xmlextras.xpt
components/xpcom.xpt
components/xpti.dat
@ -621,7 +623,6 @@ xpicleanup@BIN_SUFFIX@
components/storage-Legacy.js
components/storage-mozStorage.js
components/txEXSLTRegExFunctions.js
components/WeaveCrypto.js
components/Weave.js
components/WebContentConverter.js
defaults/autoconfig/platform.js

View File

@ -233,7 +233,7 @@ menuitem.bookmark-item {
}
/* Stock icons for the menu bar items */
menuitem:not([type]) {
menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
@ -472,6 +472,13 @@ menuitem:not([type]) {
-moz-image-region: rect(0px 48px 16px 32px);
}
#subscribeToPageMenuitem:not([disabled]),
#subscribeToPageMenupopup,
#BMB_subscribeToPageMenuitem:not([disabled]),
#BMB_subscribeToPageMenupopup {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
}
#bookmarksToolbarFolderMenu,
#BMB_bookmarksToolbar {
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");

View File

@ -36,7 +36,7 @@
}
#sanitizeEverythingWarningIcon {
list-style-image: url("chrome://global/skin/icons/warning-large.png");
list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=dialog");
padding: 0;
margin: 0;
}

View File

@ -14,11 +14,11 @@
}
.statusIcon[status="error"] {
list-style-image: url("chrome://global/skin/icons/error-16.png");
list-style-image: url("moz-icon://stock/gtk-dialog-error?size=menu");
}
.statusIcon[status="success"] {
list-style-image: url("chrome://global/skin/icons/information-16.png");
list-style-image: url("moz-icon://stock/gtk-dialog-info?size=menu");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have

View File

@ -355,8 +355,16 @@ toolbar:not([mode="icons"]) #restore-button {
opacity: .4;
}
.toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
list-style-image: url(chrome://browser/skin/toolbarbutton-dropmarker.png);
}
.toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
-moz-margin-end: 1px;
}
.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
width: 14px;
padding-top: 2px;
-moz-border-start: none !important;
@ -1937,7 +1945,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
#notification-popup {
color: #fff;
margin-left: -16px;
margin-right: -16px;
}

View File

@ -33,19 +33,12 @@
0 0 2px 1px rgba(255,255,255,.25) inset;
}
#main-window[privatebrowsingmode=temporary] #appmenu-button:not(:-moz-window-inactive) {
#main-window[privatebrowsingmode=temporary] #appmenu-button {
-moz-border-left-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
-moz-border-bottom-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
-moz-border-right-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
}
#appmenu-button:-moz-window-inactive {
-moz-border-left-colors: rgba(255,255,255,.4) rgba(0,0,0,.5);
-moz-border-bottom-colors: rgba(255,255,255,.4) rgba(0,0,0,.5);
-moz-border-right-colors: rgba(255,255,255,.4) rgba(0,0,0,.5);
box-shadow: 0 0 0 1px rgba(255,255,255,.25) inset;
}
/* Bug 413060, comment 16: Vista Aero is a special case where we use a
tooltip appearance for the address bar popup panels */
#identity-popup,

View File

@ -126,16 +126,11 @@
margin: 0;
}
#main-window[privatebrowsingmode=temporary] #appmenu-button:not(:-moz-window-inactive) {
#main-window[privatebrowsingmode=temporary] #appmenu-button {
background-image: -moz-linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%);
border-color: rgba(43,8,65,.9);
}
#appmenu-button:-moz-window-inactive {
background-image: none;
border-color: rgba(0,0,0,.4);
}
#appmenu-button:hover:not(:active):not([open]) {
background-image: -moz-radial-gradient(center bottom, farthest-side, rgba(252,240,89,.5) 10%, rgba(252,240,89,0) 70%),
-moz-radial-gradient(center bottom, farthest-side, rgb(236,133,0), rgba(255,229,172,0)),
@ -302,14 +297,6 @@
list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
}
#BMB_subscribeToPage:not([disabled]),
#BMB_subscribeToPageMenu,
#appmenu_subscribeToPage:not([disabled]),
#appmenu_subscribeToPageMenu {
list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
#BMB_bookmarkThisPage,
#appmenu_bookmarkThisPage {
list-style-image: url("chrome://browser/skin/places/bookmark.png");
@ -1872,7 +1859,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
.geolocation-text-link {
padding-top: 5px;
margin-top: 17px;
}
.popup-notification-icon[popupid="xpinstall-disabled"],
@ -1936,6 +1923,15 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
/* Bookmarks roots menu-items */
#appmenu_subscribeToPage:not([disabled]),
#appmenu_subscribeToPageMenu,
#subscribeToPageMenuitem:not([disabled]),
#subscribeToPageMenupopup,
#BMB_subscribeToPageMenuitem:not([disabled]),
#BMB_subscribeToPageMenupopup {
list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
}
#bookmarksToolbarFolderMenu,
#appmenu_bookmarksToolbar,
#BMB_bookmarksToolbar {

View File

@ -360,6 +360,7 @@ user_pref("network.http.prompt-temp-redirect", false);
user_pref("media.cache_size", 100);
user_pref("security.warn_viewing_mixed", false);
user_pref("app.update.enabled", false);
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
// Only load extensions from the application and user profile
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION

View File

@ -115,10 +115,18 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
for d in dumps:
log.info("PROCESS-CRASH | %s | application crashed (minidump found)", testName)
if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
nullfd = open(os.devnull, 'w')
# eat minidump_stackwalk errors
subprocess.call([stackwalkPath, d, symbolsPath], stderr=nullfd)
nullfd.close()
p = subprocess.Popen([stackwalkPath, d, symbolsPath],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(out, err) = p.communicate()
if len(out) > 3:
# minidump_stackwalk is chatty, so ignore stderr when it succeeds.
print out
else:
print "stderr from minidump_stackwalk:"
print err
if p.returncode != 0:
print "minidump_stackwalk exited with return code %d" % p.returncode
elif stackwalkCGI and symbolsPath and isURL(symbolsPath):
f = None
try:
@ -131,7 +139,11 @@ def checkForCrashes(dumpDir, symbolsPath, testName=None):
datagen, headers = multipart_encode({"minidump": f,
"symbols": symbolsPath})
request = urllib2.Request(stackwalkCGI, datagen, headers)
print urllib2.urlopen(request).read()
result = urllib2.urlopen(request).read()
if len(result) > 3:
print result
else:
print "stackwalkCGI returned nothing."
finally:
if f:
f.close()

View File

@ -457,7 +457,7 @@ EnumerateOverride(nsIURI* aURIKey,
struct EnumerationArgs
{
nsTArray<ChromePackage>& packages;
InfallibleTArray<ChromePackage>& packages;
const nsCString& selectedLocale;
const nsCString& selectedSkin;
};
@ -466,9 +466,9 @@ void
nsChromeRegistryChrome::SendRegisteredChrome(
mozilla::dom::PContentParent* aParent)
{
nsTArray<ChromePackage> packages;
nsTArray<ResourceMapping> resources;
nsTArray<OverrideMapping> overrides;
InfallibleTArray<ChromePackage> packages;
InfallibleTArray<ResourceMapping> resources;
InfallibleTArray<OverrideMapping> overrides;
EnumerationArgs args = {
packages, mSelectedLocale, mSelectedSkin

View File

@ -44,6 +44,7 @@ See the documentation for jar.mn on MDC for further details on the format.
import sys
import os
import os.path
import errno
import re
import logging
from time import localtime
@ -445,7 +446,7 @@ class JarMaker(object):
try:
os.remove(out)
except OSError, e:
if e.errno != 2:
if e.errno != errno.ENOENT:
raise
return open(out, 'wb')
def ensureDirFor(self, name):
@ -465,7 +466,7 @@ class JarMaker(object):
try:
os.remove(out)
except OSError, e:
if e.errno != 2:
if e.errno != errno.ENOENT:
raise
os.symlink(src, out)

View File

@ -132,6 +132,7 @@ export::
-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
-DMOZ_NATIVE_JPEG=$(MOZ_NATIVE_JPEG) \
-DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \
-DMOZ_NATIVE_LIBVPX=$(MOZ_NATIVE_LIBVPX) \
$(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
$(INSTALL) system_wrappers $(DIST)

View File

@ -101,7 +101,6 @@ MOZ_DEBUG_DISABLE_DEFS = @MOZ_DEBUG_DISABLE_DEFS@
MOZ_DEBUG_FLAGS = @MOZ_DEBUG_FLAGS@
MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
MOZ_EXTENSIONS = @MOZ_EXTENSIONS@
MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
MOZ_JSDEBUGGER = @MOZ_JSDEBUGGER@
MOZ_IPC = @MOZ_IPC@
MOZ_IPDL_TESTS = @MOZ_IPDL_TESTS@
@ -166,7 +165,11 @@ MOZ_TREMOR = @MOZ_TREMOR@
MOZ_WEBM = @MOZ_WEBM@
VPX_AS = @VPX_AS@
VPX_ASFLAGS = @VPX_ASFLAGS@
VPX_DASH_C_FLAG = @VPX_DASH_C_FLAG@
VPX_AS_CONVERSION = @VPX_AS_CONVERSION@
VPX_ASM_SUFFIX = @VPX_ASM_SUFFIX@
VPX_X86_ASM = @VPX_X86_ASM@
VPX_ARM_ASM = @VPX_ARM_ASM@
NS_PRINTING = @NS_PRINTING@
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
@ -232,6 +235,10 @@ MOZ_NATIVE_LIBEVENT = @MOZ_NATIVE_LIBEVENT@
MOZ_LIBEVENT_LIBS = @MOZ_LIBEVENT_LIBS@
MOZ_LIBEVENT_INCLUDES = @MOZ_LIBEVENT_INCLUDES@
MOZ_NATIVE_LIBVPX = @MOZ_NATIVE_LIBVPX@
MOZ_LIBVPX_LIBS = @MOZ_LIBVPX_LIBS@
MOZ_LIBVPX_INCLUDES = @MOZ_LIBVPX_INCLUDES@
MOZ_NATIVE_ZLIB = @SYSTEM_ZLIB@
MOZ_NATIVE_BZ2 = @SYSTEM_BZ2@
MOZ_NATIVE_JPEG = @SYSTEM_JPEG@
@ -605,7 +612,6 @@ AIX_OBJMODEL = @AIX_OBJMODEL@
# For OS/2 build
MOZ_OS2_TOOLS = @MOZ_OS2_TOOLS@
MOZ_OS2_USE_DECLSPEC = @MOZ_OS2_USE_DECLSPEC@
MOZ_OS2_HIGH_MEMORY = @MOZ_OS2_HIGH_MEMORY@
HAVE_XIE=@HAVE_XIE@

View File

@ -234,7 +234,7 @@ endif
#
ifdef NS_TRACE_MALLOC
MOZ_OPTIMIZE_FLAGS=-Zi -Od -UDEBUG -DNDEBUG
OS_LDFLAGS = -DEBUG -PDB:NONE -OPT:REF -OPT:nowin98
OS_LDFLAGS = -DEBUG -PDB:NONE -OPT:REF
endif # NS_TRACE_MALLOC
endif # MOZ_DEBUG

View File

@ -59,15 +59,13 @@
#define MODULE(_name) \
NSMODULE_NAME(_name),
&NSMODULE_NAME(_name),
/**
* The nsStaticModuleInfo
*/
static const mozilla::Module *const kStaticModules[] = {
const mozilla::Module *const *const kPStaticModules[] = {
%MODULE_LIST%
#line 70 "nsStaticComponents.cpp.in"
NULL
};
mozilla::Module const *const *const kPStaticModules = kStaticModules;

View File

@ -43,6 +43,6 @@
// These symbols are provided by nsStaticComponents.cpp, and also by other
// static component providers such as nsStaticXULComponents (libxul).
extern mozilla::Module const *const *const kPStaticModules;
extern mozilla::Module const *const *const kPStaticModules[];
#endif

View File

@ -1249,26 +1249,10 @@ $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@
echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
echo EXPORTS >> $@
ifeq ($(IS_COMPONENT),1)
ifeq ($(HAS_EXTRAEXPORTS),1)
ifndef MOZ_OS2_USE_DECLSPEC
$(FILTER) $(OBJS) $(SHARED_LIBRARY_LIBS) >> $@
endif
else
echo _NSModule >> $@
endif
else
ifndef MOZ_OS2_USE_DECLSPEC
$(FILTER) $(OBJS) $(SHARED_LIBRARY_LIBS) >> $@
endif
endif
$(ADD_TO_DEF_FILE)
ifdef MOZ_OS2_USE_DECLSPEC
$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
else
$(IMPORT_LIBRARY): $(DEF_FILE)
endif
rm -f $@
$(IMPLIB) $@ $^
$(RANLIB) $@

View File

@ -1051,3 +1051,7 @@ pixman.h
#if MOZ_ENABLE_MEEGOTOUCHSHARE
shareuiinterface.h
#endif
#if MOZ_NATIVE_LIBVPX==1
vpx/vpx_decoder.h
vpx/vp8dx.h
#endif

View File

@ -992,7 +992,7 @@ else
AC_MSG_RESULT([yes])
fi
MOZ_PATH_PROGS(PYTHON, $PYTHON python2.6 python2.5 python2.4 python)
MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python2.6 python2.5 python)
if test -z "$PYTHON"; then
AC_MSG_ERROR([python was not found in \$PATH])
fi
@ -1846,8 +1846,6 @@ case "$host" in
;;
*cygwin*|*mingw*|*mks*|*msvc*|*wince|*winmo)
# we need Python 2.5 on Windows
PYTHON_VERSION=2.5
if test -n "$_WIN32_MSVC"; then
HOST_AR=lib
HOST_AR_FLAGS='-NOLOGO -OUT:"$@"'
@ -1921,8 +1919,7 @@ case "$host" in
;;
esac
dnl We require version 2.4 or newer of Python to build,
dnl and 2.5 or newer on Windows.
dnl We require version 2.5 or newer of Python to build.
AC_MSG_CHECKING([for minimum required Python version >= $PYTHON_VERSION])
changequote(,)
$PYTHON -c "import sys; sys.exit(sys.version[:3] < sys.argv[1])" $PYTHON_VERSION
@ -2645,7 +2642,7 @@ ia64*-hpux*)
DSO_LDOPTS='-Zdll'
BIN_FLAGS='-Zlinker /ST:0x100000'
IMPLIB='emximp -o'
FILTER='emxexp -o'
FILTER='true'
LDFLAGS='-Zmap'
WARNINGS_AS_ERRORS='-Werror'
MOZ_DEBUG_FLAGS="-g -fno-inline"
@ -2681,9 +2678,8 @@ ia64*-hpux*)
[return 0;],
ac_os2_declspec="yes",
ac_os2_declspec="no")])
if test "$ac_os2_declspec" = "yes"; then
FILTER='true'
MOZ_OS2_USE_DECLSPEC='1'
if test "$ac_os2_declspec" != "yes"; then
AC_MSG_ERROR([Compiler does not support __declspec(dllexport), install GCC-4.3.2 or newer])
fi
;;
@ -3408,11 +3404,9 @@ case $target in
*-os2*)
;;
*)
AC_CHECK_LIB(m, atan)
AC_CHECK_LIB(dl, dlopen,
AC_CHECK_HEADER(dlfcn.h,
LIBS="-ldl $LIBS"
AC_DEFINE(HAVE_LIBDL)))
AC_SEARCH_LIBS(dlopen, dl,
AC_CHECK_HEADER(dlfcn.h,
AC_DEFINE(HAVE_DLOPEN)))
;;
esac
@ -4728,10 +4722,10 @@ AC_CHECK_PROGS(YASM, yasm, "")
if test -n "$YASM"; then
dnl Pull out yasm's version string
changequote(,)
_YASM_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*|\1|p'
_YASM_VER_FILTER='s|.* \([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\).*|\1|p'
changequote([,])
YASM_VERSION=`yasm --version | sed -nre "$_YASM_VER_FILTER"`
YASM_VERSION=`yasm --version | sed -ne "$_YASM_VER_FILTER"`
_YASM_MAJOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $1 }'`
_YASM_MINOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $2 }'`
_YASM_RELEASE=` echo ${YASM_VERSION} | $AWK -F\. '{ print $3 }'`
@ -4942,7 +4936,6 @@ MOZ_ACTIVEX_SCRIPTING_SUPPORT=
MOZ_BRANDING_DIRECTORY=
MOZ_OFFICIAL_BRANDING=
MOZ_FEEDS=1
MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
MOZ_INSTALLER=1
MOZ_IPC=1
MOZ_JAVAXPCOM=
@ -4964,7 +4957,11 @@ MOZ_MEDIA=
MOZ_WEBM=1
VPX_AS=
VPX_ASFLAGS=
VPX_AS_DASH_C_FLAG=
VPX_AS_CONVERSION=
VPX_ASM_SUFFIX=
VPX_X86_ASM=
VPX_ARM_ASM=
MOZ_PANGO=1
MOZ_PERMISSIONS=1
MOZ_PLACES=1
@ -5994,8 +5991,50 @@ MOZ_ARG_DISABLE_BOOL(webm,
MOZ_WEBM=,
MOZ_WEBM=1)
dnl system libvpx Support
dnl ========================================================
MOZ_ARG_WITH_STRING(system-libvpx,
[ --with-system-libvpx=[PFX]
Use system libvpx [installed at prefix PFX]],
LIBVPX_DIR=$withval)
MOZ_NATIVE_LIBVPX=
MOZ_LIBVPX_INCLUDES=
MOZ_LIBVPX_LIBS=
if test -n "$MOZ_WEBM"; then
AC_DEFINE(MOZ_WEBM)
if test -n "$LIBVPX_DIR" -a "$LIBVPX_DIR" != no; then
_SAVE_CFLAGS=$CFLAGS
_SAVE_LDFLAGS=$LDFLAGS
_SAVE_LIBS=$LIBS
if test "${LIBVPX_DIR}" = "yes"; then
LIBVPX_DIR=/usr
fi
CFLAGS="-I${LIBVPX_DIR}/include $CFLAGS"
LDFLAGS="-L${LIBVPX_DIR}/lib $LDFLAGS"
AC_CHECK_HEADER(vpx/vpx_decoder.h,
[if test ! -f "${LIBVPX_DIR}/include/vpx/vpx_decoder.h"; then
AC_MSG_ERROR([vpx/vpx_decoder.h found, but is not in ${LIBVPX_DIR}/include])
fi],
AC_MSG_ERROR([--with-system-libvpx requested but vpx/vpx_decoder.h not found]))
AC_CHECK_LIB(vpx, vpx_codec_dec_init_ver,
[MOZ_NATIVE_LIBVPX=1
MOZ_LIBVPX_INCLUDES="-I${LIBVPX_DIR}/include"
MOZ_LIBVPX_LIBS="-L${LIBVPX_DIR}/lib -lvpx"],
([--with-system-libvpx requested but symbol vpx_codec_dec_init_ver not found]))
CFLAGS=$_SAVE_CFLAGS
LDFLAGS=$_SAVE_LDFLAGS
LIBS=$_SAVE_LIBS
fi
fi
AC_SUBST(MOZ_NATIVE_LIBVPX)
AC_SUBST(MOZ_LIBVPX_INCLUDES)
AC_SUBST(MOZ_LIBVPX_LIBS)
if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
MOZ_SYDNEYAUDIO=1
MOZ_MEDIA=1
case "$target_cpu" in
@ -6009,8 +6048,10 @@ if test -n "$MOZ_WEBM"; then
dnl Detect if we can use an assembler to compile optimized assembly for libvpx.
dnl We currently require yasm on all platforms and require yasm 1.1.0 on Win32.
dnl We currently require yasm on all x86 platforms and require yasm 1.1.0 on Win32.
dnl We currently require gcc on all arm platforms.
VPX_AS=$YASM
VPX_ASM_SUFFIX=asm
dnl See if we have assembly on this platform.
case "$OS_ARCH:$CPU_ARCH" in
@ -6057,6 +6098,17 @@ if test -n "$MOZ_WEBM"; then
fi
fi
;;
*:arm*)
if test -n "$GNU_AS" ; then
VPX_AS=$AS
dnl These flags are a lie; they're just used to enable the requisite
dnl opcodes; actual arch detection is done at runtime.
VPX_ASFLAGS="-march=armv7-a -mfpu=neon"
VPX_DASH_C_FLAG="-c"
VPX_AS_CONVERSION="$PERL ${srcdir}/media/libvpx/build/make/ads2gas.pl"
VPX_ASM_SUFFIX="$ASM_SUFFIX"
VPX_ARM_ASM=1
fi
esac
if test -n "$COMPILE_ENVIRONMENT" -a -n "$VPX_X86_ASM" -a -z "$VPX_AS"; then
@ -6065,6 +6117,8 @@ if test -n "$MOZ_WEBM"; then
if test -n "$VPX_X86_ASM"; then
AC_DEFINE(VPX_X86_ASM)
elif test -n "$VPX_ARM_ASM"; then
AC_DEFINE(VPX_ARM_ASM)
else
AC_MSG_WARN([No assembler or assembly support for libvpx. Using unoptimized C routines.])
fi
@ -6367,15 +6421,11 @@ if test `echo "$MOZ_EXTENSIONS" | grep -c tridentprofile` -ne 0; then
MOZ_EXTENSIONS="$MOZ_EXTENSIONS tridentprofile"
fi
dnl xforms requires xtf and schema-validation
dnl xforms requires xtf
if test -z "$MOZ_XTF" -a `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0; then
AC_MSG_WARN([Cannot build XForms without XTF support. Removing XForms from MOZ_EXTENSIONS.])
MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
fi
if test `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0 && test `echo "$MOZ_EXTENSIONS" | grep -c schema-validation` -eq 0; then
AC_MSG_WARN([Cannot build XForms without schema validation. Removing XForms from MOZ_EXTENSIONS.])
MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
fi
if test `echo "$MOZ_EXTENSIONS" | grep -c auth` -ne 0; then
AC_MSG_WARN([auth is no longer an extension, use --disable-negotiateauth to disable.])
@ -6418,33 +6468,6 @@ for extension in $MOZ_EXTENSIONS; do
fi
done
dnl ========================================================
dnl Image encoders
dnl ========================================================
MOZ_ARG_ENABLE_STRING(image-encoders,
[ --enable-image-encoders[={mod1,mod2,default,all,none}]
Enable specific image encoders],
[ for option in `echo $enableval | sed 's/,/ /g'`; do
if test "$option" = "yes" -o "$option" = "all"; then
addencoder="$MOZ_IMG_ENCODERS_DEFAULT"
elif test "$option" = "no" -o "$option" = "none"; then
MOZ_IMG_ENCODERS=""
addencoder=""
elif test "$option" = "default"; then
addencoder="$MOZ_IMG_ENCODERS_DEFAULT"
elif test `echo "$option" | grep -c \^-` != 0; then
option=`echo $option | sed 's/^-//'`
addencoder=`echo "$MOZ_IMG_ENCODERS" | sed "s/ ${option}//"`
else
addencoder="$option"
fi
MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS $addencoder"
done],
MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS_DEFAULT")
dnl Remove dupes
MOZ_IMG_ENCODERS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_IMG_ENCODERS}`
dnl ========================================================
dnl MathML on by default
dnl ========================================================
@ -8573,7 +8596,7 @@ if test "$MOZ_TREE_CAIRO"; then
if test "$MOZ_TREE_PIXMAN"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS"' $(call EXPAND_LIBNAME_PATH,mozlibpixman,$(DEPTH)/gfx/cairo/libpixman/src)'
else
PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.17.3)
PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.19.2)
MOZ_CAIRO_CFLAGS="$MOZ_CAIRO_CFLAGS $PIXMAN_CFLAGS"
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $PIXMAN_LIBS"
fi
@ -8848,7 +8871,6 @@ AC_SUBST(MOZ_DEBUG_FLAGS)
AC_SUBST(MOZ_DEBUG_LDFLAGS)
AC_SUBST(WARNINGS_AS_ERRORS)
AC_SUBST(MOZ_EXTENSIONS)
AC_SUBST(MOZ_IMG_ENCODERS)
AC_SUBST(MOZ_JSDEBUGGER)
AC_SUBST(MOZ_PLUGINS)
AC_SUBST(MOZ_LOG_REFCNT)
@ -8911,7 +8933,6 @@ AC_SUBST(USE_DEPENDENT_LIBS)
AC_SUBST(MOZ_BUILD_ROOT)
AC_SUBST(MOZ_OS2_TOOLS)
AC_SUBST(MOZ_OS2_USE_DECLSPEC)
AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
@ -9078,7 +9099,11 @@ AC_SUBST(MOZ_OGG)
AC_SUBST(MOZ_ALSA_LIBS)
AC_SUBST(VPX_AS)
AC_SUBST(VPX_ASFLAGS)
AC_SUBST(VPX_DASH_C_FLAG)
AC_SUBST(VPX_AS_CONVERSION)
AC_SUBST(VPX_ASM_SUFFIX)
AC_SUBST(VPX_X86_ASM)
AC_SUBST(VPX_ARM_ASM)
if test "$USING_HCC"; then
CC='${topsrcdir}/build/hcc'

View File

@ -1700,6 +1700,14 @@ public:
*/
static bool IsSubDocumentTabbable(nsIContent* aContent);
/**
* Flushes the layout tree (recursively)
*
* @param aWindow the window the flush should start at
*
*/
static void FlushLayoutForTree(nsIDOMWindow* aWindow);
private:
static PRBool InitializeEventTable();

View File

@ -121,8 +121,8 @@ class Element;
#define NS_IDOCUMENT_IID \
{ 0x7fb1e97d, 0xbd2c, 0x47cf, \
{ 0xa3, 0x05, 0x5b, 0x31, 0xd4, 0x1d, 0x3a, 0x52 } }
{ 0xc38a7935, 0xc854, 0x4df7, \
{ 0x8f, 0xd4, 0xa2, 0x6f, 0x0d, 0x27, 0x9f, 0x31 } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1280,6 +1280,11 @@ public:
virtual nsSMILAnimationController* GetAnimationController() = 0;
#endif // MOZ_SMIL
// Makes the images on this document capable of having their animation
// active or suspended. An Image will animate as long as at least one of its
// owning Documents needs it to animate; otherwise it can suspend.
virtual void SetImagesNeedAnimating(PRBool aAnimating) = 0;
/**
* Prevents user initiated events from being dispatched to the document and
* subdocuments.

View File

@ -738,7 +738,7 @@ public:
nsSlots* s = GetSlots();
if (s) {
NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
nsTArray_base::NoIndex,
nsTArray<int>::NoIndex,
"Observer already in the list");
s->mMutationObservers.AppendElement(aMutationObserver);
}

View File

@ -85,7 +85,6 @@ var gPrefObserver = {
function CSPWarning(aMsg) {
var textMessage = 'CSP WARN: ' + aMsg + "\n";
dump(textMessage);
var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
.createInstance(Components.interfaces.nsIScriptError);
@ -99,7 +98,6 @@ function CSPWarning(aMsg) {
function CSPError(aMsg) {
var textMessage = 'CSP ERROR: ' + aMsg + "\n";
dump(textMessage);
var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
.createInstance(Components.interfaces.nsIScriptError);
@ -115,7 +113,6 @@ function CSPdebug(aMsg) {
if (!gPrefObserver.debugEnabled) return;
aMsg = 'CSP debug: ' + aMsg + "\n";
dump(aMsg);
Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService)
.logStringMessage(aMsg);

View File

@ -58,8 +58,9 @@ class nsIAtom;
class nsICSSStyleRule;
class nsISVGValue;
class nsIDocument;
template<class E> class nsTArray;
template<class E> class nsTPtrArray;
template<class E, class A> class nsTArray;
template<class E, class A> class nsTPtrArray;
struct nsTArrayDefaultAllocator;
#define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
@ -381,7 +382,7 @@ private:
PRBool aCanBePercent = PR_FALSE,
PRBool* aIsPercent = nsnull) const;
static nsTPtrArray<const EnumTable>* sEnumTableArray;
static nsTPtrArray<const EnumTable, nsTArrayDefaultAllocator>* sEnumTableArray;
PtrBits mBits;
};

View File

@ -4803,8 +4803,12 @@ static void ProcessViewportToken(nsIDocument *aDocument,
return;
/* Extract the key and value. */
const nsAString &key = Substring(tail, tip);
const nsAString &value = Substring(++tip, end);
const nsAString &key =
nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(tail, tip),
PR_TRUE);
const nsAString &value =
nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(++tip, end),
PR_TRUE);
/* Check for known keys. If we find a match, insert the appropriate
* information into the document header. */
@ -4823,7 +4827,9 @@ static void ProcessViewportToken(nsIDocument *aDocument,
aDocument->SetHeaderData(nsGkAtoms::viewport_user_scalable, value);
}
#define IS_SEPARATOR(c) ((c == ' ') || (c == ',') || (c == ';'))
#define IS_SEPARATOR(c) ((c == '=') || (c == ',') || (c == ';') || \
(c == '\t') || (c == '\n') || (c == '\r'))
/* static */
nsresult
nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
@ -4839,12 +4845,12 @@ nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
viewportInfo.EndReading(end);
/* Read the tip to the first non-separator character. */
while ((tip != end) && IS_SEPARATOR(*tip))
while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
++tip;
/* Read through and find tokens separated by separators. */
while (tip != end) {
/* Synchronize tip and tail. */
tail = tip;
@ -4852,11 +4858,22 @@ nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
while ((tip != end) && !IS_SEPARATOR(*tip))
++tip;
/* Allow white spaces that surround the '=' character */
if ((tip != end) && (*tip == '=')) {
++tip;
while ((tip != end) && nsCRT::IsAsciiSpace(*tip))
++tip;
while ((tip != end) && !(IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
++tip;
}
/* Our token consists of the characters between tail and tip. */
ProcessViewportToken(aDocument, Substring(tail, tip));
/* Skip separators. */
while ((tip != end) && IS_SEPARATOR(*tip))
while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
++tip;
}
@ -6286,6 +6303,40 @@ nsContentUtils::IsSubDocumentTabbable(nsIContent* aContent)
return !zombieViewer;
}
void
nsContentUtils::FlushLayoutForTree(nsIDOMWindow* aWindow)
{
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
if (!piWin)
return;
// Note that because FlushPendingNotifications flushes parents, this
// is O(N^2) in docshell tree depth. However, the docshell tree is
// usually pretty shallow.
nsCOMPtr<nsIDOMDocument> domDoc;
aWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
if (doc) {
doc->FlushPendingNotifications(Flush_Layout);
}
nsCOMPtr<nsIDocShellTreeNode> node =
do_QueryInterface(piWin->GetDocShell());
if (node) {
PRInt32 i = 0, i_end;
node->GetChildCount(&i_end);
for (; i < i_end; ++i) {
nsCOMPtr<nsIDocShellTreeItem> item;
node->GetChildAt(i, getter_AddRefs(item));
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
if (win) {
FlushLayoutForTree(win);
}
}
}
}
void nsContentUtils::RemoveNewlines(nsString &aString)
{
// strip CR/LF and null

View File

@ -205,6 +205,8 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
using namespace mozilla::dom;
typedef nsTArray<Link*> LinkArray;
#ifdef PR_LOGGING
static PRLogModuleInfo* gDocumentLeakPRLog;
@ -3902,7 +3904,7 @@ nsDocument::InternalAllowXULXBL()
void
nsDocument::AddObserver(nsIDocumentObserver* aObserver)
{
NS_ASSERTION(mObservers.IndexOf(aObserver) == nsTArray_base::NoIndex,
NS_ASSERTION(mObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex,
"Observer already in the list");
mObservers.AppendElement(aObserver);
AddMutationObserver(aObserver);
@ -5543,6 +5545,13 @@ nsDocument::GetAnimationController()
}
}
// If we're hidden (or being hidden), notify the newly-created animation
// controller. (Skip this check for SVG-as-an-image documents, though,
// because they don't get OnPageShow / OnPageHide calls).
if (!mIsShowing && !mIsBeingUsedAsImage) {
mAnimationController->OnPageHide();
}
return mAnimationController;
}
#endif // MOZ_SMIL
@ -7541,7 +7550,7 @@ static
PLDHashOperator
EnumerateStyledLinks(nsPtrHashKey<Link>* aEntry, void* aArray)
{
nsTArray<Link*>* array = static_cast<nsTArray<Link*>*>(aArray);
LinkArray* array = static_cast<LinkArray*>(aArray);
(void)array->AppendElement(aEntry->GetKey());
return PL_DHASH_NEXT;
}
@ -7552,12 +7561,12 @@ nsDocument::RefreshLinkHrefs()
// Get a list of all links we know about. We will reset them, which will
// remove them from the document, so we need a copy of what is in the
// hashtable.
nsTArray<Link*> linksToNotify(mStyledLinks.Count());
LinkArray linksToNotify(mStyledLinks.Count());
(void)mStyledLinks.EnumerateEntries(EnumerateStyledLinks, &linksToNotify);
// Reset all of our styled links.
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_STATE, PR_TRUE);
for (nsTArray_base::size_type i = 0; i < linksToNotify.Length(); i++) {
for (LinkArray::size_type i = 0; i < linksToNotify.Length(); i++) {
linksToNotify[i]->ResetLinkState(true);
}
}

View File

@ -919,6 +919,8 @@ public:
nsSMILAnimationController* GetAnimationController();
#endif // MOZ_SMIL
void SetImagesNeedAnimating(PRBool aAnimating);
virtual void SuppressEventHandling(PRUint32 aIncrease);
virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents);
@ -1252,12 +1254,6 @@ private:
protected:
PRBool mWillReparent;
#endif
protected:
// Makes the images on this document capable of having their animation
// active or suspended. An Image will animate as long as at least one of its
// owning Documents needs it to animate; otherwise it can suspend.
void SetImagesNeedAnimating(PRBool aAnimating);
};
#define NS_DOCUMENT_INTERFACE_TABLE_BEGIN(_class) \

View File

@ -653,7 +653,18 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
nsIntSize size;
if (!(frame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// We have a useful size already; use it, since we might get no
// more size updates.
size = GetSubDocumentSize(frame);
} else {
// Pick some default size for now. Using 10x10 because that's what the
// code here used to do.
size.SizeTo(10, 10);
}
baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0,
size.width, size.height);
// This is kinda whacky, this "Create()" call doesn't really
// create anything, one starts to wonder why this was named
// "Create"...
@ -712,8 +723,7 @@ nsFrameLoader::ShowRemoteFrame(const nsIntSize& size)
mRemoteBrowser->Show(size);
mRemoteBrowserShown = PR_TRUE;
nsCOMPtr<nsIChromeFrameMessageManager> dummy;
GetMessageManager(getter_AddRefs(dummy)); // Initialize message manager.
EnsureMessageManager();
} else {
mRemoteBrowser->Move(size);
}

View File

@ -234,7 +234,7 @@ nsFrameMessageManager::SendSyncMessage()
nsString json;
nsresult rv = GetParamsForMessage(messageName, json);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsString> retval;
InfallibleTArray<nsString> retval;
if (mSyncCallback(mCallbackData, messageName, json, &retval)) {
nsAXPCNativeCallContext* ncc = nsnull;
rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
@ -326,7 +326,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
const nsAString& aMessage,
PRBool aSync, const nsAString& aJSON,
JSObject* aObjectsArray,
nsTArray<nsString>* aJSONRetVal,
InfallibleTArray<nsString>* aJSONRetVal,
JSContext* aContext)
{
JSContext* ctx = mContext ? mContext : aContext;
@ -742,7 +742,7 @@ bool SendAsyncMessageToChildProcess(void* aCallbackData,
bool SendSyncMessageToParentProcess(void* aCallbackData,
const nsAString& aMessage,
const nsAString& aJSON,
nsTArray<nsString>* aJSONRetVal)
InfallibleTArray<nsString>* aJSONRetVal)
{
mozilla::dom::ContentChild* cc =
mozilla::dom::ContentChild::GetSingleton();

View File

@ -66,7 +66,7 @@ typedef bool (*nsLoadScriptCallback)(void* aCallbackData, const nsAString& aURL)
typedef bool (*nsSyncMessageCallback)(void* aCallbackData,
const nsAString& aMessage,
const nsAString& aJSON,
nsTArray<nsString>* aJSONRetVal);
InfallibleTArray<nsString>* aJSONRetVal);
typedef bool (*nsAsyncMessageCallback)(void* aCallbackData,
const nsAString& aMessage,
const nsAString& aJSON);
@ -129,7 +129,7 @@ public:
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
PRBool aSync, const nsAString& aJSON,
JSObject* aObjectsArray,
nsTArray<nsString>* aJSONRetVal,
InfallibleTArray<nsString>* aJSONRetVal,
JSContext* aContext = nsnull);
void AddChildManager(nsFrameMessageManager* aManager,
PRBool aLoadScripts = PR_TRUE);

View File

@ -54,7 +54,7 @@
bool SendSyncMessageToParent(void* aCallbackData,
const nsAString& aMessage,
const nsAString& aJSON,
nsTArray<nsString>* aJSONRetVal)
InfallibleTArray<nsString>* aJSONRetVal)
{
nsInProcessTabChildGlobal* tabChild =
static_cast<nsInProcessTabChildGlobal*>(aCallbackData);

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