Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2010-11-09 15:29:44 -05:00
commit 48cc92a4b0
1182 changed files with 51674 additions and 18593 deletions

View File

@ -171,7 +171,7 @@ ifdef MOZ_SYMBOLS_EXTRA_BUILDID
EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
endif
SYMBOL_INDEX_NAME = \
export SYMBOL_INDEX_NAME = \
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
buildsymbols:

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

@ -104,6 +104,7 @@ body[dir="rtl"] #searchEngineLinks {
}
#searchText {
margin-bottom: 10px;
width: 100%;
}

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

@ -72,7 +72,6 @@
<img id="searchEngineLogo"/>
<form name="searchForm" onsubmit="onSearchSubmit(event)">
<input type="text" name="searchText" value="" id="searchText" maxLength="256"/>
<br/>
<input type="submit" value="&abouthome.searchEngineButton.label;"/>
<span id="searchEngineLinks">
<a hidden="true" id="searchEngineAdvancedLink">&abouthome.searchEngineLinks.advanced;</a>

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

@ -0,0 +1,409 @@
# -*- Mode: HTML -*-
# ***** 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 Application Menu.
#
# 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):
# Dão Gottwald <dao@mozilla.com>
# Joshua M. <soapyhamhocks@gmail.com>
# Margaret Leibovic <margaret.leibovic@gmail.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 *****
<menupopup id="appmenu-popup"
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
#else
onpopupshowing="updateEditUIVisibility();">
#endif
<hbox>
<vbox id="appmenuPrimaryPane">
<hbox flex="1"
class="split-menuitem">
<menuitem id="appmenu_newTab"
class="menuitem-tooltip split-menuitem-item"
flex="1"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_newTab_popup"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"
key="key_newNavigator"/>
<menuseparator/>
<menuitem id="appmenu_openFile"
label="&openFileCmd.label;"
command="Browser:OpenFile"
key="openFileKb"/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_privateBrowsing"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&privateBrowsingCmd.start.label;"
startlabel="&privateBrowsingCmd.start.label;"
stoplabel="&privateBrowsingCmd.stop.label;"
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
<menuitem label="&goOfflineCmd.label;"
id="appmenu_offlineModeRecovery"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
<menuseparator class="appmenu-menuseparator"/>
<hbox>
<menuitem id="appmenu-edit-label"
label="&appMenuEdit.label;"
disabled="true"/>
<toolbarbutton id="appmenu-cut"
class="appmenu-edit-button"
command="cmd_cut"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&cutButton.tooltip;"/>
<toolbarbutton id="appmenu-copy"
class="appmenu-edit-button"
command="cmd_copy"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&copyButton.tooltip;"/>
<toolbarbutton id="appmenu-paste"
class="appmenu-edit-button"
command="cmd_paste"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&pasteButton.tooltip;"/>
</hbox>
<menuitem id="appmenu_find"
class="menuitem-tooltip"
label="&appMenuFind.label;"
command="cmd_find"
key="key_find"/>
<menuseparator class="appmenu-menuseparator"/>
<menuitem id="appmenu_savePage"
class="menuitem-tooltip"
label="&savePageCmd.label;"
command="Browser:SavePage"
key="key_savePage"/>
<menuitem id="appmenu_sendLink"
label="&sendPageCmd.label;"
command="Browser:SendLink"/>
<hbox flex="1"
class="split-menuitem">
<menuitem id="appmenu_print"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_print_popup"
class="menuitem-iconic"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menuitem id="appmenu_printPreview"
label="&printPreviewCmd.label;"
command="cmd_printPreview"/>
<menuitem id="appmenu_printSetup"
label="&printSetupCmd.label;"
command="cmd_pageSetup"/>
</menupopup>
</menu>
</hbox>
<menuseparator class="appmenu-menuseparator"/>
<menu id="appmenu_webDeveloper"
label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup">
<menuitem id="appmenu_webConsole"
label="&webConsoleCmd.label;"
oncommand="HUDConsoleUI.toggleHUD();"
key="key_webConsole"/>
<menuitem id="appmenu_pageInspect"
hidden="true"
label="&inspectMenu.label;"
type="checkbox"
command="Tools:Inspect"
key="key_inspect"/>
<menuseparator/>
<menuitem id="appmenu_pageSource"
label="&viewPageSourceCmd.label;"
command="View:PageSource"
key="key_viewSource"/>
<menuseparator/>
#define ID_PREFIX appmenu_developer_
#include browser-charsetmenu.inc
#undef ID_PREFIX
<menuseparator/>
<menuitem label="&goOfflineCmd.label;"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
</menupopup>
</menu>
<menuseparator class="appmenu-menuseparator"/>
#define ID_PREFIX appmenu_
#include browser-charsetmenu.inc
#undef ID_PREFIX
<menuitem id="appmenu_fullScreen"
class="menuitem-tooltip"
label="&fullScreenCmd.label;"
type="checkbox"
observes="View:FullScreen"
key="key_fullScreen"/>
<menuitem id="appmenu-quit"
class="menuitem-iconic"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
#else
label="&quitApplicationCmd.label;"
#endif
command="cmd_quitApplication"/>
</vbox>
<vbox id="appmenuSecondaryPane">
<hbox class="split-menuitem">
<menuitem id="appmenu_bookmarks"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&bookmarksMenu.label;"
command="Browser:ShowAllBookmarks"
key="manBookmarkKb"/>
<menu id="appmenu_bookmarksMenu"
class="split-menuitem-menu">
<menupopup id="appmenu_bookmarksPopup"
placespopup="true"
context="placesContext"
openInTabs="children"
oncommand="BookmarksEventHandler.onCommand(event);"
onclick="BookmarksEventHandler.onClick(event);"
onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllBookmarks"
label="&showAllBookmarks.label;"
command="Browser:ShowAllBookmarks"
context=""
key="manBookmarkKb"/>
<menuseparator/>
<menuitem id="appmenu_bookmarkThisPage"
class="menuitem-iconic"
label="&bookmarkThisPageCmd.label;"
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="appmenu_subscribeToPage"
class="menuitem-iconic"
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="appmenu_subscribeToPageMenu"
class="menu-iconic"
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="appmenu_subscribeToPageMenupopup"
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</menu>
<menuseparator/>
<menu id="appmenu_bookmarksToolbar"
placesanonid="toolbar-autohide"
class="menu-iconic bookmark-item"
label="&personalbarCmd.label;"
container="true">
<menupopup id="appmenu_bookmarksToolbarPopup"
placespopup="true"
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
</menu>
<menuseparator/>
<!-- Bookmarks menu items -->
<menuseparator builder="end"
class="hide-if-empty-places-result"/>
<menuitem id="appmenu_unsortedBookmarks"
label="&appMenuUnsorted.label;"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
class="menuitem-iconic"/>
</menupopup>
</menu>
</hbox>
<hbox class="split-menuitem">
<menuitem id="appmenu_history"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&historyMenu.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menu id="appmenu_historyMenu"
class="split-menuitem-menu">
<menupopup id="appmenu_historyMenupopup"
placespopup="true"
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllHistory"
label="&showAllHistoryCmd2.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menuseparator/>
<menuitem id="appmenu_sanitizeHistory"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator class="hide-if-empty-places-result"/>
<menuitem id="appmenu_restoreLastSession"
class="restoreLastSession"
label="&historyRestoreLastSession.label;"
oncommand="restoreLastSession();"
disabled="true"/>
<menu id="appmenu_recentlyClosedTabsMenu"
class="recentlyClosedTabsMenu"
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedTabsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="appmenu_recentlyClosedWindowsMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedWindowsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_downloads"
class="menuitem-tooltip"
label="&downloads.label;"
command="Tools:Downloads"
key="key_openDownloads"/>
<spacer id="appmenuSecondaryPane-spacer"/>
<menuitem id="appmenu_addons"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&addons.label;"
command="Tools:Addons"
key="key_openAddons"/>
<hbox class="split-menuitem">
<menuitem id="appmenu_customize"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd.label;"
#endif
class="split-menuitem-item"
flex="1"
oncommand="openPreferences();"/>
<menu class="split-menuitem-menu"
label="&preferencesCmd.label;">
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
<menuitem id="appmenu_preferences"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd.label;"
#endif
oncommand="openPreferences();"/>
<menuseparator/>
<menuseparator/>
<menuitem id="appmenu_toggleTabsOnTop"
label="&viewTabsOnTop.label;"
type="checkbox"
command="cmd_ToggleTabsOnTop"/>
<menuitem id="appmenu_toolbarLayout"
label="&appMenuToolbarLayout.label;"
command="cmd_CustomizeToolbars"/>
</menupopup>
</menu>
</hbox>
<hbox class="split-menuitem">
<menuitem id="appmenu_help"
class="split-menuitem-item"
flex="1"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"/>
<menu class="split-menuitem-menu">
<menupopup id="appmenu_helpMenupopup">
<menuitem id="appmenu_openHelp"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_gettingStarted"
label="&appMenuGettingStarted.label;"
oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_troubleshootingInfo"
label="&helpTroubleshootingInfo.label;"
oncommand="openTroubleshootingPage()"
onclick="checkForMiddleClick(this,event);"/>
<menuitem id="appmenu_feedbackPage"
label="&helpFeedbackPage.label;"
oncommand="openFeedbackPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator/>
<menuitem id="appmenu_safeMode"
accesskey="&appMenuSafeMode.accesskey;"
label="&appMenuSafeMode.label;"
oncommand="safeModeRestart();"/>
<menuseparator/>
<menuitem id="appmenu_about"
label="&aboutProduct.label;"
oncommand="openAboutDialog();"/>
</menupopup>
</menu>
</hbox>
#ifdef MOZ_SERVICES_SYNC
<spacer flex="1"/>
<!-- only one of sync-setup or sync-syncnow will be showing at once -->
<menuitem id="sync-setup-appmenu"
label="&syncSetup.label;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem-appmenu"
label="&syncSyncNowItem.label;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
</vbox>
</hbox>
</menupopup>

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

