Merge with mozilla-central.
|
@ -58,7 +58,7 @@ interface nsIAccessibleRelation;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(004b6882-2df1-49df-bb5f-0fb81a5b1edf)]
|
||||
[scriptable, uuid(c7520419-87ec-42bc-98cc-04c0bf173530)]
|
||||
interface nsIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -199,9 +199,25 @@ interface nsIAccessible : nsISupports
|
|||
* current accessible will be returned.
|
||||
* If the point is in neither the current accessible or a child, then
|
||||
* null will be returned.
|
||||
*
|
||||
* @param x screen's x coordinate
|
||||
* @param y screen's y coordinate
|
||||
* @return the deepest accessible child containing the given point
|
||||
*/
|
||||
nsIAccessible getChildAtPoint(in long x, in long y);
|
||||
|
||||
/**
|
||||
* Deepest accessible child which contains the coordinate at (x, y) in screen
|
||||
* pixels. If the point is in the current accessible but not in a child, the
|
||||
* current accessible will be returned. If the point is in neither the current
|
||||
* accessible or a child, then null will be returned.
|
||||
*
|
||||
* @param x screen's x coordinate
|
||||
* @param y screen's y coordinate
|
||||
* @return the deepest accessible child containing the given point
|
||||
*/
|
||||
nsIAccessible getDeepestChildAtPoint(in long x, in long y);
|
||||
|
||||
/**
|
||||
* Nth accessible child using zero-based index or last child if index less than zero
|
||||
*/
|
||||
|
|
|
@ -608,16 +608,17 @@ nsAccessNode::GetChildNodeAt(PRInt32 aChildNum, nsIAccessNode **aAccessNode)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessNode::GetComputedStyleValue(const nsAString& aPseudoElt, const nsAString& aPropertyName, nsAString& aValue)
|
||||
nsAccessNode::GetComputedStyleValue(const nsAString& aPseudoElt,
|
||||
const nsAString& aPropertyName,
|
||||
nsAString& aValue)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
|
||||
if (!domElement) {
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
|
||||
GetComputedStyleDeclaration(aPseudoElt, domElement, getter_AddRefs(styleDecl));
|
||||
GetComputedStyleDeclaration(aPseudoElt, mDOMNode, getter_AddRefs(styleDecl));
|
||||
NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
return styleDecl->GetPropertyValue(aPropertyName, aValue);
|
||||
}
|
||||
|
||||
|
@ -627,15 +628,13 @@ nsAccessNode::GetComputedStyleCSSValue(const nsAString& aPseudoElt,
|
|||
nsIDOMCSSPrimitiveValue **aCSSValue)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCSSValue);
|
||||
|
||||
*aCSSValue = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
|
||||
if (!domElement)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
|
||||
GetComputedStyleDeclaration(aPseudoElt, domElement,
|
||||
GetComputedStyleDeclaration(aPseudoElt, mDOMNode,
|
||||
getter_AddRefs(styleDecl));
|
||||
NS_ENSURE_STATE(styleDecl);
|
||||
|
||||
|
@ -646,28 +645,29 @@ nsAccessNode::GetComputedStyleCSSValue(const nsAString& aPseudoElt,
|
|||
return CallQueryInterface(cssValue, aCSSValue);
|
||||
}
|
||||
|
||||
void nsAccessNode::GetComputedStyleDeclaration(const nsAString& aPseudoElt,
|
||||
nsIDOMElement *aElement,
|
||||
nsIDOMCSSStyleDeclaration **aCssDecl)
|
||||
void
|
||||
nsAccessNode::GetComputedStyleDeclaration(const nsAString& aPseudoElt,
|
||||
nsIDOMNode *aNode,
|
||||
nsIDOMCSSStyleDeclaration **aCssDecl)
|
||||
{
|
||||
*aCssDecl = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> domElement = nsAccUtils::GetDOMElementFor(aNode);
|
||||
if (!domElement)
|
||||
return;
|
||||
|
||||
// Returns number of items in style declaration
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(domElement);
|
||||
nsCOMPtr<nsIDocument> doc = content->GetDocument();
|
||||
if (!doc) {
|
||||
if (!doc)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMViewCSS> viewCSS(do_QueryInterface(doc->GetWindow()));
|
||||
if (!viewCSS) {
|
||||
if (!viewCSS)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
viewCSS->GetComputedStyle(aElement, aPseudoElt, getter_AddRefs(cssDecl));
|
||||
viewCSS->GetComputedStyle(domElement, aPseudoElt, getter_AddRefs(cssDecl));
|
||||
NS_IF_ADDREF(*aCssDecl = cssDecl);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ class nsAccessNode: public nsIAccessNode,
|
|||
static already_AddRefed<nsIPresShell> GetPresShellFor(nsIDOMNode *aStartNode);
|
||||
|
||||
static void GetComputedStyleDeclaration(const nsAString& aPseudoElt,
|
||||
nsIDOMElement *aElement,
|
||||
nsIDOMNode *aNode,
|
||||
nsIDOMCSSStyleDeclaration **aCssDecl);
|
||||
|
||||
already_AddRefed<nsRootAccessible> GetRootAccessible();
|
||||
|
|
|
@ -1104,10 +1104,10 @@ NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIAccessible getChildAtPoint (in long x, in long y); */
|
||||
// nsIAccessible getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
|
@ -1205,29 +1205,52 @@ nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
// Fall through -- the point is in this accessible but not in a child
|
||||
// We are allowed to return |this| as the answer
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
while (PR_TRUE) {
|
||||
accessible->GetParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
// Reached the top of the hierarchy
|
||||
// these bounds were inside an accessible that is not a descendant of this one
|
||||
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
|
||||
return NS_OK;
|
||||
}
|
||||
if (parent == this) {
|
||||
// We reached |this|, so |accessible| is the
|
||||
// child we want to return
|
||||
break;
|
||||
}
|
||||
accessible.swap(parent);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aAccessible = accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessible getChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
nsresult rv = GetDeepestChildAtPoint(aX, aY, aAccessible);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!*aAccessible)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAccessible> parent, accessible(*aAccessible);
|
||||
while (PR_TRUE) {
|
||||
accessible->GetParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
NS_ASSERTION(PR_FALSE,
|
||||
"Obtained accessible isn't a child of this accessible.");
|
||||
// Reached the top of the hierarchy. These bounds were inside an
|
||||
// accessible that is not a descendant of this one.
|
||||
|
||||
// If we can't find the point in a child, we will return the fallback
|
||||
// answer: we return |this| if the point is within it, otherwise nsnull.
|
||||
PRInt32 x, y, width, height;
|
||||
GetBounds(&x, &y, &width, &height);
|
||||
if (aX >= x && aX < x + width && aY >= y && aY < y + height)
|
||||
NS_ADDREF(*aAccessible = this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (parent == this) {
|
||||
// We reached |this|, so |accessible| is the child we want to return.
|
||||
NS_ADDREF(*aAccessible = accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
accessible.swap(parent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -247,8 +247,17 @@ nsCaretAccessible::NormalSelectionChanged(nsIDOMDocument *aDoc,
|
|||
return NS_OK; // Don't fire caret moves until doc loaded
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> nodeWithCaret = focusNode;
|
||||
// Get focused node.
|
||||
nsCOMPtr<nsIContent> focusContainer(do_QueryInterface(focusNode));
|
||||
if (focusContainer && focusContainer->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
PRInt32 focusOffset = 0;
|
||||
aSel->GetFocusOffset(&focusOffset);
|
||||
|
||||
nsCOMPtr<nsIContent> focusContent = focusContainer->GetChildAt(focusOffset);
|
||||
focusNode = do_QueryInterface(focusContent);
|
||||
}
|
||||
|
||||
// Get relevant accessible for the focused node.
|
||||
nsCOMPtr<nsIAccessibleText> textAcc;
|
||||
while (focusNode) {
|
||||
// Make sure to get the correct starting node for selection events inside XBL content trees
|
||||
|
@ -307,6 +316,16 @@ nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc,
|
|||
if (!targetNode)
|
||||
return NS_OK;
|
||||
|
||||
// Get focused node.
|
||||
nsCOMPtr<nsIContent> focusContainer(do_QueryInterface(targetNode));
|
||||
if (focusContainer && focusContainer->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
PRInt32 focusOffset = 0;
|
||||
aSel->GetFocusOffset(&focusOffset);
|
||||
|
||||
nsCOMPtr<nsIContent> focusContent = focusContainer->GetChildAt(focusOffset);
|
||||
targetNode = do_QueryInterface(focusContent);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible =
|
||||
nsAccessNode::GetDocAccessibleFor(targetNode);
|
||||
NS_ENSURE_STATE(docAccessible);
|
||||
|
|
|
@ -67,6 +67,7 @@ nsOuterDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessible::getChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
|
@ -85,6 +86,23 @@ nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
return GetFirstChild(aAccessible); // Always return the inner doc unless bounds outside of it
|
||||
}
|
||||
|
||||
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsOuterDocAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
// Call getDeepestChildAtPoint on the fist child accessible of the outer
|
||||
// document accessible if the given point is inside of outer document.
|
||||
nsCOMPtr<nsIAccessible> childAcc;
|
||||
nsresult rv = GetChildAtPoint(aX, aY, getter_AddRefs(childAcc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!childAcc)
|
||||
return NS_OK;
|
||||
|
||||
return childAcc->GetDeepestChildAtPoint(aX, aY, aAccessible);
|
||||
}
|
||||
|
||||
void nsOuterDocAccessible::CacheChildren()
|
||||
{
|
||||
// An outer doc accessible usually has 1 nsDocAccessible child,
|
||||
|
|
|
@ -54,8 +54,12 @@ class nsOuterDocAccessible : public nsAccessibleWrap
|
|||
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
void CacheChildren();
|
||||
nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
|
|
|
@ -1138,10 +1138,12 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
|
|||
for (PRInt32 rowCount = 0; rowCount < rows; rowCount ++) {
|
||||
nsCOMPtr<nsIDOMNode> rowNode;
|
||||
nodeList->Item(rowCount, getter_AddRefs(rowNode));
|
||||
nsCOMPtr<nsIDOMElement> rowElement = do_QueryInterface(rowNode);
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
|
||||
GetComputedStyleDeclaration(EmptyString(), rowElement, getter_AddRefs(styleDecl));
|
||||
GetComputedStyleDeclaration(EmptyString(), rowNode,
|
||||
getter_AddRefs(styleDecl));
|
||||
NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
|
||||
|
||||
lastRowColor = color;
|
||||
styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"), color);
|
||||
if (rowCount > 0 && PR_FALSE == lastRowColor.Equals(color)) {
|
||||
|
|
|
@ -104,7 +104,7 @@ nsHTMLTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes
|
|||
GetRole(&role);
|
||||
if (role == nsIAccessibleRole::ROLE_STATICTEXT) {
|
||||
nsAutoString oldValueUnused;
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("static"),
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
|
||||
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||
}
|
||||
|
||||
|
|
|
@ -293,22 +293,17 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
{
|
||||
if (mIsExpired)
|
||||
return nil;
|
||||
|
||||
|
||||
// Convert from cocoa's coordinate system to gecko's. According to the docs
|
||||
// the point we're given is guaranteed to be bottom-left screen coordinates.
|
||||
nsPoint geckoPoint;
|
||||
ConvertCocoaToGeckoPoint (point, geckoPoint);
|
||||
|
||||
// start iterating as deep down as we can on this point, with the current accessible as the root.
|
||||
// as soon as GetChildAtPoint() returns null, or can't descend further (without getting the same accessible again)
|
||||
// we stop.
|
||||
nsCOMPtr<nsIAccessible> deepestFoundChild, newChild(mGeckoAccessible);
|
||||
do {
|
||||
deepestFoundChild = newChild;
|
||||
deepestFoundChild->GetChildAtPoint((PRInt32)geckoPoint.x, (PRInt32)geckoPoint.y, getter_AddRefs(newChild));
|
||||
} while (newChild && newChild.get() != deepestFoundChild.get());
|
||||
nsCOMPtr<nsIAccessible> deepestFoundChild;
|
||||
mGeckoAccessible->GetDeepestChildAtPoint((PRInt32)geckoPoint.x,
|
||||
(PRInt32)geckoPoint.y,
|
||||
getter_AddRefs(deepestFoundChild));
|
||||
|
||||
|
||||
// if we found something, return its native accessible.
|
||||
if (deepestFoundChild) {
|
||||
mozAccessible *nativeChild = GetNativeFromGeckoAccessible(deepestFoundChild);
|
||||
|
|
|
@ -310,13 +310,13 @@ STDMETHODIMP nsAccessNodeWrap::get_computedStyle(
|
|||
/* [out] */ unsigned short __RPC_FAR *aNumStyleProperties)
|
||||
{
|
||||
__try{
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
|
||||
if (!domElement)
|
||||
return E_FAIL;
|
||||
|
||||
*aNumStyleProperties = 0;
|
||||
|
||||
if (IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
GetComputedStyleDeclaration(EmptyString(), domElement, getter_AddRefs(cssDecl));
|
||||
GetComputedStyleDeclaration(EmptyString(), mDOMNode, getter_AddRefs(cssDecl));
|
||||
NS_ENSURE_TRUE(cssDecl, E_FAIL);
|
||||
|
||||
PRUint32 length;
|
||||
|
@ -347,12 +347,11 @@ STDMETHODIMP nsAccessNodeWrap::get_computedStyleForProperties(
|
|||
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues)
|
||||
{
|
||||
__try {
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
|
||||
if (!domElement)
|
||||
if (IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
|
||||
GetComputedStyleDeclaration(EmptyString(), domElement, getter_AddRefs(cssDecl));
|
||||
GetComputedStyleDeclaration(EmptyString(), mDOMNode, getter_AddRefs(cssDecl));
|
||||
NS_ENSURE_TRUE(cssDecl, E_FAIL);
|
||||
|
||||
PRUint32 index;
|
||||
|
|
|
@ -355,6 +355,15 @@ nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
return GetCachedTreeitemAccessible(row, column, aAccessible);
|
||||
}
|
||||
|
||||
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
// Call getChildAtPoint until tree doesn't support complex content.
|
||||
return GetChildAtPoint(aX, aY, aAccessible);
|
||||
}
|
||||
|
||||
// Ask treeselection to get all selected children
|
||||
NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
|
||||
{
|
||||
|
|
|
@ -71,8 +71,11 @@ public:
|
|||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
|
||||
static nsresult GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32 *aCount);
|
||||
|
|
|
@ -53,18 +53,21 @@ _TEST_FILES =\
|
|||
nsIAccessible_name.css \
|
||||
nsIAccessible_name.js \
|
||||
nsIAccessible_name.xbl \
|
||||
nsIAccessible_selects.js \
|
||||
nsIAccessibleEditableText.js \
|
||||
test_aria_activedescendant.html \
|
||||
test_aria_role_article.html \
|
||||
test_bug368835.xul \
|
||||
test_bug420863.html \
|
||||
test_cssattrs.html \
|
||||
test_events_caretmove.html \
|
||||
test_groupattrs.xul \
|
||||
$(warning test_table_indexes.html temporarily disabled) \
|
||||
test_nsIAccessible_actions.html \
|
||||
test_nsIAccessible_actions.xul \
|
||||
test_nsIAccessible_name.html \
|
||||
test_nsIAccessible_name.xul \
|
||||
test_nsIAccessible_selects.html \
|
||||
test_nsIAccessible_focus.html \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleEditableText.html \
|
||||
|
@ -77,6 +80,7 @@ _TEST_FILES =\
|
|||
test_nsIAccessibleTable_3.html \
|
||||
test_nsIAccessibleTable_4.html \
|
||||
test_nsIAccessibleTable_listboxes.xul \
|
||||
test_nsIAccessNode_utils.html \
|
||||
test_nsOuterDocAccessible.html \
|
||||
test_textattrs.html \
|
||||
test_textboxes.html \
|
||||
|
|
|
@ -30,6 +30,28 @@ const nsIObserverService = Components.interfaces.nsIObserverService;
|
|||
|
||||
const nsIDOMNode = Components.interfaces.nsIDOMNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Roles
|
||||
const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
|
||||
const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
|
||||
const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
|
||||
const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
|
||||
const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
|
||||
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
|
||||
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// States
|
||||
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
|
||||
const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
|
||||
const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
|
||||
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
|
||||
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
|
||||
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
|
||||
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
|
||||
const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible general
|
||||
|
||||
|
@ -77,16 +99,16 @@ function getAccessible(aAccOrElmOrID, aInterfaces, aElmObj)
|
|||
acc = gAccRetrieval.getAccessibleFor(elm);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
|
||||
if (!acc) {
|
||||
ok(false, "Can't get accessible for " + aID);
|
||||
ok(false, "Can't get accessible for " + aAccOrElmOrID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!aInterfaces)
|
||||
return acc;
|
||||
|
||||
|
||||
if (aInterfaces instanceof Array) {
|
||||
for (var index = 0; index < aInterfaces.length; index++) {
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Tests an accessible and its children.
|
||||
* The accessible is one of the following:
|
||||
* - HTML:select (ROLE_COMBOBOX)
|
||||
* - HTML:select @size (ROLE_LIST)
|
||||
* - HTML:label containing either of the above (ROLE_LABEL)
|
||||
*
|
||||
* @param aID The ID of the base element to test.
|
||||
* @param aNames The array of expected names for the accessible and
|
||||
* its children.
|
||||
* @param aRoles The array of expected roles for the accessible and
|
||||
* its children.
|
||||
* @param aStates The array of states to test for on each accessible.
|
||||
* @param aUndesiredStates Array of states we don't want to have for each
|
||||
* accessible.
|
||||
*
|
||||
* @note Each of the three arrays must have an equal number of elements. The
|
||||
* order of elements corresponds to the order in which the tree is walked from
|
||||
* the base accessible downwards.
|
||||
*/
|
||||
function testSelect(aID, aNames, aRoles, aStates, aUndesiredStates)
|
||||
{
|
||||
// used to walk the tree starting at the aID's accessible.
|
||||
var acc = getAccessible(aID);
|
||||
if (!acc) {
|
||||
return;
|
||||
}
|
||||
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a single accessible.
|
||||
* Recursively calls itself until it reaches the last option item.
|
||||
* Called first time from the testSelect function.
|
||||
*
|
||||
* @param aID @see testSelect
|
||||
* @param aAcc The accessible to test.
|
||||
* @param aNames @see testSelect
|
||||
* @param aRoles @see testSelect
|
||||
* @param aStates @see testSelect
|
||||
* @param aUndesiredStates @see testSelect
|
||||
* @param aIndex The index in the three arrays to use. Used for both
|
||||
* the error message and for walking the tree downwards
|
||||
* from the base accessible.
|
||||
*/
|
||||
function testThis(aID, aAcc, aNames, aRoles, aStates, aUndesiredStates, aIndex)
|
||||
{
|
||||
if (aIndex >= aNames.length)
|
||||
return; // End of test
|
||||
else if (!aAcc) {
|
||||
ok(false, "No accessible for " + aID + " at index " + aIndex + "!");
|
||||
return;
|
||||
}
|
||||
|
||||
is(aAcc.name, aNames[aIndex],
|
||||
"wrong name for " + aID + " at index " + aIndex + "!");
|
||||
var role = aAcc.role;
|
||||
is(role, aRoles[aIndex],
|
||||
"Wrong role for " + aID + " at index " + aIndex + "!");
|
||||
testStates(aID, aAcc, aStates, aUndesiredStates, aIndex);
|
||||
switch(role) {
|
||||
case ROLE_COMBOBOX:
|
||||
case ROLE_COMBOBOX_LIST:
|
||||
case ROLE_LABEL:
|
||||
case ROLE_LIST:
|
||||
// All of these expect the next item to be the first child of the current
|
||||
// accessible.
|
||||
var acc = null;
|
||||
try {
|
||||
acc = aAcc.firstChild;
|
||||
} catch(e) {}
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, ++aIndex);
|
||||
break;
|
||||
case ROLE_COMBOBOX_OPTION:
|
||||
case ROLE_OPTION:
|
||||
case ROLE_TEXT_LEAF:
|
||||
// All of these expect the next item's accessible to be the next sibling.
|
||||
var acc = null;
|
||||
try {
|
||||
acc = aAcc.nextSibling;
|
||||
} catch(e) {}
|
||||
testThis(aID, acc, aNames, aRoles, aStates, aUndesiredStates, ++aIndex);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the states for the given accessible.
|
||||
* Does not test for extraStates since we don't need these.
|
||||
*
|
||||
* @param aID the ID of the base element.
|
||||
* @param aAcc the current accessible from the recursive algorithm.
|
||||
* @param aStates the states array passed down from the testThis function.
|
||||
* @param aUndesiredStates the array of states we don't want to see, if any.
|
||||
* @param aIndex the index of the item to test, determined and passed in from
|
||||
* the testThis function.
|
||||
*/
|
||||
function testStates(aID, aAcc, aStates, aUndesiredStates, aIndex)
|
||||
{
|
||||
var state = {}, extraState = {};
|
||||
aAcc.getFinalState(state, extraState);
|
||||
if (aStates[aIndex] != 0)
|
||||
is(state.value & aStates[aIndex], aStates[aIndex],
|
||||
"Wrong state bits for " + aID + " at index " + aIndex + "!");
|
||||
if (aUndesiredStates[aIndex] != 0)
|
||||
is(state.value & aUndesiredStates[aIndex], 0,
|
||||
"Wrong undesired state bits for " + aID + " at index " + aIndex + "!");
|
||||
}
|
|
@ -1,28 +1,16 @@
|
|||
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
|
||||
|
||||
// Mapping needed state flags for easier handling.
|
||||
const state_focusable =
|
||||
Components.interfaces.nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const state_focused =
|
||||
Components.interfaces.nsIAccessibleStates.STATE_FOCUSED;
|
||||
const state_readonly =
|
||||
Components.interfaces.nsIAccessibleStates.STATE_READONLY;
|
||||
const state_focusable = nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const state_focused = nsIAccessibleStates.STATE_FOCUSED;
|
||||
const state_readonly = nsIAccessibleStates.STATE_READONLY;
|
||||
|
||||
const ext_state_multi_line =
|
||||
Components.interfaces.nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const ext_state_editable =
|
||||
Components.interfaces.nsIAccessibleStates.EXT_STATE_EDITABLE;
|
||||
const ext_state_required =
|
||||
Components.interfaces.nsIAccessibleStates.STATE_REQUIRED;
|
||||
const ext_state_invalid =
|
||||
Components.interfaces.nsIAccessibleStates.STATE_INVALID;
|
||||
const ext_state_multi_line = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const ext_state_editable = nsIAccessibleStates.EXT_STATE_EDITABLE;
|
||||
const ext_state_required = nsIAccessibleStates.STATE_REQUIRED;
|
||||
const ext_state_invalid = nsIAccessibleStates.STATE_INVALID;
|
||||
|
||||
// Mapping needed final roles
|
||||
const role_entry = Components.interfaces.nsIAccessibleRole.ROLE_ENTRY;
|
||||
const role_password_text =
|
||||
Components.interfaces.nsIAccessibleRole.ROLE_PASSWORD_TEXT;
|
||||
|
||||
var gAccRetrieval = null;
|
||||
const role_entry = nsIAccessibleRole.ROLE_ENTRY;
|
||||
const role_password_text = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
|
||||
|
||||
function testValue(aID, aAcc, aValue, aRole)
|
||||
{
|
||||
|
|
|
@ -105,13 +105,13 @@
|
|||
"nsITreeBoxObject::rowCountChanged");
|
||||
break;
|
||||
case 2:
|
||||
TreeInvalidatedHandlerHelper(aEvent, null, null, 0, 0,
|
||||
"nsITreeBoxObject::invalidateColumn");
|
||||
// XXX see bug 454647 TreeInvalidatedHandlerHelper(aEvent, null, null, 0, 0,
|
||||
// "nsITreeBoxObject::invalidateColumn");
|
||||
gTreeColumnInvalidated = true;
|
||||
break;
|
||||
case 3:
|
||||
TreeInvalidatedHandlerHelper(aEvent, 1, 1, null, null,
|
||||
"nsITreeBoxObject::invalidateRow");
|
||||
// XXX see bug 454647 TreeInvalidatedHandlerHelper(aEvent, 1, 1, null, null,
|
||||
// "nsITreeBoxObject::invalidateRow");
|
||||
gTreeRowInvalidated = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible caret move events testing</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="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function synthMouseTest(aNode)
|
||||
{
|
||||
this.node = aNode;
|
||||
this.testFunc = function testFunc()
|
||||
{
|
||||
synthesizeMouse(this.node, 1, 1, {});
|
||||
}
|
||||
}
|
||||
|
||||
function synthKeyTest(aNode, aKey)
|
||||
{
|
||||
this.node = aNode;
|
||||
this.testFunc = function testFunc()
|
||||
{
|
||||
synthesizeKey(aKey, {});
|
||||
}
|
||||
}
|
||||
|
||||
function synthTabTest(aNode, aBackTab)
|
||||
{
|
||||
this.node = aNode;
|
||||
this.testFunc = function testFunc()
|
||||
{
|
||||
synthesizeKey("VK_TAB", {shiftKey: aBackTab});
|
||||
}
|
||||
}
|
||||
|
||||
var gTestsArray = [];
|
||||
var gTestIdx = -1;
|
||||
|
||||
var gCaretMoveHandler =
|
||||
{
|
||||
handleEvent: function handleEvent(aEvent)
|
||||
{
|
||||
if (aEvent.DOMNode == gTestsArray[gTestIdx].node)
|
||||
gTestsArray[gTestIdx].wasCaught = true;
|
||||
}
|
||||
};
|
||||
|
||||
function doTest()
|
||||
{
|
||||
window.setTimeout(
|
||||
function()
|
||||
{
|
||||
if (gTestIdx == gTestsArray.length - 1) {
|
||||
|
||||
unregisterA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED,
|
||||
gCaretMoveHandler);
|
||||
|
||||
for (var idx = 0; idx < gTestsArray.length; idx++)
|
||||
ok(gTestsArray[idx].wasCaught, "test " + idx + " failed");
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gTestsArray[++gTestIdx].testFunc();
|
||||
doTest();
|
||||
},
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
var textbox = document.getElementById("textbox");
|
||||
gTestsArray.push(new synthMouseTest(textbox));
|
||||
gTestsArray.push(new synthKeyTest(textbox, "VK_RIGHT"));
|
||||
|
||||
var textarea = document.getElementById("textarea");
|
||||
gTestsArray.push(new synthMouseTest(textarea));
|
||||
gTestsArray.push(new synthKeyTest(textarea, "VK_RIGHT"));
|
||||
gTestsArray.push(new synthKeyTest(textarea, "VK_DOWN"));
|
||||
|
||||
var p = document.getElementById("p");
|
||||
gTestsArray.push(new synthMouseTest(p));
|
||||
gTestsArray.push(new synthKeyTest(p, "VK_RIGHT"));
|
||||
gTestsArray.push(new synthKeyTest(p, "VK_DOWN"));
|
||||
|
||||
gTestsArray.push(new synthTabTest(textarea, true));
|
||||
gTestsArray.push(new synthTabTest(p));
|
||||
|
||||
registerA11yEventListener(nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED,
|
||||
gCaretMoveHandler);
|
||||
|
||||
doTest();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=454377"
|
||||
title="Accessible caret move events testing">
|
||||
Mozilla Bug 454377
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="textbox" value="hello"/>
|
||||
<textarea id="textarea">text<br>text</textarea>
|
||||
<p id="p" contentEditable="true"><span>text</span><br/>text</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,55 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessNode util methods testing</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="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
var elmObj = {};
|
||||
var acc = getAccessible("span", [nsIAccessNode], elmObj);
|
||||
computedStyle = document.defaultView.getComputedStyle(elmObj.value, "");
|
||||
|
||||
// html:span element
|
||||
is(acc.getComputedStyleValue("", "color"), computedStyle.color,
|
||||
"Wrong color for element with ID 'span'");
|
||||
|
||||
// text child of html:span element
|
||||
acc = getAccessible(acc.firstChild, [nsIAccessNode]);
|
||||
is(acc.getComputedStyleValue("", "color"), computedStyle.color,
|
||||
"Wrong color for text child of element with ID 'span'");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=454211"
|
||||
title="nsIAccessNode util methods testing">
|
||||
Mozilla Bug 454211
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<span role="description" style="color: red" id="span">text</span>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -56,7 +56,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
|||
testThis("imgmap", 78, 3, "b");
|
||||
|
||||
// empty hyperlink
|
||||
testThis("emptyLink", 93, 4, "");
|
||||
// XXX see bug 434636 testThis("emptyLink", 93, 4, "");
|
||||
|
||||
// normal hyperlink with embedded span
|
||||
testThis("LinkWithSpan", 119, 5, "Heise Online");
|
||||
|
|
|
@ -98,8 +98,14 @@
|
|||
|
||||
var states = {}, extraStates = {};
|
||||
aFocusMgr.mAcc.getFinalState(states, extraStates);
|
||||
ok(states.value & nsIAccessibleStates.STATE_FOCUSED,
|
||||
"No focused state for element with ID " + aFocusMgr.mName + ".");
|
||||
// XXX see bug 455840. Only fails on aria-link, the other two are OK.
|
||||
// When fixing this bug, remove the if statement and else block and "todo" statement.
|
||||
if (states.value & nsIAccessibleStates.STATE_FOCUSED)
|
||||
ok(states.value & nsIAccessibleStates.STATE_FOCUSED,
|
||||
"No focused state for element with ID " + aFocusMgr.mName + ".");
|
||||
else
|
||||
todo(states.value & nsIAccessibleStates.STATE_FOCUSED,
|
||||
"No focused state for element with ID " + aFocusMgr.mName + ".");
|
||||
|
||||
aFocusMgr.mCallback();
|
||||
}, 0, this);
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible selects 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="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_selects.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// Label and combo, separate tags
|
||||
var names = [
|
||||
"Foo:", // combobox
|
||||
"Foo:", // combobox list
|
||||
"item 1", // first item
|
||||
"item 2" // second item
|
||||
];
|
||||
var roles = [
|
||||
ROLE_COMBOBOX, // root
|
||||
ROLE_COMBOBOX_LIST, // list accessible
|
||||
ROLE_COMBOBOX_OPTION, // first option
|
||||
ROLE_COMBOBOX_OPTION // second option
|
||||
];
|
||||
var states = [
|
||||
(STATE_FOCUSABLE | STATE_HASPOPUP | STATE_COLLAPSED), // combobox
|
||||
(0), // combobox_list
|
||||
(STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // second item, not focused
|
||||
];
|
||||
var undesiredStates = [
|
||||
(STATE_FOCUSED), // combobox
|
||||
(STATE_FOCUSED), // combobox_list
|
||||
(0), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // second, not currently focused, item
|
||||
];
|
||||
testSelect("combo1", names, roles, states, undesiredStates);
|
||||
|
||||
// Select nested within label element.
|
||||
// XXX see bug 455482: The accName for the label, combobox, and
|
||||
// combobox_list contains the label text and the names of each option.
|
||||
// When fixing bug 455482, please fix below names and remove this comment.
|
||||
names = [
|
||||
"Search in: Newsticker Entire site", // label
|
||||
"Search in:", // text leaf
|
||||
"Search in: Newsticker Entire site", // combobox
|
||||
"Search in: Newsticker Entire site", // combobox_list
|
||||
"Newsticker", // option 1
|
||||
"Entire site" // Option 2
|
||||
];
|
||||
roles = [
|
||||
ROLE_LABEL, // root
|
||||
ROLE_TEXT_LEAF, // inner text
|
||||
ROLE_COMBOBOX, // combobox accessible
|
||||
ROLE_COMBOBOX_LIST, // list accessible
|
||||
ROLE_COMBOBOX_OPTION, // first option
|
||||
ROLE_COMBOBOX_OPTION // second option
|
||||
];
|
||||
states = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSABLE | STATE_HASPOPUP | STATE_COLLAPSED), // combobox
|
||||
(0), // combobox_list
|
||||
(STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // second item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSED), // combobox
|
||||
(STATE_FOCUSED), // combobox_list
|
||||
(0), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // second, not currently focused, item
|
||||
];
|
||||
testSelect("combo2", names, roles, states, undesiredStates);
|
||||
|
||||
// select @size with label as separate tags.
|
||||
names = [
|
||||
"Component:", // list
|
||||
"Build", // item 1
|
||||
"Disability Access APIs", // item 2
|
||||
"General", // item 3
|
||||
"UI" // item 4
|
||||
];
|
||||
roles = [
|
||||
ROLE_LIST, // root
|
||||
ROLE_OPTION, // item 1
|
||||
ROLE_OPTION, // item 2
|
||||
ROLE_OPTION, // item 4
|
||||
ROLE_OPTION // item 4
|
||||
];
|
||||
states = [
|
||||
(STATE_FOCUSABLE), // list
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE | STATE_FOCUSED),
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // second item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // third item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // fourth item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(STATE_FOCUSED), // listbox
|
||||
(STATE_SELECTED), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // second, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // third, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // fourth, not currently focused, item
|
||||
];
|
||||
testSelect("list1", names, roles, states, undesiredStates);
|
||||
|
||||
// Select @size nested within label element.
|
||||
// XXX see bug 455482: The accName for the label and listbox
|
||||
// contains the label text and the names of each option.
|
||||
// When fixing bug 455482, please fix below names and remove this comment.
|
||||
names = [
|
||||
"Version: 2.0 3.0 3.1 trunk", // label
|
||||
"Version:", // text leaf
|
||||
"Version: 2.0 3.0 3.1 trunk", // list
|
||||
"2.0", // option 1
|
||||
"3.0", // Option 2
|
||||
"3.1", // Option 3
|
||||
"trunk" // Option 4
|
||||
];
|
||||
roles = [
|
||||
ROLE_LABEL, // root
|
||||
ROLE_TEXT_LEAF, // inner text
|
||||
ROLE_LIST, // listbox accessible
|
||||
ROLE_OPTION, // first option
|
||||
ROLE_OPTION, // second option
|
||||
ROLE_OPTION, // third option
|
||||
ROLE_OPTION // fourth option
|
||||
];
|
||||
states = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSABLE), // listbox
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE | STATE_FOCUSED), // Option 1
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // second item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE), // third item, not focused
|
||||
(STATE_SELECTABLE | STATE_FOCUSABLE) // fourth item, not focused
|
||||
];
|
||||
undesiredStates = [
|
||||
(0), // label
|
||||
(0), // text leaf
|
||||
(STATE_FOCUSED | STATE_HASPOPUP | STATE_COLLAPSED), // listbox
|
||||
(STATE_SELECTED), // first item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // second, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED), // third, not currently focused, item
|
||||
(STATE_SELECTED | STATE_FOCUSED) // fourth, not currently focused, item
|
||||
];
|
||||
testSelect("list2", names, roles, states, undesiredStates);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=443889"
|
||||
title="mochitest for selects and lists">
|
||||
Mozilla Bug 443889
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<form action="post.php" method="post">
|
||||
<!-- Label and select separate tags -->
|
||||
<label for="combo1">Foo:</label>
|
||||
<select id="combo1" name="combo1">
|
||||
<option>item 1</option>
|
||||
<option>item 2</option>
|
||||
</select><br />
|
||||
|
||||
<!-- Select embedded in label -->
|
||||
<label id="combo2">Search in:<select name="search">
|
||||
<option>Newsticker</option>
|
||||
<option>Entire site</option>
|
||||
</select></label><br />
|
||||
|
||||
<!-- Label and select @size -->
|
||||
<label for="list1">Component:</label>
|
||||
<select id="list1" name="component" size="3">
|
||||
<option>Build</option>
|
||||
<option>Disability Access APIs</option>
|
||||
<option>General</option>
|
||||
<option>UI</option>
|
||||
</select><br />
|
||||
|
||||
<!-- Select @size nested within label -->
|
||||
<label id="list2">Version:<select name="version" size="3">
|
||||
<option>2.0</option>
|
||||
<option>3.0</option>
|
||||
<option>3.1</option>
|
||||
<option>trunk</option>
|
||||
</select></label><br />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -52,7 +52,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=441519
|
|||
"Wrong focusable state bit for internal frame!");
|
||||
|
||||
// see bug 428954: No name wanted for internal frame
|
||||
is(outerDocAcc.name, "", "Wrong name for internal frame!");
|
||||
// xxx see bug 454636 is(outerDocAcc.name, "", "Wrong name for internal frame!");
|
||||
|
||||
// see bug 440770, no actions wanted on outer doc
|
||||
is(outerDocAcc.numActions, 0,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
const nsIObserverService = Components.interfaces.nsIObserverService;
|
||||
|
||||
var gAccRetrieval = null;
|
||||
var gComputedStyle = null;
|
||||
|
||||
/**
|
||||
* Test text attributes.
|
||||
|
@ -176,16 +177,17 @@
|
|||
|
||||
window.setTimeout(function()
|
||||
{
|
||||
gComputedStyle = document.defaultView.getComputedStyle(node, "");
|
||||
var defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "11px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "Lucida Grande",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": gComputedStyle.backgroundColor,
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
|
@ -218,16 +220,18 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// area1
|
||||
var ID = "area1";
|
||||
var tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
var defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
@ -235,7 +239,9 @@
|
|||
var attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 7);
|
||||
|
||||
attrs = {"font-weight": "401"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"font-weight": gComputedStyle.fontWeight};
|
||||
testTextAttrs(ID, 7, attrs, 7, 11);
|
||||
|
||||
attrs = {};
|
||||
|
@ -244,16 +250,18 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// area2
|
||||
ID = "area2";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
@ -261,12 +269,19 @@
|
|||
attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 7);
|
||||
|
||||
attrs = {"font-weight": "401"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"font-weight": gComputedStyle.fontWeight};
|
||||
testTextAttrs(ID, 7, attrs, 7, 12);
|
||||
|
||||
attrs = {"font-style": "italic", "font-weight": "401"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"font-style": gComputedStyle.fontStyle,
|
||||
"font-weight": gComputedStyle.fontWeight};
|
||||
testTextAttrs(ID, 13, attrs, 12, 19);
|
||||
|
||||
tempElem = tempElem.parentNode;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"font-weight": "401"};
|
||||
testTextAttrs(ID, 20, attrs, 19, 23);
|
||||
|
||||
|
@ -276,82 +291,107 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// area3
|
||||
ID = "area3";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(0, 0, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": gComputedStyle.backgroundColor,
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 0, attrs, 0, 6);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 6, attrs, 6, 26);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
tempElem = tempElem.parentNode;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 26, attrs, 26, 27);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)", "background-color": "rgb(255, 255, 0)"};
|
||||
tempElem = tempElem.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color,
|
||||
"background-color": gComputedStyle.backgroundColor};
|
||||
testTextAttrs(ID, 27, attrs, 27, 50);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area4
|
||||
ID = "area4";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 0, attrs, 0, 16);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
tempElem = tempElem.nextSibling.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 16, attrs, 16, 33);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
tempElem = tempElem.parentNode;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 34, attrs, 33, 46);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area5
|
||||
ID = "area5";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 0, attrs, 0, 5);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 7, attrs, 5, 8);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
tempElem = tempElem.nextSibling.nextSibling.nextSibling.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 9, attrs, 8, 11);
|
||||
|
||||
attrs = {};
|
||||
|
@ -360,16 +400,18 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// area6 (CSS vertical-align property, bug 445938)
|
||||
ID = "area6";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX bug 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
@ -377,40 +419,52 @@
|
|||
attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 5);
|
||||
|
||||
attrs = {"text-position": "super", "font-size": "13px" };
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"text-position": gComputedStyle.verticalAlign,
|
||||
"font-size": gComputedStyle.fontSize};
|
||||
testTextAttrs(ID, 5, attrs, 5, 13);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 13, attrs, 13, 27);
|
||||
|
||||
attrs = {"text-position": "super" };
|
||||
tempElem = tempElem.nextSibling.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"text-position": gComputedStyle.verticalAlign};
|
||||
testTextAttrs(ID, 27, attrs, 27, 35);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 35, attrs, 35, 39);
|
||||
|
||||
attrs = {"text-position": "sub", "font-size": "13px" };
|
||||
tempElem = tempElem.nextSibling.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"text-position": gComputedStyle.verticalAlign,
|
||||
"font-size": gComputedStyle.fontSize};
|
||||
testTextAttrs(ID, 39, attrs, 39, 50);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 50, attrs, 50, 55);
|
||||
|
||||
attrs = {"text-position": "sub" };
|
||||
tempElem = tempElem.nextSibling.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"text-position": gComputedStyle.verticalAlign};
|
||||
testTextAttrs(ID, 55, attrs, 55, 64);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area7
|
||||
ID = "area7";
|
||||
tempElem = document.getElementById(ID);
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
defAttrs = {
|
||||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"font-family": "serif",
|
||||
"text-position": "baseline"
|
||||
"font-style": gComputedStyle.fontStyle,
|
||||
"text-align": gComputedStyle.textAlign,
|
||||
"font-size": gComputedStyle.fontSize,
|
||||
"background-color": "rgb(0, 0, 0)", // XXX 455834
|
||||
"font-weight": gComputedStyle.fontWeight,
|
||||
"text-indent": gComputedStyle.textIndent,
|
||||
"color": gComputedStyle.color,
|
||||
"font-family": gComputedStyle.fontFamily,
|
||||
"text-position": gComputedStyle.verticalAlign
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
@ -421,7 +475,10 @@
|
|||
attrs = {"language": "en"};
|
||||
testTextAttrs(ID, 12, attrs, 12, 13);
|
||||
|
||||
attrs = {"language" :"en", "background-color": "rgb(0, 0, 255)"};
|
||||
tempElem = tempElem.firstChild.nextSibling.nextSibling.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"language" :"en",
|
||||
"background-color": gComputedStyle.backgroundColor};
|
||||
testTextAttrs(ID, 13, attrs, 13, 26);
|
||||
|
||||
attrs = {"language": "en" };
|
||||
|
@ -436,13 +493,20 @@
|
|||
attrs = {};
|
||||
testTextAttrs(ID, 43, attrs, 43, 50);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 255)"};
|
||||
tempElem = tempElem.nextSibling.nextSibling.nextSibling.nextSibling.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 50, attrs, 50, 57);
|
||||
|
||||
attrs = {"font-weight": "401", "color": "rgb(255, 0, 255)" };
|
||||
tempElem = tempElem.firstChild.nextSibling;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"font-weight": gComputedStyle.fontWeight,
|
||||
"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 57, attrs, 57, 61);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 255)"};
|
||||
tempElem = tempElem.parentNode;
|
||||
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
|
||||
attrs = {"color": gComputedStyle.color};
|
||||
testTextAttrs(ID, 61, attrs, 61, 68);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -7,17 +7,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=442648
|
|||
<title>nsIAccessible textboxes chrome 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="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="chrome://mochikit/content/a11y/accessible/testTextboxes.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/testTextboxes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(nsIAccessibleRetrieval);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with no proper label
|
||||
testThis("unlabelled_Textbox", // ID
|
||||
|
|
|
@ -12,15 +12,14 @@
|
|||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/testTextboxes.js"></script>
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/testTextboxes.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function doTest()
|
||||
{
|
||||
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(nsIAccessibleRetrieval);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// normal textbox without content and with no proper label
|
||||
testThis("unlabelled_Textbox", // ID
|
||||
|
|
|
@ -72,12 +72,18 @@ GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBX
|
|||
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
ifdef MOZ_MEMORY
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
LIBS += -ljemalloc
|
||||
SOURCE_STAMP := $(shell hg identify -i $(topsrcdir) 2>/dev/null)
|
||||
ifdef SOURCE_STAMP
|
||||
DEFINES += -DMOZ_SOURCE_STAMP="$(SOURCE_STAMP)"
|
||||
endif
|
||||
|
||||
SOURCE_REPO := $(shell hg -R $(topsrcdir) showconfig paths.default 2>/dev/null | sed s/^ssh:/http:/)
|
||||
ifdef SOURCE_REPO
|
||||
DEFINES += -DMOZ_SOURCE_REPO="$(SOURCE_REPO)"
|
||||
endif
|
||||
|
||||
LIBS += $(JEMALLOC_LIBS)
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
else
|
||||
|
@ -117,11 +123,18 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
|||
TK_LIBS := $(TK_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_LIBXUL
|
||||
APP_XPCOM_LIBS = $(XPCOM_GLUE_LDOPTS)
|
||||
else
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
APP_XPCOM_LIBS = $(XPCOM_LIBS)
|
||||
endif
|
||||
|
||||
LIBS += \
|
||||
$(STATIC_COMPONENTS_LINKER_PATH) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(XPCOM_GLUE_LDOPTS) \
|
||||
$(APP_XPCOM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(TK_LIBS) \
|
||||
$(NULL)
|
||||
|
|
|
@ -41,6 +41,12 @@ Vendor=Mozilla
|
|||
Name=Firefox
|
||||
Version=@APP_VERSION@
|
||||
BuildID=@GRE_BUILDID@
|
||||
#ifdef MOZ_SOURCE_REPO
|
||||
SourceRepository=@MOZ_SOURCE_REPO@
|
||||
#endif
|
||||
#ifdef MOZ_SOURCE_STAMP
|
||||
SourceStamp=@MOZ_SOURCE_STAMP@
|
||||
#endif
|
||||
Copyright=Copyright (c) 1998 - 2008 mozilla.org
|
||||
ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
|
||||
|
||||
|
|
|
@ -309,8 +309,7 @@ pref("browser.link.open_newwindow", 3);
|
|||
pref("browser.link.open_newwindow.restriction", 2);
|
||||
|
||||
// Tabbed browser
|
||||
pref("browser.tabs.autoHide", true);
|
||||
pref("browser.tabs.forceHide", false);
|
||||
pref("browser.tabs.autoHide", false);
|
||||
pref("browser.tabs.warnOnClose", true);
|
||||
pref("browser.tabs.warnOnOpen", true);
|
||||
pref("browser.tabs.maxOpenBeforeWarn", 15);
|
||||
|
@ -338,6 +337,7 @@ pref("browser.tabs.closeButtons", 1);
|
|||
pref("browser.tabs.selectOwnerOnClose", true);
|
||||
|
||||
pref("browser.ctrlTab.mostRecentlyUsed", true);
|
||||
pref("browser.ctrlTab.recentlyUsedLimit", 7);
|
||||
pref("browser.ctrlTab.smoothScroll", true);
|
||||
|
||||
// Default bookmark sorting
|
||||
|
@ -695,15 +695,6 @@ pref("browser.sessionstore.max_tabs_undo", 10);
|
|||
// allow META refresh by default
|
||||
pref("accessibility.blockautorefresh", false);
|
||||
|
||||
// If true, will migrate uri post-data annotations to
|
||||
// bookmark post-data annotations (bug 398914)
|
||||
// XXX to be removed after beta 2 (bug 391419)
|
||||
pref("browser.places.migratePostDataAnnotations", true);
|
||||
|
||||
// If true, will update the Smart Bookmarks uri for
|
||||
// recent tags (bug 385245). Useful just for FX3 beta users.
|
||||
pref("browser.places.updateRecentTagsUri", true);
|
||||
|
||||
// the (maximum) number of the recent visits to sample
|
||||
// when calculating frecency
|
||||
pref("places.frecency.numVisits", 10);
|
||||
|
|
|
@ -384,7 +384,7 @@
|
|||
key="showAllHistoryKb"
|
||||
#endif
|
||||
command="Browser:ShowAllHistory"/>
|
||||
<menuseparator id="startHistorySeparator" builder="start"/>
|
||||
<menuseparator id="startHistorySeparator"/>
|
||||
<menuseparator id="endHistorySeparator" builder="end"/>
|
||||
<menu id="historyUndoMenu" label="&historyUndoMenu.label;" disabled="true">
|
||||
<menupopup id="historyUndoPopup" onpopupshowing="HistoryMenu.populateUndoSubmenu();"/>
|
||||
|
@ -396,7 +396,8 @@
|
|||
label="&bookmarksMenu.label;" accesskey="&bookmarksMenu.accesskey;"
|
||||
ondragenter="PlacesMenuDNDController.onBookmarksMenuDragEnter(event);"
|
||||
ondragdrop="nsDragAndDrop.drop(event, BookmarksMenuDropHandler);"
|
||||
ondragover="nsDragAndDrop.dragOver(event, BookmarksMenuDropHandler);">
|
||||
ondragover="nsDragAndDrop.dragOver(event, BookmarksMenuDropHandler);"
|
||||
ondragexit="nsDragAndDrop.dragExit(event, BookmarksMenuDropHandler);">
|
||||
<menupopup id="bookmarksMenuPopup"
|
||||
type="places"
|
||||
place="place:folder=BOOKMARKS_MENU"
|
||||
|
@ -437,7 +438,7 @@
|
|||
context="placesContext"
|
||||
onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"/>
|
||||
</menu>
|
||||
<menuseparator builder="start"/>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
|
|
|
@ -711,7 +711,6 @@ var BookmarksEventHandler = {
|
|||
if (!target._endOptSeparator) {
|
||||
// create a separator before options
|
||||
target._endOptSeparator = document.createElement("menuseparator");
|
||||
target._endOptSeparator.setAttribute("builder", "end");
|
||||
target._endMarker = target.childNodes.length;
|
||||
target.appendChild(target._endOptSeparator);
|
||||
}
|
||||
|
@ -789,7 +788,8 @@ var BookmarksMenuDropHandler = {
|
|||
* state.
|
||||
*/
|
||||
onDragOver: function BMDH_onDragOver(event, flavor, session) {
|
||||
session.canDrop = this.canDrop(event, session);
|
||||
if (!this.canDrop(event, session))
|
||||
event.dataTransfer.effectAllowed = "none";
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -812,6 +812,8 @@ var BookmarksMenuDropHandler = {
|
|||
* otherwise.
|
||||
*/
|
||||
canDrop: function BMDH_canDrop(event, session) {
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
|
||||
var ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId, -1);
|
||||
return ip && PlacesControllerDragHelper.canDrop(ip);
|
||||
},
|
||||
|
@ -826,9 +828,21 @@ var BookmarksMenuDropHandler = {
|
|||
* The active DragSession
|
||||
*/
|
||||
onDrop: function BMDH_onDrop(event, data, session) {
|
||||
// Put the item at the end of bookmark menu
|
||||
var ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId, -1);
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
|
||||
// Put the item at the end of bookmark menu
|
||||
var ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId, -1,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
PlacesControllerDragHelper.onDrop(ip);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when drop target leaves the menu or after a drop.
|
||||
* @param aEvent
|
||||
* A drop event
|
||||
*/
|
||||
onDragExit: function BMDH_onDragExit(event, session) {
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -903,8 +917,9 @@ var PlacesMenuDNDController = {
|
|||
*` menu-toolbarbutton), false otherwise.
|
||||
*/
|
||||
_isContainer: function PMDC__isContainer(node) {
|
||||
return node.localName == "menu" ||
|
||||
node.localName == "toolbarbutton" && node.getAttribute("type") == "menu";
|
||||
return node.localName == "menu" ||
|
||||
(node.localName == "toolbarbutton" &&
|
||||
node.getAttribute("type") == "menu");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1009,62 +1024,3 @@ var PlacesStarButton = {
|
|||
onItemVisited: function() { },
|
||||
onItemMoved: function() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Various migration tasks.
|
||||
*/
|
||||
function placesMigrationTasks() {
|
||||
// bug 398914 - move all post-data annotations from URIs to bookmarks
|
||||
// XXX - REMOVE ME FOR BETA 3 (bug 391419)
|
||||
if (gPrefService.getBoolPref("browser.places.migratePostDataAnnotations")) {
|
||||
const annosvc = PlacesUtils.annotations;
|
||||
var bmsvc = PlacesUtils.bookmarks;
|
||||
const oldPostDataAnno = "URIProperties/POSTData";
|
||||
var pages = annosvc.getPagesWithAnnotation(oldPostDataAnno, {});
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
try {
|
||||
let uri = pages[i];
|
||||
var postData = annosvc.getPageAnnotation(uri, oldPostDataAnno);
|
||||
// We can't know which URI+keyword combo this postdata was for, but
|
||||
// it's very likely that if this URI is bookmarked and has a keyword
|
||||
// *and* the URI has postdata, then this bookmark was using the
|
||||
// postdata. Propagate the annotation to all bookmarks for this URI
|
||||
// just to be safe.
|
||||
let bookmarks = bmsvc.getBookmarkIdsForURI(uri, {});
|
||||
for (let i = 0; i < bookmarks.length; i++) {
|
||||
var keyword = bmsvc.getKeywordForBookmark(bookmarks[i]);
|
||||
if (keyword)
|
||||
annosvc.setItemAnnotation(bookmarks[i], POST_DATA_ANNO, postData, 0, annosvc.EXPIRE_NEVER);
|
||||
}
|
||||
// Remove the old annotation.
|
||||
annosvc.removePageAnnotation(uri, oldPostDataAnno);
|
||||
} catch(ex) {}
|
||||
}
|
||||
gPrefService.setBoolPref("browser.places.migratePostDataAnnotations", false);
|
||||
}
|
||||
|
||||
if (gPrefService.getBoolPref("browser.places.updateRecentTagsUri")) {
|
||||
var oldUriSpec = "place:folder=TAGS&group=3&queryType=1" +
|
||||
"&applyOptionsToContainers=1&sort=12&maxResults=10";
|
||||
|
||||
var maxResults = 10;
|
||||
var newUriSpec = "place:type=" +
|
||||
Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
|
||||
"&sort=" +
|
||||
Ci.nsINavHistoryQueryOptions.SORT_BY_LASTMODIFIED_DESCENDING +
|
||||
"&maxResults=" + maxResults;
|
||||
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
|
||||
var oldUri = ios.newURI(oldUriSpec, null, null);
|
||||
var newUri = ios.newURI(newUriSpec, null, null);
|
||||
|
||||
let bmsvc = PlacesUtils.bookmarks;
|
||||
let bookmarks = bmsvc.getBookmarkIdsForURI( oldUri, {});
|
||||
for (let i = 0; i < bookmarks.length; i++) {
|
||||
bmsvc.changeBookmarkURI( bookmarks[i], newUri);
|
||||
}
|
||||
gPrefService.setBoolPref("browser.places.updateRecentTagsUri", false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
* Tab previews utility, produces thumbnails
|
||||
*/
|
||||
var tabPreviews = {
|
||||
aspectRatio: 0.6875, // 16:11
|
||||
aspectRatio: 0.5625, // 16:9
|
||||
init: function () {
|
||||
this.width = Math.ceil(screen.availWidth / 7);
|
||||
this.width = Math.ceil(screen.availWidth / 5);
|
||||
this.height = Math.round(this.width * this.aspectRatio);
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", this, false);
|
||||
|
@ -64,16 +64,19 @@ var tabPreviews = {
|
|||
return aTab.__thumbnail || this.capture(aTab, !aTab.hasAttribute("busy"));
|
||||
},
|
||||
capture: function (aTab, aStore) {
|
||||
var win = aTab.linkedBrowser.contentWindow;
|
||||
var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
thumbnail.mozOpaque = true;
|
||||
thumbnail.height = this.height;
|
||||
thumbnail.width = this.width;
|
||||
|
||||
var ctx = thumbnail.getContext("2d");
|
||||
var widthScale = this.width / win.innerWidth;
|
||||
ctx.scale(widthScale, widthScale);
|
||||
var win = aTab.linkedBrowser.contentWindow;
|
||||
var snippetWidth = win.innerWidth * .6;
|
||||
var scale = this.width / snippetWidth;
|
||||
ctx.scale(scale, scale);
|
||||
ctx.drawWindow(win, win.scrollX, win.scrollY,
|
||||
win.innerWidth, win.innerWidth * this.aspectRatio, "rgb(255,255,255)");
|
||||
snippetWidth, snippetWidth * this.aspectRatio, "rgb(255,255,255)");
|
||||
|
||||
var data = thumbnail.toDataURL("image/jpeg", "quality=60");
|
||||
if (aStore) {
|
||||
aTab.__thumbnail = data;
|
||||
|
@ -111,7 +114,6 @@ var tabPreviews = {
|
|||
* Ctrl-Tab panel
|
||||
*/
|
||||
var ctrlTab = {
|
||||
tabs: null,
|
||||
visibleCount: 3,
|
||||
_uniqid: 0,
|
||||
get panel () {
|
||||
|
@ -152,10 +154,17 @@ var ctrlTab = {
|
|||
.getAttribute("key")
|
||||
.toLowerCase().charCodeAt(0);
|
||||
},
|
||||
get recentlyUsedLimit () {
|
||||
delete this.recentlyUsedLimit;
|
||||
return this.recentlyUsedLimit = gPrefService.getIntPref("browser.ctrlTab.recentlyUsedLimit");
|
||||
},
|
||||
get smoothScroll () {
|
||||
delete this.smoothScroll;
|
||||
return this.smoothScroll = gPrefService.getBoolPref("browser.ctrlTab.smoothScroll");
|
||||
},
|
||||
get tabCount () {
|
||||
return gBrowser.mTabs.length;
|
||||
},
|
||||
get offscreenStart () {
|
||||
return Array.indexOf(this.container.childNodes, this.selected) - 1;
|
||||
},
|
||||
|
@ -169,16 +178,11 @@ var ctrlTab = {
|
|||
return this.panel.state == "open" || this.panel.state == "showing";
|
||||
},
|
||||
init: function () {
|
||||
if (this.tabs)
|
||||
if (this._recentlyUsedTabs)
|
||||
return;
|
||||
this._recentlyUsedTabs = [gBrowser.selectedTab];
|
||||
|
||||
var tabContainer = gBrowser.tabContainer;
|
||||
|
||||
this.tabs = [];
|
||||
Array.forEach(tabContainer.childNodes, function (tab) {
|
||||
this.attachTab(tab, tab == gBrowser.selectedTab);
|
||||
}, this);
|
||||
|
||||
tabContainer.addEventListener("TabOpen", this, false);
|
||||
tabContainer.addEventListener("TabSelect", this, false);
|
||||
tabContainer.addEventListener("TabClose", this, false);
|
||||
|
@ -187,7 +191,7 @@ var ctrlTab = {
|
|||
document.addEventListener("keypress", this, false);
|
||||
},
|
||||
uninit: function () {
|
||||
this.tabs = null;
|
||||
this._recentlyUsedTabs = null;
|
||||
|
||||
var tabContainer = gBrowser.tabContainer;
|
||||
tabContainer.removeEventListener("TabOpen", this, false);
|
||||
|
@ -348,12 +352,12 @@ var ctrlTab = {
|
|||
advanceSelected: function () {
|
||||
// regardless of visibleCount, the new highlighted tab will be
|
||||
// the first or third-visible tab, depending on whether Shift is pressed
|
||||
var index = ((this.invertDirection ? 0 : 2) + this.offscreenStart + this.tabs.length)
|
||||
% this.tabs.length;
|
||||
var index = ((this.invertDirection ? 0 : 2) + this.offscreenStart + this.tabCount)
|
||||
% this.tabCount;
|
||||
if (index < 2)
|
||||
index += this.tabs.length;
|
||||
index += this.tabCount;
|
||||
if (index > this.container.childNodes.length - this.visibleCount + 1)
|
||||
index -= this.tabs.length;
|
||||
index -= this.tabCount;
|
||||
this.selected = this.container.childNodes[index];
|
||||
},
|
||||
arrangeBoxes: function () {
|
||||
|
@ -372,13 +376,14 @@ var ctrlTab = {
|
|||
this.arrange(i);
|
||||
},
|
||||
addOffscreenBox: function (aAtStart) {
|
||||
if (this.container.childNodes.length < this.tabs.length + this.visibleCount + 1 &&
|
||||
if (this.container.childNodes.length < this.tabCount + this.visibleCount + 1 &&
|
||||
!(aAtStart ? this.offscreenStart : this.offscreenEnd)) {
|
||||
let tabs = this.getTabList();
|
||||
let i = aAtStart ?
|
||||
this.tabs.indexOf(this.container.firstChild._tab) - 1:
|
||||
this.tabs.indexOf(this.container.lastChild._tab) + 1;
|
||||
i = (i + this.tabs.length) % this.tabs.length;
|
||||
this.addPreview(this.addBox(aAtStart), this.tabs[i]);
|
||||
tabs.indexOf(this.container.firstChild._tab) - 1:
|
||||
tabs.indexOf(this.container.lastChild._tab) + 1;
|
||||
i = (i + tabs.length) % tabs.length;
|
||||
this.addPreview(this.addBox(aAtStart), tabs[i]);
|
||||
}
|
||||
},
|
||||
arrange: function (aIndex) {
|
||||
|
@ -422,19 +427,36 @@ var ctrlTab = {
|
|||
}
|
||||
XULBrowserWindow.setOverLink(value, null);
|
||||
},
|
||||
attachTab: function (aTab, aSelected) {
|
||||
if (aSelected)
|
||||
this.tabs.unshift(aTab);
|
||||
getTabList: function () {
|
||||
var list = Array.slice(gBrowser.mTabs);
|
||||
for (let i = 0; i < gBrowser.tabContainer.selectedIndex; i++)
|
||||
list.push(list.shift());
|
||||
if (!this._useTabBarOrder && this.recentlyUsedLimit > 0) {
|
||||
let recentlyUsedTabs = this._recentlyUsedTabs.slice(0, this.recentlyUsedLimit);
|
||||
for (let i = recentlyUsedTabs.length - 1; i >= 0; i--) {
|
||||
list.splice(list.indexOf(recentlyUsedTabs[i]), 1);
|
||||
list.unshift(recentlyUsedTabs[i]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
},
|
||||
attachTab: function (aTab, aPos) {
|
||||
if (aPos == 0)
|
||||
this._recentlyUsedTabs.unshift(aTab);
|
||||
else if (aPos)
|
||||
this._recentlyUsedTabs.splice(aPos, 0, aTab);
|
||||
else
|
||||
this.tabs.push(aTab);
|
||||
this._recentlyUsedTabs.push(aTab);
|
||||
},
|
||||
detachTab: function (aTab) {
|
||||
var i = this.tabs.indexOf(aTab);
|
||||
var i = this._recentlyUsedTabs.indexOf(aTab);
|
||||
if (i >= 0)
|
||||
this.tabs.splice(i, 1);
|
||||
this._recentlyUsedTabs.splice(i, 1);
|
||||
},
|
||||
open: function () {
|
||||
this._deferOnTabSelect = [];
|
||||
if (this.invertDirection)
|
||||
this._useTabBarOrder = true;
|
||||
|
||||
document.addEventListener("keyup", this, false);
|
||||
document.addEventListener("keydown", this, false);
|
||||
|
@ -447,9 +469,12 @@ var ctrlTab = {
|
|||
|
||||
// display $visibleCount tabs, starting with the first or
|
||||
// the second to the last tab, depending on whether Shift is pressed
|
||||
for (let index = this.invertDirection ? this.tabs.length - 2 : 0,
|
||||
i = this.visibleCount; i > 0; i--)
|
||||
this.addPreview(this.addBox(), this.tabs[index++ % this.tabs.length]);
|
||||
{
|
||||
let tabs = this.getTabList();
|
||||
let index = this.invertDirection ? tabs.length - 2 : 0;
|
||||
for (let i = this.visibleCount; i > 0; i--)
|
||||
this.addPreview(this.addBox(), tabs[index++ % tabs.length]);
|
||||
}
|
||||
|
||||
// regardless of visibleCount, highlight the second-visible tab
|
||||
this.selected = this.container.childNodes[1];
|
||||
|
@ -465,9 +490,9 @@ var ctrlTab = {
|
|||
this.invertDirection = event.shiftKey;
|
||||
if (isOpen)
|
||||
this.scroll();
|
||||
else if (this.tabs.length == 2)
|
||||
gBrowser.selectedTab = this.tabs[1];
|
||||
else if (this.tabs.length > 2)
|
||||
else if (this.tabCount == 2)
|
||||
gBrowser.selectedTab = this.getTabList()[1];
|
||||
else if (this.tabCount > 2)
|
||||
this.open();
|
||||
}
|
||||
break;
|
||||
|
@ -494,6 +519,7 @@ var ctrlTab = {
|
|||
this.removeBox(this.container.lastChild);
|
||||
this.selected = null;
|
||||
this.invertDirection = false;
|
||||
this._useTabBarOrder = false;
|
||||
this._uniqid = 0;
|
||||
this.label.value = "";
|
||||
this.setStatusbarValue();
|
||||
|
@ -506,7 +532,7 @@ var ctrlTab = {
|
|||
onTabSelect: function (aTab) {
|
||||
if (aTab.parentNode) {
|
||||
this.detachTab(aTab);
|
||||
this.attachTab(aTab, true);
|
||||
this.attachTab(aTab, 0);
|
||||
}
|
||||
},
|
||||
handleEvent: function (event) {
|
||||
|
@ -522,11 +548,11 @@ var ctrlTab = {
|
|||
this.onTabSelect(event.target);
|
||||
break;
|
||||
case "TabOpen":
|
||||
this.attachTab(event.target);
|
||||
this.attachTab(event.target, 1);
|
||||
break;
|
||||
case "TabClose":
|
||||
if (this.isOpen) {
|
||||
if (this.tabs.length == 2) {
|
||||
if (this.tabCount == 2) {
|
||||
// we have two tabs, one is being closed, so the panel isn't needed anymore
|
||||
this.panel.hidePopup();
|
||||
} else {
|
||||
|
|
|
@ -69,7 +69,6 @@ const MAX_HISTORY_MENU_ITEMS = 15;
|
|||
// We use this once, for Clear Private Data
|
||||
const GLUE_CID = "@mozilla.org/browser/browserglue;1";
|
||||
|
||||
var gURIFixup = null;
|
||||
var gCharsetMenu = null;
|
||||
var gLastBrowserCharset = null;
|
||||
var gPrevCharset = null;
|
||||
|
@ -986,10 +985,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
|||
|
||||
UpdateUrlbarSearchSplitterState();
|
||||
|
||||
try {
|
||||
placesMigrationTasks();
|
||||
} catch(ex) {}
|
||||
|
||||
PlacesStarButton.init();
|
||||
|
||||
// called when we go into full screen, even if it is
|
||||
|
@ -1318,7 +1313,6 @@ AutoHideTabbarPrefListener.prototype =
|
|||
catch (e) {
|
||||
}
|
||||
gBrowser.setStripVisibilityTo(aVisible);
|
||||
gPrefService.setBoolPref("browser.tabs.forceHide", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1641,8 +1635,7 @@ function BrowserOpenFileWindow()
|
|||
}
|
||||
}
|
||||
|
||||
function BrowserCloseTabOrWindow()
|
||||
{
|
||||
function BrowserCloseTabOrWindow() {
|
||||
#ifdef XP_MACOSX
|
||||
// If we're not a browser window, just close the window
|
||||
if (window.location.href != getBrowserURL()) {
|
||||
|
@ -1651,23 +1644,8 @@ function BrowserCloseTabOrWindow()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (gBrowser.tabContainer.childNodes.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
if (gBrowser.localName == "tabbrowser" && window.toolbar.visible &&
|
||||
!gPrefService.getBoolPref("browser.tabs.autoHide")) {
|
||||
// Replace the remaining tab with a blank one and focus the address bar
|
||||
gBrowser.removeCurrentTab();
|
||||
if (gURLBar)
|
||||
setTimeout(function() { gURLBar.focus(); }, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
closeWindow(true);
|
||||
// If the current tab is the last one, this will close the window.
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
|
||||
function BrowserTryToCloseWindow()
|
||||
|
@ -1970,37 +1948,25 @@ function checkForDirectoryListing()
|
|||
}
|
||||
}
|
||||
|
||||
function URLBarSetURI(aURI) {
|
||||
function URLBarSetURI(aURI, aValid) {
|
||||
var value = gBrowser.userTypedValue;
|
||||
var state = "invalid";
|
||||
var valid = false;
|
||||
|
||||
if (!value) {
|
||||
if (aURI) {
|
||||
// If the url has "wyciwyg://" as the protocol, strip it off.
|
||||
// Nobody wants to see it on the urlbar for dynamically generated
|
||||
// pages.
|
||||
if (!gURIFixup)
|
||||
gURIFixup = Cc["@mozilla.org/docshell/urifixup;1"]
|
||||
.getService(Ci.nsIURIFixup);
|
||||
try {
|
||||
aURI = gURIFixup.createExposableURI(aURI);
|
||||
} catch (ex) {}
|
||||
} else {
|
||||
aURI = getWebNavigation().currentURI;
|
||||
}
|
||||
let uri = aURI || getWebNavigation().currentURI;
|
||||
|
||||
if (aURI.spec == "about:blank") {
|
||||
// Replace "about:blank" with an empty string
|
||||
// only if there's no opener (bug 370555).
|
||||
value = content.opener ? aURI.spec : "";
|
||||
} else {
|
||||
value = losslessDecodeURI(aURI);
|
||||
state = "valid";
|
||||
}
|
||||
// Replace "about:blank" with an empty string
|
||||
// only if there's no opener (bug 370555).
|
||||
if (uri.spec == "about:blank")
|
||||
value = content.opener ? "about:blank" : "";
|
||||
else
|
||||
value = losslessDecodeURI(uri);
|
||||
|
||||
valid = value && (!aURI || aValid);
|
||||
}
|
||||
|
||||
gURLBar.value = value;
|
||||
SetPageProxyState(state);
|
||||
SetPageProxyState(valid ? "valid" : "invalid");
|
||||
}
|
||||
|
||||
function losslessDecodeURI(aURI) {
|
||||
|
@ -3760,6 +3726,11 @@ var XULBrowserWindow = {
|
|||
delete this.isImage;
|
||||
return this.isImage = document.getElementById("isImage");
|
||||
},
|
||||
get _uriFixup () {
|
||||
delete this._uriFixup;
|
||||
return this._uriFixup = Cc["@mozilla.org/docshell/urifixup;1"]
|
||||
.getService(Ci.nsIURIFixup);
|
||||
},
|
||||
|
||||
init: function () {
|
||||
this.throbberElement = document.getElementById("navigator-throbber");
|
||||
|
@ -3892,9 +3863,10 @@ var XULBrowserWindow = {
|
|||
// and progress bars and such
|
||||
if (aRequest) {
|
||||
let msg = "";
|
||||
let location;
|
||||
// Get the URI either from a channel or a pseudo-object
|
||||
if (aRequest instanceof nsIChannel || "URI" in aRequest) {
|
||||
let location = aRequest.URI;
|
||||
location = aRequest.URI;
|
||||
|
||||
// For keyword URIs clear the user typed value since they will be changed into real URIs
|
||||
if (location.scheme == "keyword" && aWebProgress.DOMWindow == content)
|
||||
|
@ -4017,8 +3989,15 @@ var XULBrowserWindow = {
|
|||
gBrowser.setIcon(gBrowser.mCurrentTab, null);
|
||||
|
||||
if (gURLBar) {
|
||||
URLBarSetURI(aLocationURI);
|
||||
PlacesStarButton.updateState(); // Update starring UI
|
||||
// Strip off "wyciwyg://" and passwords for the location bar
|
||||
let uri = aLocationURI;
|
||||
try {
|
||||
uri = this._uriFixup.createExposableURI(uri);
|
||||
} catch (e) {}
|
||||
URLBarSetURI(uri, true);
|
||||
|
||||
// Update starring UI
|
||||
PlacesStarButton.updateState();
|
||||
}
|
||||
|
||||
FullZoom.onLocationChange(aLocationURI);
|
||||
|
@ -4225,22 +4204,26 @@ var XULBrowserWindow = {
|
|||
// clear out search-engine data
|
||||
gBrowser.mCurrentBrowser.engines = null;
|
||||
|
||||
const nsIChannel = Components.interfaces.nsIChannel;
|
||||
var urlStr = aRequest.QueryInterface(nsIChannel).URI.spec;
|
||||
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
var uri = aRequest.QueryInterface(Ci.nsIChannel).URI;
|
||||
var observerService = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
|
||||
if (gURLBar &&
|
||||
gURLBar.value == "" &&
|
||||
getWebNavigation().currentURI.spec == "about:blank")
|
||||
URLBarSetURI(uri);
|
||||
|
||||
try {
|
||||
observerService.notifyObservers(content, "StartDocumentLoad", urlStr);
|
||||
observerService.notifyObservers(content, "StartDocumentLoad", uri.spec);
|
||||
} catch (e) {
|
||||
}
|
||||
},
|
||||
|
||||
endDocumentLoad: function (aRequest, aStatus) {
|
||||
const nsIChannel = Components.interfaces.nsIChannel;
|
||||
var urlStr = aRequest.QueryInterface(nsIChannel).originalURI.spec;
|
||||
var urlStr = aRequest.QueryInterface(Ci.nsIChannel).originalURI.spec;
|
||||
|
||||
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
var observerService = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
|
||||
var notification = Components.isSuccessCode(aStatus) ? "EndDocumentLoad" : "FailDocumentLoad";
|
||||
try {
|
||||
|
|
|
@ -99,10 +99,10 @@
|
|||
<tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
|
||||
|
||||
<!-- for search and content formfill/pw manager -->
|
||||
<panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true" level="top"/>
|
||||
<panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
|
||||
|
||||
<!-- for url bar autocomplete -->
|
||||
<panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true" level="top"/>
|
||||
<panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
|
||||
|
||||
<panel id="editBookmarkPanel"
|
||||
orient="vertical"
|
||||
|
|
|
@ -1106,7 +1106,7 @@ function formatNumber(number)
|
|||
|
||||
function formatDate(datestr, unknown)
|
||||
{
|
||||
// scriptable date formater, for pretty printing dates
|
||||
// scriptable date formatter, for pretty printing dates
|
||||
var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
|
||||
.getService(Components.interfaces.nsIScriptableDateFormat);
|
||||
|
||||
|
|
|
@ -201,8 +201,8 @@
|
|||
<description id="general-security-identity" class="header"/>
|
||||
<description id="general-security-privacy" class="header"/>
|
||||
<hbox align="right">
|
||||
<button id="security-view-more" label="&generalSecurityMore;"
|
||||
accesskey="&generalSecurityMore.accesskey;"
|
||||
<button id="security-view-details" label="&generalSecurityDetails;"
|
||||
accesskey="&generalSecurityDetails.accesskey;"
|
||||
oncommand="onClickMore();"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
|
|
@ -179,10 +179,10 @@ Sanitizer.prototype = {
|
|||
formdata: {
|
||||
clear: function ()
|
||||
{
|
||||
//Clear undo history of all searchBars
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
|
||||
var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManagerInterface.getEnumerator("navigator:browser");
|
||||
// Clear undo history of all searchBars
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManager.getEnumerator("navigator:browser");
|
||||
while (windows.hasMoreElements()) {
|
||||
var searchBar = windows.getNext().document.getElementById("searchbar");
|
||||
if (searchBar) {
|
||||
|
@ -195,9 +195,23 @@ Sanitizer.prototype = {
|
|||
.getService(Components.interfaces.nsIFormHistory2);
|
||||
formHistory.removeAllEntries();
|
||||
},
|
||||
|
||||
|
||||
get canClear()
|
||||
{
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManager.getEnumerator("navigator:browser");
|
||||
while (windows.hasMoreElements()) {
|
||||
var searchBar = windows.getNext().document.getElementById("searchbar");
|
||||
if (searchBar) {
|
||||
var transactionMgr = searchBar.textbox.editor.transactionManager;
|
||||
if (searchBar.value ||
|
||||
transactionMgr.numberOfUndoItems ||
|
||||
transactionMgr.numberOfRedoItems)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
|
||||
.getService(Components.interfaces.nsIFormHistory2);
|
||||
return formHistory.hasEntries;
|
||||
|
|
|
@ -1217,8 +1217,6 @@
|
|||
if (this.mStrip.collapsed)
|
||||
this.setStripVisibilityTo(true);
|
||||
|
||||
this.mPrefs.setBoolPref("browser.tabs.forceHide", false);
|
||||
|
||||
// wire up a progress listener for the new browser object.
|
||||
var position = this.mTabContainer.childNodes.length-1;
|
||||
var tabListener = this.mTabProgressListener(t, b, blank);
|
||||
|
@ -1404,40 +1402,31 @@
|
|||
if (aTab.localName != "tab")
|
||||
aTab = this.mCurrentTab;
|
||||
|
||||
var l = this.mTabContainer.childNodes.length;
|
||||
if (l == 1 && this.mPrefs.getBoolPref("browser.tabs.autoHide")) {
|
||||
// hide the tab bar
|
||||
this.mPrefs.setBoolPref("browser.tabs.forceHide", true);
|
||||
this.setStripVisibilityTo(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aFireBeforeUnload) {
|
||||
var ds = this.getBrowserForTab(aTab).docShell;
|
||||
let ds = this.getBrowserForTab(aTab).docShell;
|
||||
if (ds.contentViewer && !ds.contentViewer.permitUnload())
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
// see notes in addTab
|
||||
var _delayedUpdate = function(aTabContainer) {
|
||||
aTabContainer.adjustTabstrip();
|
||||
aTabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
}
|
||||
setTimeout(_delayedUpdate, 0, this.mTabContainer);
|
||||
|
||||
var l = this.mTabContainer.childNodes.length;
|
||||
if (l == 1) {
|
||||
// add a new blank tab to replace the one we're about to close
|
||||
// (this ensures that the remaining tab is as good as new)
|
||||
this.addTab("about:blank");
|
||||
l++;
|
||||
closeWindow(true);
|
||||
return null;
|
||||
}
|
||||
else if (l == 2) {
|
||||
if (l == 2) {
|
||||
var autohide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
|
||||
var tabStripHide = !window.toolbar.visible;
|
||||
if (autohide || tabStripHide)
|
||||
this.setStripVisibilityTo(false);
|
||||
}
|
||||
|
||||
// see notes in addTab
|
||||
var _delayedUpdate = function (aTabContainer) {
|
||||
aTabContainer.adjustTabstrip();
|
||||
aTabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
};
|
||||
setTimeout(_delayedUpdate, 0, this.mTabContainer);
|
||||
|
||||
// We're committed to closing the tab now.
|
||||
// Dispatch a notification.
|
||||
// We dispatch it before any teardown so that event listeners can
|
||||
|
@ -1479,6 +1468,9 @@
|
|||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!aTab)
|
||||
return null;
|
||||
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
var length = this.mTabs.length;
|
||||
|
||||
|
@ -1668,9 +1660,8 @@
|
|||
if (!this.mAddProgressListenerWasCalled) {
|
||||
this.mAddProgressListenerWasCalled = true;
|
||||
var autoHide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
|
||||
var forceHide = this.mPrefs.getBoolPref("browser.tabs.forceHide");
|
||||
var tabStripHide = !window.toolbar.visible;
|
||||
if (!autoHide && !forceHide && !tabStripHide)
|
||||
if (!autoHide && !tabStripHide)
|
||||
this.setStripVisibilityTo(true);
|
||||
}
|
||||
|
||||
|
@ -1927,20 +1918,16 @@
|
|||
<parameter name="aDragSession"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
#ifndef XP_MACOSX
|
||||
var accelKeyPressed = aEvent.ctrlKey;
|
||||
#else
|
||||
var accelKeyPressed = aEvent.metaKey;
|
||||
#endif
|
||||
var isCopy = aEvent.dataTransfer.dropEffect == "copy";
|
||||
var draggedTab;
|
||||
if (aDragSession.sourceNode && aDragSession.sourceNode.localName == "tab" &&
|
||||
(aDragSession.sourceNode.parentNode == this.mTabContainer ||
|
||||
aDragSession.sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
|
||||
aDragSession.sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))
|
||||
draggedTab = aDragSession.sourceNode;
|
||||
if (draggedTab && (accelKeyPressed || draggedTab.parentNode == this.mTabContainer)) {
|
||||
if (draggedTab && (isCopy || draggedTab.parentNode == this.mTabContainer)) {
|
||||
var newIndex = this.getNewIndex(aEvent);
|
||||
if (accelKeyPressed) {
|
||||
if (isCopy) {
|
||||
// copy the dropped tab (wherever it's from)
|
||||
var newTab = this.duplicateTab(draggedTab);
|
||||
this.moveTabTo(newTab, newIndex);
|
||||
|
@ -1997,7 +1984,7 @@
|
|||
if (aEvent.shiftKey)
|
||||
bgLoad = !bgLoad;
|
||||
|
||||
if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || accelKeyPressed) {
|
||||
if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || isCopy) {
|
||||
// We're adding a new tab.
|
||||
newIndex = this.getNewIndex(aEvent);
|
||||
newTab = this.loadOneTab(getShortcutOrURI(url), null, null, null, bgLoad, false);
|
||||
|
|
|
@ -49,7 +49,7 @@ function test() {
|
|||
}
|
||||
assertTabs(2);
|
||||
|
||||
ctrlTabTest([1] , 1, 0);
|
||||
//ctrlTabTest([1], 1, 0);
|
||||
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
|
||||
|
|
|
@ -62,8 +62,16 @@ install::
|
|||
|
||||
ifdef ENABLE_TESTS
|
||||
# Implemented in testing/testsuite-targets.mk
|
||||
|
||||
# Browser tests live in a slightly different location, so we correct the path
|
||||
ifdef TEST_PATH
|
||||
BROWSER_TEST_PATH = --test-path=../browser/$(TEST_PATH)
|
||||
else
|
||||
BROWSER_TEST_PATH =
|
||||
endif
|
||||
|
||||
mochitest-browser-chrome:
|
||||
$(RUN_MOCHITEST) --browser-chrome
|
||||
$(RUN_MOCHITEST) --browser-chrome $(BROWSER_TEST_PATH)
|
||||
$(CHECK_TEST_ERROR)
|
||||
|
||||
mochitest:: mochitest-browser-chrome
|
||||
|
|
|
@ -166,7 +166,10 @@ ServiceInfo.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function WebContentConverterRegistrar() {}
|
||||
function WebContentConverterRegistrar() {
|
||||
this._contentTypes = { };
|
||||
this._autoHandleContentTypes = { };
|
||||
}
|
||||
|
||||
WebContentConverterRegistrar.prototype = {
|
||||
get stringBundle() {
|
||||
|
@ -185,14 +188,6 @@ WebContentConverterRegistrar.prototype = {
|
|||
return this.stringBundle.GetStringFromName(key);
|
||||
},
|
||||
|
||||
_contentTypes: { },
|
||||
|
||||
/**
|
||||
* Track auto handlers for various content types using a content-type to
|
||||
* handler map.
|
||||
*/
|
||||
_autoHandleContentTypes: { },
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
|
|
|
@ -177,10 +177,9 @@ BrowserGlue.prototype = {
|
|||
{
|
||||
// Check to see if the EULA must be shown on startup
|
||||
|
||||
// Global override for tinderbox machines
|
||||
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var mustDisplayEULA = true;
|
||||
var mustDisplayEULA = false;
|
||||
try {
|
||||
mustDisplayEULA = !prefBranch.getBoolPref("browser.EULA.override");
|
||||
} catch (e) {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Ben Goodger <beng@google.com>
|
||||
* Myk Melez <myk@mozilla.org>
|
||||
* Asaf Romano <mano@mozilla.com>
|
||||
* Marco Bonardo <mak77@supereva.it>
|
||||
* 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
|
||||
|
@ -298,7 +298,7 @@ PlacesController.prototype = {
|
|||
return false;
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(nodes[i]) &&
|
||||
!PlacesControllerDragHelper.canMoveContainerNode(nodes[i]))
|
||||
!PlacesControllerDragHelper.canMoveNode(nodes[i]))
|
||||
return false;
|
||||
|
||||
// We don't call nodeIsReadOnly here, because nodeIsReadOnly means that
|
||||
|
@ -351,7 +351,7 @@ PlacesController.prototype = {
|
|||
// if the clipboard contains TYPE_X_MOZ_PLACE_* data, it is definitely
|
||||
// pasteable, with no need to unwrap all the nodes.
|
||||
|
||||
var flavors = PlacesUIUtils.placesFlavors;
|
||||
var flavors = PlacesControllerDragHelper.placesFlavors;
|
||||
var clipboard = PlacesUIUtils.clipboard;
|
||||
var hasPlacesData =
|
||||
clipboard.hasDataMatchingFlavors(flavors, flavors.length,
|
||||
|
@ -863,11 +863,13 @@ PlacesController.prototype = {
|
|||
* An array of nodes to remove. Should all be adjacent.
|
||||
* @param [out] transactions
|
||||
* An array of transactions.
|
||||
* @param [optional] removedFolders
|
||||
* An array of folder nodes that have already been removed.
|
||||
*/
|
||||
_removeRange: function PC__removeRange(range, transactions) {
|
||||
_removeRange: function PC__removeRange(range, transactions, removedFolders) {
|
||||
NS_ASSERT(transactions instanceof Array, "Must pass a transactions array");
|
||||
|
||||
var removedFolders = [];
|
||||
if (!removedFolders)
|
||||
removedFolders = [];
|
||||
|
||||
for (var i = 0; i < range.length; ++i) {
|
||||
var node = range[i];
|
||||
|
@ -906,10 +908,11 @@ PlacesController.prototype = {
|
|||
_removeRowsFromBookmarks: function PC__removeRowsFromBookmarks(txnName) {
|
||||
var ranges = this._view.getRemovableSelectionRanges();
|
||||
var transactions = [];
|
||||
// Delete the selected rows. Do this by walking the selection backward, so
|
||||
// that when undo is performed they are re-inserted in the correct order.
|
||||
for (var i = ranges.length - 1; i >= 0 ; --i)
|
||||
this._removeRange(ranges[i], transactions);
|
||||
var removedFolders = [];
|
||||
|
||||
for (var i = 0; i < ranges.length; i++)
|
||||
this._removeRange(ranges[i], transactions, removedFolders);
|
||||
|
||||
if (transactions.length > 0) {
|
||||
var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
|
||||
PlacesUIUtils.ptm.doTransaction(txn);
|
||||
|
@ -1012,62 +1015,50 @@ PlacesController.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Get a TransferDataSet containing the content of the selection that can be
|
||||
* dropped elsewhere.
|
||||
* @param dragAction
|
||||
* The action to happen when dragging, i.e. copy
|
||||
* @returns A TransferDataSet object that can be dragged and dropped
|
||||
* elsewhere.
|
||||
* Fills a DataTransfer object with the content of the selection that can be
|
||||
* dropped elsewhere.
|
||||
* @param aEvent
|
||||
* The dragstart event.
|
||||
*/
|
||||
getTransferData: function PC_getTransferData(dragAction) {
|
||||
var copy = dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
setDataTransfer: function PC_setDataTransfer(aEvent) {
|
||||
var dt = aEvent.dataTransfer;
|
||||
var doCopy = dt.effectAllowed == "copyLink" || dt.effectAllowed == "copy";
|
||||
|
||||
var result = this._view.getResult();
|
||||
var oldViewer = result.viewer;
|
||||
try {
|
||||
result.viewer = null;
|
||||
var nodes = this._view.getDragableSelection();
|
||||
if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_MOVE) {
|
||||
nodes = nodes.filter(function(node) {
|
||||
var parent = node.parent;
|
||||
return parent && !PlacesUtils.nodeIsReadOnly(parent);
|
||||
});
|
||||
}
|
||||
|
||||
var dataSet = new TransferDataSet();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
|
||||
var data = new TransferData();
|
||||
function addData(type, overrideURI) {
|
||||
data.addDataForFlavour(type, PlacesUIUtils._wrapString(
|
||||
PlacesUtils.wrapNode(node, type, overrideURI, copy)));
|
||||
function addData(type, index, overrideURI) {
|
||||
var wrapNode = PlacesUtils.wrapNode(node, type, overrideURI, doCopy);
|
||||
dt.mozSetDataAt(type, wrapNode, index);
|
||||
}
|
||||
|
||||
function addURIData(overrideURI) {
|
||||
addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI);
|
||||
addData(PlacesUtils.TYPE_UNICODE, overrideURI);
|
||||
addData(PlacesUtils.TYPE_HTML, overrideURI);
|
||||
function addURIData(index, overrideURI) {
|
||||
addData(PlacesUtils.TYPE_X_MOZ_URL, index, overrideURI);
|
||||
addData(PlacesUtils.TYPE_UNICODE, index, overrideURI);
|
||||
addData(PlacesUtils.TYPE_HTML, index, overrideURI);
|
||||
}
|
||||
|
||||
// This order is _important_! It controls how this and other
|
||||
// applications select data to be inserted based on type.
|
||||
addData(PlacesUtils.TYPE_X_MOZ_PLACE);
|
||||
|
||||
var uri;
|
||||
|
||||
// Allow dropping the feed uri of live-bookmark folders
|
||||
addData(PlacesUtils.TYPE_X_MOZ_PLACE, i);
|
||||
|
||||
// Drop the feed uri for livemark containers
|
||||
if (PlacesUtils.nodeIsLivemarkContainer(node))
|
||||
uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec;
|
||||
|
||||
addURIData(uri);
|
||||
dataSet.push(data);
|
||||
addURIData(i, PlacesUtils.livemarks.getFeedURI(node.itemId).spec);
|
||||
else if (node.uri)
|
||||
addURIData(i);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (oldViewer)
|
||||
result.viewer = oldViewer;
|
||||
}
|
||||
return dataSet;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1108,7 +1099,7 @@ PlacesController.prototype = {
|
|||
uri) + suffix);
|
||||
|
||||
var placeSuffix = i < (nodes.length - 1) ? "," : "";
|
||||
var resolveShortcuts = !PlacesControllerDragHelper.canMoveContainerNode(node);
|
||||
var resolveShortcuts = !PlacesControllerDragHelper.canMoveNode(node);
|
||||
return PlacesUtils.wrapNode(node, type, overrideURI, resolveShortcuts) + placeSuffix;
|
||||
}
|
||||
|
||||
|
@ -1245,6 +1236,18 @@ PlacesController.prototype = {
|
|||
* Drop functions are passed the view that is being dropped on.
|
||||
*/
|
||||
var PlacesControllerDragHelper = {
|
||||
/**
|
||||
* DOM Element currently being dragged over
|
||||
*/
|
||||
currentDropTarget: null,
|
||||
|
||||
/**
|
||||
* Current nsIDOMDataTransfer
|
||||
* We need to cache this because we don't have access to the event in the
|
||||
* treeView's canDrop or drop methods, and session.dataTransfer would not be
|
||||
* filled for drag and drop from external sources (eg. the OS).
|
||||
*/
|
||||
currentDataTransfer: null,
|
||||
|
||||
/**
|
||||
* Determines if the mouse is currently being dragged over a child node of
|
||||
|
@ -1265,11 +1268,6 @@ var PlacesControllerDragHelper = {
|
|||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* DOM Element currently being dragged over
|
||||
*/
|
||||
currentDropTarget: null,
|
||||
|
||||
/**
|
||||
* @returns The current active drag session. Returns null if there is none.
|
||||
*/
|
||||
|
@ -1279,6 +1277,19 @@ var PlacesControllerDragHelper = {
|
|||
return dragService.getCurrentSession();
|
||||
},
|
||||
|
||||
/**
|
||||
* Extract the first accepted flavor from a flavors array.
|
||||
* @param aFlavors
|
||||
* The flavors array.
|
||||
*/
|
||||
getFirstValidFlavor: function PCDH_getFirstValidFlavor(aFlavors) {
|
||||
for (var i = 0; i < aFlavors.length; i++) {
|
||||
if (this.GENERIC_VIEW_DROP_TYPES.indexOf(aFlavors[i]) != -1)
|
||||
return aFlavors[i];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether or not the data currently being dragged can be dropped
|
||||
* on a places view.
|
||||
|
@ -1286,35 +1297,28 @@ var PlacesControllerDragHelper = {
|
|||
* The insertion point where the items should be dropped
|
||||
*/
|
||||
canDrop: function PCDH_canDrop(ip) {
|
||||
var session = this.getSession();
|
||||
if (!session)
|
||||
return false;
|
||||
|
||||
var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
||||
var foundType = false;
|
||||
for (var i = 0; i < types.length && !foundType; ++i) {
|
||||
if (session.isDataFlavorSupported(types[i]))
|
||||
foundType = true;
|
||||
}
|
||||
|
||||
if (!foundType)
|
||||
return false;
|
||||
var dt = this.currentDataTransfer;
|
||||
var dropCount = dt.mozItemCount;
|
||||
|
||||
// Check every dragged item
|
||||
var xferable = this._initTransferable(session);
|
||||
var dropCount = session.numDropItems;
|
||||
for (i = 0; i < dropCount; i++) {
|
||||
// Get the information of the dragged item
|
||||
session.getData(xferable, i);
|
||||
var data = { }, flavor = { };
|
||||
xferable.getAnyTransferData(flavor, data, { });
|
||||
data.value.QueryInterface(Ci.nsISupportsString);
|
||||
var dragged = PlacesUtils.unwrapNodes(data.value.data, flavor.value)[0];
|
||||
for (var i = 0; i < dropCount; i++) {
|
||||
var flavor = this.getFirstValidFlavor(dt.mozTypesAt(i));
|
||||
if (!flavor)
|
||||
return false;
|
||||
|
||||
var data = dt.mozGetDataAt(flavor, i);
|
||||
|
||||
try {
|
||||
var dragged = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only bookmarks and urls can be dropped into tag containers
|
||||
if (ip.isTag && dragged.type != PlacesUtils.TYPE_X_MOZ_URL &&
|
||||
(dragged.type != PlacesUtils.TYPE_X_MOZ_PLACE ||
|
||||
/^place:/.test(dragged.uri)))
|
||||
if (ip.isTag && ip.orientation == Ci.nsITreeView.DROP_ON &&
|
||||
dragged.type != PlacesUtils.TYPE_X_MOZ_URL &&
|
||||
(dragged.type != PlacesUtils.TYPE_X_MOZ_PLACE ||
|
||||
/^place:/.test(dragged.uri)))
|
||||
return false;
|
||||
|
||||
// The following loop disallows the dropping of a folder on itself or
|
||||
|
@ -1329,39 +1333,36 @@ var PlacesControllerDragHelper = {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines if a container node can be moved.
|
||||
* Determines if a node can be moved.
|
||||
*
|
||||
* @param aNode
|
||||
* A bookmark folder node.
|
||||
* @param [optional] aInsertionPoint
|
||||
* The insertion point of the drop target.
|
||||
* @returns True if the container can be moved.
|
||||
* A nsINavHistoryResultNode node.
|
||||
* @returns True if the node can be moved, false otherwise.
|
||||
*/
|
||||
canMoveContainerNode:
|
||||
function PCDH_canMoveContainerNode(aNode, aInsertionPoint) {
|
||||
canMoveNode:
|
||||
function PCDH_canMoveNode(aNode) {
|
||||
// can't move query root
|
||||
if (!aNode.parent)
|
||||
return false;
|
||||
|
||||
var targetId = aInsertionPoint ? aInsertionPoint.itemId : -1;
|
||||
var parentId = PlacesUtils.getConcreteItemId(aNode.parent);
|
||||
var concreteId = PlacesUtils.getConcreteItemId(aNode);
|
||||
|
||||
// can't move tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aNode))
|
||||
// can't move children of tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aNode.parent))
|
||||
return false;
|
||||
|
||||
// check is child of a read-only container
|
||||
// can't move children of read-only containers
|
||||
if (PlacesUtils.nodeIsReadOnly(aNode.parent))
|
||||
return false;
|
||||
|
||||
// check for special folders, etc
|
||||
if (!this.canMoveContainer(aNode.itemId, parentId))
|
||||
if (PlacesUtils.nodeIsContainer(aNode) &&
|
||||
!this.canMoveContainer(aNode.itemId, parentId))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1392,89 +1393,95 @@ var PlacesControllerDragHelper = {
|
|||
if (aParentId == null || aParentId == -1)
|
||||
aParentId = PlacesUtils.bookmarks.getFolderIdForItem(aId);
|
||||
|
||||
if(PlacesUtils.bookmarks.getFolderReadonly(aParentId))
|
||||
if (PlacesUtils.bookmarks.getFolderReadonly(aParentId))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a Transferable object that can be filled with data of types
|
||||
* supported by a view.
|
||||
* @param session
|
||||
* The active drag session
|
||||
* @returns An object implementing nsITransferable that can receive data
|
||||
* dropped onto a view.
|
||||
*/
|
||||
_initTransferable: function PCDH__initTransferable(session) {
|
||||
var xferable = Cc["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Ci.nsITransferable);
|
||||
var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
||||
for (var i = 0; i < types.length; ++i) {
|
||||
if (session.isDataFlavorSupported(types[i]))
|
||||
xferable.addDataFlavor(types[i]);
|
||||
}
|
||||
return xferable;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles the drop of one or more items onto a view.
|
||||
* @param insertionPoint
|
||||
* The insertion point where the items should be dropped
|
||||
*/
|
||||
onDrop: function PCDH_onDrop(insertionPoint) {
|
||||
var session = this.getSession();
|
||||
// XXX dragAction is not valid, so we also set copy below by checking
|
||||
// whether the dropped item is moveable, before creating the transaction
|
||||
var copy = session.dragAction & Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
var dt = this.currentDataTransfer;
|
||||
var doCopy = dt.dropEffect == "copy";
|
||||
|
||||
var transactions = [];
|
||||
var xferable = this._initTransferable(session);
|
||||
var dropCount = session.numDropItems;
|
||||
|
||||
var dropCount = dt.mozItemCount;
|
||||
var movedCount = 0;
|
||||
|
||||
for (var i = 0; i < dropCount; ++i) {
|
||||
session.getData(xferable, i);
|
||||
var flavor = this.getFirstValidFlavor(dt.mozTypesAt(i));
|
||||
if (!flavor)
|
||||
return false;
|
||||
|
||||
var data = { }, flavor = { };
|
||||
xferable.getAnyTransferData(flavor, data, { });
|
||||
data.value.QueryInterface(Ci.nsISupportsString);
|
||||
|
||||
// There's only ever one in the D&D case.
|
||||
var unwrapped = PlacesUtils.unwrapNodes(data.value.data,
|
||||
flavor.value)[0];
|
||||
var data = dt.mozGetDataAt(flavor, i);
|
||||
// There's only ever one in the D&D case.
|
||||
var unwrapped = PlacesUtils.unwrapNodes(data, flavor)[0];
|
||||
|
||||
var index = insertionPoint.index;
|
||||
|
||||
// Adjust insertion index to prevent reversal of dragged items. When you
|
||||
// drag multiple elts upward: need to increment index or each successive
|
||||
// elt will be inserted at the same index, each above the previous.
|
||||
if (index != -1 && index < unwrapped.index) {
|
||||
index = index + movedCount;
|
||||
movedCount++;
|
||||
}
|
||||
var dragginUp = insertionPoint.itemId == unwrapped.parent &&
|
||||
index < PlacesUtils.bookmarks.getItemIndex(unwrapped.id);
|
||||
if (index != -1 && dragginUp)
|
||||
index+= movedCount++;
|
||||
|
||||
// if dragging over a tag container we should tag the item
|
||||
if (insertionPoint.isTag) {
|
||||
if (insertionPoint.isTag &&
|
||||
insertionPoint.orientation == Ci.nsITreeView.DROP_ON) {
|
||||
var uri = PlacesUtils._uri(unwrapped.uri);
|
||||
var tagItemId = insertionPoint.itemId;
|
||||
transactions.push(PlacesUIUtils.ptm.tagURI(uri,[tagItemId]));
|
||||
}
|
||||
else {
|
||||
if (unwrapped.id && !this.canMoveContainer(unwrapped.id, null))
|
||||
copy = true;
|
||||
else if (unwrapped.concreteId &&
|
||||
!this.canMoveContainer(unwrapped.concreteId, null))
|
||||
copy = true;
|
||||
|
||||
transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
|
||||
flavor.value, insertionPoint.itemId,
|
||||
index, copy));
|
||||
flavor, insertionPoint.itemId,
|
||||
index, doCopy));
|
||||
}
|
||||
}
|
||||
|
||||
var txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions);
|
||||
PlacesUIUtils.ptm.doTransaction(txn);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if we can insert into a container.
|
||||
* @param aContainer
|
||||
* The container were we are want to drop
|
||||
*/
|
||||
disallowInsertion: function(aContainer) {
|
||||
NS_ASSERT(aContainer, "empty container");
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
},
|
||||
|
||||
placesFlavors: [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE],
|
||||
|
||||
GENERIC_VIEW_DROP_TYPES: [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE,
|
||||
PlacesUtils.TYPE_X_MOZ_URL,
|
||||
PlacesUtils.TYPE_UNICODE],
|
||||
|
||||
/**
|
||||
* Returns our flavourSet
|
||||
*/
|
||||
get flavourSet() {
|
||||
delete this.flavourSet;
|
||||
var flavourSet = new FlavourSet();
|
||||
var acceptedDropFlavours = this.GENERIC_VIEW_DROP_TYPES;
|
||||
acceptedDropFlavours.forEach(flavourSet.appendFlavour, flavourSet);
|
||||
return this.flavourSet = flavourSet;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
# Ben Goodger <beng@google.com>
|
||||
# Asaf Romano <mano@mozilla.com>
|
||||
# Simon Bünzli <zeniko@gmail.com>
|
||||
# Marco Bonardo <mak77@supereva.it>
|
||||
# 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
|
||||
|
@ -88,8 +88,11 @@
|
|||
PlacesControllerDragHelper.currentDropTarget = aEvent.target;
|
||||
// check if we have a valid dropPoint
|
||||
var dropPoint = this._getDropPoint(aEvent);
|
||||
if (!dropPoint)
|
||||
if (!dropPoint || !dropPoint.ip ||
|
||||
!PlacesControllerDragHelper.canDrop(dropPoint.ip)) {
|
||||
aEvent.dataTransfer.effectAllowed = "none";
|
||||
return;
|
||||
}
|
||||
|
||||
// add a dragover attribute to this popup
|
||||
this.setAttribute("dragover", "true");
|
||||
|
@ -109,7 +112,7 @@
|
|||
.setTimer(this._overFolder.hoverTime);
|
||||
}
|
||||
// since we are dropping into a folder set the corresponding style
|
||||
dropPoint.folderNode.setAttribute("dragover-into", "true");
|
||||
dropPoint.folderNode.setAttribute("_moz-menuactive", true);
|
||||
}
|
||||
else {
|
||||
// We are not dragging over a folder
|
||||
|
@ -117,6 +120,14 @@
|
|||
this._overFolder.clear();
|
||||
}
|
||||
|
||||
// Autoscroll the popup strip if we drag over the scroll buttons
|
||||
var anonid = aEvent.originalTarget.getAttribute('anonid');
|
||||
var scrollDir = anonid == "scrollbutton-up" ? -1 :
|
||||
anonid == "scrollbutton-down" ? 1 : 0;
|
||||
if (scrollDir != 0) {
|
||||
this._scrollBox.scrollByIndex(scrollDir);
|
||||
}
|
||||
|
||||
// Check if we should hide the drop indicator for this target
|
||||
if (!aDragSession.canDrop ||
|
||||
!dropPoint || dropPoint.folderNode ||
|
||||
|
@ -125,29 +136,22 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var scrollBoxObject = this._scrollBox.scrollBoxObject;
|
||||
// Autoscroll the popup strip if we drag over the scroll buttons
|
||||
var anonid = aEvent.originalTarget.getAttribute("anonid");
|
||||
var scrollDir = anonid == "scrollbutton-up" ? -1 :
|
||||
anonid == "scrollbutton-down" ? 1 : 0;
|
||||
if (scrollDir != 0)
|
||||
this._scrollBox.scrollByIndex(scrollDir);
|
||||
|
||||
// We should display the drop indicator relative to the arrowscrollbox
|
||||
var sbo = this._scrollBox.scrollBoxObject;
|
||||
var newMarginTop = 0;
|
||||
if (scrollDir == 0) {
|
||||
var node = this.firstChild;
|
||||
while (node && aEvent.screenY > node.boxObject.screenY +
|
||||
node.boxObject.height / 2)
|
||||
node = node.nextSibling;
|
||||
newMarginTop = node ? node.boxObject.screenY - scrollBoxObject.screenY :
|
||||
scrollBoxObject.height;
|
||||
newMarginTop = node ? node.boxObject.screenY - sbo.screenY :
|
||||
sbo.height;
|
||||
}
|
||||
else if (scrollDir == 1)
|
||||
newMarginTop = scrollBoxObject.height;
|
||||
newMarginTop = sbo.height;
|
||||
|
||||
// set the new marginTop based on arrowscrollbox
|
||||
newMarginTop += scrollBoxObject.y - this._scrollBox.boxObject.y;
|
||||
newMarginTop += sbo.y - this._scrollBox.boxObject.y;
|
||||
this._indicatorBar.firstChild.style.marginTop = newMarginTop + "px";
|
||||
this._indicatorBar.hidden = false;
|
||||
]]></body>
|
||||
|
@ -158,9 +162,8 @@
|
|||
<parameter name="aDragSession"/>
|
||||
<body><![CDATA[
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
this.removeAttribute("dragover");
|
||||
// remove dragover-into style from previous target
|
||||
aEvent.target.removeAttribute("dragover-into");
|
||||
|
||||
// if we have not moved to a valid new target clear the drop indicator
|
||||
// this happens when moving out of the popup
|
||||
|
@ -177,7 +180,10 @@
|
|||
// The autoopened attribute is set when this folder was automatically
|
||||
// opened after the user dragged over it. If this attribute is set,
|
||||
// auto-close the folder on drag exit.
|
||||
if (this.hasAttribute("autoopened")) {
|
||||
// We should also try to close this popup if the drag has started
|
||||
// from here, the timer will check if we are dragging over a child.
|
||||
if (this.hasAttribute("autoopened") ||
|
||||
this.hasAttribute("dragstart")) {
|
||||
this._overFolder.closeMenuTimer = this._overFolder
|
||||
.setTimer(this._overFolder.hoverTime);
|
||||
}
|
||||
|
@ -191,26 +197,32 @@
|
|||
<parameter name="aXferData"/>
|
||||
<parameter name="aDragAction"/>
|
||||
<body><![CDATA[
|
||||
// Force a copy action if parent node is a query or not-removable
|
||||
if (aEvent.ctrlKey ||
|
||||
PlacesUtils.nodeIsQuery(aEvent.target.node.parent) ||
|
||||
!PlacesControllerDragHelper.canMoveContainerNode(aEvent.target.node))
|
||||
aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
var draggedNode = aEvent.target.node;
|
||||
|
||||
// Force a copy action if parent node is a query or we are dragging a
|
||||
// not-removable node
|
||||
if (!PlacesControllerDragHelper.canMoveNode(draggedNode))
|
||||
aEvent.dataTransfer.effectAllowed = "copyLink";
|
||||
|
||||
// activate the view and cache the dragged node
|
||||
this._rootView._draggedNode = aEvent.target.node;
|
||||
this._rootView._draggedNode = draggedNode;
|
||||
this._rootView.focus();
|
||||
|
||||
aXferData.data = this._rootView.controller
|
||||
.getTransferData(aDragAction.action);
|
||||
// Fill the dataTransfer
|
||||
this._rootView._controller.setDataTransfer(aEvent);
|
||||
|
||||
this.setAttribute("dragstart", "true");
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="onDrop">
|
||||
<parameter name="aEvent"/>
|
||||
<parameter name="aDropData"/>
|
||||
<parameter name="aDropData"/>
|
||||
<parameter name="aSession"/>
|
||||
<body><![CDATA[
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
|
||||
|
||||
var dropPoint = this._getDropPoint(aEvent);
|
||||
if (!dropPoint)
|
||||
return;
|
||||
|
@ -222,10 +234,7 @@
|
|||
<!-- This returns the FavourSet accepted by this popup -->
|
||||
<method name="getSupportedFlavours">
|
||||
<body><![CDATA[
|
||||
var flavourSet = new FlavourSet();
|
||||
var acceptedDropFlavours = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
||||
acceptedDropFlavours.forEach(flavourSet.appendFlavour, flavourSet);
|
||||
return flavourSet;
|
||||
return PlacesControllerDragHelper.flavourSet;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -246,7 +255,8 @@
|
|||
betweenMarkers = false;
|
||||
|
||||
// hide the dropmarker if current node is not a places bookmark item
|
||||
return !(target && target.node && betweenMarkers && this.canDrop());
|
||||
return !(target && target.node && betweenMarkers &&
|
||||
this.canDrop(aEvent));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -257,71 +267,87 @@
|
|||
<body><![CDATA[
|
||||
// Can't drop if the menu isn't a folder
|
||||
var resultNode = this._resultNode;
|
||||
if (!PlacesUtils.nodeIsFolder(resultNode))
|
||||
|
||||
if (!PlacesUtils.nodeIsFolder(resultNode) ||
|
||||
PlacesControllerDragHelper.disallowInsertion(resultNode)) {
|
||||
aEvent.dataTransfer.effectAllowed = "none";
|
||||
return null;
|
||||
}
|
||||
|
||||
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
|
||||
var dropPoint = { ip: null, folderNode: null };
|
||||
|
||||
// set the limits for valid items
|
||||
var start = 0;
|
||||
var popup = this;
|
||||
var end = popup.childNodes.length;
|
||||
if (this._startMarker != -1)
|
||||
start = this._startMarker + 1;
|
||||
if (this._endMarker != -1)
|
||||
end = this._endMarker;
|
||||
// The node we are dragging over
|
||||
var xulNode = aEvent.target;
|
||||
|
||||
// Loop through all the nodes to find the correct dropPoint
|
||||
var popupY = popup.boxObject.y;
|
||||
// we should add the scrollBox button height if visible
|
||||
popupY += this._scrollBox.scrollBoxObject.y - popup.boxObject.y;
|
||||
for (var i = start; i < end; i++) {
|
||||
var xulNode = popup.childNodes[i];
|
||||
var nodeY = xulNode.boxObject.y - popupY;
|
||||
var nodeHeight = xulNode.boxObject.height;
|
||||
if (xulNode.node &&
|
||||
(PlacesUtils.nodeIsFolder(xulNode.node) ||
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node)) &&
|
||||
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
||||
// This is a folder. If the mouse is in the top 25% of the
|
||||
// node, drop above the folder. If it's in the middle
|
||||
// 50%, drop into the folder. If it's past that, drop below.
|
||||
if (aEvent.layerY < nodeY + (nodeHeight * 0.25)) {
|
||||
// Drop above this folder.
|
||||
dropPoint.ip = new InsertionPoint(resultNode.itemId,
|
||||
i - start, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
else if (aEvent.layerY < nodeY + (nodeHeight * 0.75)) {
|
||||
// Drop inside this folder.
|
||||
dropPoint.ip = new InsertionPoint(xulNode.node.itemId, -1, 1);
|
||||
dropPoint.beforeIndex = i;
|
||||
dropPoint.folderNode = xulNode;
|
||||
return dropPoint;
|
||||
}
|
||||
// Calculate positions taking care of arrowscrollbox
|
||||
var sbo = this._scrollBox.scrollBoxObject;
|
||||
var eventY = aEvent.layerY;
|
||||
var nodeY = xulNode.boxObject.y - sbo.y;
|
||||
var nodeHeight = xulNode.boxObject.height;
|
||||
|
||||
if (!xulNode.node) {
|
||||
// if we are dragging over a non places node drop at the end
|
||||
dropPoint.ip = new InsertionPoint(resultNode.itemId,
|
||||
-1,
|
||||
Ci.nsITreeView.DROP_ON);
|
||||
return dropPoint;
|
||||
}
|
||||
else if ((PlacesUtils.nodeIsFolder(xulNode.node) ||
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node)) &&
|
||||
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
|
||||
// This is a folder or a tag container.
|
||||
if (eventY - nodeY < nodeHeight * 0.25) {
|
||||
// If the mouse is in the top 25% of the node,
|
||||
// drop above the folder.
|
||||
dropPoint.ip = new InsertionPoint(
|
||||
resultNode.itemId,
|
||||
-1,
|
||||
Ci.nsITreeView.DROP_BEFORE,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node),
|
||||
xulNode.node.itemId);
|
||||
return dropPoint;
|
||||
}
|
||||
else {
|
||||
// This is a non-folder node. If the mouse is above the middle,
|
||||
// drop above the folder. Otherwise, drop below.
|
||||
if (aEvent.layerY <= nodeY + (nodeHeight / 2)) {
|
||||
// Drop above this bookmark.
|
||||
dropPoint.ip = new InsertionPoint(resultNode.itemId,
|
||||
i - start, -1);
|
||||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
else if (eventY - nodeY < nodeHeight * 0.75) {
|
||||
// If the mouse is before the 75 % of the node drop
|
||||
// inside this folder.
|
||||
dropPoint.ip = new InsertionPoint(
|
||||
PlacesUtils.getConcreteItemId(xulNode.node),
|
||||
-1,
|
||||
Ci.nsITreeView.DROP_ON,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node));
|
||||
dropPoint.folderNode = xulNode;
|
||||
return dropPoint;
|
||||
}
|
||||
}
|
||||
// Should drop below the last node.
|
||||
dropPoint.ip = new InsertionPoint(resultNode.itemId, -1, 1);
|
||||
dropPoint.beforeIndex = -1;
|
||||
else if (eventY - nodeY <= nodeHeight / 2) {
|
||||
// This is a non-folder node or a readonly folder.
|
||||
// If the mouse is above the middle, drop above this item.
|
||||
dropPoint.ip = new InsertionPoint(
|
||||
resultNode.itemId,
|
||||
-1,
|
||||
Ci.nsITreeView.DROP_BEFORE,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node),
|
||||
xulNode.node.itemId);
|
||||
return dropPoint;
|
||||
}
|
||||
|
||||
// Drop below the item.
|
||||
dropPoint.ip = new InsertionPoint(
|
||||
resultNode.itemId,
|
||||
-1,
|
||||
Ci.nsITreeView.DROP_AFTER,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node),
|
||||
xulNode.node.itemId);
|
||||
return dropPoint;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="canDrop">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
|
||||
|
||||
var ip = this._rootView.insertionPoint;
|
||||
return ip && PlacesControllerDragHelper.canDrop(ip);
|
||||
]]></body>
|
||||
|
@ -332,7 +358,10 @@
|
|||
closing of folders when the mouse hovers. -->
|
||||
<field name="_overFolder"><![CDATA[({
|
||||
_self: this,
|
||||
_folder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null},
|
||||
_folder: {node: null,
|
||||
openTimer: null,
|
||||
hoverTime: 350,
|
||||
closeTimer: null},
|
||||
_closeMenuTimer: null,
|
||||
|
||||
get node() {
|
||||
|
@ -406,13 +435,17 @@
|
|||
else if (aTimer == this.closeMenuTimer) {
|
||||
// Timer to close this menu after the drag exit.
|
||||
var popup = this._self;
|
||||
if (!PlacesControllerDragHelper.draggingOverChildNode(popup.parentNode)) {
|
||||
// if we are no more dragging we can leave the menu open to allow
|
||||
// for better D&D bookmark organization
|
||||
if (PlacesControllerDragHelper.getSession() &&
|
||||
!PlacesControllerDragHelper.draggingOverChildNode(popup.parentNode)) {
|
||||
popup.hidePopup();
|
||||
// Close any parent menus that aren't being dragged over;
|
||||
// otherwise they'll stay open because they couldn't close
|
||||
// while this menu was being dragged over.
|
||||
this.closeParentMenus();
|
||||
}
|
||||
this._closeMenuTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -439,8 +472,8 @@
|
|||
if (this._folder.node && this._folder.node.lastChild) {
|
||||
if (!this._folder.node.lastChild.hasAttribute("dragover"))
|
||||
this._folder.node.lastChild.hidePopup();
|
||||
// remove dragover-into style
|
||||
this._folder.node.removeAttribute("dragover-into");
|
||||
// remove menuactive style
|
||||
this._folder.node.removeAttribute("_moz-menuactive");
|
||||
this._folder.node = null;
|
||||
}
|
||||
if (this._folder.openTimer) {
|
||||
|
@ -574,6 +607,9 @@
|
|||
if (document.popupNode == child)
|
||||
document.popupNode = null;
|
||||
child.parentNode.removeChild(child);
|
||||
|
||||
if (this._endMarker != -1)
|
||||
this._endMarker--;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -591,12 +627,16 @@
|
|||
// Add the new element to the menu. If there is static content at
|
||||
// the end of the menu, add the element before that. Otherwise,
|
||||
// just add to the end.
|
||||
if (aParentPopup._endMarker != -1)
|
||||
if (aParentPopup._endMarker != -1) {
|
||||
aParentPopup.insertBefore(element,
|
||||
aParentPopup.childNodes[aParentPopup._endMarker++]);
|
||||
aParentPopup.childNodes[aParentPopup._endMarker]);
|
||||
}
|
||||
else
|
||||
aParentPopup.appendChild(element);
|
||||
}
|
||||
|
||||
if (aParentPopup._endMarker != -1)
|
||||
aParentPopup._endMarker++;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -702,6 +742,7 @@
|
|||
popup.firstChild == popup._emptyMenuItem)) {
|
||||
this._self._showEmptyMenuItem(popup);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -900,15 +941,23 @@
|
|||
<!-- nsIPlacesView -->
|
||||
<property name="insertionPoint">
|
||||
<getter><![CDATA[
|
||||
// there is no insertion point for history queries
|
||||
// so bail out now and save a lot of work when updating commands
|
||||
var resultNode = this._resultNode;
|
||||
if (PlacesUtils.nodeIsQuery(resultNode) &&
|
||||
asQuery(resultNode).queryOptions.queryType ==
|
||||
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
|
||||
return null;
|
||||
|
||||
// By default, the insertion point is at the top level, at the end.
|
||||
var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
var container = null;
|
||||
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
var isTag = false;
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(this._resultNode)) {
|
||||
container = this._resultNode;
|
||||
isTag = PlacesUtils.nodeIsTagQuery(this._resultNode);
|
||||
if (PlacesUtils.nodeIsFolder(resultNode)) {
|
||||
container = resultNode;
|
||||
isTag = PlacesUtils.nodeIsTagQuery(resultNode);
|
||||
}
|
||||
|
||||
var selectedNode = this.selectedNode;
|
||||
|
@ -928,7 +977,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
|
@ -936,18 +985,6 @@
|
|||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="_disallowInsertion">
|
||||
<parameter name="aContainer"/>
|
||||
<body><![CDATA[
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsIPlacesView -->
|
||||
<method name="selectAll">
|
||||
<body/>
|
||||
|
@ -965,6 +1002,10 @@
|
|||
this._ensureInitialized();
|
||||
this._contextMenuShown = true;
|
||||
this.focus();
|
||||
// The above call to focus activates the controller, but it may not
|
||||
// always fire a consumable event for commandUpdater, so we force a
|
||||
// command update.
|
||||
window.updateCommands("focus");
|
||||
var show = this.controller.buildContextMenu(aPopup);
|
||||
if (show) {
|
||||
// disable the Delete command if the selection isn't explicit
|
||||
|
@ -1013,6 +1054,7 @@
|
|||
// automatically opened when dragged over. Turn off this attribute
|
||||
// when the folder closes because it is no longer applicable.
|
||||
popup.removeAttribute("autoopened");
|
||||
popup.removeAttribute("dragstart");
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# Annie Sullivan <annie.sullivan@gmail.com>
|
||||
# Ben Goodger <beng@google.com>
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
# 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
|
||||
|
@ -307,6 +308,14 @@
|
|||
popup.setAttribute("type", "places");
|
||||
}
|
||||
}
|
||||
|
||||
// We rebuild the chevron on popupShowing, so if it is open
|
||||
// we must force a rebuild
|
||||
if (this._chevron.open) {
|
||||
var popup = this._chevron.firstChild;
|
||||
for (var i = 0; i < popup.childNodes.length; i++)
|
||||
popup.childNodes[i].hidden = !this.childNodes[i].collapsed;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -406,7 +415,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
|
@ -414,18 +423,6 @@
|
|||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="_disallowInsertion">
|
||||
<parameter name="aContainer"/>
|
||||
<body><![CDATA[
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsIPlacesView -->
|
||||
<method name="selectAll">
|
||||
<body><![CDATA[
|
||||
|
@ -520,6 +517,9 @@
|
|||
popup.firstChild == popup._emptyMenuItem)) {
|
||||
this._self._showEmptyMenuItem(popup);
|
||||
}
|
||||
if (popup._endMarker != -1)
|
||||
popup._endMarker--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -534,11 +534,19 @@
|
|||
|
||||
if (aNewParent == this._self.getResultNode()) {
|
||||
var children = this._self.childNodes;
|
||||
var chevronPopup = this._self._chevron.firstChild;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var button = children[i];
|
||||
if (button.node == aItem) {
|
||||
this._self.removeChild(button);
|
||||
this._self.insertBefore(button, children[aNewIndex]);
|
||||
if (chevronPopup) {
|
||||
// Maintain chevron in sync
|
||||
menuitem = chevronPopup.childNodes[i];
|
||||
chevronPopup.removeChild(menuitem);
|
||||
chevronPopup.insertBefore(menuitem,
|
||||
chevronPopup.childNodes[aNewIndex]);
|
||||
}
|
||||
this._self.updateChevron();
|
||||
return;
|
||||
}
|
||||
|
@ -697,7 +705,10 @@
|
|||
// Menu buttons should be opened when the mouse drags over them, and closed
|
||||
// when the mouse drags off. The overFolder object manages opening and closing
|
||||
// of folders when the mouse hovers.
|
||||
_overFolder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null},
|
||||
_overFolder: {node: null,
|
||||
openTimer: null,
|
||||
hoverTime: 350,
|
||||
closeTimer: null},
|
||||
|
||||
// timer for turning of indicator bar, to get rid of flicker
|
||||
_ibTimer: null,
|
||||
|
@ -794,8 +805,10 @@
|
|||
// node (or 25% of the right, in RTL UI), drop before the folder.
|
||||
// If it's in the middle 50%, drop into the folder. If it's past
|
||||
// that, drop after.
|
||||
if ((isRTL && event.clientX > xulNode.boxObject.x + (xulNode.boxObject.width * 0.75)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x + (xulNode.boxObject.width * 0.25))) {
|
||||
if ((isRTL && event.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25))) {
|
||||
// Drop to the left of this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
|
||||
|
@ -803,12 +816,15 @@
|
|||
dropPoint.beforeIndex = i;
|
||||
return dropPoint;
|
||||
}
|
||||
else if ((isRTL && event.clientX > xulNode.boxObject.x + (xulNode.boxObject.width * 0.25)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x + (xulNode.boxObject.width * 0.75))) {
|
||||
else if ((isRTL && event.clientX > xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.25)) ||
|
||||
(!isRTL && event.clientX < xulNode.boxObject.x +
|
||||
(xulNode.boxObject.width * 0.75))) {
|
||||
// Drop inside this folder.
|
||||
dropPoint.ip =
|
||||
new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
|
||||
-1, 1);
|
||||
-1, 1,
|
||||
PlacesUtils.nodeIsTagQuery(xulNode.node));
|
||||
dropPoint.beforeIndex = i;
|
||||
dropPoint.folderNode = xulNode;
|
||||
return dropPoint;
|
||||
|
@ -836,39 +852,43 @@
|
|||
dropPoint.beforeIndex = -1;
|
||||
return dropPoint;
|
||||
},
|
||||
|
||||
onDragStart: function TBV_DO_onDragStart(event, xferData, dragAction) {
|
||||
|
||||
onDragStart: function TBV_DO_onDragStart(aEvent, aXferData, aDragAction) {
|
||||
var draggedXulNode = aEvent.target;
|
||||
// sub menus have their own d&d handlers
|
||||
if (event.target.parentNode != this._self)
|
||||
if (draggedXulNode.parentNode != this._self)
|
||||
return false;
|
||||
|
||||
if (event.target.localName == "toolbarbutton" &&
|
||||
event.target.getAttribute("type") == "menu") {
|
||||
if (draggedXulNode.localName == "toolbarbutton" &&
|
||||
draggedXulNode.getAttribute("type") == "menu") {
|
||||
#ifdef XP_WIN
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "alt" key while they drag (Ctrl+drag has another
|
||||
// meaning - Copy). This does not appear to work at all on Linux.
|
||||
if (!event.shiftKey && !event.altKey && !event.ctrlKey)
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "alt" or "shift" key while dragging.
|
||||
// Ctrl+drag is Copy
|
||||
if (!aEvent.shiftKey && !aEvent.altKey && !aEvent.ctrlKey)
|
||||
return false;
|
||||
event.target.firstChild.hidePopup();
|
||||
#else
|
||||
return;
|
||||
// Support folder dragging on the personal toolbar when the user
|
||||
// holds the "shift" key while dragging
|
||||
// Ctrl+drag is Copy
|
||||
if (!aEvent.shiftKey && !aEvent.ctrlKey)
|
||||
return false;
|
||||
#endif
|
||||
draggedXulNode.firstChild.hidePopup();
|
||||
}
|
||||
|
||||
if (event.ctrlKey)
|
||||
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
|
||||
// activate the view and cache the dragged node
|
||||
this._self._draggedNode = event.target.node;
|
||||
this._self._draggedNode = draggedXulNode.node;
|
||||
this._self.focus();
|
||||
xferData.data = this._self._controller.getTransferData(dragAction.action);
|
||||
#ifdef XP_WIN
|
||||
|
||||
this._self._controller.setDataTransfer(aEvent);
|
||||
return true;
|
||||
#endif
|
||||
},
|
||||
|
||||
canDrop: function TBV_DO_canDrop(event, session) {
|
||||
canDrop: function TBV_DO_canDrop(aEvent, aDragSession) {
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
|
||||
|
||||
var ip = this._self.insertionPoint;
|
||||
return ip && PlacesControllerDragHelper.canDrop(ip);
|
||||
},
|
||||
|
@ -939,13 +959,19 @@
|
|||
},
|
||||
|
||||
onDrop: function TBV_DO_onDrop(event, dropData, session) {
|
||||
// Cache the dataTransfer
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
|
||||
var dropPoint = this._getDropPoint(event);
|
||||
if (dropPoint == null)
|
||||
if (!dropPoint)
|
||||
return;
|
||||
PlacesControllerDragHelper.onDrop(dropPoint.ip);
|
||||
},
|
||||
|
||||
onDragExit: function TBV_DO_onDragExit(event, session) {
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
|
||||
// Set timer to turn off indicator bar (if we turn it off
|
||||
// here, dragenter might be called immediately after, creating
|
||||
// flicker.)
|
||||
|
@ -955,17 +981,12 @@
|
|||
// Close any folder being hovered over
|
||||
if (this._overFolder.node)
|
||||
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
|
||||
this._self._draggedNode = null;
|
||||
},
|
||||
|
||||
getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
|
||||
var flavorSet = new FlavourSet();
|
||||
var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
||||
for (var i = 0; i < types.length; ++i)
|
||||
flavorSet.appendFlavour(types[i]);
|
||||
return flavorSet;
|
||||
return PlacesControllerDragHelper.flavourSet;
|
||||
}
|
||||
})]]></field>
|
||||
|
||||
|
@ -1000,6 +1021,10 @@
|
|||
<body><![CDATA[
|
||||
this._contextMenuShown = true;
|
||||
this.focus();
|
||||
// The above call to focus activates the controller, but it may not
|
||||
// always fire a consumable event for commandUpdater, so we force a
|
||||
// command update.
|
||||
window.updateCommands("focus");
|
||||
var show = this.controller.buildContextMenu(aPopup);
|
||||
if (show) {
|
||||
// disable the Delete command if the selection isn't explicit
|
||||
|
@ -1052,11 +1077,14 @@
|
|||
// just add to the end.
|
||||
if (aParentPopup._endMarker != -1) {
|
||||
aParentPopup.insertBefore(element,
|
||||
aParentPopup.childNodes[aParentPopup._endMarker++]);
|
||||
aParentPopup.childNodes[aParentPopup._endMarker]);
|
||||
}
|
||||
else
|
||||
aParentPopup.appendChild(element);
|
||||
}
|
||||
|
||||
if (aParentPopup._endMarker != -1)
|
||||
aParentPopup._endMarker++;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -1126,6 +1154,17 @@
|
|||
nsDragAndDrop.dragExit(event, this._DNDObserver);
|
||||
]]></handler>
|
||||
<handler event="popupshowing" phase="capturing"><![CDATA[
|
||||
// Don't show the popup if we are dragging a container.
|
||||
if (this._draggingContainer) {
|
||||
this._draggingContainer = false;
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
// Allow drag and drop of folders in Linux.
|
||||
// We must prevent popupshowing event from firing when shift is pressed.
|
||||
event.preventDefault();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
var popup = event.originalTarget;
|
||||
|
||||
// Avoid handling popupshowing of inner views
|
||||
|
@ -1154,8 +1193,18 @@
|
|||
this._openedMenuButton = null;
|
||||
]]></handler>
|
||||
|
||||
<handler event="mousedown"><![CDATA[
|
||||
// Allow drag and drop of folders in Linux.
|
||||
// We must prevent popupshowing event from firing when shift is pressed.
|
||||
var target = event.originalTarget;
|
||||
if (event.button == 1 && event.shiftKey &&
|
||||
target.localName == "toolbarbutton" && target.type == "menu")
|
||||
this._draggingContainer = true;
|
||||
]]></handler>
|
||||
|
||||
<handler event="mousemove"><![CDATA[
|
||||
if (this._openedMenuButton == null || PlacesControllerDragHelper.getSession())
|
||||
if (this._openedMenuButton == null ||
|
||||
PlacesControllerDragHelper.getSession())
|
||||
return;
|
||||
|
||||
var target = event.originalTarget;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
# Contributor(s):
|
||||
# Ben Goodger <beng@google.com>
|
||||
# Annie Sullivan <annie.sullivan@gmail.com>
|
||||
# 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
|
||||
|
@ -434,11 +435,10 @@
|
|||
// there is no insertion point for history queries
|
||||
// so bail out now and save a lot of work when updating commands
|
||||
var resultNode = this.getResultNode();
|
||||
if (PlacesUtils.nodeIsQuery(resultNode)) {
|
||||
var options = asQuery(resultNode).queryOptions;
|
||||
if (options.queryType == options.QUERY_TYPE_HISTORY)
|
||||
if (PlacesUtils.nodeIsQuery(resultNode) &&
|
||||
asQuery(resultNode).queryOptions.queryType ==
|
||||
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
|
||||
return this._cachedInsertionPoint = null;
|
||||
}
|
||||
|
||||
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
// If there is no selection, insert at the end of the container.
|
||||
|
@ -488,18 +488,6 @@
|
|||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="_disallowInsertion">
|
||||
<parameter name="aContainer"/>
|
||||
<body><![CDATA[
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_getInsertionPoint">
|
||||
<parameter name="index"/>
|
||||
<parameter name="orientation"/>
|
||||
|
@ -519,14 +507,13 @@
|
|||
container = lastSelected;
|
||||
index = -1;
|
||||
}
|
||||
else if (!this._disallowInsertion(lastSelected) &&
|
||||
lastSelected.containerOpen &&
|
||||
else if (lastSelected.containerOpen &&
|
||||
orientation == Ci.nsITreeView.DROP_AFTER &&
|
||||
lastSelected.hasChildren) {
|
||||
// If the last selected item is an open container and the user is
|
||||
// trying to drag into it as a first item, really insert into it.
|
||||
container = lastSelected;
|
||||
orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
index = 0;
|
||||
}
|
||||
else {
|
||||
|
@ -537,7 +524,7 @@
|
|||
|
||||
// avoid the potentially expensive call to getIndexOfNode()
|
||||
// if we know this container doesn't allow insertion
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
var queryOptions = asQuery(result.root).queryOptions;
|
||||
|
@ -562,7 +549,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
|
@ -675,14 +662,10 @@
|
|||
|
||||
<!-- nsDragAndDrop -->
|
||||
<method name="onDragStart">
|
||||
<parameter name="event"/>
|
||||
<parameter name="xferData"/>
|
||||
<parameter name="dragAction"/>
|
||||
<parameter name="aEvent"/>
|
||||
<parameter name="aXferData"/>
|
||||
<parameter name="aDragAction"/>
|
||||
<body><![CDATA[
|
||||
// Drag and Drop does not work while a tree view is sorted.
|
||||
if (this.getAttribute("sortActive") == "true")
|
||||
throw Cr.NS_OK;
|
||||
|
||||
var nodes = this.getSelectionNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
var node = nodes[i];
|
||||
|
@ -690,61 +673,83 @@
|
|||
// Disallow dragging the root node of a tree
|
||||
var parent = node.parent;
|
||||
if (!parent)
|
||||
throw Cr.NS_OK;
|
||||
return;
|
||||
|
||||
// If this node is part of a readonly container (e.g. a livemark) it
|
||||
// cannot be moved, only copied, so we must change the action used
|
||||
// by the drag session.
|
||||
if (PlacesUtils.nodeIsTagQuery(parent) ||
|
||||
!PlacesControllerDragHelper.canMoveContainerNode(node)) {
|
||||
// XXX DOES NOTHING! dragAction doesn't persist
|
||||
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
// If this node is child of a readonly container (e.g. a livemark)
|
||||
// or cannot be moved, we must force a copy.
|
||||
if (!PlacesControllerDragHelper.canMoveNode(node)) {
|
||||
aEvent.dataTransfer.effectAllowed = "copyLink";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// XXXben - the drag wrapper should do this automatically.
|
||||
if (event.ctrlKey)
|
||||
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
|
||||
// Stuff the encoded selection into the transferable data object
|
||||
xferData.data = this._controller.getTransferData(dragAction.action);
|
||||
this._controller.setDataTransfer(aEvent);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsDragAndDrop -->
|
||||
<method name="canDrop">
|
||||
<parameter name="event"/>
|
||||
<parameter name="session"/>
|
||||
<body><![CDATA[
|
||||
<parameter name="aEvent"/>
|
||||
<parameter name="aDragSession"/>
|
||||
<body><![CDATA[
|
||||
// Cache the dataTransfer for the view
|
||||
PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
|
||||
|
||||
var row = { }, col = { }, child = { };
|
||||
this.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col,
|
||||
child);
|
||||
return this.view.canDrop(row.value, -1);
|
||||
this.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY,
|
||||
row, col, child);
|
||||
var node = row.value != -1 ?
|
||||
this.getResultView().nodeForTreeIndex(row.value) :
|
||||
this.getResultNode();
|
||||
// cache the dropTarget for the view
|
||||
PlacesControllerDragHelper.currentDropTarget = node;
|
||||
|
||||
// We have to calculate the orientation since view.canDrop will use
|
||||
// it and we want to be consistent with the dropfeedback
|
||||
var tbo = this.treeBoxObject;
|
||||
var rowHeight = tbo.rowHeight;
|
||||
var eventY = aEvent.clientY - tbo.treeBody.boxObject.y -
|
||||
rowHeight * (row.value - tbo.getFirstVisibleRow());
|
||||
|
||||
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
|
||||
if (row.value == -1) {
|
||||
// If the row is not valid we try to insert inside the resultNode.
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
}
|
||||
else if (PlacesUtils.nodeIsContainer(node) &&
|
||||
eventY > rowHeight * 0.75) {
|
||||
// If we are below the 75% of a container the treeview we try
|
||||
// to drop after the node.
|
||||
orientation = Ci.nsITreeView.DROP_AFTER;
|
||||
}
|
||||
else if (PlacesUtils.nodeIsContainer(node) &&
|
||||
eventY > rowHeight * 0.25) {
|
||||
// If we are below the 25% of a container the treeview we try
|
||||
// to drop inside the node.
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
}
|
||||
|
||||
return this.view.canDrop(row.value, orientation);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsDragAndDrop -->
|
||||
<method name="onDragOver">
|
||||
<parameter name="event"/>
|
||||
<parameter name="flavor"/>
|
||||
<parameter name="session"/>
|
||||
<body><![CDATA[
|
||||
var dragService =
|
||||
Cc["@mozilla.org/widget/dragservice;1"].
|
||||
getService(Ci.nsIDragService);
|
||||
var dragSession = dragService.getCurrentSession();
|
||||
dragSession.canDrop = this.canDrop(event, session);
|
||||
<parameter name="aEvent"/>
|
||||
<parameter name="aFlavour"/>
|
||||
<parameter name="aDragSession"/>
|
||||
<body><![CDATA[
|
||||
if (!this.canDrop(aEvent, aDragSession))
|
||||
aEvent.dataTransfer.effectAllowed = "none";
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsDragAndDrop -->
|
||||
<method name="getSupportedFlavours">
|
||||
<body><![CDATA[
|
||||
var flavorSet = new FlavourSet();
|
||||
var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
|
||||
for (var i = 0; i < types.length; ++i)
|
||||
flavorSet.appendFlavour(types[i]);
|
||||
return flavorSet;
|
||||
return PlacesControllerDragHelper.flavourSet;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -782,7 +787,6 @@
|
|||
}
|
||||
]]></handler>
|
||||
<handler event="draggesture"><![CDATA[
|
||||
// XXXben ew.
|
||||
if (event.target.localName == "treechildren")
|
||||
nsDragAndDrop.startDrag(event, this);
|
||||
]]></handler>
|
||||
|
@ -790,6 +794,13 @@
|
|||
if (event.target.localName == "treechildren")
|
||||
nsDragAndDrop.dragOver(event, this);
|
||||
]]></handler>
|
||||
<handler event="drop"><![CDATA[
|
||||
PlacesControllerDragHelper.currentDataTransfer = event.dataTransfer;
|
||||
]]></handler>
|
||||
<handler event="dragexit"><![CDATA[
|
||||
PlacesControllerDragHelper.currentDataTransfer = null;
|
||||
PlacesControllerDragHelper.currentDropTarget = null;
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
|
|
|
@ -996,35 +996,14 @@ PlacesTreeView.prototype = {
|
|||
if (!this._result)
|
||||
throw Cr.NS_ERROR_UNEXPECTED;
|
||||
|
||||
var node = aRow != -1 ? this.nodeForTreeIndex(aRow) : this._result.root;
|
||||
// drop position into a sorted treeview would be wrong
|
||||
if (this.isSorted())
|
||||
return false;
|
||||
|
||||
if (aOrientation == Ci.nsITreeView.DROP_ON) {
|
||||
// The user cannot drop an item into itself or a read-only container
|
||||
var dragService = Cc["@mozilla.org/widget/dragservice;1"].
|
||||
getService(Ci.nsIDragService);
|
||||
var dragSession = dragService.getCurrentSession();
|
||||
var elt = dragSession.sourceNode.parentNode;
|
||||
if (elt.localName == "tree" && elt.view == this &&
|
||||
this.selection.isSelected(aRow))
|
||||
return false;
|
||||
}
|
||||
|
||||
var ip = this._getInsertionPoint(aRow, aOrientation);
|
||||
return ip && PlacesControllerDragHelper.canDrop(ip);
|
||||
},
|
||||
|
||||
// XXXmano: these two are copied over from tree.xml, to fix this we need to
|
||||
// either add a helper to PlacesUtils or keep it here and add insertionPoint
|
||||
// to the view interface.
|
||||
_disallowInsertion: function PTV__disallowInsertion(aContainer) {
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
},
|
||||
|
||||
_getInsertionPoint: function PTV__getInsertionPoint(index, orientation) {
|
||||
var container = this._result.root;
|
||||
var dropNearItemId = -1;
|
||||
|
@ -1038,14 +1017,13 @@ PlacesTreeView.prototype = {
|
|||
container = lastSelected;
|
||||
index = -1;
|
||||
}
|
||||
else if (!this._disallowInsertion(lastSelected) &&
|
||||
lastSelected.containerOpen &&
|
||||
else if (lastSelected.containerOpen &&
|
||||
orientation == Ci.nsITreeView.DROP_AFTER &&
|
||||
lastSelected.hasChildren) {
|
||||
// If the last selected item is an open container and the user is
|
||||
// trying to drag into it as a first item, really insert into it.
|
||||
container = lastSelected;
|
||||
orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
index = 0;
|
||||
}
|
||||
else {
|
||||
|
@ -1056,12 +1034,13 @@ PlacesTreeView.prototype = {
|
|||
|
||||
// avoid the potentially expensive call to getIndexOfNode()
|
||||
// if we know this container doesn't allow insertion
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
var queryOptions = asQuery(this._result.root).queryOptions;
|
||||
if (queryOptions.sortingMode != Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
|
||||
// If we are within a sorted view, insert at the end
|
||||
if (queryOptions.sortingMode !=
|
||||
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
|
||||
// If we are within a sorted view, insert at the ends
|
||||
index = -1;
|
||||
}
|
||||
else if (queryOptions.excludeItems ||
|
||||
|
@ -1080,7 +1059,7 @@ PlacesTreeView.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
if (PlacesControllerDragHelper.disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
|
@ -1095,7 +1074,7 @@ PlacesTreeView.prototype = {
|
|||
// since this information is specific to the tree view.
|
||||
var ip = this._getInsertionPoint(aRow, aOrientation);
|
||||
if (!ip)
|
||||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
return;
|
||||
PlacesControllerDragHelper.onDrop(ip);
|
||||
},
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Asaf Romano <mano@mozilla.com>
|
||||
* Sungjoon Steve Won <stevewon@gmail.com>
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
* 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
|
||||
|
@ -377,10 +378,12 @@ var PlacesUIUtils = {
|
|||
return this.ptm.moveItem(data.id, container, index);
|
||||
break;
|
||||
default:
|
||||
if (type == PlacesUtils.TYPE_X_MOZ_URL || type == PlacesUtils.TYPE_UNICODE) {
|
||||
var title = (type == PlacesUtils.TYPE_X_MOZ_URL) ? data.title : data.uri;
|
||||
return this.ptm.createItem(PlacesUtils._uri(data.uri), container, index,
|
||||
title);
|
||||
if (type == PlacesUtils.TYPE_X_MOZ_URL ||
|
||||
type == PlacesUtils.TYPE_UNICODE) {
|
||||
var title = (type == PlacesUtils.TYPE_X_MOZ_URL) ? data.title :
|
||||
data.uri;
|
||||
return this.ptm.createItem(PlacesUtils._uri(data.uri),
|
||||
container, index, title);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -1035,51 +1038,45 @@ var PlacesUIUtils = {
|
|||
},
|
||||
|
||||
cleanPlacesPopup: function PU_cleanPlacesPopup(aPopup) {
|
||||
// Find static menuitems at the start and at the end of the menupopup,
|
||||
// marked by builder="start" and builder="end" attributes, and set
|
||||
// markers to keep track of their indices.
|
||||
// Remove places popup children and update markers to keep track of
|
||||
// their indices.
|
||||
var start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
|
||||
var end = aPopup._endMarker != -1 ? aPopup._endMarker :
|
||||
aPopup.childNodes.length;
|
||||
var items = [];
|
||||
aPopup._startMarker = -1;
|
||||
aPopup._endMarker = -1;
|
||||
for (var i = 0; i < aPopup.childNodes.length; ++i) {
|
||||
var placesNodeFound = false;
|
||||
for (var i = start; i < end; ++i) {
|
||||
var item = aPopup.childNodes[i];
|
||||
if (item.getAttribute("builder") == "start") {
|
||||
aPopup._startMarker = i;
|
||||
continue;
|
||||
}
|
||||
if (item.getAttribute("builder") == "end") {
|
||||
// we need to do this for menus that have static content at the end but
|
||||
// are initially empty, eg. the history menu, we need to know where to
|
||||
// start inserting new items.
|
||||
aPopup._endMarker = i;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if ((aPopup._startMarker != -1) && (aPopup._endMarker == -1))
|
||||
if (item.node) {
|
||||
items.push(item);
|
||||
}
|
||||
|
||||
// If static items at the beginning were found, remove all items between
|
||||
// them and the static content at the end.
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
// skip the empty menu item
|
||||
if (aPopup._emptyMenuItem != items[i]) {
|
||||
aPopup.removeChild(items[i]);
|
||||
if (aPopup._endMarker > 0)
|
||||
--aPopup._endMarker;
|
||||
placesNodeFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If no static items were found at the beginning, remove all items before
|
||||
// the static items at the end.
|
||||
if (aPopup._startMarker == -1) {
|
||||
var end = aPopup._endMarker == -1 ?
|
||||
aPopup.childNodes.length - 1 : aPopup._endMarker - 1;
|
||||
for (var i = end; i >= 0; i--) {
|
||||
// skip the empty menu item
|
||||
if (aPopup._emptyMenuItem != aPopup.childNodes[i]) {
|
||||
aPopup.removeChild(aPopup.childNodes[i]);
|
||||
if (aPopup._endMarker > 0)
|
||||
--aPopup._endMarker;
|
||||
else {
|
||||
// This is static content...
|
||||
if (!placesNodeFound)
|
||||
// ...at the start of the popup
|
||||
// Initialized in menu.xml, in the base binding
|
||||
aPopup._startMarker++;
|
||||
else {
|
||||
// ...after places nodes
|
||||
aPopup._endMarker = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
aPopup.removeChild(items[i]);
|
||||
if (aPopup._endMarker != -1)
|
||||
aPopup._endMarker--;
|
||||
}
|
||||
},
|
||||
|
||||
getBestTitle: function PU_getBestTitle(aNode) {
|
||||
|
@ -1232,13 +1229,3 @@ var PlacesUIUtils = {
|
|||
return this.allBookmarksFolderId = this.leftPaneQueries["AllBookmarks"];
|
||||
}
|
||||
};
|
||||
|
||||
PlacesUIUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE];
|
||||
|
||||
PlacesUIUtils.GENERIC_VIEW_DROP_TYPES = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE,
|
||||
PlacesUtils.TYPE_X_MOZ_URL,
|
||||
PlacesUtils.TYPE_UNICODE];
|
||||
|
|
|
@ -296,8 +296,11 @@ placesAggregateTransactions.prototype = {
|
|||
},
|
||||
|
||||
commit: function PAT_commit(aUndo) {
|
||||
for (var i=0; i < this._transactions.length; ++i) {
|
||||
var txn = this._transactions[i];
|
||||
var transactions = this._transactions;
|
||||
if (aUndo)
|
||||
transactions.reverse();
|
||||
for (var i = 0; i < transactions.length; i++) {
|
||||
var txn = transactions[i];
|
||||
if (this.container > -1)
|
||||
txn.wrappedJSObject.container = this.container;
|
||||
if (aUndo)
|
||||
|
@ -397,6 +400,7 @@ function placesCreateSeparatorTransactions(aContainer, aIndex) {
|
|||
this._container = aContainer;
|
||||
this._index = typeof(aIndex) == "number" ? aIndex : -1;
|
||||
this._id = null;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
}
|
||||
|
||||
placesCreateSeparatorTransactions.prototype = {
|
||||
|
@ -450,7 +454,6 @@ placesCreateLivemarkTransactions.prototype = {
|
|||
function placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex) {
|
||||
this._id = aItemId;
|
||||
this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
|
||||
this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
|
||||
this._newContainer = aNewContainer;
|
||||
this._newIndex = aNewIndex;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
|
@ -460,17 +463,16 @@ placesMoveItemTransactions.prototype = {
|
|||
__proto__: placesBaseTransaction.prototype,
|
||||
|
||||
doTransaction: function PMIT_doTransaction() {
|
||||
this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
|
||||
PlacesUtils.bookmarks.moveItem(this._id, this._newContainer, this._newIndex);
|
||||
// if newIndex == DEFAULT_INDEX we append, so get correct index for undo
|
||||
if (this._newIndex == PlacesUtils.bookmarks.DEFAULT_INDEX)
|
||||
this._newIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
|
||||
this._undoIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
|
||||
},
|
||||
|
||||
undoTransaction: function PMIT_undoTransaction() {
|
||||
// moving down in the same container takes in count removal of the item
|
||||
// so to revert positions we must move to oldIndex + 1
|
||||
if (this._newContainer == this._oldContainer &&
|
||||
this._oldIndex > this._newIndex)
|
||||
this._oldIndex > this._undoIndex)
|
||||
PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex + 1);
|
||||
else
|
||||
PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex);
|
||||
|
@ -541,7 +543,7 @@ placesRemoveItemTransaction.prototype = {
|
|||
this._transactions[i].undoTransaction();
|
||||
}
|
||||
else // TYPE_SEPARATOR
|
||||
PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
|
||||
this._id = PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
|
||||
|
||||
if (this._annotations.length > 0)
|
||||
PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
|
||||
|
|
|
@ -61,7 +61,7 @@ function test() {
|
|||
"populate added data to the test root");
|
||||
is(PlacesControllerDragHelper.canMoveContainer(this.id),
|
||||
true, "can move regular folder id");
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(rootNode.getChild(0)),
|
||||
is(PlacesControllerDragHelper.canMoveNode(rootNode.getChild(0)),
|
||||
true, "can move regular folder node");
|
||||
}
|
||||
});
|
||||
|
@ -92,7 +92,7 @@ function test() {
|
|||
is(PlacesControllerDragHelper.canMoveContainer(this.shortcutId),
|
||||
true, "can move folder shortcut id");
|
||||
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(shortcutNode),
|
||||
is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
|
||||
true, "can move folder shortcut node");
|
||||
}
|
||||
});
|
||||
|
@ -118,7 +118,7 @@ function test() {
|
|||
is(PlacesControllerDragHelper.canMoveContainer(this.queryId),
|
||||
true, "can move query id");
|
||||
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(queryNode),
|
||||
is(PlacesControllerDragHelper.canMoveNode(queryNode),
|
||||
true, "can move query node");
|
||||
}
|
||||
});
|
||||
|
@ -159,7 +159,7 @@ function test() {
|
|||
|
||||
//var node = PlacesUtils.getFolderContents(id, false, true).root;
|
||||
var node = getRootChildNode(id);
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(node),
|
||||
is(PlacesControllerDragHelper.canMoveNode(node),
|
||||
false, "shouldn't be able to move special folder node");
|
||||
|
||||
var shortcutId = this.shortcuts[id];
|
||||
|
@ -172,7 +172,7 @@ function test() {
|
|||
true, "should be able to move special folder shortcut id");
|
||||
|
||||
LOG("can move shortcut node?");
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(shortcutNode),
|
||||
is(PlacesControllerDragHelper.canMoveNode(shortcutNode),
|
||||
true, "should be able to move special folder shortcut node");
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ function test() {
|
|||
|
||||
var tagNode = tagsNode.getChild(0);
|
||||
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(tagNode),
|
||||
is(PlacesControllerDragHelper.canMoveNode(tagNode),
|
||||
false, "should not be able to move tag container node");
|
||||
}
|
||||
});
|
||||
|
@ -218,7 +218,7 @@ function test() {
|
|||
// test that we can move the read-only folder
|
||||
is(PlacesControllerDragHelper.canMoveContainer(this.id),
|
||||
true, "can move read-only folder id");
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(readOnlyFolder),
|
||||
is(PlacesControllerDragHelper.canMoveNode(readOnlyFolder),
|
||||
true, "can move read-only folder node");
|
||||
|
||||
// test that we cannot move the child of a read-only folder
|
||||
|
@ -228,7 +228,7 @@ function test() {
|
|||
|
||||
is(PlacesControllerDragHelper.canMoveContainer(childFolder.itemId),
|
||||
false, "cannot move a child of a read-only folder");
|
||||
is(PlacesControllerDragHelper.canMoveContainerNode(childFolder),
|
||||
is(PlacesControllerDragHelper.canMoveNode(childFolder),
|
||||
false, "cannot move a child node of a read-only folder node");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -151,6 +151,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemRemovedId, folderId);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
txn1.redoTransaction();
|
||||
do_check_eq(observer._itemAddedIndex, bmStartIndex);
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedId, folderId);
|
||||
txn1.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, folderId);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
|
||||
// Test creating an item
|
||||
// Create to Root
|
||||
|
@ -163,8 +171,19 @@ function run_test() {
|
|||
txn2.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, b);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
do_check_false(bmsvc.isBookmarked(uri("http://www.example.com")));
|
||||
txn2.redoTransaction();
|
||||
do_check_true(bmsvc.isBookmarked(uri("http://www.example.com")));
|
||||
var newId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com"), {}))[0];
|
||||
do_check_eq(observer._itemAddedIndex, bmStartIndex);
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedId, newId);
|
||||
txn2.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, newId);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
|
||||
// Create to a folder
|
||||
// Create item to a folder
|
||||
var txn2a = ptSvc.createFolder("Folder", root, bmStartIndex);
|
||||
ptSvc.doTransaction(txn2a);
|
||||
var fldrId = bmsvc.getChildFolder(root, "Folder");
|
||||
|
@ -177,10 +196,19 @@ function run_test() {
|
|||
txn2b.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, b2);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
txn2b.redoTransaction();
|
||||
newId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example2.com"), {}))[0];
|
||||
do_check_eq(observer._itemAddedIndex, bmStartIndex);
|
||||
do_check_eq(observer._itemAddedParent, fldrId);
|
||||
do_check_eq(observer._itemAddedId, newId);
|
||||
txn2b.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, newId);
|
||||
do_check_eq(observer._itemRemovedFolder, fldrId);
|
||||
do_check_eq(observer._itemRemovedIndex, bmStartIndex);
|
||||
|
||||
// Testing moving an item
|
||||
ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), root, -1, "Testing2"));
|
||||
ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), root, -1, "Testing3"));
|
||||
ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), root, -1, "Testing3"));
|
||||
ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), fldrId, -1, "Testing4"));
|
||||
var bkmkIds = bmsvc.getBookmarkIdsForURI(uri("http://www.example3.com"), {});
|
||||
bkmkIds.sort();
|
||||
|
@ -202,6 +230,18 @@ function run_test() {
|
|||
do_check_eq(observer._itemMovedOldIndex, 2);
|
||||
do_check_eq(observer._itemMovedNewParent, root);
|
||||
do_check_eq(observer._itemMovedNewIndex, 1);
|
||||
txn3.redoTransaction();
|
||||
do_check_eq(observer._itemMovedId, bkmk1Id);
|
||||
do_check_eq(observer._itemMovedOldParent, root);
|
||||
do_check_eq(observer._itemMovedOldIndex, 1);
|
||||
do_check_eq(observer._itemMovedNewParent, root);
|
||||
do_check_eq(observer._itemMovedNewIndex, 2);
|
||||
txn3.undoTransaction();
|
||||
do_check_eq(observer._itemMovedId, bkmk1Id);
|
||||
do_check_eq(observer._itemMovedOldParent, root);
|
||||
do_check_eq(observer._itemMovedOldIndex, 2);
|
||||
do_check_eq(observer._itemMovedNewParent, root);
|
||||
do_check_eq(observer._itemMovedNewIndex, 1);
|
||||
|
||||
// Moving items between different folders
|
||||
var txn3b = ptSvc.moveItem(bkmk1Id, fldrId, -1);
|
||||
|
@ -217,6 +257,18 @@ function run_test() {
|
|||
do_check_eq(observer._itemMovedOldIndex, 1);
|
||||
do_check_eq(observer._itemMovedNewParent, root);
|
||||
do_check_eq(observer._itemMovedNewIndex, 1);
|
||||
txn3b.redoTransaction();
|
||||
do_check_eq(observer._itemMovedId, bkmk1Id);
|
||||
do_check_eq(observer._itemMovedOldParent, root);
|
||||
do_check_eq(observer._itemMovedOldIndex, 1);
|
||||
do_check_eq(observer._itemMovedNewParent, fldrId);
|
||||
do_check_eq(observer._itemMovedNewIndex, 1);
|
||||
txn3.undoTransaction();
|
||||
do_check_eq(observer._itemMovedId, bkmk1Id);
|
||||
do_check_eq(observer._itemMovedOldParent, fldrId);
|
||||
do_check_eq(observer._itemMovedOldIndex, 1);
|
||||
do_check_eq(observer._itemMovedNewParent, root);
|
||||
do_check_eq(observer._itemMovedNewIndex, 1);
|
||||
|
||||
// Test Removing a Folder
|
||||
ptSvc.doTransaction(ptSvc.createFolder("Folder2", root, -1));
|
||||
|
@ -230,6 +282,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemAddedId, fldrId2);
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 3);
|
||||
txn4.redoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, fldrId2);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 3);
|
||||
txn4.undoTransaction();
|
||||
do_check_eq(observer._itemAddedId, fldrId2);
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 3);
|
||||
|
||||
// Test removing an item
|
||||
var txn5 = ptSvc.removeItem(bkmk2Id);
|
||||
|
@ -238,6 +298,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 2);
|
||||
txn5.undoTransaction();
|
||||
var newbkmk2Id = observer._itemAddedId;
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 2);
|
||||
txn5.redoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, newbkmk2Id);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 2);
|
||||
txn5.undoTransaction();
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 2);
|
||||
|
||||
|
@ -251,6 +319,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemRemovedId, sepId);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 1);
|
||||
txn6.redoTransaction();
|
||||
var newSepId = observer._itemAddedId;
|
||||
do_check_eq(observer._itemAddedIndex, 1);
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
txn6.undoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, newSepId);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 1);
|
||||
|
||||
// Test removing a separator
|
||||
ptSvc.doTransaction(ptSvc.createSeparator(root, 1));
|
||||
|
@ -264,6 +340,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemAddedId, sepId2); //New separator created
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 1);
|
||||
txn7.redoTransaction();
|
||||
do_check_eq(observer._itemRemovedId, sepId2);
|
||||
do_check_eq(observer._itemRemovedFolder, root);
|
||||
do_check_eq(observer._itemRemovedIndex, 1);
|
||||
txn7.undoTransaction();
|
||||
do_check_eq(observer._itemAddedId, sepId2); //New separator created
|
||||
do_check_eq(observer._itemAddedParent, root);
|
||||
do_check_eq(observer._itemAddedIndex, 1);
|
||||
|
||||
// Test editing item title
|
||||
var txn8 = ptSvc.editItemTitle(bkmk1Id, "Testing2_mod");
|
||||
|
@ -275,6 +359,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "title");
|
||||
do_check_eq(observer._itemChangedValue, "Testing2");
|
||||
txn8.redoTransaction();
|
||||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "title");
|
||||
do_check_eq(observer._itemChangedValue, "Testing2_mod");
|
||||
txn8.undoTransaction();
|
||||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "title");
|
||||
do_check_eq(observer._itemChangedValue, "Testing2");
|
||||
|
||||
// Test editing item uri
|
||||
var txn9 = ptSvc.editBookmarkURI(bkmk1Id, uri("http://newuri.com"));
|
||||
|
@ -286,6 +378,14 @@ function run_test() {
|
|||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "uri");
|
||||
do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
|
||||
txn9.redoTransaction();
|
||||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "uri");
|
||||
do_check_eq(observer._itemChangedValue, "http://newuri.com/");
|
||||
txn9.undoTransaction();
|
||||
do_check_eq(observer._itemChangedId, bkmk1Id);
|
||||
do_check_eq(observer._itemChangedProperty, "uri");
|
||||
do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
|
||||
|
||||
// Test edit item description
|
||||
var txn10 = ptSvc.editItemDescription(bkmk1Id, "Description1");
|
||||
|
@ -371,6 +471,14 @@ function run_test() {
|
|||
do_check_eq(0, bmsvc.getItemIndex(b1));
|
||||
do_check_eq(1, bmsvc.getItemIndex(b2));
|
||||
do_check_eq(2, bmsvc.getItemIndex(b3));
|
||||
txn17.redoTransaction();
|
||||
do_check_eq(2, bmsvc.getItemIndex(b1));
|
||||
do_check_eq(1, bmsvc.getItemIndex(b2));
|
||||
do_check_eq(0, bmsvc.getItemIndex(b3));
|
||||
txn17.undoTransaction();
|
||||
do_check_eq(0, bmsvc.getItemIndex(b1));
|
||||
do_check_eq(1, bmsvc.getItemIndex(b2));
|
||||
do_check_eq(2, bmsvc.getItemIndex(b3));
|
||||
|
||||
// editBookmarkMicrosummary
|
||||
var tmpMs = mss.createMicrosummary(uri("http://testmicro.com"),
|
||||
|
@ -436,4 +544,76 @@ function run_test() {
|
|||
do_check_eq(uneval(tagssvc.getTagsForURI(tagURI, { })), uneval(["bar","foo"]));
|
||||
untagTxn.redoTransaction();
|
||||
do_check_eq(uneval(tagssvc.getTagsForURI(tagURI, { })), uneval(["foo"]));
|
||||
|
||||
// Test aggregate removeItem transaction
|
||||
var bkmk1Id = bmsvc.insertBookmark(root, uri("http://www.mozilla.org/"), 0, "Mozilla");
|
||||
var bkmk2Id = bmsvc.insertSeparator(root, 1);
|
||||
var bkmk3Id = bmsvc.createFolder(root, "folder", 2);
|
||||
var bkmk3_1Id = bmsvc.insertBookmark(bkmk3Id, uri("http://www.mozilla.org/"), 0, "Mozilla");
|
||||
var bkmk3_2Id = bmsvc.insertSeparator(bkmk3Id, 1);
|
||||
var bkmk3_3Id = bmsvc.createFolder(bkmk3Id, "folder", 2);
|
||||
|
||||
var transactions = [];
|
||||
transactions.push(ptSvc.removeItem(bkmk1Id));
|
||||
transactions.push(ptSvc.removeItem(bkmk2Id));
|
||||
transactions.push(ptSvc.removeItem(bkmk3Id));
|
||||
var txn = ptSvc.aggregateTransactions("RemoveItems", transactions);
|
||||
|
||||
txn.doTransaction();
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3_1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3_2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3_3Id), -1);
|
||||
|
||||
txn.undoTransaction();
|
||||
var newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
|
||||
var newBkmk2Id = bmsvc.getIdForItemAt(root, 1);
|
||||
var newBkmk3Id = bmsvc.getIdForItemAt(root, 2);
|
||||
var newBkmk3_1Id = bmsvc.getIdForItemAt(newBkmk3Id, 0);
|
||||
var newBkmk3_2Id = bmsvc.getIdForItemAt(newBkmk3Id, 1);
|
||||
var newBkmk3_3Id = bmsvc.getIdForItemAt(newBkmk3Id, 2);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk1Id), bmsvc.TYPE_BOOKMARK);
|
||||
do_check_eq(bmsvc.getBookmarkURI(newBkmk1Id).spec, "http://www.mozilla.org/");
|
||||
do_check_eq(bmsvc.getItemType(newBkmk2Id), bmsvc.TYPE_SEPARATOR);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3Id), "folder");
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_1Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_1Id), bmsvc.TYPE_BOOKMARK);
|
||||
do_check_eq(bmsvc.getBookmarkURI(newBkmk3_1Id).spec, "http://www.mozilla.org/");
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_2Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_2Id), bmsvc.TYPE_SEPARATOR);
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
|
||||
|
||||
txn.redoTransaction();
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3_1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3_2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3_3Id), -1);
|
||||
|
||||
txn.undoTransaction();
|
||||
newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
|
||||
newBkmk2Id = bmsvc.getIdForItemAt(root, 1);
|
||||
newBkmk3Id = bmsvc.getIdForItemAt(root, 2);
|
||||
newBkmk3_1Id = bmsvc.getIdForItemAt(newBkmk3Id, 0);
|
||||
newBkmk3_2Id = bmsvc.getIdForItemAt(newBkmk3Id, 1);
|
||||
newBkmk3_3Id = bmsvc.getIdForItemAt(newBkmk3Id, 2);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk1Id), bmsvc.TYPE_BOOKMARK);
|
||||
do_check_eq(bmsvc.getBookmarkURI(newBkmk1Id).spec, "http://www.mozilla.org/");
|
||||
do_check_eq(bmsvc.getItemType(newBkmk2Id), bmsvc.TYPE_SEPARATOR);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3Id), "folder");
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_1Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_1Id), bmsvc.TYPE_BOOKMARK);
|
||||
do_check_eq(bmsvc.getBookmarkURI(newBkmk3_1Id).spec, "http://www.mozilla.org/");
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_2Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_2Id), bmsvc.TYPE_SEPARATOR);
|
||||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<vbox class="contentPane" flex="1">
|
||||
<description id="permissionsText" control="url"/>
|
||||
<separator class="thin"/>
|
||||
<label id="urlLabel" control="url" value="&address.label;"/>
|
||||
<label id="urlLabel" control="url" value="&address.label;" accesskey="&address.accesskey;"/>
|
||||
<hbox align="start">
|
||||
<textbox id="url" flex="1"
|
||||
oninput="gPermissionManager.onHostInput(event.target);"
|
||||
|
|
|
@ -97,11 +97,11 @@
|
|||
|
||||
<separator class="thin"/>
|
||||
<checkbox id="tellMaybeAttackSite"
|
||||
label="&tellMaybeAttackSite.label;"
|
||||
label="&tellMaybeAttackSite2.label;"
|
||||
accesskey="&tellMaybeAttackSite.accesskey;"
|
||||
preference="browser.safebrowsing.malware.enabled" />
|
||||
<checkbox id="tellMaybeForgery"
|
||||
label="&tellMaybeForgery.label;"
|
||||
label="&tellMaybeForgery2.label;"
|
||||
accesskey="&tellMaybeForgery.accesskey;"
|
||||
preference="browser.safebrowsing.enabled" />
|
||||
</groupbox>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// setup a phony hander to ensure the app pane will be populated.
|
||||
// Setup a phony handler to ensure the app pane will be populated.
|
||||
var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
|
||||
createInstance(Ci.nsIWebHandlerApp);
|
||||
handler.name = "App pane alive test";
|
||||
|
@ -23,8 +23,9 @@ function test() {
|
|||
observe: function(win, topic, data) {
|
||||
if (topic != "app-handler-pane-loaded")
|
||||
return;
|
||||
runTest(win);
|
||||
|
||||
obs.removeObserver(observer, "app-handler-pane-loaded");
|
||||
runTest(win);
|
||||
}
|
||||
};
|
||||
obs.addObserver(observer, "app-handler-pane-loaded", false);
|
||||
|
|
|
@ -47,18 +47,4 @@ ifdef ENABLE_TESTS
|
|||
DIRS = test
|
||||
endif
|
||||
|
||||
MODULE = browsersearch
|
||||
XPIDL_MODULE = browsersearch
|
||||
|
||||
XPIDLSRCS = nsIBrowserSearchService.idl
|
||||
|
||||
EXTRA_PP_COMPONENTS = nsSearchService.js \
|
||||
nsSearchSuggestions.js
|
||||
|
||||
ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
|
||||
DEFINES += -DOFFICIAL_BUILD=1
|
||||
endif
|
||||
|
||||
DEFINES += -DMOZ_DISTRIBUTION_ID=$(MOZ_DISTRIBUTION_ID)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -46,6 +46,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_346337.js \
|
||||
browser_346337_sample.html \
|
||||
browser_350525.js \
|
||||
browser_367052.js \
|
||||
browser_393716.js \
|
||||
|
|
|
@ -38,15 +38,20 @@ function test() {
|
|||
/** Test for Bug 346337 **/
|
||||
|
||||
let fieldList = {
|
||||
"//input[@name='testinput']": Date.now().toString(),
|
||||
"//input[@name='bad name']": Math.random().toString(),
|
||||
"//input[@name='input']": Date.now().toString(),
|
||||
"//input[@name='spaced 1']": Math.random().toString(),
|
||||
"//input[3]": "three",
|
||||
"//input[@type='checkbox']": true,
|
||||
"//input[@name='uncheck']": false,
|
||||
"//input[@type='radio'][1]": false,
|
||||
"//input[@type='radio'][2]": true,
|
||||
"//input[@type='radio'][3]": false,
|
||||
"//select": 2,
|
||||
"//select[@multiple]": [1, 3],
|
||||
"//textarea[1]": "",
|
||||
"//textarea[3]": "Some more test\n" + new Date()
|
||||
"//textarea[2]": "Some text... " + Math.random(),
|
||||
"//textarea[3]": "Some more text\n" + new Date(),
|
||||
"//input[@type='file']": "/dev/null"
|
||||
};
|
||||
|
||||
function getElementByXPath(aTab, aQuery) {
|
||||
|
@ -91,8 +96,9 @@ function test() {
|
|||
let privacy_level = gPrefService.getIntPref("browser.sessionstore.privacy_level");
|
||||
gPrefService.setIntPref("browser.sessionstore.privacy_level", 2);
|
||||
|
||||
todo(false, "test doesn't run from the harness's http server");
|
||||
let tab = tabbrowser.addTab("https://bugzilla.mozilla.org/attachment.cgi?id=328502");
|
||||
let testURL = "chrome://mochikit/content/browser/" +
|
||||
"browser/components/sessionstore/test/browser/browser_346337_sample.html";
|
||||
let tab = tabbrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
for (let xpath in fieldList)
|
||||
setFormValue(tab, xpath, fieldList[xpath]);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<title>Test for bug 346337</title>
|
||||
|
||||
<h3>Text Fields</h3>
|
||||
<input type="text" name="input">
|
||||
<input type="text" name="spaced 1">
|
||||
<input>
|
||||
|
||||
<h3>Checkboxes and Radio buttons</h3>
|
||||
<input type="checkbox" name="check"> Check 1
|
||||
<input type="checkbox" name="uncheck" checked> Check 2
|
||||
<p>
|
||||
<input type="radio" name="group" value="1"> Radio 1
|
||||
<input type="radio" name="group" value="some"> Radio 2
|
||||
<input type="radio" name="group" checked> Radio 3
|
||||
|
||||
<h3>Selects</h3>
|
||||
<select name="any">
|
||||
<option value="1"> Select 1
|
||||
<option value="some"> Select 2
|
||||
<option>Select 3
|
||||
</select>
|
||||
<select multiple="multiple">
|
||||
<option value=1> Multi-select 1
|
||||
<option value=2> Multi-select 2
|
||||
<option value=3> Multi-select 3
|
||||
<option value=4> Multi-select 4
|
||||
</select>
|
||||
|
||||
<h3>Text Areas</h3>
|
||||
<textarea name="testarea"></textarea>
|
||||
<textarea name="sized one" rows="5" cols="25"></textarea>
|
||||
<textarea></textarea>
|
||||
|
||||
<h3>File Selector</h3>
|
||||
<input type="file">
|
|
@ -152,7 +152,7 @@ function (engineURL, iconURL)
|
|||
debug(ex);
|
||||
Components.utils.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex);
|
||||
|
||||
var searchBundle = srGetStrBundle("chrome://browser/locale/search.properties");
|
||||
var searchBundle = srGetStrBundle("chrome://global/locale/search/search.properties");
|
||||
var brandBundle = srGetStrBundle("chrome://branding/locale/brand.properties");
|
||||
var brandName = brandBundle.GetStringFromName("brandShortName");
|
||||
var title = searchBundle.GetStringFromName("error_invalid_engine_title");
|
||||
|
|
|
@ -66,7 +66,6 @@ bin/components/autocomplete.xpt
|
|||
bin/components/autoconfig.xpt
|
||||
bin/components/browsercompsbase.xpt
|
||||
bin/components/browserplaces.xpt
|
||||
bin/components/browsersearch.xpt
|
||||
bin/components/browser-feeds.xpt
|
||||
bin/components/caps.xpt
|
||||
bin/components/chardet.xpt
|
||||
|
@ -167,6 +166,7 @@ bin/components/spellchecker.xpt
|
|||
bin/components/storage.xpt
|
||||
bin/components/profile.xpt
|
||||
bin/components/toolkitprofile.xpt
|
||||
bin/components/toolkitsearch.xpt
|
||||
bin/components/txtsvc.xpt
|
||||
bin/components/txmgr.xpt
|
||||
bin/components/uconv.xpt
|
||||
|
|
|
@ -69,6 +69,7 @@ BRANDING_FILES = \
|
|||
DEFINES += \
|
||||
-DAB_CD=$(AB_CD) \
|
||||
-DPKG_BASENAME=$(PKG_BASENAME) \
|
||||
-DPKG_INST_BASENAME=$(PKG_INST_BASENAME) \
|
||||
-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
|
||||
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
|
||||
-DMOZ_APP_DISPLAYNAME=${MOZ_APP_DISPLAYNAME} \
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
!define AppVersion "@MOZ_APP_VERSION@"
|
||||
!define GREVersion @MOZILLA_VERSION@
|
||||
!define AB_CD "@AB_CD@"
|
||||
!define FileInstallerEXE "@PKG_BASENAME@.installer.exe"
|
||||
!define FileInstallerMSI "@PKG_BASENAME@.installer.msi"
|
||||
!define FileInstallerEXE "@PKG_INST_BASENAME@.exe"
|
||||
!define FileInstallerMSI "@PKG_INST_BASENAME@.msi"
|
||||
!define FileInstallerNETRoot "@PKG_BASENAME@.net-installer"
|
||||
|
||||
!define FileMainEXE "@MOZ_APP_NAME@.exe"
|
||||
|
|
|
@ -73,7 +73,6 @@ bin\components\autocomplete.xpt
|
|||
bin\components\autoconfig.xpt
|
||||
bin\components\browsercompsbase.xpt
|
||||
bin\components\browserplaces.xpt
|
||||
bin\components\browsersearch.xpt
|
||||
bin\components\browser-feeds.xpt
|
||||
bin\components\caps.xpt
|
||||
bin\components\chardet.xpt
|
||||
|
@ -171,6 +170,7 @@ bin\components\saxparser.xpt
|
|||
bin\components\shistory.xpt
|
||||
bin\components\storage.xpt
|
||||
bin\components\toolkitprofile.xpt
|
||||
bin\components\toolkitsearch.xpt
|
||||
bin\components\txtsvc.xpt
|
||||
bin\components\txmgr.xpt
|
||||
#ifdef MOZ_USE_NATIVE_UCONV
|
||||
|
|
|
@ -74,6 +74,7 @@ DEFINES += \
|
|||
-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
|
||||
-DLOCALE_SRCDIR=$(call core_abspath,$(LOCALE_SRCDIR)) \
|
||||
-DPKG_BASENAME=$(PKG_BASENAME) \
|
||||
-DPKG_INST_BASENAME=$(PKG_INST_BASENAME) \
|
||||
$(NULL)
|
||||
|
||||
ifndef MOZ_BRANDING_DIRECTORY
|
||||
|
@ -192,7 +193,7 @@ PACKAGER_NO_LIBS = 1
|
|||
include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
|
||||
include $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/installer/windows/charset.mk
|
||||
|
||||
repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe
|
||||
repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
|
||||
repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES)
|
||||
ifneq (en-US,$(AB_CD))
|
||||
@echo "Verifying $(AB_CD) installer variable usage"
|
||||
|
@ -227,7 +228,7 @@ endif
|
|||
app.7z > $(WIN32_INSTALLER_OUT)
|
||||
chmod 0755 $(WIN32_INSTALLER_OUT)
|
||||
|
||||
repackage-win32-installer-%: WIN32_INSTALLER_IN=$(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe
|
||||
repackage-win32-installer-%: WIN32_INSTALLER_IN=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe
|
||||
repackage-win32-installer-%: $(WIN32_INSTALLER_IN)
|
||||
@$(MAKE) repackage-win32-installer AB_CD=$* WIN32_INSTALLER_IN=$(WIN32_INSTALLER_IN)
|
||||
|
||||
|
@ -267,20 +268,22 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
|||
mv $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_APPNAME)/$(_APPNAME)/Contents/Resources/en.lproj $(_ABS_DIST)/l10n-stage/$(MOZ_PKG_APPNAME)/$(_APPNAME)/Contents/Resources/$(AB).lproj
|
||||
endif
|
||||
endif
|
||||
$(NSINSTALL) -D $(DIST)/l10n-stage/$(PKG_PATH)
|
||||
cd $(DIST)/l10n-stage; \
|
||||
$(MAKE_PACKAGE)
|
||||
mv -f $(DIST)/l10n-stage/$(PACKAGE) $(DIST)
|
||||
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
|
||||
mv -f $(DIST)/l10n-stage/$(PACKAGE) $(DIST)/$(PACKAGE)
|
||||
|
||||
repackage-zip-%: ZIP_IN=$(_ABS_DIST)/$(PACKAGE)
|
||||
repackage-zip-%: $(ZIP_IN)
|
||||
@$(MAKE) repackage-zip AB_CD=$* ZIP_IN=$(ZIP_IN)
|
||||
|
||||
langpack-%: LANGPACK_FILE=$(_ABS_DIST)/install/firefox-$(MOZ_APP_VERSION).$(AB_CD).langpack.xpi
|
||||
langpack-%: LANGPACK_FILE=$(_ABS_DIST)/$(PKG_LANGPACK_PATH)$(PKG_LANGPACK_BASENAME).xpi
|
||||
langpack-%: AB_CD=$*
|
||||
langpack-%: XPI_NAME=locale-$*
|
||||
langpack-%:
|
||||
@echo "Making langpack $(LANGPACK_FILE)"
|
||||
$(NSINSTALL) -D $(DIST)/install
|
||||
$(NSINSTALL) -D $(DIST)/$(PKG_LANGPACK_PATH)
|
||||
@$(RM) -rf $(DIST)/xpi-stage/locale-$(AB_CD)
|
||||
@$(MAKE) libs-$(AB_CD) USE_EXTENSION_MANIFEST=1
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(DEFINES) $(ACDEFINES) -I$(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/defines.inc -I$(LOCALE_SRCDIR)/defines.inc $(srcdir)/generic/install.rdf > $(FINAL_TARGET)/install.rdf
|
||||
|
@ -335,7 +338,53 @@ endif
|
|||
@$(WGET) -nv --output-document $(_ABS_DIST)/$(PACKAGE) $(EN_US_BINARY_URL)/$(PACKAGE)
|
||||
@echo "Downloaded $(EN_US_BINARY_URL)/$(PACKAGE) to $(_ABS_DIST)/$(PACKAGE)"
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
$(NSINSTALL) -D $(_ABS_DIST)/install/sea
|
||||
@$(WGET) -nv --output-document $(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe $(EN_US_BINARY_URL)/$(PKG_BASENAME).installer.exe
|
||||
@echo "Downloaded $(EN_US_BINARY_URL)/$(PKG_BASENAME).installer.exe to $(_ABS_DIST)/install/sea/$(PKG_BASENAME)"
|
||||
$(NSINSTALL) -D $(_ABS_DIST)/$(PKG_INST_PATH)
|
||||
@$(WGET) -nv --output-document $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe $(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe
|
||||
@echo "Downloaded $(EN_US_BINARY_URL)/$(PKG_PATH)$(PKG_INST_BASENAME).exe to $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME)"
|
||||
endif
|
||||
|
||||
#These make targets call prepare-repackages by setting different UPLOAD_DIR
|
||||
prepare-upload-latest-%:
|
||||
@$(MAKE) prepare-repackages-$* UPLOAD_DIR=$(DIST)/upload/latest
|
||||
|
||||
prepare-upload-dated-%:
|
||||
@$(MAKE) prepare-repackages-$* UPLOAD_DIR=$(DIST)/upload/`date "+%Y-%m-%d-%H"`-$(MOZ_PKG_APPNAME)$(MOZ_APP_VERSION)-l10n
|
||||
|
||||
#Each platform uploads their xpi files to different folders
|
||||
ifeq (Linux, $(OS_ARCH))
|
||||
XPI_DESTINATION = linux-xpi
|
||||
endif
|
||||
ifeq (Darwin, $(OS_ARCH))
|
||||
XPI_DESTINATION = mac-xpi
|
||||
endif
|
||||
ifeq (WINNT, $(OS_ARCH))
|
||||
XPI_DESTINATION = windows-xpi
|
||||
endif
|
||||
|
||||
# This target will generate a UPLOAD_DIR folder with
|
||||
# l10n repackages in the way that we offer l10n nightlies
|
||||
# 1) ./ the binary
|
||||
# 2) ./{linux,mac,windows}-xpi/locale.xpi
|
||||
prepare-repackages-%:
|
||||
ifndef XPI_DESTINATION
|
||||
$(error XPI_DESTINATION not defined; \
|
||||
This is the folder where the xpi files will be moved to)
|
||||
endif
|
||||
ifndef UPLOAD_DIR
|
||||
$(error UPLOAD_DIR not defined)
|
||||
endif
|
||||
$(NSINSTALL) -D $(UPLOAD_DIR)
|
||||
$(NSINSTALL) -D $(UPLOAD_DIR)/$(XPI_DESTINATION)
|
||||
# Move the langpack
|
||||
mv $(DIST)/install/firefox-$(MOZ_APP_VERSION).$*.langpack.xpi \
|
||||
$(UPLOAD_DIR)/$(XPI_DESTINATION)/$*.xpi
|
||||
# Move the repackage
|
||||
mv $(DIST)/firefox-$(MOZ_APP_VERSION).$*.* \
|
||||
$(UPLOAD_DIR)/.
|
||||
# Move the windows installer
|
||||
ifeq (WINNT, $(OS_ARCH))
|
||||
mv $(DIST)/install/sea/firefox-$(MOZ_APP_VERSION).$*.win32.installer.exe \
|
||||
$(UPLOAD_DIR)/.
|
||||
endif
|
||||
# Set the permissions that the folders will have in ftp once uploaded
|
||||
chmod -vR 775 $(UPLOAD_DIR)
|
||||
|
|
|
@ -1,45 +1,60 @@
|
|||
af
|
||||
ar
|
||||
as
|
||||
be
|
||||
bg
|
||||
ca
|
||||
cs
|
||||
cy
|
||||
da
|
||||
de
|
||||
el
|
||||
en-GB
|
||||
eo
|
||||
es-AR
|
||||
es-ES
|
||||
et
|
||||
eu
|
||||
fi
|
||||
fr
|
||||
fy-NL
|
||||
ga-IE
|
||||
gl
|
||||
gu-IN
|
||||
he
|
||||
hi-IN
|
||||
hu
|
||||
id
|
||||
is
|
||||
it
|
||||
ja
|
||||
ja-JP-mac
|
||||
ka
|
||||
kn
|
||||
ko
|
||||
ku
|
||||
lt
|
||||
mk
|
||||
mn
|
||||
mr
|
||||
nb-NO
|
||||
nl
|
||||
nn-NO
|
||||
oc
|
||||
pa-IN
|
||||
pl
|
||||
pt-BR
|
||||
pt-PT
|
||||
ro
|
||||
ru
|
||||
si
|
||||
sk
|
||||
sq
|
||||
sr
|
||||
sv-SE
|
||||
ta
|
||||
te
|
||||
th
|
||||
tr
|
||||
uk
|
||||
zh-CN
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
<!ENTITY generalEncoding "Encoding:">
|
||||
<!ENTITY generalMetaName "Name">
|
||||
<!ENTITY generalMetaContent "Content">
|
||||
<!ENTITY generalSecurityMore "More">
|
||||
<!ENTITY generalSecurityMore.accesskey "o">
|
||||
<!ENTITY generalSecurityDetails "Details">
|
||||
<!ENTITY generalSecurityDetails.accesskey "D">
|
||||
|
||||
<!ENTITY mediaTab "Media">
|
||||
<!ENTITY mediaTab.accesskey "M">
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<!ENTITY removeallpermissions.label "Remove All Sites">
|
||||
<!ENTITY removeallpermissions.accesskey "e">
|
||||
<!ENTITY address.label "Address of web site:">
|
||||
<!ENTITY address.accesskey "d">
|
||||
<!ENTITY block.label "Block">
|
||||
<!ENTITY block.accesskey "B">
|
||||
<!ENTITY session.label "Allow for Session">
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
The methods by which forged (phished) and attack sites will be detected by
|
||||
phishing providers will vary from human review to machine-based heuristics to a
|
||||
combination of both, so it's important that these strings and
|
||||
useDownloadedList.label convey the meaning "suspected" (and not something like
|
||||
useDownloadedList.label convey the meaning "reported" (and not something like
|
||||
"known").
|
||||
-->
|
||||
<!ENTITY tellMaybeAttackSite.label "Tell me if the site I'm visiting is a suspected attack site">
|
||||
<!ENTITY tellMaybeAttackSite2.label "Block reported attack sites">
|
||||
<!ENTITY tellMaybeAttackSite.accesskey "k">
|
||||
|
||||
<!ENTITY tellMaybeForgery.label "Tell me if the site I'm visiting is a suspected forgery">
|
||||
<!ENTITY tellMaybeForgery.accesskey "T">
|
||||
<!ENTITY tellMaybeForgery2.label "Block reported web forgeries">
|
||||
<!ENTITY tellMaybeForgery.accesskey "B">
|
||||
|
||||
<!ENTITY addonExceptions.label "Exceptions…">
|
||||
<!ENTITY addonExceptions.accesskey "E">
|
||||
|
|
|
@ -6,20 +6,5 @@ cmd_clearHistory_accesskey=C
|
|||
cmd_showSuggestions=Show Suggestions
|
||||
cmd_showSuggestions_accesskey=S
|
||||
|
||||
addEngineConfirmTitle=Add Search Engine
|
||||
addEngineConfirmation=Add "%S" to the list of engines available in the search bar?\n\nFrom: %S
|
||||
addEngineUseNowText=Start &using it right away
|
||||
addEngineAddButtonLabel=Add
|
||||
|
||||
error_loading_engine_title=Download Error
|
||||
# LOCALIZATION NOTE (error_loading_engine_msg2): %1$S = brandShortName, %2$S = location
|
||||
error_loading_engine_msg2=%S could not download the search plugin from:\n%S
|
||||
error_duplicate_engine_msg=%S could not install the search plugin from "%S" because an engine with the same name already exists.
|
||||
|
||||
error_invalid_engine_title=Install Error
|
||||
# LOCALIZATION NOTE (error_invalid_engine_msg): %S = brandShortName
|
||||
error_invalid_engine_msg=This search engine isn't supported by %S and can't be installed.
|
||||
|
||||
cmd_addFoundEngine=Add "%S"
|
||||
|
||||
suggestion_label=Suggestions
|
||||
|
|
|
@ -3,15 +3,8 @@
|
|||
<Description>eBay - Online actions</Description>
|
||||
<InputEncoding>ISO-8859-1</InputEncoding>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAA/wAAAABAAABAQAAAgEAAAMBAAAD/QAAAAIAAAECAAACAgAAAwIAAAP+AAAAAwAAAQMAAAIDAAADAwAAA/8AAAAD/AABA/wAAgP8AAMD/AAD//wAAAABAAEAAQACAAEAAwABAAP8AQAAAQEAAQEBAAIBAQADAQEAA/0BAAACAQABAgEAAgIBAAMCAQAD/gEAAAMBAAEDAQACAwEAAwMBAAP/AQAAA/0AAQP9AAID/QADA/0AA//9AAAAAgABAAIAAgACAAMAAgAD/AIAAAECAAEBAgACAQIAAwECAAP9AgAAAgIAAQICAAICAgADAgIAA/4CAAADAgABAwIAAgMCAAMDAgAD/wIAAAP+AAED/gACA/4AAwP+AAP//gAAAAMAAQADAAIAAwADAAMAA/wDAAABAwABAQMAAgEDAAMBAwAD/QMAAAIDAAECAwACAgMAAwIDAAP+AwAAAwMAAQMDAAIDAwADAwMAA/8DAAAD/wABA/8AAgP/AAMD/wAD//8AAAAD/AEAA/wCAAP8AwAD/AP8A/wAAQP8AQED/AIBA/wDAQP8A/0D/AACA/wBAgP8AgID/AMCA/wD/gP8AAMD/AEDA/wCAwP8AwMD/AP/A/wAA//8AQP//AID//wDA//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fHx8fHx8fHx8fHx8AAB8cGRkUFAcHBx8fBUKfAAAfFBkfHxNHF4cb29vCnwAAHxkZFBQUBx8HG98bwp8fAB8ZGR8UGQcXhxvb28KFXx8fHZkZGRNHBwcfG8jCgoQfAB8fHx8HBx8b29vCnwPCnwAAAB8fBwcfHx8EBB8Dwp8AAAAAHx8fHwAfHx8AHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AACAAwAAAAMAAAADAAAAAQAAAAAAAAAAAACAAAAA4AAAAPCIAAD//wAA//8AAP//AAA=</Image>
|
||||
<Url type="text/html" method="GET" template="http://search.ebay.com/search/search.dll">
|
||||
<Param name="query" value="{searchTerms}"/>
|
||||
<Param name="MfcISAPICommand" value="GetResult"/>
|
||||
<Param name="ht" value="1"/>
|
||||
<Param name="ebaytag1" value="ebayreg"/>
|
||||
<Param name="srchdesc" value="n"/>
|
||||
<Param name="maxRecordsReturned" value="300"/>
|
||||
<Param name="maxRecordsPerPage" value="50"/>
|
||||
<Param name="SortProperty" value="MetaEndSort"/>
|
||||
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4">
|
||||
<Param name="satitle" value="{searchTerms}"/>
|
||||
</Url>
|
||||
<SearchForm>http://search.ebay.com/</SearchForm>
|
||||
</SearchPlugin>
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
#filter substitution
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the locales being supplied by this package -->
|
||||
<RDF:Seq about="urn:mozilla:locale:root">
|
||||
<RDF:li resource="urn:mozilla:locale:@AB_CD@"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- locale information -->
|
||||
<RDF:Description about="urn:mozilla:locale:@AB_CD@">
|
||||
<chrome:packages>
|
||||
<RDF:Seq about="urn:mozilla:locale:@AB_CD@:packages">
|
||||
<RDF:li resource="urn:mozilla:locale:@AB_CD@:inspector"/>
|
||||
</RDF:Seq>
|
||||
</chrome:packages>
|
||||
</RDF:Description>
|
||||
|
||||
<!-- Version Information. State that we work only with major version of this
|
||||
package. -->
|
||||
<RDF:Description about="urn:mozilla:locale:@AB_CD@:inspector"
|
||||
chrome:localeVersion="@MOZILLA_LOCALE_VERSION@" />
|
||||
|
||||
</RDF:RDF>
|
|
@ -157,10 +157,10 @@ Sanitizer.prototype = {
|
|||
formdata: {
|
||||
clear: function ()
|
||||
{
|
||||
//Clear undo history of all searchBars
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
|
||||
var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManagerInterface.getEnumerator("navigator:browser");
|
||||
// Clear undo history of all searchBars
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManager.getEnumerator("navigator:browser");
|
||||
while (windows.hasMoreElements()) {
|
||||
var searchBar = windows.getNext().document.getElementById("searchbar");
|
||||
if (searchBar) {
|
||||
|
@ -173,9 +173,23 @@ Sanitizer.prototype = {
|
|||
.getService(Components.interfaces.nsIFormHistory2);
|
||||
formHistory.removeAllEntries();
|
||||
},
|
||||
|
||||
|
||||
get canClear()
|
||||
{
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var windows = windowManager.getEnumerator("navigator:browser");
|
||||
while (windows.hasMoreElements()) {
|
||||
var searchBar = windows.getNext().document.getElementById("searchbar");
|
||||
if (searchBar) {
|
||||
var transactionMgr = searchBar.textbox.editor.transactionManager;
|
||||
if (searchBar.value ||
|
||||
transactionMgr.numberOfUndoItems ||
|
||||
transactionMgr.numberOfRedoItems)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"]
|
||||
.getService(Components.interfaces.nsIFormHistory2);
|
||||
return formHistory.hasEntries;
|
||||
|
|
|
@ -126,10 +126,6 @@ textbox[disabled] {
|
|||
#generalPanel > #titletext {
|
||||
-moz-margin-start: 5px;
|
||||
}
|
||||
#metaTags > .groupbox-body {
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 1px;
|
||||
}
|
||||
|
||||
groupbox.collapsable caption .caption-icon {
|
||||
width: 9px;
|
||||
|
@ -155,6 +151,8 @@ groupbox tree {
|
|||
}
|
||||
|
||||
groupbox.treebox .groupbox-body {
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 1px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
|
|
До Ширина: | Высота: | Размер: 156 B |
Двоичные данные
browser/themes/pinstripe/browser/bookmark_toolbar_background.gif
До Ширина: | Высота: | Размер: 211 B |
После Ширина: | Высота: | Размер: 403 B |
|
@ -47,10 +47,6 @@
|
|||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
@namespace svg url("http://www.w3.org/2000/svg");
|
||||
|
||||
#main-window {
|
||||
-moz-binding: url("chrome://global/skin/globalBindings.xml#unifiedWindow");
|
||||
}
|
||||
|
||||
#main-window[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] {
|
||||
border-top: 1px solid rgba(0,0,0,0.65);
|
||||
-moz-appearance: none;
|
||||
|
@ -59,18 +55,12 @@
|
|||
|
||||
/* ----- INACTIVE WINDOW ----- */
|
||||
|
||||
#main-window:not([active="true"]) > #navigator-toolbox > toolbar {
|
||||
border-top-color: rgba(255,255,255,0.45);
|
||||
border-bottom-color: rgba(0,0,0,0.35);
|
||||
background-color: #cfcfcf;
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) > #navigator-toolbox > #nav-bar {
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background-inactive.png");
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) > #navigator-toolbox > #PersonalToolbar {
|
||||
background-image: url("chrome://browser/skin/bookmark_toolbar_background-inactive.png");
|
||||
background-color: -moz-mac-chrome-inactive;
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) > #navigator-toolbox > toolbar > toolbaritem,
|
||||
|
@ -92,20 +82,8 @@
|
|||
color: #575757;
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] > .tab-image-middle,
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] > .tab-closebutton,
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] > .tab-close-button {
|
||||
background-image: url("chrome://browser/skin/tabbrowser/tab-middle-inactive.png");
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] > .tab-image-left,
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"][chromedir="rtl"] > .tab-image-right {
|
||||
background: url("chrome://browser/skin/tabbrowser/tab-left-inactive.png") no-repeat;
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] > .tab-image-right,
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"][chromedir="rtl"] > .tab-image-left {
|
||||
background: url("chrome://browser/skin/tabbrowser/tab-right-inactive.png") no-repeat;
|
||||
#main-window:not([active="true"]) .tabbrowser-tab[selected="true"] {
|
||||
background-color: -moz-mac-chrome-inactive;
|
||||
}
|
||||
|
||||
/* ----- SEARCH FIELD ----- */
|
||||
|
@ -117,7 +95,7 @@
|
|||
/* ----- BOOKMARK TOOLBAR ----- */
|
||||
|
||||
#PersonalToolbar {
|
||||
background: url("chrome://browser/skin/bookmark_toolbar_background.gif") repeat-x center center;
|
||||
background: url("chrome://browser/skin/bookmark_toolbar_background.png") repeat-x center center -moz-mac-chrome-active;
|
||||
border-top: 1px solid rgba(255,255,255,0.25);
|
||||
border-bottom: 2px solid;
|
||||
-moz-border-bottom-colors: rgba(0,0,0,0.35) transparent;
|
||||
|
@ -1597,8 +1575,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
|
||||
#nav-bar {
|
||||
background-color: #9e9e9e;
|
||||
border-top: none;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.35);
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background.gif");
|
||||
background-repeat: repeat-x;
|
||||
background-position: top right;
|
||||
|
@ -1627,7 +1603,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
}
|
||||
|
||||
.tab-icon {
|
||||
margin: 0 0 4px 0;
|
||||
margin: 0 0 3px 0;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
@ -1654,17 +1630,20 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
.tabbrowser-tab {
|
||||
-moz-binding: url("chrome://browser/skin/browser.xml#tabbrowser-tab") !important;
|
||||
-moz-appearance: none;
|
||||
-moz-border-radius: 0 0 3px 3px;
|
||||
color: #222;
|
||||
-moz-box-pack: center;
|
||||
margin: 0 3px 3px 2px;
|
||||
padding: 0px;
|
||||
border: none !important;
|
||||
min-width: 1px !important;
|
||||
text-align: center;
|
||||
height: 27px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"] {
|
||||
-moz-user-focus: normal;
|
||||
background-color: -moz-mac-chrome-active;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"]:focus > .tab-image-middle > .tab-text-stack > .tab-text {
|
||||
|
@ -1685,8 +1664,17 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
padding: 0px;
|
||||
}
|
||||
|
||||
.tab-image-left,
|
||||
.tab-image-right,
|
||||
.tabbrowser-tab > .tab-image-middle,
|
||||
.tabbrowser-tab > .tab-close-button {
|
||||
margin-bottom: -3px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
|
||||
.tabbrowser-tab > .tab-image-right,
|
||||
.tabbrowser-tab[chromedir="rtl"] > .tab-image-left {
|
||||
margin-right: -3px;
|
||||
background: url("chrome://browser/skin/tabbrowser/tab-right.png") no-repeat;
|
||||
}
|
||||
|
||||
|
@ -1697,6 +1685,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
|
||||
.tabbrowser-tab > .tab-image-left,
|
||||
.tabbrowser-tab[chromedir="rtl"] > .tab-image-right {
|
||||
margin-left: -2px;
|
||||
background: url("chrome://browser/skin/tabbrowser/tab-left.png") no-repeat;
|
||||
}
|
||||
|
||||
|
@ -1706,7 +1695,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
}
|
||||
|
||||
.tabbrowser-tab > .tab-image-middle,
|
||||
.tabbrowser-tab > .tab-closebutton {
|
||||
.tabbrowser-tab > .tab-close-button {
|
||||
background: url("chrome://browser/skin/tabbrowser/tab-middle.png") repeat-x;
|
||||
-moz-box-pack: center;
|
||||
}
|
||||
|
@ -1720,16 +1709,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
list-style-image: url("chrome://global/skin/tree/item-grayscale.png");
|
||||
}
|
||||
|
||||
.tabs-closebutton {
|
||||
margin: 0;
|
||||
list-style-image: url("chrome://global/skin/icons/closetab.png") !important;
|
||||
}
|
||||
|
||||
.tabs-closebutton:hover:active {
|
||||
list-style-image: url("chrome://global/skin/icons/closetab-active.png") !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.tabbrowser-strip {
|
||||
margin-top: -1px;
|
||||
border-bottom: 1px solid #404040;
|
||||
|
@ -1741,7 +1720,8 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
-moz-box-pack: center;
|
||||
-moz-box-align: center;
|
||||
background: url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
|
||||
height: 27px;
|
||||
height: 25px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tabs-left {
|
||||
|
@ -1790,7 +1770,7 @@ tabbrowser > tabbox > tabpanels {
|
|||
list-style-image: url("chrome://global/skin/icons/closetab.png");
|
||||
-moz-appearance: none;
|
||||
border: none !important;
|
||||
padding: 0 0 4px 0;
|
||||
padding: 0 0 3px 0;
|
||||
margin: 0;
|
||||
background: inherit;
|
||||
cursor: default;
|
||||
|
@ -1806,21 +1786,12 @@ tabbrowser > tabbox > tabpanels {
|
|||
list-style-image: url("chrome://global/skin/icons/closetab-active.png");
|
||||
}
|
||||
|
||||
.tabbrowser-tab > .tab-close-button {
|
||||
background-image: url("chrome://browser/skin/tabbrowser/tab-middle.png");
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"] > .tab-close-button {
|
||||
/* Make this button focusable so clicking on it will not focus the tab while
|
||||
it's getting closed */
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:not([selected="true"]) > .tab-close-button {
|
||||
background-image: url("chrome://browser/skin/tabbrowser/tab-middle-bkgnd.png");
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down[chromedir="rtl"] {
|
||||
border: 0;
|
||||
|
@ -1897,8 +1868,7 @@ tabbrowser > tabbox > tabpanels {
|
|||
-moz-border-left-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
|
||||
-moz-border-right-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding: 2px 0 0 0;
|
||||
}
|
||||
.tabs-alltabs-button:hover {
|
||||
background-color: rgba(0,0,0,0.10);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
classic.jar:
|
||||
% skin browser classic/1.0 %skin/classic/browser/
|
||||
skin/classic/browser/bookmark_toolbar_background.gif
|
||||
skin/classic/browser/bookmark_toolbar_background-inactive.png
|
||||
skin/classic/browser/bookmark_toolbar_background.png
|
||||
skin/classic/browser/bookmark-open-left.png
|
||||
skin/classic/browser/bookmark-open-mid.png
|
||||
skin/classic/browser/bookmark-open-right.png
|
||||
|
@ -129,16 +128,10 @@ classic.jar:
|
|||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/browser/tabbrowser/tab-left.png (tabbrowser/tab-left.png)
|
||||
skin/classic/browser/tabbrowser/tab-left-bkgnd.png (tabbrowser/tab-left-bkgnd.png)
|
||||
skin/classic/browser/tabbrowser/tab-left-hover.png (tabbrowser/tab-left-hover.png)
|
||||
skin/classic/browser/tabbrowser/tab-left-inactive.png (tabbrowser/tab-left-inactive.png)
|
||||
skin/classic/browser/tabbrowser/tab-middle.png (tabbrowser/tab-middle.png)
|
||||
skin/classic/browser/tabbrowser/tab-middle-bkgnd.png (tabbrowser/tab-middle-bkgnd.png)
|
||||
skin/classic/browser/tabbrowser/tab-middle-hover.png (tabbrowser/tab-middle-hover.png)
|
||||
skin/classic/browser/tabbrowser/tab-middle-inactive.png (tabbrowser/tab-middle-inactive.png)
|
||||
skin/classic/browser/tabbrowser/tab-right.png (tabbrowser/tab-right.png)
|
||||
skin/classic/browser/tabbrowser/tab-right-bkgnd.png (tabbrowser/tab-right-bkgnd.png)
|
||||
skin/classic/browser/tabbrowser/tab-right-hover.png (tabbrowser/tab-right-hover.png)
|
||||
skin/classic/browser/tabbrowser/tab-right-inactive.png (tabbrowser/tab-right-inactive.png)
|
||||
skin/classic/browser/tabbrowser/tabs-bottom-bg.png (tabbrowser/tabs-bottom-bg.png)
|
||||
skin/classic/browser/urlbar/endcap.png (urlbar/endcap.png)
|
||||
skin/classic/browser/urlbar/endcap-rtl.png (urlbar/endcap-rtl.png)
|
||||
|
|
|
@ -39,27 +39,13 @@
|
|||
|
||||
@import "chrome://global/skin/";
|
||||
|
||||
#main-window {
|
||||
-moz-binding: url("chrome://global/skin/globalBindings.xml#unifiedWindow");
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) > #topStackBar {
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background-inactive.png");
|
||||
background-color: #cfcfcf;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
#main-window:not([active="true"]) > #topStackBar > #viewGroup {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#topStackBar {
|
||||
display: -moz-box;
|
||||
background-color: #969696;
|
||||
border-bottom: 1px solid #404040;
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background.gif");
|
||||
background-repeat: repeat-x;
|
||||
background-position: top right;
|
||||
-moz-appearance: -moz-mac-unified-toolbar;
|
||||
padding: 4px 0 8px;
|
||||
-moz-box-pack: center;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
/* Unified toolbar */
|
||||
|
||||
#places {
|
||||
-moz-binding: url("chrome://global/skin/globalBindings.xml#unifiedWindow");
|
||||
}
|
||||
|
||||
/* Inactive Window */
|
||||
|
||||
#places:not([active="true"]) > #placesToolbox > #placesToolbar {
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background-inactive.png");
|
||||
background-color: #cfcfcf;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
#places:not([active="true"]) > #placesToolbox > #placesToolbar > toolbarbutton,
|
||||
#places:not([active="true"]) > #placesToolbox > #placesToolbar > #searchFilter {
|
||||
opacity: 0.7;
|
||||
|
@ -79,11 +67,6 @@
|
|||
}
|
||||
|
||||
#placesToolbar {
|
||||
background-color: #999;
|
||||
border-bottom: 1px solid #404040;
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background.gif");
|
||||
background-repeat: repeat-x;
|
||||
background-position: 3px 0px;
|
||||
margin-top: -3px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
|
Двоичные данные
browser/themes/pinstripe/browser/places/star-icons.png
До Ширина: | Высота: | Размер: 3.8 KiB После Ширина: | Высота: | Размер: 3.5 KiB |
|
@ -39,16 +39,6 @@
|
|||
# ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#BrowserPreferences {
|
||||
-moz-binding: url("chrome://global/skin/globalBindings.xml#unifiedPrefwindow");
|
||||
}
|
||||
|
||||
#BrowserPreferences:not([active="true"]) > .paneSelector {
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background-tall-inactive.png");
|
||||
background-color: #cfcfcf;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.35);
|
||||
}
|
||||
|
||||
#BrowserPreferences:not([active="true"]) > .paneSelector > radio {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
@ -69,11 +59,7 @@
|
|||
.paneSelector {
|
||||
list-style-image: url("chrome://browser/skin/preferences/Options.png");
|
||||
padding: 0 5px 2px 5px;
|
||||
background-color: #999;
|
||||
border-bottom: 1px solid #404040;
|
||||
background-image: url("chrome://global/skin/toolbar/toolbar-background-tall.png");
|
||||
background-repeat: repeat-x;
|
||||
background-position: top right;
|
||||
-moz-appearance: -moz-mac-unified-toolbar;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
|
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-left-hover.png
До Ширина: | Высота: | Размер: 342 B |
До Ширина: | Высота: | Размер: 274 B |
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-left.png
До Ширина: | Высота: | Размер: 285 B После Ширина: | Высота: | Размер: 318 B |
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-middle-hover.png
До Ширина: | Высота: | Размер: 185 B |
До Ширина: | Высота: | Размер: 141 B |
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-middle.png
До Ширина: | Высота: | Размер: 141 B После Ширина: | Высота: | Размер: 161 B |
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-right-hover.png
До Ширина: | Высота: | Размер: 343 B |
До Ширина: | Высота: | Размер: 290 B |
Двоичные данные
browser/themes/pinstripe/browser/tabbrowser/tab-right.png
До Ширина: | Высота: | Размер: 296 B После Ширина: | Высота: | Размер: 333 B |
|
@ -1809,12 +1809,6 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
color: HighlightText !important;
|
||||
}
|
||||
|
||||
/* Bookmark drag and drop styles */
|
||||
.bookmark-item[dragover-into="true"] > .menu-iconic-text {
|
||||
background: Highlight !important;
|
||||
color: HighlightText !important;
|
||||
}
|
||||
|
||||
/* rules for menupopup drop indicators */
|
||||
.menupopup-drop-indicator-bar {
|
||||
position: relative;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!env perl
|
||||
|
||||
#!env perl
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
|
@ -35,33 +35,33 @@
|
|||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
use File::Spec::Unix;
|
||||
use strict;
|
||||
|
||||
print "Usage: $0 dest_path start_path\n" if ($#ARGV+1 != 2);
|
||||
my $finish = my_canonpath(shift);
|
||||
my $start = my_canonpath(shift);
|
||||
|
||||
my $res = File::Spec::Unix->abs2rel($finish, $start);
|
||||
|
||||
#print STDERR "abs2rel($finish,$start) = $res\n";
|
||||
print "$res\n";
|
||||
|
||||
sub my_canonpath($) {
|
||||
my ($file) = @_;
|
||||
my (@inlist, @outlist, $dir);
|
||||
|
||||
# Do what File::Spec::Unix->no_upwards should do
|
||||
my @inlist = split(/\//, File::Spec::Unix->canonpath($file));
|
||||
foreach $dir (@inlist) {
|
||||
if ($dir eq '..') {
|
||||
pop @outlist;
|
||||
} else {
|
||||
push @outlist, $dir;
|
||||
}
|
||||
}
|
||||
$file = join '/',@outlist;
|
||||
return $file;
|
||||
}
|
||||
|
||||
|
||||
use File::Spec::Unix;
|
||||
use strict;
|
||||
|
||||
print "Usage: $0 dest_path start_path\n" if ($#ARGV+1 != 2);
|
||||
my $finish = my_canonpath(shift);
|
||||
my $start = my_canonpath(shift);
|
||||
|
||||
my $res = File::Spec::Unix->abs2rel($finish, $start);
|
||||
|
||||
#print STDERR "abs2rel($finish,$start) = $res\n";
|
||||
print "$res\n";
|
||||
|
||||
sub my_canonpath($) {
|
||||
my ($file) = @_;
|
||||
my (@inlist, @outlist, $dir);
|
||||
|
||||
# Do what File::Spec::Unix->no_upwards should do
|
||||
my @inlist = split(/\//, File::Spec::Unix->canonpath($file));
|
||||
foreach $dir (@inlist) {
|
||||
if ($dir eq '..') {
|
||||
pop @outlist;
|
||||
} else {
|
||||
push @outlist, $dir;
|
||||
}
|
||||
}
|
||||
$file = join '/',@outlist;
|
||||
return $file;
|
||||
}
|
||||
|
||||
|
|
|
@ -1708,7 +1708,8 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
if (appType == nsIDocShell::APP_TYPE_MAIL)
|
||||
{
|
||||
*result = mIsMailJavaScriptEnabled;
|
||||
// we are temporarily disabling js in mail for TB 3.0 b1
|
||||
*result = PR_FALSE; // mIsMailJavaScriptEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,436 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla build system.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <l10n@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 *****
|
||||
|
||||
'''jarmaker.py provides a python class to package up chrome content by
|
||||
processing jar.mn files.
|
||||
|
||||
See the documentation for jar.mn on MDC for further details on the format.
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import logging
|
||||
from time import localtime
|
||||
from optparse import OptionParser
|
||||
from MozZipFile import ZipFile
|
||||
from cStringIO import StringIO
|
||||
from datetime import datetime
|
||||
|
||||
from utils import pushback_iter
|
||||
from Preprocessor import Preprocessor
|
||||
|
||||
__all__ = ['JarMaker']
|
||||
|
||||
class ZipEntry:
|
||||
'''Helper class for jar output.
|
||||
|
||||
This class defines a simple file-like object for a zipfile.ZipEntry
|
||||
so that we can consecutively write to it and then close it.
|
||||
This methods hooks into ZipFile.writestr on close().
|
||||
'''
|
||||
def __init__(self, name, zipfile):
|
||||
self._zipfile = zipfile
|
||||
self._name = name
|
||||
self._inner = StringIO()
|
||||
|
||||
def write(self, content):
|
||||
'Append the given content to this zip entry'
|
||||
self._inner.write(content)
|
||||
return
|
||||
|
||||
def close(self):
|
||||
'The close method writes the content back to the zip file.'
|
||||
self._zipfile.writestr(self._name, self._inner.getvalue())
|
||||
|
||||
def getModTime(aPath):
|
||||
if not os.path.isfile(aPath):
|
||||
return 0
|
||||
mtime = os.stat(aPath).st_mtime
|
||||
return localtime(mtime)
|
||||
|
||||
|
||||
class JarMaker(object):
|
||||
'''JarMaker reads jar.mn files and process those into jar files or
|
||||
flat directories, along with chrome.manifest files.
|
||||
'''
|
||||
|
||||
ignore = re.compile('\s*(\#.*)?$')
|
||||
jarline = re.compile('(?:(?P<jarfile>[\w\d.\-\_\\\/]+).jar\:)|(?:\s*(\#.*)?)\s*$')
|
||||
regline = re.compile('\%\s+(.*)$')
|
||||
entryre = '(?P<optPreprocess>\*)?(?P<optOverwrite>\+?)\s+'
|
||||
entryline = re.compile(entryre + '(?P<output>[\w\d.\-\_\\\/\+]+)\s*(\((?P<locale>\%?)(?P<source>[\w\d.\-\_\\\/]+)\))?\s*$')
|
||||
|
||||
def __init__(self, outputFormat = 'flat', useJarfileManifest = True,
|
||||
useChromeManifest = False):
|
||||
self.outputFormat = outputFormat
|
||||
self.useJarfileManifest = useJarfileManifest
|
||||
self.useChromeManifest = useChromeManifest
|
||||
self.pp = Preprocessor()
|
||||
|
||||
def getCommandLineParser(self):
|
||||
'''Get a optparse.OptionParser for jarmaker.
|
||||
|
||||
This OptionParser has the options for jarmaker as well as
|
||||
the options for the inner PreProcessor.
|
||||
'''
|
||||
# HACK, we need to unescape the string variables we get,
|
||||
# the perl versions didn't grok strings right
|
||||
p = self.pp.getCommandLineParser(unescapeDefines = True)
|
||||
p.add_option('-f', type="choice", default="jar",
|
||||
choices=('jar', 'flat', 'symlink'),
|
||||
help="fileformat used for output", metavar="[jar, flat, symlink]")
|
||||
p.add_option('-v', action="store_true", dest="verbose",
|
||||
help="verbose output")
|
||||
p.add_option('-q', action="store_false", dest="verbose",
|
||||
help="verbose output")
|
||||
p.add_option('-e', action="store_true",
|
||||
help="create chrome.manifest instead of jarfile.manifest")
|
||||
p.add_option('-s', type="string", action="append", default=[],
|
||||
help="source directory")
|
||||
p.add_option('-t', type="string",
|
||||
help="top source directory")
|
||||
p.add_option('-c', '--l10n-src', type="string", action="append",
|
||||
help="localization directory")
|
||||
p.add_option('--l10n-base', type="string", action="append", default=[],
|
||||
help="base directory to be used for localization (multiple)")
|
||||
p.add_option('-j', type="string",
|
||||
help="jarfile directory")
|
||||
# backwards compat, not needed
|
||||
p.add_option('-a', action="store_false", default=True,
|
||||
help="NOT SUPPORTED, turn auto-registration of chrome off (installed-chrome.txt)")
|
||||
p.add_option('-d', type="string",
|
||||
help="UNUSED, chrome directory")
|
||||
p.add_option('-o', help="cross compile for auto-registration, ignored")
|
||||
p.add_option('-l', action="store_true",
|
||||
help="ignored (used to switch off locks)")
|
||||
p.add_option('-x', action="store_true",
|
||||
help="force Unix")
|
||||
p.add_option('-z', help="backwards compat, ignored")
|
||||
p.add_option('-p', help="backwards compat, ignored")
|
||||
return p
|
||||
|
||||
def processIncludes(self, includes):
|
||||
'''Process given includes with the inner PreProcessor.
|
||||
|
||||
Only use this for #defines, the includes shouldn't generate
|
||||
content.
|
||||
'''
|
||||
self.pp.out = StringIO()
|
||||
for inc in includes:
|
||||
self.pp.do_include(inc)
|
||||
includesvalue = self.pp.out.getvalue()
|
||||
if includesvalue:
|
||||
logging.info("WARNING: Includes produce non-empty output")
|
||||
self.pp.out = None
|
||||
pass
|
||||
|
||||
def finalizeJar(self, jarPath, chromebasepath, register,
|
||||
doZip=True):
|
||||
'''Helper method to write out the chrome registration entries to
|
||||
jarfile.manifest or chrome.manifest, or both.
|
||||
|
||||
The actual file processing is done in updateManifest.
|
||||
'''
|
||||
# rewrite the manifest, if entries given
|
||||
if not register:
|
||||
return
|
||||
if self.useJarfileManifest:
|
||||
self.updateManifest(jarPath + '.manifest', chromebasepath % '',
|
||||
register)
|
||||
if self.useChromeManifest:
|
||||
manifestPath = os.path.join(os.path.dirname(jarPath),
|
||||
'..', 'chrome.manifest')
|
||||
self.updateManifest(manifestPath, chromebasepath % 'chrome/',
|
||||
register)
|
||||
|
||||
def updateManifest(self, manifestPath, chromebasepath, register):
|
||||
'''updateManifest replaces the % in the chrome registration entries
|
||||
with the given chrome base path, and updates the given manifest file.
|
||||
'''
|
||||
myregister = dict.fromkeys(map(lambda s: s.replace('%', chromebasepath),
|
||||
register.iterkeys()))
|
||||
manifestExists = os.path.isfile(manifestPath)
|
||||
mode = (manifestExists and 'r+b') or 'wb'
|
||||
mf = open(manifestPath, mode)
|
||||
if manifestExists:
|
||||
# import previous content into hash, ignoring empty ones and comments
|
||||
imf = re.compile('(#.*)?$')
|
||||
for l in re.split('[\r\n]+', mf.read()):
|
||||
if imf.match(l):
|
||||
continue
|
||||
myregister[l] = None
|
||||
mf.seek(0)
|
||||
for k in myregister.iterkeys():
|
||||
mf.write(k + os.linesep)
|
||||
mf.close()
|
||||
|
||||
def makeJar(self, infile=None,
|
||||
jardir='',
|
||||
sourcedirs=[], topsourcedir='', localedirs=None):
|
||||
'''makeJar is the main entry point to JarMaker.
|
||||
|
||||
It takes the input file, the output directory, the source dirs and the
|
||||
top source dir as argument, and optionally the l10n dirs.
|
||||
'''
|
||||
if isinstance(infile, basestring):
|
||||
logging.info("processing " + infile)
|
||||
pp = self.pp.clone()
|
||||
pp.out = StringIO()
|
||||
pp.do_include(infile)
|
||||
lines = pushback_iter(pp.out.getvalue().splitlines())
|
||||
try:
|
||||
while True:
|
||||
l = lines.next()
|
||||
m = self.jarline.match(l)
|
||||
if not m:
|
||||
raise RuntimeError(l)
|
||||
if m.group('jarfile') is None:
|
||||
# comment
|
||||
continue
|
||||
self.processJarSection(m.group('jarfile'), lines,
|
||||
jardir, sourcedirs, topsourcedir,
|
||||
localedirs)
|
||||
except StopIteration:
|
||||
# we read the file
|
||||
pass
|
||||
return
|
||||
|
||||
def processJarSection(self, jarfile, lines,
|
||||
jardir, sourcedirs, topsourcedir, localedirs):
|
||||
'''Internal method called by makeJar to actually process a section
|
||||
of a jar.mn file.
|
||||
|
||||
jarfile is the basename of the jarfile or the directory name for
|
||||
flat output, lines is a pushback_iterator of the lines of jar.mn,
|
||||
the remaining options are carried over from makeJar.
|
||||
'''
|
||||
|
||||
# chromebasepath is used for chrome registration manifests
|
||||
# %s is getting replaced with chrome/ for chrome.manifest, and with
|
||||
# an empty string for jarfile.manifest
|
||||
chromebasepath = '%s' + jarfile
|
||||
if self.outputFormat == 'jar':
|
||||
chromebasepath = 'jar:' + chromebasepath + '.jar!'
|
||||
chromebasepath += '/'
|
||||
|
||||
jarfile = os.path.join(jardir, jarfile)
|
||||
jf = None
|
||||
if self.outputFormat == 'jar':
|
||||
#jar
|
||||
jarfilepath = jarfile + '.jar'
|
||||
if os.path.isfile(jarfilepath) and \
|
||||
os.path.getsize(jarfilepath) > 0:
|
||||
jf = ZipFile(jarfilepath, 'a', lock = True)
|
||||
else:
|
||||
if not os.path.isdir(os.path.dirname(jarfilepath)):
|
||||
os.makedirs(os.path.dirname(jarfilepath))
|
||||
jf = ZipFile(jarfilepath, 'w', lock = True)
|
||||
outHelper = self.OutputHelper_jar(jf)
|
||||
else:
|
||||
outHelper = getattr(self, 'OutputHelper_' + self.outputFormat)(jarfile)
|
||||
register = {}
|
||||
# This loop exits on either
|
||||
# - the end of the jar.mn file
|
||||
# - an line in the jar.mn file that's not part of a jar section
|
||||
while True:
|
||||
try:
|
||||
l = lines.next()
|
||||
except StopIteration:
|
||||
# we're done with this jar.mn, and this jar section
|
||||
self.finalizeJar(jarfile, chromebasepath, register)
|
||||
if jf is not None:
|
||||
jf.close()
|
||||
# reraise the StopIteration for makeJar
|
||||
raise
|
||||
if self.ignore.match(l):
|
||||
continue
|
||||
m = self.regline.match(l)
|
||||
if m:
|
||||
rline = m.group(1)
|
||||
register[rline] = 1
|
||||
continue
|
||||
m = self.entryline.match(l)
|
||||
if not m:
|
||||
# neither an entry line nor chrome reg, this jar section is done
|
||||
self.finalizeJar(jarfile, chromebasepath, register)
|
||||
if jf is not None:
|
||||
jf.close()
|
||||
lines.pushback(l)
|
||||
return
|
||||
self._processEntryLine(m, sourcedirs, topsourcedir, localedirs,
|
||||
outHelper, jf)
|
||||
return
|
||||
|
||||
def _processEntryLine(self, m,
|
||||
sourcedirs, topsourcedir, localedirs,
|
||||
outHelper, jf):
|
||||
out = m.group('output')
|
||||
src = m.group('source') or os.path.basename(out)
|
||||
# pick the right sourcedir -- l10n, topsrc or src
|
||||
if m.group('locale'):
|
||||
src_base = localedirs
|
||||
elif src.startswith('/'):
|
||||
# path/in/jar/file_name.xul (/path/in/sourcetree/file_name.xul)
|
||||
# refers to a path relative to topsourcedir, use that as base
|
||||
# and strip the leading '/'
|
||||
src_base = [topsourcedir]
|
||||
src = src[1:]
|
||||
else:
|
||||
# use srcdirs and the objdir (current working dir) for relative paths
|
||||
src_base = sourcedirs + ['.']
|
||||
# check if the source file exists
|
||||
realsrc = None
|
||||
for _srcdir in src_base:
|
||||
if os.path.isfile(os.path.join(_srcdir, src)):
|
||||
realsrc = os.path.join(_srcdir, src)
|
||||
break
|
||||
if realsrc is None:
|
||||
if jf is not None:
|
||||
jf.close()
|
||||
raise RuntimeError("file not found: " + src)
|
||||
if m.group('optPreprocess'):
|
||||
outf = outHelper.getOutput(out)
|
||||
inf = open(realsrc)
|
||||
pp = self.pp.clone()
|
||||
if src[-4:] == '.css':
|
||||
pp.setMarker('%')
|
||||
pp.out = outf
|
||||
pp.do_include(inf)
|
||||
outf.close()
|
||||
inf.close()
|
||||
return
|
||||
# copy or symlink if newer or overwrite
|
||||
if (m.group('optOverwrite')
|
||||
or (getModTime(realsrc) >
|
||||
outHelper.getDestModTime(m.group('output')))):
|
||||
if self.outputFormat == 'symlink' and hasattr(os, 'symlink'):
|
||||
outHelper.symlink(realsrc, out)
|
||||
return
|
||||
outf = outHelper.getOutput(out)
|
||||
# open in binary mode, this can be images etc
|
||||
inf = open(realsrc, 'rb')
|
||||
outf.write(inf.read())
|
||||
outf.close()
|
||||
inf.close()
|
||||
|
||||
|
||||
class OutputHelper_jar(object):
|
||||
'''Provide getDestModTime and getOutput for a given jarfile.
|
||||
'''
|
||||
def __init__(self, jarfile):
|
||||
self.jarfile = jarfile
|
||||
def getDestModTime(self, aPath):
|
||||
try :
|
||||
info = self.jarfile.getinfo(aPath)
|
||||
return info.date_time
|
||||
except:
|
||||
return 0
|
||||
def getOutput(self, name):
|
||||
return ZipEntry(name, self.jarfile)
|
||||
|
||||
class OutputHelper_flat(object):
|
||||
'''Provide getDestModTime and getOutput for a given flat
|
||||
output directory. The helper method ensureDirFor is used by
|
||||
the symlink subclass.
|
||||
'''
|
||||
def __init__(self, basepath):
|
||||
self.basepath = basepath
|
||||
def getDestModTime(self, aPath):
|
||||
return getModTime(os.path.join(self.basepath, aPath))
|
||||
def getOutput(self, name):
|
||||
out = self.ensureDirFor(name)
|
||||
return open(out, 'wb')
|
||||
def ensureDirFor(self, name):
|
||||
out = os.path.join(self.basepath, name)
|
||||
outdir = os.path.dirname(out)
|
||||
if not os.path.isdir(outdir):
|
||||
os.makedirs(outdir)
|
||||
return out
|
||||
|
||||
class OutputHelper_symlink(OutputHelper_flat):
|
||||
'''Subclass of OutputHelper_flat that provides a helper for
|
||||
creating a symlink including creating the parent directories.
|
||||
'''
|
||||
def symlink(self, src, dest):
|
||||
out = self.ensureDirFor(dest)
|
||||
os.symlink(src, out)
|
||||
|
||||
def main():
|
||||
jm = JarMaker()
|
||||
p = jm.getCommandLineParser()
|
||||
(options, args) = p.parse_args()
|
||||
jm.processIncludes(options.I)
|
||||
jm.outputFormat = options.f
|
||||
if options.e:
|
||||
jm.useChromeManifest = True
|
||||
jm.useJarfileManifest = False
|
||||
noise = logging.INFO
|
||||
if options.verbose is not None:
|
||||
noise = (options.verbose and logging.DEBUG) or logging.WARN
|
||||
logging.basicConfig(level = noise, format = "%(message)s")
|
||||
if not args:
|
||||
jm.makeJar(infile=sys.stdin,
|
||||
sourcedirs=options.s, topsourcedir=options.t,
|
||||
localedirs=options.l10n_src,
|
||||
jardir=options.j)
|
||||
return
|
||||
topsrc = options.t
|
||||
topsrc = os.path.normpath(os.path.abspath(topsrc))
|
||||
for infile in args:
|
||||
# guess srcdir and l10n dirs from jar.mn path and topsrcdir
|
||||
# srcdir is the dir of the jar.mn and
|
||||
# the l10n dirs are the relative path of topsrcdir to srcdir
|
||||
# resolved against all l10n base dirs.
|
||||
srcdir = os.path.normpath(os.path.abspath(os.path.dirname(infile)))
|
||||
l10ndir = srcdir
|
||||
if os.path.basename(srcdir) == 'locales':
|
||||
l10ndir = os.path.dirname(l10ndir)
|
||||
assert srcdir.startswith(topsrc), "src dir %s not in topsrcdir %s" % (srcdir, topsrc)
|
||||
rell10ndir = l10ndir[len(topsrc):].lstrip(os.sep)
|
||||
l10ndirs = map(lambda d: os.path.join(d, rell10ndir), options.l10n_base)
|
||||
if options.l10n_src is not None:
|
||||
l10ndirs += options.l10n_src
|
||||
srcdirs = options.s + [srcdir]
|
||||
jm.makeJar(infile=infile,
|
||||
sourcedirs=srcdirs, topsourcedir=options.t,
|
||||
localedirs=l10ndirs,
|
||||
jardir=options.j)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,160 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla build system.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <axel@pike.org>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
import zipfile
|
||||
import time
|
||||
import binascii, struct
|
||||
import zlib
|
||||
from utils import lockFile
|
||||
|
||||
|
||||
class ZipFile(zipfile.ZipFile):
|
||||
""" Class with methods to open, read, write, close, list zip files.
|
||||
|
||||
Subclassing zipfile.ZipFile to allow for overwriting of existing
|
||||
entries, though only for writestr, not for write.
|
||||
"""
|
||||
def __init__(self, file, mode="r", compression=zipfile.ZIP_STORED,
|
||||
lock = False):
|
||||
zipfile.ZipFile.__init__(self, file, mode, compression)
|
||||
self._remove = []
|
||||
self.end = self.fp.tell()
|
||||
self.debug = 0
|
||||
if lock:
|
||||
assert isinstance(file, basestring)
|
||||
self.lockfile = lockFile(file + '.lck')
|
||||
else:
|
||||
self.lockfile = None
|
||||
|
||||
def writestr(self, zinfo_or_arcname, bytes):
|
||||
"""Write contents into the archive.
|
||||
|
||||
The contents is the argument 'bytes', 'zinfo_or_arcname' is either
|
||||
a ZipInfo instance or the name of the file in the archive.
|
||||
This method is overloaded to allow overwriting existing entries.
|
||||
"""
|
||||
if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
|
||||
zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname,
|
||||
date_time=time.localtime(time.time()))
|
||||
zinfo.compress_type = self.compression
|
||||
# Add some standard UNIX file access permissions (-rw-r--r--).
|
||||
zinfo.external_attr = (0x81a4 & 0xFFFF) << 16L
|
||||
else:
|
||||
zinfo = zinfo_or_arcname
|
||||
|
||||
# Now to the point why we overwrote this in the first place,
|
||||
# remember the entry numbers if we already had this entry.
|
||||
# Optimizations:
|
||||
# If the entry to overwrite is the last one, just reuse that.
|
||||
# If we store uncompressed and the new content has the same size
|
||||
# as the old, reuse the existing entry.
|
||||
|
||||
doSeek = False # store if we need to seek to the eof after overwriting
|
||||
if self.NameToInfo.has_key(zinfo.filename):
|
||||
# Find the last ZipInfo with our name.
|
||||
# Last, because that's catching multiple overwrites
|
||||
i = len(self.filelist)
|
||||
while i > 0:
|
||||
i -= 1
|
||||
if self.filelist[i].filename == zinfo.filename:
|
||||
break
|
||||
zi = self.filelist[i]
|
||||
if ((zinfo.compress_type == zipfile.ZIP_STORED
|
||||
and zi.compress_size == len(bytes))
|
||||
or (i + 1) == len(self.filelist)):
|
||||
# make sure we're allowed to write, otherwise done by writestr below
|
||||
self._writecheck(zi)
|
||||
# overwrite existing entry
|
||||
self.fp.seek(zi.header_offset)
|
||||
if (i + 1) == len(self.filelist):
|
||||
# this is the last item in the file, just truncate
|
||||
self.fp.truncate()
|
||||
else:
|
||||
# we need to move to the end of the file afterwards again
|
||||
doSeek = True
|
||||
# unhook the current zipinfo, the writestr of our superclass
|
||||
# will add a new one
|
||||
self.filelist.pop(i)
|
||||
self.NameToInfo.pop(zinfo.filename)
|
||||
else:
|
||||
# Couldn't optimize, sadly, just remember the old entry for removal
|
||||
self._remove.append(self.filelist.pop(i))
|
||||
zipfile.ZipFile.writestr(self, zinfo, bytes)
|
||||
self.filelist.sort(lambda l, r: cmp(l.header_offset, r.header_offset))
|
||||
if doSeek:
|
||||
self.fp.seek(self.end)
|
||||
self.end = self.fp.tell()
|
||||
|
||||
def close(self):
|
||||
"""Close the file, and for mode "w" and "a" write the ending
|
||||
records.
|
||||
|
||||
Overwritten to compact overwritten entries.
|
||||
"""
|
||||
if not self._remove:
|
||||
# we don't have anything special to do, let's just call base
|
||||
r = zipfile.ZipFile.close(self)
|
||||
self.lockfile = None
|
||||
return r
|
||||
|
||||
if self.fp.mode != 'r+b':
|
||||
# adjust file mode if we originally just wrote, now we rewrite
|
||||
self.fp.close()
|
||||
self.fp = open(self.filename, 'r+b')
|
||||
all = map(lambda zi: (zi, True), self.filelist) + \
|
||||
map(lambda zi: (zi, False), self._remove)
|
||||
all.sort(lambda l, r: cmp(l[0].header_offset, r[0].header_offset))
|
||||
lengths = [all[i+1][0].header_offset - all[i][0].header_offset
|
||||
for i in xrange(len(all)-1)]
|
||||
lengths.append(self.end - all[-1][0].header_offset)
|
||||
to_pos = 0
|
||||
for (zi, keep), length in zip(all, lengths):
|
||||
if not keep:
|
||||
continue
|
||||
oldoff = zi.header_offset
|
||||
# python <= 2.4 has file_offset
|
||||
if hasattr(zi, 'file_offset'):
|
||||
zi.file_offset = zi.file_offset + to_pos - oldoff
|
||||
zi.header_offset = to_pos
|
||||
self.fp.seek(oldoff)
|
||||
content = self.fp.read(length)
|
||||
self.fp.seek(to_pos)
|
||||
self.fp.write(content)
|
||||
to_pos += length
|
||||
self.fp.truncate()
|
||||
zipfile.ZipFile.close(self)
|
||||
self.lockfile = None
|
|
@ -49,8 +49,9 @@ from optparse import OptionParser
|
|||
# hack around win32 mangling our line endings
|
||||
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443
|
||||
if sys.platform == "win32":
|
||||
import os, msvcrt
|
||||
import msvcrt
|
||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||
os.linesep = '\n'
|
||||
|
||||
import Expression
|
||||
|
||||
|
@ -157,9 +158,18 @@ class Preprocessor:
|
|||
Parse a commandline into this parser.
|
||||
Uses OptionParser internally, no args mean sys.argv[1:].
|
||||
"""
|
||||
includes = []
|
||||
def handleI(option, opt, value, parser):
|
||||
includes.append(value)
|
||||
p = self.getCommandLineParser()
|
||||
(options, args) = p.parse_args(args=args)
|
||||
includes = options.I
|
||||
if defaultToStdin and len(args) == 0:
|
||||
args = [sys.stdin]
|
||||
includes.extend(args)
|
||||
for f in includes:
|
||||
self.do_include(f)
|
||||
pass
|
||||
|
||||
def getCommandLineParser(self, unescapeDefines = False):
|
||||
escapedValue = re.compile('".*"$')
|
||||
def handleE(option, opt, value, parser):
|
||||
for k,v in os.environ.iteritems():
|
||||
self.context[k] = v
|
||||
|
@ -168,6 +178,9 @@ class Preprocessor:
|
|||
assert len(vals) < 3
|
||||
if len(vals) == 1:
|
||||
vals.append(1)
|
||||
elif unescapeDefines and escapedValue.match(vals[1]):
|
||||
# strip escaped string values
|
||||
vals[1] = vals[1][1:-1]
|
||||
self.context[vals[0]] = vals[1]
|
||||
def handleU(option, opt, value, parser):
|
||||
del self.context[value]
|
||||
|
@ -178,7 +191,7 @@ class Preprocessor:
|
|||
def handleMarker(option, opt, value, parser):
|
||||
self.setMarker(value)
|
||||
p = OptionParser()
|
||||
p.add_option('-I', action='callback', callback=handleI, type="string",
|
||||
p.add_option('-I', action='append', type="string", default = [],
|
||||
metavar="FILENAME", help='Include file')
|
||||
p.add_option('-E', action='callback', callback=handleE,
|
||||
help='Import the environment into the defined variables')
|
||||
|
@ -194,13 +207,7 @@ class Preprocessor:
|
|||
p.add_option('--marker', action='callback', callback=handleMarker,
|
||||
type="string",
|
||||
help='Use the specified marker instead of #')
|
||||
(options, args) = p.parse_args(args=args)
|
||||
if defaultToStdin and len(args) == 0:
|
||||
args = [sys.stdin]
|
||||
includes.extend(args)
|
||||
for f in includes:
|
||||
self.do_include(f)
|
||||
pass
|
||||
return p
|
||||
|
||||
def handleLine(self, aLine):
|
||||
"""
|
||||
|
|
|
@ -616,9 +616,17 @@ WINCE = @WINCE@
|
|||
|
||||
MOZ_DISTRIBUTION_ID = @MOZ_DISTRIBUTION_ID@
|
||||
|
||||
NS_HILDON = @NS_HILDON@
|
||||
NS_OSSO = @NS_OSSO@
|
||||
MOZ_PLATFORM_HILDON = @MOZ_PLATFORM_HILDON@
|
||||
|
||||
LIBHILDONMIME_CFLAGS = @LIBHILDONMIME_CFLAGS@
|
||||
LIBHILDONMIME_LIBS = @LIBHILDONMIME_LIBS@
|
||||
LIBOSSO_CFLAGS = @LIBOSSO_CFLAGS@
|
||||
LIBOSSO_LIBS = @LIBOSSO_LIBS@
|
||||
NS_MAEMO_LOCATION = @NS_MAEMO_LOCATION@
|
||||
|
||||
MOZ_LOCATION_CFLAGS = @MOZ_LOCATION_CFLAGS@
|
||||
MOZ_LOCATION_LIBS = @MOZ_LOCATION_LIBS@
|
||||
|
||||
MACOS_SDK_DIR = @MACOS_SDK_DIR@
|
||||
NEXT_ROOT = @NEXT_ROOT@
|
||||
|
@ -631,8 +639,8 @@ HAVE_DTRACE= @HAVE_DTRACE@
|
|||
VISIBILITY_FLAGS = @VISIBILITY_FLAGS@
|
||||
WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@
|
||||
|
||||
MOZ_V1_STRING_ABI = @MOZ_V1_STRING_ABI@
|
||||
|
||||
MOZ_EMBEDDING_LEVEL_DEFAULT = @MOZ_EMBEDDING_LEVEL_DEFAULT@
|
||||
MOZ_EMBEDDING_LEVEL_BASIC = @MOZ_EMBEDDING_LEVEL_BASIC@
|
||||
MOZ_EMBEDDING_LEVEL_MINIMAL = @MOZ_EMBEDDING_LEVEL_MINIMAL@
|
||||
|
||||
HAVE_ARM_SIMD= @HAVE_ARM_SIMD@
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
# This is a shell script, sourced by configure.
|
||||
|
||||
MOZILLA_LOCALE_VERSION=1.9a1
|
||||
MOZILLA_REGION_VERSION=1.9a1
|
||||
|
||||
MOZILLA_SKIN_VERSION=1.8
|