mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Merge mozilla-central to tracemonkey.
This commit is contained in:
commit
48cc92a4b0
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() ?
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
68
accessible/tests/mochitest/test_elm_landmarks.html
Normal file
68
accessible/tests/mochitest/test_elm_landmarks.html
Normal 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>
|
@ -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>
|
||||
|
@ -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 \
|
||||
|
370
accessible/tests/mochitest/treeupdate/test_doc.html
Normal file
370
accessible/tests/mochitest/treeupdate/test_doc.html
Normal 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>
|
@ -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);
|
||||
|
@ -82,6 +82,7 @@ endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
|
||||
DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
|
||||
DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
|
||||
endif
|
||||
|
||||
|
@ -104,6 +104,7 @@ body[dir="rtl"] #searchEngineLinks {
|
||||
}
|
||||
|
||||
#searchText {
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;"
|
||||
|
409
browser/base/content/browser-appmenu.inc
Normal file
409
browser/base/content/browser-appmenu.inc
Normal 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="©Button.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>
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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="©Button.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"
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
@ -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
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
13
browser/base/content/test/browser_bug565575.js
Normal file
13
browser/base/content/test/browser_bug565575.js
Normal 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();
|
||||
}
|
296
browser/base/content/test/browser_contentAreaClick.js
Normal file
296
browser/base/content/test/browser_contentAreaClick.js
Normal 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();
|
||||
}
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
101
browser/base/content/test/tabview/browser_tabview_bug595521.js
Normal file
101
browser/base/content/test/tabview/browser_tabview_bug595521.js
Normal 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);
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
},
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -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));
|
||||
},
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
})
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
8
browser/components/places/tests/browser/frameLeft.html
Normal file
8
browser/components/places/tests/browser/frameLeft.html
Normal 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>
|
8
browser/components/places/tests/browser/frameRight.html
Normal file
8
browser/components/places/tests/browser/frameRight.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Right Frame</title>
|
||||
</head>
|
||||
<body>
|
||||
This is the right frame.
|
||||
</body>
|
||||
</html>
|
9
browser/components/places/tests/browser/framedPage.html
Normal file
9
browser/components/places/tests/browser/framedPage.html
Normal 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>
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -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);"/>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
276
browser/components/sessionstore/test/browser/browser_589246.js
Normal file
276
browser/components/sessionstore/test/browser/browser_589246.js
Normal 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 O’Shannessy <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();
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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>
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ public class SUTAgentAndroid extends Activity
|
||||
{
|
||||
sb.append("Overheated ");
|
||||
sb.append((((float)(nBatteryTemp))/10));
|
||||
sb.append("(°C)");
|
||||
sb.append("(C)");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -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
|
||||
|
16
client.mk
16
client.mk
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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|")
|
||||
|
@ -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
|
||||
|
131
configure.in
131
configure.in
@ -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'
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user