@ -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,393 +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;">
<menupopup id="appmenu-popup"
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
#else
onpopupshowing="updateEditUIVisibility();">
#endif
<hbox>
<vbox id="appmenuPrimaryPane">
<hbox flex="1"
class="split-menuitem">
<menuitem id="appmenu_newTab"
class="menuitem-tooltip split-menuitem-item"
flex="1"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_newTab_popup"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"/>
<menuitem id="appmenu_newNavigator"
label="&newNavigatorCmd.label;"
command="cmd_newNavigator"
key="key_newNavigator"/>
<menuseparator/>
<menuitem id="appmenu_openFile"
label="&openFileCmd.label;"
command="Browser:OpenFile"
key="openFileKb"/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_privateBrowsing"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&privateBrowsingCmd.start.label;"
startlabel="&privateBrowsingCmd.start.label;"
stoplabel="&privateBrowsingCmd.stop.label;"
command="Tools:PrivateBrowsing"
key="key_privatebrowsing"/>
<menuitem label="&goOfflineCmd.label;"
id="appmenu_offlineModeRecovery"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
<menuseparator class="appmenu-menuseparator"/>
<hbox>
<menuitem id="appmenu-edit-label"
label="&appMenuEdit.label;"
disabled="true"/>
<toolbarbutton id="appmenu-cut"
class="appmenu-edit-button"
command="cmd_cut"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&cutButton.tooltip;"/>
<toolbarbutton id="appmenu-copy"
class="appmenu-edit-button"
command="cmd_copy"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&copyButton.tooltip;"/>
<toolbarbutton id="appmenu-paste"
class="appmenu-edit-button"
command="cmd_paste"
onclick="if (!this.disabled) hidePopup();"
tooltiptext="&pasteButton.tooltip;"/>
</hbox>
<menuitem id="appmenu_find"
class="menuitem-tooltip"
label="&appMenuFind.label;"
command="cmd_find"
key="key_find"/>
<menuseparator class="appmenu-menuseparator"/>
<menuitem id="appmenu_savePage"
class="menuitem-tooltip"
label="&savePageCmd.label;"
command="Browser:SavePage"
key="key_savePage"/>
<menuitem id="appmenu_sendLink"
label="&sendPageCmd.label;"
command="Browser:SendLink"/>
<hbox flex="1"
class="split-menuitem">
<menuitem id="appmenu_print"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menu class="split-menuitem-menu">
<menupopup>
<menuitem id="appmenu_print_popup"
class="menuitem-iconic"
label="&printCmd.label;"
command="cmd_print"
key="printKb"/>
<menuitem id="appmenu_printPreview"
label="&printPreviewCmd.label;"
command="cmd_printPreview"/>
<menuitem id="appmenu_printSetup"
label="&printSetupCmd.label;"
command="cmd_pageSetup"/>
</menupopup>
</menu>
</hbox>
<menuseparator class="appmenu-menuseparator"/>
<menu id="appmenu_webDeveloper"
label="&appMenuWebDeveloper.label;">
<menupopup id="appmenu_webDeveloper_popup">
<menuitem id="appmenu_webConsole"
label="&webConsoleCmd.label;"
oncommand="HUDConsoleUI.toggleHUD();"
key="key_webConsole"/>
<menuitem id="appmenu_pageInspect"
hidden="true"
label="&inspectMenu.label;"
type="checkbox"
command="Tools:Inspect"
key="key_inspect"/>
<menuseparator/>
<menuitem id="appmenu_pageSource"
label="&viewPageSourceCmd.label;"
command="View:PageSource"
key="key_viewSource"/>
<menuseparator/>
#define ID_PREFIX appmenu_developer_
#include browser-charsetmenu.inc
#undef ID_PREFIX
<menuseparator/>
<menuitem label="&goOfflineCmd.label;"
type="checkbox"
observes="workOfflineMenuitemState"
oncommand="BrowserOffline.toggleOfflineStatus();"/>
</menupopup>
</menu>
<menuseparator class="appmenu-menuseparator"/>
#define ID_PREFIX appmenu_
#include browser-charsetmenu.inc
#undef ID_PREFIX
<menuitem id="appmenu_fullScreen"
class="menuitem-tooltip"
label="&fullScreenCmd.label;"
type="checkbox"
observes="View:FullScreen"
key="key_fullScreen"/>
<menuitem id="appmenu-quit"
class="menuitem-iconic"
#ifdef XP_WIN
label="&quitApplicationCmdWin.label;"
#else
label="&quitApplicationCmd.label;"
#endif
command="cmd_quitApplication"/>
</vbox>
<vbox id="appmenuSecondaryPane">
<hbox class="split-menuitem">
<menuitem id="appmenu_bookmarks"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&bookmarksMenu.label;"
command="Browser:ShowAllBookmarks"
key="manBookmarkKb"/>
<menu id="appmenu_bookmarksMenu"
class="split-menuitem-menu">
<menupopup id="appmenu_bookmarksPopup"
placespopup="true"
context="placesContext"
openInTabs="children"
oncommand="BookmarksEventHandler.onCommand(event);"
onclick="BookmarksEventHandler.onClick(event);"
onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllBookmarks"
label="&showAllBookmarks.label;"
command="Browser:ShowAllBookmarks"
context=""
key="manBookmarkKb"/>
<menuseparator/>
<menuitem id="appmenu_bookmarkThisPage"
class="menuitem-iconic"
label="&bookmarkThisPageCmd.label;"
command="Browser:AddBookmarkAs"
key="addBookmarkAsKb"/>
<menuitem id="appmenu_subscribeToPage"
class="menuitem-iconic"
label="&subscribeToPageMenuitem.label;"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"
observes="singleFeedMenuitemState"/>
<menu id="appmenu_subscribeToPageMenu"
class="menu-iconic"
label="&subscribeToPageMenupopup.label;"
observes="multipleFeedsMenuState">
<menupopup id="appmenu_subscribeToPageMenupopup"
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/>
</menu>
<menuseparator/>
<menu id="appmenu_bookmarksToolbar"
placesanonid="toolbar-autohide"
class="menu-iconic bookmark-item"
label="&personalbarCmd.label;"
container="true">
<menupopup id="appmenu_bookmarksToolbarPopup"
placespopup="true"
context="placesContext"
onpopupshowing="if (!this.parentNode._placesView)
new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
</menu>
<menuseparator/>
<!-- Bookmarks menu items -->
<menuseparator builder="end"
class="hide-if-empty-places-result"/>
<menuitem id="appmenu_unsortedBookmarks"
label="&appMenuUnsorted.label;"
oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
class="menuitem-iconic"/>
</menupopup>
</menu>
</hbox>
<hbox class="split-menuitem">
<menuitem id="appmenu_history"
class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
flex="1"
label="&historyMenu.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menu id="appmenu_historyMenu"
class="split-menuitem-menu">
<menupopup id="appmenu_historyMenupopup"
placespopup="true"
oncommand="this.parentNode._placesView._onCommand(event);"
onclick="checkForMiddleClick(this, event);"
onpopupshowing="if (!this.parentNode._placesView)
new HistoryMenu(event);"
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="appmenu_showAllHistory"
label="&showAllHistoryCmd2.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb"/>
<menuseparator/>
<menuitem id="appmenu_sanitizeHistory"
label="&clearRecentHistory.label;"
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator class="hide-if-empty-places-result"/>
<menuitem id="appmenu_restoreLastSession"
class="restoreLastSession"
label="&historyRestoreLastSession.label;"
oncommand="restoreLastSession();"
disabled="true"/>
<menu id="appmenu_recentlyClosedTabsMenu"
class="recentlyClosedTabsMenu"
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedTabsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="appmenu_recentlyClosedWindowsMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedWindowsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator/>
</menupopup>
</menu>
</hbox>
<menuitem id="appmenu_downloads"
class="menuitem-tooltip"
label="&downloads.label;"
command="Tools:Downloads"
key="key_openDownloads"/>
<spacer id="appmenuSecondaryPane-spacer"/>
<menuitem id="appmenu_addons"
class="menuitem-iconic menuitem-iconic-tooltip"
label="&addons.label;"
command="Tools:Addons"
key="key_openAddons"/>
<hbox class="split-menuitem">
<menuitem id="appmenu_customize"
label="&preferencesCmd.label;"
class="split-menuitem-item"
flex="1"
oncommand="openPreferences();"/>
<menu class="split-menuitem-menu"
label="&preferencesCmd.label;">
<menupopup id="appmenu_customizeMenu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
<menuitem id="appmenu_preferences"
#ifdef XP_UNIX
label="&preferencesCmdUnix.label;"
#else
label="&preferencesCmd.label;"
#endif
oncommand="openPreferences();"/>
<menuseparator/>
<menuseparator/>
<menuitem id="appmenu_toggleTabsOnTop"
label="&viewTabsOnTop.label;"
type="checkbox"
command="cmd_ToggleTabsOnTop"/>
<menuitem id="appmenu_toolbarLayout"
label="&appMenuToolbarLayout.label;"
command="cmd_CustomizeToolbars"/>
</menupopup>
</menu>
</hbox>
<hbox class="split-menuitem">
<menuitem id="appmenu_help"
class="split-menuitem-item"
flex="1"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"/>
<menu class="split-menuitem-menu">
<menupopup id="appmenu_helpMenupopup">
<menuitem id="appmenu_openHelp"
label="&helpMenu.label;"
oncommand="openHelpLink('firefox-help')"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_gettingStarted"
label="&appMenuGettingStarted.label;"
oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="appmenu_troubleshootingInfo"
label="&helpTroubleshootingInfo.label;"
oncommand="openTroubleshootingPage()"
onclick="checkForMiddleClick(this,event);"/>
<menuitem id="appmenu_feedbackPage"
label="&helpFeedbackPage.label;"
oncommand="openFeedbackPage()"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator/>
<menuitem id="appmenu_safeMode"
accesskey="&appMenuSafeMode.accesskey;"
label="&appMenuSafeMode.label;"
oncommand="safeModeRestart();"/>
<menuseparator/>
<menuitem id="appmenu_about"
label="&aboutProduct.label;"
oncommand="openAboutDialog();"/>
</menupopup>
</menu>
</hbox>
#ifdef MOZ_SERVICES_SYNC
<spacer flex="1"/>
<!-- only one of sync-setup or sync-syncnow will be showing at once -->
<menuitem id="sync-setup-appmenu"
label="&syncSetup.label;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem-appmenu"
label="&syncSyncNowItem.label;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
</vbox>
</hbox>
</menupopup>
</button>
<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>
</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">
@ -944,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>
@ -1016,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>

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();
},
// ----------

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

@ -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 \
@ -221,6 +222,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

@ -33,26 +33,21 @@ function wait_for_install_dialog(aCallback) {
info("Waiting for install dialog");
Services.wm.addListener({
onOpenWindow: function(aXULWindow) {
info("Install dialog opened, waiting for load");
info("Install dialog opened, waiting for focus");
Services.wm.removeListener(this);
var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal);
domwindow.addEventListener("load", function() {
domwindow.removeEventListener("load", arguments.callee, false);
waitForFocus(function() {
info("Saw install dialog");
is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
// Allow other window load listeners to execute before passing to callback
executeSoon(function() {
info("Saw install dialog");
// Override the countdown timer on the accept button
var button = domwindow.document.documentElement.getButton("accept");
button.disabled = false;
// Override the countdown timer on the accept button
var button = domwindow.document.documentElement.getButton("accept");
button.disabled = false;
aCallback(domwindow);
});
}, false);
aCallback(domwindow);
}, domwindow);
},
onCloseWindow: function(aXULWindow) {
@ -597,7 +592,7 @@ var XPInstallObserver = {
};
function test() {
requestLongerTimeout(2);
requestLongerTimeout(4);
waitForExplicitFinish();
Services.prefs.setBoolPref("extensions.logging.enabled", true);

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,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();
@ -209,6 +209,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
@ -249,6 +251,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

@ -55,13 +55,28 @@ function test() {
function onTabViewLoadedAndShown() {
window.removeEventListener("tabviewshown", onTabViewLoadedAndShown, false);
ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
tabViewShownCount++;
// Evidently sometimes isVisible (which is based on the selectedIndex of the
// tabview deck) isn't updated immediately when called from button.doCommand,
// so we add a little timeout here to get outside of the doCommand call.
// If the initial timeout isn't enough, we keep waiting in case it's taking
// longer than expected.
// See bug 594909.
let deck = document.getElementById("tab-view-deck");
function waitForSwitch() {
if (deck.selectedIndex == 1) {
ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
tabViewShownCount++;
// kick off the series
window.addEventListener("tabviewshown", onTabViewShown, false);
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.toggle();
} else {
setTimeout(waitForSwitch, 10);
}
}
// kick off the series
window.addEventListener("tabviewshown", onTabViewShown, false);
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.toggle();
setTimeout(waitForSwitch, 1);
}
// ----------

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

@ -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

@ -65,6 +65,10 @@ _BROWSER_TEST_FILES = \
browser_views_liveupdate.js \
browser_sidebarpanels_click.js \
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
@ -384,8 +385,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

@ -2,6 +2,7 @@ af
ak
ar
as
ast
be
bg
bn-BD
@ -18,6 +19,7 @@ en-GB
en-ZA
eo
es-AR
es-CL
es-ES
es-MX
et
@ -27,6 +29,7 @@ fi
fr
fy-NL
ga-IE
gd
gl
gu-IN
he
@ -40,12 +43,14 @@ it
ja
ja-JP-mac
ka
km
kn
ko
ku
lg
lt
lv
mai
mk
ml
mn
@ -71,6 +76,7 @@ sq
sr
sv-SE
ta
ta-LK
te
th
tr

View File

@ -71,7 +71,7 @@ can reach it easily. -->
<!ENTITY personalbarCmd.accesskey "B">
<!ENTITY bookmarksToolbarItem.label "Bookmarks Toolbar Items">
<!ENTITY addonBarCmd.label "Add-on Bar">
<!ENTITY addonBarCmd.accesskey "B">
<!ENTITY addonBarCmd.accesskey "A">
<!ENTITY pageSourceCmd.label "Page Source">
<!ENTITY pageSourceCmd.accesskey "o">

View File

@ -17,10 +17,12 @@ eo
es-AR
es-ES
et
eu
fi
fr
fy-NL
ga-IE
gd
he
hu
hy-AM
@ -34,6 +36,7 @@ ku
lg
lt
lv
mk
nb-NO
nl
nn-NO
@ -42,6 +45,7 @@ pa-IN
pl
pt-BR
pt-PT
rm
ro
ru
sk

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

@ -302,14 +302,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 +1864,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 +1928,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

@ -65,4 +65,7 @@
<uses-permission android:name="android.permission.SET_TIME"></uses-permission>
<uses-permission android:name="android.permission.SET_TIME_ZONE"></uses-permission>
</manifest>

View File

@ -51,6 +51,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
@ -59,9 +60,12 @@ import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.Timer;
import java.util.zip.Adler32;
@ -87,6 +91,7 @@ import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ContextWrapper;
@ -95,12 +100,14 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Debug;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
@ -118,13 +125,13 @@ public class DoCommand {
String currentDir = "/";
String sErrorPrefix = "##AGENT-WARNING## ";
private final String prgVersion = "SUTAgentAndroid Version 0.85";
private final String prgVersion = "SUTAgentAndroid Version 0.87";
public enum Command
{
RUN ("run"),
EXEC ("exec"),
ARUN ("arun"),
ENVRUN ("envrun"),
KILL ("kill"),
PS ("ps"),
DEVINFO ("info"),
@ -173,6 +180,8 @@ public class DoCommand {
UNINST ("uninst"),
TEST ("test"),
VER ("ver"),
TZGET ("tzget"),
TZSET ("tzset"),
UNKNOWN ("unknown");
private final String theCmd;
@ -207,7 +216,7 @@ public class DoCommand {
Command cCmd = null;
Command cSubCmd = null;
String [] Argv = parseCmdLine(theCmdLine);
String [] Argv = parseCmdLine2(theCmdLine);
int Argc = Argv.length;
@ -223,6 +232,17 @@ public class DoCommand {
strReturn = GetClok();
break;
case TZGET:
strReturn = GetTimeZone();
break;
case TZSET:
if (Argc == 2)
strReturn = SetTimeZone(Argv[1]);
else
strReturn = sErrorPrefix + "Wrong number of arguments for settz command!";
break;
case UPDT:
strReturn = StartUpdateOMatic(Argv[1], Argv[2]);
break;
@ -327,16 +347,6 @@ public class DoCommand {
break;
case REBT:
// try {
// reboot(null);
// Power.reboot(null);
// Power.shutdown();
// }
// catch (IOException e)
// {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
RunReboot(cmdOut);
break;
@ -497,6 +507,25 @@ public class DoCommand {
case TEST:
// boolean bRet = false;
/*
Configuration userConfig = new Configuration();
Settings.System.getConfiguration( contextWrapper.getContentResolver(), userConfig );
Calendar cal = Calendar.getInstance( userConfig.locale);
TimeZone ctz = cal.getTimeZone();
String sctzLongName = ctz.getDisplayName();
String pstzName = TimeZone.getDefault().getDisplayName();
*/
String sTimeZoneName = GetTimeZone();
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone tz2 = TimeZone.getTimeZone("GMT-08:00");
int nOffset = (-8 * 3600000);
String [] zoneNames = TimeZone.getAvailableIDs(nOffset);
int nNumMatches = zoneNames.length;
TimeZone.setDefault(tz);
String sOldTZ = System.setProperty("persist.sys.timezone", "America/Los_Angeles");
/*
byte[] buffer = new byte [4096];
int nRead = 0;
@ -591,7 +620,7 @@ public class DoCommand {
}
*/
// strReturn = InstallApplication();
strReturn = InstallApp(Argv[1], cmdOut);
// strReturn = InstallApp(Argv[1], cmdOut);
// strReturn = UninstallApplication();
// String sPingCheck = SendPing("www.mozilla.org",null);
@ -653,6 +682,24 @@ public class DoCommand {
*/
break;
case ENVRUN:
if (Argc >= 2)
{
String [] theArgs = new String [Argc - 1];
for (int lcv = 1; lcv < Argc; lcv++)
{
theArgs[lcv - 1] = Argv[lcv];
}
strReturn = StartPrg2(theArgs, cmdOut);
}
else
{
strReturn = sErrorPrefix + "Wrong number of arguments for " + Argv[0] + " command!";
}
break;
case EXEC:
case RUN:
if (Argc >= 2)
@ -828,12 +875,28 @@ public class DoCommand {
}
}
public String [] parseCmdLine(String theCmdLine) {
public String [] parseCmdLine2(String theCmdLine)
{
String cmdString;
String workingString;
String workingString2;
String workingString3;
List<String> lst = new ArrayList<String>();
int nLength = theCmdLine.length();
int nFirstSpace = theCmdLine.indexOf(' ');
int nLength = 0;
int nFirstSpace = -1;
// Null cmd line
if (theCmdLine == null)
{
String [] theArgs = new String [1];
theArgs[0] = new String("");
return(theArgs);
}
else
{
nLength = theCmdLine.length();
nFirstSpace = theCmdLine.indexOf(' ');
}
if (nFirstSpace == -1)
{
@ -843,7 +906,134 @@ public class DoCommand {
}
// Get the command
lst.add(new String(theCmdLine.substring(0, nFirstSpace)));
cmdString = new String(theCmdLine.substring(0, nFirstSpace));
lst.add(cmdString);
// Jump past the command and trim
workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
while ((nLength = workingString.length()) > 0)
{
int nEnd = 0;
int nStart = 0;
// if we have a quote
if (workingString.startsWith("\""))
{
// point to the first non quote char
nStart = 1;
// find the matching quote
nEnd = workingString.indexOf('"', nStart);
char prevChar;
while(nEnd != -1)
{
// check to see if the quotation mark has been escaped
prevChar = workingString.charAt(nEnd - 1);
if (prevChar == '\\')
{
// if escaped, point past this quotation mark and find the next
nEnd++;
if (nEnd < nLength)
nEnd = workingString.indexOf('"', nEnd);
else
nEnd = -1;
}
else
break;
}
// there isn't one
if (nEnd == -1)
{
// point at the quote
nStart = 0;
// so find the next space
nEnd = workingString.indexOf(' ', nStart);
// there isn't one of those either
if (nEnd == -1)
nEnd = nLength; // Just grab the rest of the cmdline
}
}
else // no quote so find the next space
{
nEnd = workingString.indexOf(' ', nStart);
// there isn't one of those
if (nEnd == -1)
nEnd = nLength; // Just grab the rest of the cmdline
}
// get the substring
workingString2 = workingString.substring(nStart, nEnd);
// if we have escaped quotes
if (workingString2.contains("\\\""))
{
do
{
// replace escaped quote with embedded quote
workingString3 = workingString2.replace("\\\"", "\"");
workingString2 = workingString3;
}
while(workingString2.contains("\\\""));
}
// add it to the list
lst.add(new String(workingString2));
// if we are dealing with a quote
if (nStart > 0)
nEnd++; // point past the end one
// jump past the substring and trim it
workingString = (workingString.substring(nEnd)).trim();
}
// ok we're done package up the results
int nItems = lst.size();
String [] theArgs = new String [nItems];
for (int lcv = 0; lcv < nItems; lcv++)
{
theArgs[lcv] = lst.get(lcv);
}
return(theArgs);
}
public String [] parseCmdLine(String theCmdLine) {
String cmdString;
String workingString;
String workingString2;
List<String> lst = new ArrayList<String>();
int nLength = 0;
int nFirstSpace = -1;
// Null cmd line
if (theCmdLine == null)
{
String [] theArgs = new String [1];
theArgs[0] = new String("");
return(theArgs);
}
else
{
nLength = theCmdLine.length();
nFirstSpace = theCmdLine.indexOf(' ');
}
if (nFirstSpace == -1)
{
String [] theArgs = new String [1];
theArgs[0] = new String(theCmdLine);
return(theArgs);
}
// Get the command
cmdString = new String(theCmdLine.substring(0, nFirstSpace));
lst.add(cmdString);
// Jump past the command and trim
workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
@ -871,6 +1061,11 @@ public class DoCommand {
if (nEnd == -1)
nEnd = nLength; // Just grab the rest of the cmdline
}
else
{
nStart = 0;
nEnd++;
}
}
else // no quote so find the next space
{
@ -887,8 +1082,8 @@ public class DoCommand {
lst.add(new String(workingString2));
// if we are dealing with a quote
if (nStart > 0)
nEnd++; // point past the end one
// if (nStart > 0)
// nEnd++; // point past the end one
// jump past the substring and trim it
workingString = (workingString.substring(nEnd)).trim();
@ -1116,7 +1311,6 @@ public class DoCommand {
public String StatProcess(String string)
{
String sRet = "";
// ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
int [] nPids = new int [1];
@ -1160,7 +1354,6 @@ public class DoCommand {
public String GetAppRoot(String AppName)
{
String sRet = "";
// Context ctx = SUTAgentAndroid.me.getApplicationContext();
Context ctx = contextWrapper.getApplicationContext();
if (ctx != null)
@ -1234,8 +1427,8 @@ public class DoCommand {
try {
digest = java.security.MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
@ -1420,12 +1613,10 @@ public class DoCommand {
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
@ -1534,12 +1725,6 @@ public class DoCommand {
@SuppressWarnings("unused")
boolean bRet = ftp.completePendingCommand();
outStream.flush();
/*
if (ftp.retrieveFile("pub/mozilla.org/firefox/releases/3.6b4/wince-arm/en-US/firefox-3.6b4.cab", outStream))
{
outStream.flush();
}
*/
outStream.close();
strRet = ftp.getReplyString();
reply = ftp.getReplyCode();
@ -1564,7 +1749,6 @@ public class DoCommand {
}
catch (SocketException e)
{
// TODO Auto-generated catch block
sRet = e.getMessage();
strRet = ftp.getReplyString();
reply = ftp.getReplyCode();
@ -1573,7 +1757,6 @@ public class DoCommand {
}
catch (IOException e)
{
// TODO Auto-generated catch block
sRet = e.getMessage();
strRet = ftp.getReplyString();
reply = ftp.getReplyCode();
@ -1652,7 +1835,6 @@ public class DoCommand {
theArgs[2] = "kill";
String sRet = sErrorPrefix + "Unable to kill " + sProcName + "\n";
// ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
int lcv = 0;
@ -1661,7 +1843,6 @@ public class DoCommand {
for (lcv = 0; lcv < lProcesses.size(); lcv++)
{
// if (lProcesses.get(lcv).processName.contentEquals(sProcName))
if (lProcesses.get(lcv).processName.contains(sProcName))
{
strProcName = lProcesses.get(lcv).processName;
@ -1684,12 +1865,9 @@ public class DoCommand {
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// SUTAgentAndroid.me.finishActivity(SUTAgentAndroid.START_PRG);
// Give the messages a chance to be processed
try {
Thread.sleep(2000);
@ -1698,7 +1876,6 @@ public class DoCommand {
{
e.printStackTrace();
}
// aMgr.restartPackage(strProcName);
break;
}
}
@ -1709,7 +1886,6 @@ public class DoCommand {
lProcesses = aMgr.getRunningAppProcesses();
for (lcv = 0; lcv < lProcesses.size(); lcv++)
{
// if (lProcesses.get(lcv).processName.contentEquals(sProcName))
if (lProcesses.get(lcv).processName.contains(sProcName))
{
sRet = sErrorPrefix + "Unable to kill " + nPID + " " + strProcName + "\n";
@ -1724,12 +1900,9 @@ public class DoCommand {
public boolean IsProcessDead(String sProcName)
{
boolean bRet = false;
// ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
List <ActivityManager.ProcessErrorStateInfo> lProcesses = aMgr.getProcessesInErrorState();
int lcv = 0;
// String strProcName = "";
// int nPID = 0;
if (lProcesses != null)
{
@ -1738,8 +1911,6 @@ public class DoCommand {
if (lProcesses.get(lcv).processName.contentEquals(sProcName) &&
lProcesses.get(lcv).condition != ActivityManager.ProcessErrorStateInfo.NO_ERROR)
{
// strProcName = lProcesses.get(lcv).processName;
// nPID = lProcesses.get(lcv).pid;
bRet = true;
break;
}
@ -1752,7 +1923,6 @@ public class DoCommand {
public String GetProcessInfo()
{
String sRet = "";
// ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
int nProcs = lProcesses.size();
@ -1817,12 +1987,10 @@ public class DoCommand {
public long GetMemoryConfig()
{
// ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
aMgr.getMemoryInfo(outInfo);
long lMem = outInfo.availMem;
// float fMem = (float) lMem / (float)(1024.0 * 1024.0);
return (lMem);
}
@ -1866,12 +2034,10 @@ public class DoCommand {
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
sRet += "reg exception thrown";
e.printStackTrace();
}
@ -1911,25 +2077,76 @@ public class DoCommand {
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
sRet = e.getLocalizedMessage();
e.printStackTrace();
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
sRet = e.getLocalizedMessage();
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
sRet = e.getLocalizedMessage();
e.printStackTrace();
}
return(sRet);
}
public String GetTimeZone()
{
String sRet = "";
TimeZone tz;
tz = TimeZone.getDefault();
Date now = new Date();
sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
return(sRet);
}
public String SetTimeZone(String sTimeZone)
{
String sRet = "Unable to set timezone to " + sTimeZone;
TimeZone tz = null;
AlarmManager amgr = null;
if ((sTimeZone.length() > 0) && (sTimeZone.startsWith("GMT")))
{
amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
if (amgr != null)
amgr.setTimeZone(sTimeZone);
}
else
{
String [] zoneNames = TimeZone.getAvailableIDs();
int nNumMatches = zoneNames.length;
int lcv = 0;
for (lcv = 0; lcv < nNumMatches; lcv++)
{
if (zoneNames[lcv].equalsIgnoreCase(sTimeZone))
break;
}
if (lcv < nNumMatches)
{
amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
if (amgr != null)
amgr.setTimeZone(zoneNames[lcv]);
}
}
if (amgr != null)
{
tz = TimeZone.getDefault();
Date now = new Date();
sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
}
return(sRet);
}
public String GetSystemTime()
{
@ -1943,17 +2160,8 @@ public class DoCommand {
public String SetSystemTime(String sDate, String sTime, OutputStream out)
{
// Debug.waitForDebugger();
String sRet = "";
// Intent prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS);
// prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// contextWrapper.startActivity(prgIntent);
// 2010/09/22
// 15:41:00
// 0123456789012345678
if (((sDate != null) && (sTime != null)) &&
(sDate.contains("/") || sDate.contains(".")) &&
(sTime.contains(":")))
@ -1966,14 +2174,11 @@ public class DoCommand {
int mins = Integer.parseInt(sTime.substring(3,5));
int secs = Integer.parseInt(sTime.substring(6,8));
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Calendar cal = new GregorianCalendar(TimeZone.getDefault());
cal.set(year, month - 1, day, hour, mins, secs);
long lMillisecs = cal.getTime().getTime();
// boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs);
String sM = Long.toString(lMillisecs);
// long lm = 1285175618316L;
String sTest = cal.getTime().toGMTString();
String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3);
String [] theArgs = new String [3];
@ -1996,7 +2201,6 @@ public class DoCommand {
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@ -2045,24 +2249,6 @@ public class DoCommand {
return (sRet);
}
/*
private boolean IsProcRunning(Process pProc)
{
boolean bRet = false;
int nExitCode = 0;
try
{
nExitCode = pProc.exitValue();
}
catch (IllegalThreadStateException z)
{
bRet = true;
}
return(bRet);
}
*/
public String NewKillProc(String sProcId, OutputStream out)
{
@ -2107,9 +2293,6 @@ public class DoCommand {
try
{
pProc = Runtime.getRuntime().exec(theArgs);
// sutErr = pProc.getErrorStream(); // Stderr
// sutIn = pProc.getOutputStream(); // Stdin
// sutOut = pProc.getInputStream(); // Stdout
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();
outThrd.join(5000);
@ -2123,7 +2306,6 @@ public class DoCommand {
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
@ -2133,7 +2315,6 @@ public class DoCommand {
public String GetTmpDir()
{
String sRet = "";
// Context ctx = SUTAgentAndroid.me.getApplicationContext();
Context ctx = contextWrapper.getApplicationContext();
File dir = ctx.getFilesDir();
ctx = null;
@ -2245,7 +2426,6 @@ public class DoCommand {
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
@ -2269,7 +2449,6 @@ public class DoCommand {
outThrd.start();
outThrd.join(60000);
int nRet = pProc.exitValue();
// boolean bRet = outThrd.isAlive();
sRet = "\nuninst complete [" + nRet + "]";
}
catch (IOException e)
@ -2403,7 +2582,6 @@ public class DoCommand {
{
String sRet = "";
// Context ctx = SUTAgentAndroid.me.getApplicationContext();
Context ctx = contextWrapper.getApplicationContext();
PackageManager pm = ctx.getPackageManager();
@ -2435,17 +2613,12 @@ public class DoCommand {
try
{
contextWrapper.startActivity(prgIntent);
// Thread.sleep(5000);
sRet = "exit";
}
catch(ActivityNotFoundException anf)
{
anf.printStackTrace();
}
// catch (InterruptedException e)
// {
// e.printStackTrace();
// }
ctx = null;
return (sRet);
@ -2458,7 +2631,6 @@ public class DoCommand {
String sUrl = "";
String sRedirFileName = "";
// Context ctx = SUTAgentAndroid.me.getApplicationContext();
Context ctx = contextWrapper.getApplicationContext();
PackageManager pm = ctx.getPackageManager();
@ -2486,7 +2658,7 @@ public class DoCommand {
if (sArgs.length > 1)
{
if (sArgs[0].contains("android.browser"))
// if (sArgs[0].contains("android.browser"))
prgIntent.setAction(Intent.ACTION_VIEW);
if (sArgs[0].contains("fennec"))
@ -2530,10 +2702,7 @@ public class DoCommand {
try
{
// ctx.startActivity(prgIntent);
contextWrapper.startActivity(prgIntent);
// SUTAgentAndroid.me.startActivity(prgIntent);
// SUTAgentAndroid.me.startActivityForResult(prgIntent, SUTAgentAndroid.START_PRG);
}
catch(ActivityNotFoundException anf)
{
@ -2551,12 +2720,11 @@ public class DoCommand {
try
{
pProc = Runtime.getRuntime().exec(progArray);
sutErr = pProc.getErrorStream(); // Stderr
sutIn = pProc.getOutputStream(); // Stdin
sutOut = pProc.getInputStream(); // Stdout
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();
outThrd.join(10000);
int nRetCode = pProc.exitValue();
sRet = "return code [" + nRetCode + "]";
}
catch (IOException e)
{
@ -2564,8 +2732,147 @@ public class DoCommand {
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
sRet = "Timed out!";
}
return (sRet);
}
/*
@SuppressWarnings("unchecked")
public static void set(String key, String value) throws Exception
{
Class[] classes = Collections.class.getDeclaredClasses();
Map env = System.getenv();
for(Class cl : classes)
{
if("java.util.Collections$UnmodifiableMap".equals(cl.getName()))
{
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.put(key, value);
}
}
}
*/
public String StartPrg2(String [] progArray, OutputStream out)
{
String sRet = "";
int nArraySize = 0;
int nArgs = progArray.length - 1; // 1st arg is the environment string
int lcv = 0;
int temp = 0;
String sEnvString = progArray[0];
// Set up command line args stripping off the environment string
String [] theArgs = new String [nArgs];
for (lcv = 0; lcv < nArgs; lcv++)
{
theArgs[lcv] = progArray[lcv + 1];
}
try
{
String [] envStrings = sEnvString.split(",");
Map<String, String> newEnv = new HashMap<String, String>();
for (lcv = 0; lcv < envStrings.length; lcv++)
{
temp = envStrings[lcv].indexOf("=");
if (temp > 0)
{
newEnv.put( envStrings[lcv].substring(0, temp),
envStrings[lcv].substring(temp + 1, envStrings[lcv].length()));
}
}
Map<String, String> sysEnv = System.getenv();
nArraySize = sysEnv.size();
for (Map.Entry<String, String> entry : newEnv.entrySet())
{
if (!sysEnv.containsKey(entry.getKey()))
{
nArraySize++;
}
}
String[] envArray = new String[nArraySize];
int i = 0;
int offset;
String sKey = "";
String sValue = "";
for (Map.Entry<String, String> entry : sysEnv.entrySet())
{
sKey = entry.getKey();
if (newEnv.containsKey(sKey))
{
sValue = newEnv.get(sKey);
if ((offset = sValue.indexOf("$" + sKey)) != -1)
{
envArray[i++] = sKey +
"=" +
sValue.substring(0, offset) +
entry.getValue() +
sValue.substring(offset + sKey.length() + 1);
}
else
envArray[i++] = sKey + "=" + sValue;
newEnv.remove(sKey);
}
else
envArray[i++] = entry.getKey() + "=" + entry.getValue();
}
for (Map.Entry<String, String> entry : newEnv.entrySet())
{
envArray[i++] = entry.getKey() + "=" + entry.getValue();
}
pProc = Runtime.getRuntime().exec(theArgs, envArray);
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();
outThrd.join(10000);
int nRetCode = pProc.exitValue();
sRet = "return code [" + nRetCode + "]";
}
catch(UnsupportedOperationException e)
{
if (e != null)
e.printStackTrace();
}
catch(ClassCastException e)
{
if (e != null)
e.printStackTrace();
}
catch(IllegalArgumentException e)
{
if (e != null)
e.printStackTrace();
}
catch(NullPointerException e)
{
if (e != null)
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
sRet = "Timed out!";
}
return (sRet);
@ -2603,55 +2910,58 @@ public class DoCommand {
*/
private String PrintUsage()
{
String sRet = "run [executable] [args] - start program no wait\n" +
"exec [executable] [args] - start program wait\n" +
"fire [executable] [args] - start program no wait\n" +
"arun [executable] [args] - start program no wait\n" +
"kill [program name] - kill program no path\n" +
"killall - kill all processes started\n" +
"ps - list of running processes\n" +
"info - list of device info\n" +
" [os] - os version for device\n" +
" [id] - unique identifier for device\n" +
" [uptime] - uptime for device\n" +
" [systime] - current system time on device\n" +
" [screen] - width, height and bits per pixel for device\n" +
" [memory] - physical, free, available, storage memory for device\n" +
" [processes] - list of running processes see 'ps'\n" +
"deadman timeout - set the duration for the deadman timer\n" +
"alrt [on/off] - start or stop sysalert behavior\n" +
"disk [arg] - prints disk space info\n" +
"cp file1 file2 - copy file1 to file2 on device\n" +
"time file - timestamp for file on device\n" +
"hash file - generate hash for file on device\n" +
"cd directory - change cwd on device\n" +
"cat file - cat file on device\n" +
"cwd - display cwd on device\n" +
"mv file1 file2 - move file1 to file2 on device\n" +
"push filename - push file to device\n" +
"rm file - delete file on device\n" +
"rmdr directory - delete directory on device even if not empty\n" +
"mkdr directory - create directory on device\n" +
"dirw directory - tests whether the directory is writable on the device\n" +
"stat processid - stat process on device\n" +
"dead processid - print whether the process is alive or hung on device\n" +
"mems - dump memory stats on device\n" +
"ls - print directory on device\n" +
"tmpd - print temp directory on device\n" +
"ping [hostname/ipaddr] - ping a network device\n" +
"unzp zipfile destdir - unzip the zipfile into the destination dir\n" +
"zip zipfile src - zip the source file/dir into zipfile\n" +
"rebt - reboot device\n" +
"inst /path/filename.apk - install the referenced apk file\n" +
"uninst packagename - uninstall the referenced package\n" +
"updt pkgname pkgfile - unpdate the referenced package\n" +
"clok - the current device time expressed as the number of millisecs since epoch\n" +
"settime date time - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
"rebt - reboot device\n" +
"quit - disconnect SUTAgent\n" +
"exit - close SUTAgent\n" +
"ver - SUTAgent version\n" +
"help - you're reading it";
String sRet =
"run [executable] [args] - start program no wait\n" +
"exec [executable] [args] - start program wait\n" +
"fire [executable] [args] - start program no wait\n" +
"envrun [env pairs] [cmdline] - start program no wait\n" +
"kill [program name] - kill program no path\n" +
"killall - kill all processes started\n" +
"ps - list of running processes\n" +
"info - list of device info\n" +
" [os] - os version for device\n" +
" [id] - unique identifier for device\n" +
" [uptime] - uptime for device\n" +
" [systime] - current system time on device\n" +
" [screen] - width, height and bits per pixel for device\n" +
" [memory] - physical, free, available, storage memory for device\n" +
" [processes] - list of running processes see 'ps'\n" +
"deadman timeout - set the duration for the deadman timer\n" +
"alrt [on/off] - start or stop sysalert behavior\n" +
"disk [arg] - prints disk space info\n" +
"cp file1 file2 - copy file1 to file2 on device\n" +
"time file - timestamp for file on device\n" +
"hash file - generate hash for file on device\n" +
"cd directory - change cwd on device\n" +
"cat file - cat file on device\n" +
"cwd - display cwd on device\n" +
"mv file1 file2 - move file1 to file2 on device\n" +
"push filename - push file to device\n" +
"rm file - delete file on device\n" +
"rmdr directory - delete directory on device even if not empty\n" +
"mkdr directory - create directory on device\n" +
"dirw directory - tests whether the directory is writable on the device\n" +
"stat processid - stat process on device\n" +
"dead processid - print whether the process is alive or hung on device\n" +
"mems - dump memory stats on device\n" +
"ls - print directory on device\n" +
"tmpd - print temp directory on device\n" +
"ping [hostname/ipaddr] - ping a network device\n" +
"unzp zipfile destdir - unzip the zipfile into the destination dir\n" +
"zip zipfile src - zip the source file/dir into zipfile\n" +
"rebt - reboot device\n" +
"inst /path/filename.apk - install the referenced apk file\n" +
"uninst packagename - uninstall the referenced package\n" +
"updt pkgname pkgfile - unpdate the referenced package\n" +
"clok - the current device time expressed as the number of millisecs since epoch\n" +
"settime date time - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
"tzset timezone - sets the device timezone format is GMTxhh:mm x = +/- or a recognized Olsen string\n" +
"tzget - returns the current timezone set on the device\n" +
"rebt - reboot device\n" +
"quit - disconnect SUTAgent\n" +
"exit - close SUTAgent\n" +
"ver - SUTAgent version\n" +
"help - you're reading it";
return (sRet);
}
}

View File

@ -391,7 +391,7 @@ public class SUTAgentAndroid extends Activity
{
sb.append("Overheated ");
sb.append((((float)(nBatteryTemp))/10));
sb.append("(°C)");
sb.append("(C)");
}
else
{

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

@ -69,8 +69,7 @@
#
#######################################################################
# Defines
#
CVS = cvs
comma := ,
CWD := $(CURDIR)
@ -107,7 +106,6 @@ endif
PERL ?= perl
PYTHON ?= python
RUN_AUTOCONF_LOCALLY = 1
CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
ifdef CONFIG_GUESS_SCRIPT
CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
@ -170,7 +168,6 @@ CONFIGURES += $(TOPSRCDIR)/js/src/configure
#######################################################################
# Rules
#
# The default rule is build
build::
@ -272,7 +269,6 @@ else
CONFIG_STATUS = $(wildcard $(OBJDIR)/config.status)
CONFIG_CACHE = $(wildcard $(OBJDIR)/config.cache)
ifdef RUN_AUTOCONF_LOCALLY
EXTRA_CONFIG_DEPS := \
$(TOPSRCDIR)/aclocal.m4 \
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
@ -282,7 +278,6 @@ EXTRA_CONFIG_DEPS := \
$(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
@echo Generating $@ using autoconf
cd $(@D); $(AUTOCONF)
endif
CONFIG_STATUS_DEPS := \
$(wildcard $(CONFIGURES)) \
@ -290,8 +285,7 @@ CONFIG_STATUS_DEPS := \
$(TOPSRCDIR)/.mozconfig.mk \
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
$(wildcard $(TOPSRCDIR)/config/chrome-versions.sh) \
$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
$(NULL)
# configure uses the program name to determine @srcdir@. Calling it without
@ -303,10 +297,6 @@ else
CONFIGURE = $(TOPSRCDIR)/configure
endif
ifdef MOZ_TOOLS
CONFIGURE = $(TOPSRCDIR)/configure
endif
configure-files: $(CONFIGURES)
configure:: configure-files
@ -417,4 +407,4 @@ echo-variable-%:
# in parallel.
.NOTPARALLEL:
.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all
.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all upload sdk

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@
@ -696,3 +702,16 @@ ANDROID_TOOLS = @ANDROID_TOOLS@
ANDROID_VERSION = @ANDROID_VERSION@
JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
# We only want to do the pymake sanity on Windows, other os's can cope
ifeq (,$(filter-out WINNT WINCE,$(HOST_OS_ARCH)))
# Ensure invariants between GNU Make and pymake
# Checked here since we want the sane error in a file that
# actually can be found regardless of path-style.
ifeq (_:,$(.PYMAKE)_$(findstring :,$(srcdir)))
$(error Windows-style srcdir being used with GNU make. Did you mean to run $(topsrcdir)/build/pymake/make.py instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
endif
ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(srcdir))))
$(error MSYS-style srcdir being used with Pymake. Did you mean to run GNU Make instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
endif
endif # Windows

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

@ -171,8 +171,8 @@ SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-inter
libs::
$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
$(testxpcobjdir)/all-test-dirs.list \
$(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
$(testxpcobjdir)/all-test-dirs.list \
$(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
testxpcsrcdir = $(topsrcdir)/testing/xpcshell
@ -180,39 +180,39 @@ testxpcsrcdir = $(topsrcdir)/testing/xpcshell
# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
xpcshell-tests:
$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
$(EXTRA_TEST_ARGS) \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
$(EXTRA_TEST_ARGS) \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
# Execute a single test, specified in $(SOLO_FILE), but don't automatically
# start the test. Instead, present the xpcshell prompt so the user can
# attach a debugger and then start the test.
check-interactive:
$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--test-path=$(SOLO_FILE) \
--profile-name=$(MOZ_APP_NAME) \
--interactive \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--test-path=$(SOLO_FILE) \
--profile-name=$(MOZ_APP_NAME) \
--interactive \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
# Execute a single test, specified in $(SOLO_FILE)
check-one:
$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--test-path=$(SOLO_FILE) \
--profile-name=$(MOZ_APP_NAME) \
--verbose \
$(EXTRA_TEST_ARGS) \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-I$(topsrcdir)/build \
$(testxpcsrcdir)/runxpcshelltests.py \
--symbols-path=$(DIST)/crashreporter-symbols \
--test-path=$(SOLO_FILE) \
--profile-name=$(MOZ_APP_NAME) \
--verbose \
$(EXTRA_TEST_ARGS) \
$(DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
endif # XPCSHELL_TESTS
@ -846,7 +846,7 @@ ifdef MODULE_NAME
@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
endif
endif # BUILD_STATIC_LIBS
else # !IS_COMPONENT
else # !IS_COMPONENT
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
endif # IS_COMPONENT
endif # EXPORT_LIBRARY
@ -874,7 +874,7 @@ endif # _LIBDIRS
endif # _LIBNAME_RELATIVE_PATHS
# Dependancies which, if modified, should cause everything to rebuild
# Dependencies which, if modified, should cause everything to rebuild
GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
##############################################
@ -1198,7 +1198,7 @@ CLEANUP2 := true
endif
SUB_LOBJS = $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
endif # EXPAND_FAKELIBS
endif # SHARED_LIBARY_LIBS
endif # SHARED_LIBRARY_LIBS
endif
ifdef MOZILLA_PROBE_LIBS
PROBE_LOBJS = $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
@ -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) $@
@ -1578,7 +1562,7 @@ normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
else
# assume MSYS
# We use 'pwd -W' to get DOS form of the path. However, since the given path
# could be a file or a nonexistent path, we cannot call 'pwd -W' directly
# could be a file or a non-existent path, we cannot call 'pwd -W' directly
# on the path. Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
# on it, then merge with the rest of the path.
root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")

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

@ -1,4 +1,3 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -12,19 +11,18 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
* The Original Code is Mozilla.org code.
*
* The Initial Developer of the Original Code is
* Crocodile Clips Ltd..
* Portions created by the Initial Developer are Copyright (C) 2001
* Ms2ger <Ms2ger@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* 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
@ -36,12 +34,24 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_SVGPATHSEGLIST_H__
#define __NS_SVGPATHSEGLIST_H__
#ifndef mozilla_dom_FromParser_h
#define mozilla_dom_FromParser_h
#include "nsIDOMSVGPathSegList.h"
namespace mozilla {
namespace dom {
nsresult
NS_NewSVGPathSegList(nsIDOMSVGPathSegList** result);
/**
* Constants for passing as aFromParser
*/
enum FromParser {
NOT_FROM_PARSER = 0,
FROM_PARSER_NETWORK = 1,
FROM_PARSER_DOCUMENT_WRITE = 1 << 1,
FROM_PARSER_FRAGMENT = 1 << 2,
FROM_PARSER_XSLT = 1 << 3
};
#endif //__NS_SVGPATHSEGLIST_H__
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FromParser_h

View File

@ -84,8 +84,9 @@ $(NULL)
EXPORTS_NAMESPACES = mozilla/dom
EXPORTS_mozilla/dom = \
Element.h \
$(NULL)
Element.h \
FromParser.h \
$(NULL)
ifndef DISABLE_XFORMS_HOOKS
EXPORTS += nsIXFormsUtilityService.h

View File

@ -42,6 +42,7 @@
#include "nscore.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/FromParser.h"
/**
* Functions to create content, to be used only inside Gecko
@ -56,17 +57,10 @@ class imgIRequest;
class nsNodeInfoManager;
class nsGenericHTMLElement;
/**
* Constants for passing as aFromParser
*/
#define NS_NOT_FROM_PARSER 0
#define NS_FROM_PARSER_NETWORK 1
#define NS_FROM_PARSER_DOCUMENT_WRITE (1 << 1)
#define NS_FROM_PARSER_FRAGMENT (1 << 2)
nsresult
NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser);
already_AddRefed<nsINodeInfo> aNodeInfo,
mozilla::dom::FromParser aFromParser);
nsresult
NS_NewXMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
@ -109,13 +103,13 @@ NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
nsresult
NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
PRUint32 aFromParser);
mozilla::dom::FromParser aFromParser);
// First argument should be nsHTMLTag, but that adds dependency to parser
// for a bunch of files.
already_AddRefed<nsGenericHTMLElement>
CreateHTMLElement(PRUint32 aNodeType, already_AddRefed<nsINodeInfo> aNodeInfo,
PRUint32 aFromParser);
mozilla::dom::FromParser aFromParser);
#ifdef MOZ_MATHML
nsresult
@ -134,7 +128,7 @@ NS_TrustedNewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNod
#ifdef MOZ_SVG
nsresult
NS_NewSVGElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
PRUint32 aFromParser);
mozilla::dom::FromParser aFromParser);
#endif
nsresult

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.

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