mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Merge mozilla-central into electrolysis.
This commit is contained in:
commit
d8c7dfc1dd
@ -196,6 +196,7 @@ ifdef MOZ_CRASHREPORTER
|
||||
$(MAKE_SYM_STORE_PATH) > \
|
||||
$(DIST)/crashreporter-symbols/$(SYMBOL_INDEX_NAME)
|
||||
echo packing symbols
|
||||
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
|
||||
cd $(DIST)/crashreporter-symbols && \
|
||||
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" .
|
||||
endif # MOZ_CRASHREPORTER
|
||||
|
@ -902,13 +902,15 @@ nsAccUtils::MustPrune(nsIAccessible *aAccessible)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
|
||||
// We don't prune buttons any more however AT don't expect children inside of
|
||||
// button in general, we allow menu buttons to have children to make them
|
||||
// accessible.
|
||||
return role == nsIAccessibleRole::ROLE_MENUITEM ||
|
||||
role == nsIAccessibleRole::ROLE_COMBOBOX_OPTION ||
|
||||
role == nsIAccessibleRole::ROLE_OPTION ||
|
||||
role == nsIAccessibleRole::ROLE_ENTRY ||
|
||||
role == nsIAccessibleRole::ROLE_FLAT_EQUATION ||
|
||||
role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
|
||||
role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_GRAPHIC ||
|
||||
role == nsIAccessibleRole::ROLE_SLIDER ||
|
||||
|
@ -279,6 +279,19 @@ public:
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extended state for the given accessible.
|
||||
*/
|
||||
static PRUint32 ExtendedState(nsIAccessible *aAcc)
|
||||
{
|
||||
PRUint32 state = 0;
|
||||
PRUint32 extstate = 0;
|
||||
if (aAcc)
|
||||
aAcc->GetState(&state, &extstate);
|
||||
|
||||
return extstate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ARIA attribute characteristics for a given ARIA attribute.
|
||||
*
|
||||
|
@ -61,6 +61,9 @@ ACCESSIBILITY_ATOM(col, "col")
|
||||
ACCESSIBILITY_ATOM(_empty, "")
|
||||
ACCESSIBILITY_ATOM(_false, "false")
|
||||
ACCESSIBILITY_ATOM(image, "image")
|
||||
ACCESSIBILITY_ATOM(menu, "menu")
|
||||
ACCESSIBILITY_ATOM(menuButton, "menu-button")
|
||||
ACCESSIBILITY_ATOM(menugenerated, "menugenerated")
|
||||
ACCESSIBILITY_ATOM(password, "password")
|
||||
ACCESSIBILITY_ATOM(reset, "reset")
|
||||
ACCESSIBILITY_ATOM(row, "row")
|
||||
@ -125,12 +128,12 @@ ACCESSIBILITY_ATOM(listhead, "listhead") // XUL
|
||||
ACCESSIBILITY_ATOM(listheader, "listheader") // XUL
|
||||
ACCESSIBILITY_ATOM(map, "map")
|
||||
ACCESSIBILITY_ATOM(math, "math")
|
||||
ACCESSIBILITY_ATOM(menu, "menu") // XUL
|
||||
ACCESSIBILITY_ATOM(menupopup, "menupopup") // XUL
|
||||
ACCESSIBILITY_ATOM(object, "object")
|
||||
ACCESSIBILITY_ATOM(ol, "ol")
|
||||
ACCESSIBILITY_ATOM(optgroup, "optgroup")
|
||||
ACCESSIBILITY_ATOM(option, "option")
|
||||
ACCESSIBILITY_ATOM(panel, "panel") // XUL
|
||||
ACCESSIBILITY_ATOM(q, "q")
|
||||
ACCESSIBILITY_ATOM(select, "select")
|
||||
ACCESSIBILITY_ATOM(select1, "select1") // XForms
|
||||
@ -164,6 +167,7 @@ ACCESSIBILITY_ATOM(_class, "class")
|
||||
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
|
||||
ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
|
||||
ACCESSIBILITY_ATOM(data, "data")
|
||||
ACCESSIBILITY_ATOM(_default, "default") // XUL button
|
||||
ACCESSIBILITY_ATOM(draggable, "draggable")
|
||||
ACCESSIBILITY_ATOM(droppable, "droppable") // XUL combo box
|
||||
ACCESSIBILITY_ATOM(editable, "editable")
|
||||
|
@ -1107,3 +1107,45 @@ nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
|
||||
return content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::hidden,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::GeneratePopupTree(nsIDOMNode *aNode, PRBool aIsAnon)
|
||||
{
|
||||
// Set menugenerated="true" on the menupopup node to generate the sub-menu
|
||||
// items if they have not been generated.
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> list;
|
||||
if (aIsAnon) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
nsIDocument* document = content->GetCurrentDoc();
|
||||
if (document)
|
||||
document->GetXBLChildNodesFor(content, getter_AddRefs(list));
|
||||
|
||||
} else {
|
||||
aNode->GetChildNodes(getter_AddRefs(list));
|
||||
}
|
||||
|
||||
PRUint32 length = 0;
|
||||
if (!list || NS_FAILED(list->GetLength(&length)))
|
||||
return;
|
||||
|
||||
for (PRUint32 idx = 0; idx < length; idx++) {
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
list->Item(idx, getter_AddRefs(childNode));
|
||||
nsCOMPtr<nsIContent> child(do_QueryInterface(childNode));
|
||||
|
||||
PRBool isPopup = child->NodeInfo()->Equals(nsAccessibilityAtoms::menupopup,
|
||||
kNameSpaceID_XUL) ||
|
||||
child->NodeInfo()->Equals(nsAccessibilityAtoms::panel,
|
||||
kNameSpaceID_XUL);
|
||||
if (isPopup && !child->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::menugenerated,
|
||||
nsAccessibilityAtoms::_true,
|
||||
eCaseMatters)) {
|
||||
|
||||
child->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::menugenerated,
|
||||
NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -446,6 +446,15 @@ public:
|
||||
return aContent->NodeInfo()->Equals(nsAccessibilityAtoms::th) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates frames for popup subtree.
|
||||
*
|
||||
* @param aNode [in] DOM node containing the menupopup element as a child
|
||||
* @param aIsAnon [in] specifies whether popup should be searched inside of
|
||||
* anonymous or explicit content
|
||||
*/
|
||||
static void GeneratePopupTree(nsIDOMNode *aNode, PRBool aIsAnon = PR_FALSE);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -401,11 +401,12 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
nsIDOMNode *aNode,
|
||||
nsIDOMEvent *aFocusEvent,
|
||||
PRBool aForceEvent,
|
||||
PRBool aIsAsynch)
|
||||
PRBool
|
||||
nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
nsIDOMNode *aNode,
|
||||
nsIDOMEvent *aFocusEvent,
|
||||
PRBool aForceEvent,
|
||||
PRBool aIsAsynch)
|
||||
{
|
||||
if (mCaretAccessible) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aFocusEvent));
|
||||
@ -531,10 +532,16 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
if (docAccessible) {
|
||||
// Doc is gaining focus, but actual focus may be on an element within document
|
||||
nsCOMPtr<nsIDOMNode> realFocusedNode = GetCurrentFocus();
|
||||
if (realFocusedNode != aNode || realFocusedNode == mDOMNode) {
|
||||
if ((realFocusedNode != aNode || realFocusedNode == mDOMNode) &&
|
||||
!(nsAccUtils::ExtendedState(finalFocusAccessible) &
|
||||
nsIAccessibleStates::EXT_STATE_EDITABLE)) {
|
||||
// Suppress document focus, because real DOM focus will be fired next,
|
||||
// and that's what we care about
|
||||
// except in the case of editable documents because we can't rely on a
|
||||
// followup focus event for an element in an editable document.
|
||||
// Make sure we never fire focus for the nsRootAccessible (mDOMNode)
|
||||
|
||||
// XXX todo dig deeper on editor focus inconsistency in bug 526313
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ PRUint32 nsTextEquivUtils::gRoleToNameRulesMap[] =
|
||||
eFromValue, // ROLE_ENTRY
|
||||
eNoRule, // ROLE_CAPTION
|
||||
eNoRule, // ROLE_DOCUMENT_FRAME
|
||||
eNoRule, // ROLE_HEADING
|
||||
eFromSubtreeIfRec, // ROLE_HEADING
|
||||
eNoRule, // ROLE_PAGE
|
||||
eFromSubtreeIfRec, // ROLE_SECTION
|
||||
eNoRule, // ROLE_REDUNDANT_OBJECT
|
||||
|
@ -403,6 +403,8 @@ nsHTMLTableHeaderCellAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
// Assume it's columnheader if there are headers in siblings, oterwise
|
||||
// rowheader.
|
||||
nsIContent* parent = content->GetParent();
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
PRInt32 indexInParent = parent->IndexOf(content);
|
||||
|
||||
for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
|
||||
|
@ -2032,6 +2032,11 @@ nsHyperTextAccessible::ScrollSubstringToPoint(PRInt32 aStartIndex,
|
||||
presContext->DevPixelsToAppUnits(devOffsetY));
|
||||
|
||||
nsSize size(parentFrame->GetSize());
|
||||
|
||||
// avoid divide by zero
|
||||
size.width = size.width ? size.width : 1;
|
||||
size.height = size.height ? size.height : 1;
|
||||
|
||||
PRInt16 hPercent = offsetPoint.x * 100 / size.width;
|
||||
PRInt16 vPercent = offsetPoint.y * 100 / size.height;
|
||||
|
||||
|
@ -36,26 +36,43 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
#include "nsXULColorPickerAccessible.h"
|
||||
|
||||
#include "nsAccessibleTreeWalker.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
|
||||
/**
|
||||
* XUL Color Picker Tile
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerTileAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
nsXULColorPickerTileAccessible::nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
||||
nsFormControlAccessible(aNode, aShell)
|
||||
{
|
||||
nsXULColorPickerTileAccessible::
|
||||
nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsAccessibleWrap(aNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* We are a pushbutton
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerTileAccessible: nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULColorPickerTileAccessible::GetValue(nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::color, aValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerTileAccessible: nsAccessible
|
||||
|
||||
nsresult
|
||||
nsXULColorPickerTileAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
{
|
||||
@ -63,15 +80,14 @@ nsXULColorPickerTileAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible states: focused, focusable, selected
|
||||
*/
|
||||
nsresult
|
||||
nsXULColorPickerTileAccessible::GetStateInternal(PRUint32 *aState,
|
||||
PRUint32 *aExtraState)
|
||||
{
|
||||
// Possible states: focused, focusable, selected.
|
||||
|
||||
// get focus and disable status from base class
|
||||
nsresult rv = nsFormControlAccessible::GetStateInternal(aState, aExtraState);
|
||||
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_FOCUSABLE;
|
||||
@ -92,19 +108,10 @@ nsXULColorPickerTileAccessible::GetStateInternal(PRUint32 *aState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULColorPickerTileAccessible::GetValue(nsAString& _retval)
|
||||
{
|
||||
if (!mDOMNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ASSERTION(element, "No XUL Element for colorpicker");
|
||||
return element->GetAttribute(NS_LITERAL_STRING("color"), _retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* XUL Color Picker
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
@ -114,15 +121,30 @@ nsXULColorPickerTileAccessible(aNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible states: focused, focusable, unavailable(disabled)
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible: nsAccessNode
|
||||
|
||||
nsresult
|
||||
nsXULColorPickerAccessible::Init()
|
||||
{
|
||||
nsresult rv = nsXULColorPickerTileAccessible::Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCoreUtils::GeneratePopupTree(mDOMNode, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible: nsAccessible
|
||||
|
||||
nsresult
|
||||
nsXULColorPickerAccessible::GetStateInternal(PRUint32 *aState,
|
||||
PRUint32 *aExtraState)
|
||||
{
|
||||
// Possible states: focused, focusable, unavailable(disabled).
|
||||
|
||||
// get focus and disable status from base class
|
||||
nsresult rv = nsFormControlAccessible::GetStateInternal(aState, aExtraState);
|
||||
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
*aState |= nsIAccessibleStates::STATE_FOCUSABLE |
|
||||
@ -138,3 +160,46 @@ nsXULColorPickerAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible: protected nsAccessible
|
||||
|
||||
void
|
||||
nsXULColorPickerAccessible::CacheChildren()
|
||||
{
|
||||
if (IsDefunct()) {
|
||||
mAccChildCount = eChildCountUninitialized;
|
||||
return; // This outer doc node has been shut down
|
||||
}
|
||||
|
||||
if (mAccChildCount != eChildCountUninitialized)
|
||||
return;
|
||||
|
||||
mAccChildCount = 0; // Avoid reentry
|
||||
|
||||
nsCOMPtr<nsIAccessible> menupopupAccessible;
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
|
||||
walker.GetFirstChild();
|
||||
|
||||
while (walker.mState.accessible) {
|
||||
PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
|
||||
|
||||
if (role == nsIAccessibleRole::ROLE_ALERT) {
|
||||
// Get an accessbile for menupopup or panel elements.
|
||||
menupopupAccessible = walker.mState.accessible;
|
||||
break;
|
||||
}
|
||||
|
||||
walker.GetNextSibling();
|
||||
}
|
||||
|
||||
if (!menupopupAccessible)
|
||||
return;
|
||||
|
||||
SetFirstChild(menupopupAccessible);
|
||||
|
||||
nsRefPtr<nsAccessible> menupopupAcc =
|
||||
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
|
||||
menupopupAcc->SetParent(this);
|
||||
|
||||
mAccChildCount++;
|
||||
}
|
||||
|
@ -40,9 +40,12 @@
|
||||
#define _nsXULColorPickerAccessible_H_
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
#include "nsFormControlAccessible.h"
|
||||
#include "nsAccessibleWrap.h"
|
||||
|
||||
class nsXULColorPickerTileAccessible : public nsFormControlAccessible
|
||||
/**
|
||||
* Used for color button in colorpicker palette.
|
||||
*/
|
||||
class nsXULColorPickerTileAccessible : public nsAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
@ -55,14 +58,26 @@ public:
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used for colorpicker button (xul:colorpicker@type="button").
|
||||
*/
|
||||
class nsXULColorPickerAccessible : public nsXULColorPickerTileAccessible
|
||||
{
|
||||
public:
|
||||
nsXULColorPickerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ nsresult
|
||||
nsXULComboboxAccessible::Init()
|
||||
{
|
||||
nsresult rv = nsAccessibleWrap::Init();
|
||||
nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
|
||||
nsCoreUtils::GeneratePopupTree(mDOMNode);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -56,33 +56,35 @@
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
/**
|
||||
* XUL Button: can contain arbitrary HTML content
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
|
||||
// Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
|
||||
nsXULButtonAccessible::nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
||||
nsAccessibleWrap(aNode, aShell)
|
||||
{
|
||||
nsXULButtonAccessible::
|
||||
nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsAccessibleWrap(aNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Only one actions available
|
||||
*/
|
||||
NS_IMETHODIMP nsXULButtonAccessible::GetNumActions(PRUint8 *_retval)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsXULButtonAccessible, nsAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULButtonAccessible::GetNumActions(PRUint8 *aCount)
|
||||
{
|
||||
*_retval = 1;
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
|
||||
*aCount = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of our only action
|
||||
*/
|
||||
NS_IMETHODIMP nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
if (aIndex == eAction_Click) {
|
||||
aName.AssignLiteral("press");
|
||||
@ -91,20 +93,33 @@ NS_IMETHODIMP nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aN
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell the button to do its action
|
||||
*/
|
||||
NS_IMETHODIMP nsXULButtonAccessible::DoAction(PRUint8 index)
|
||||
NS_IMETHODIMP
|
||||
nsXULButtonAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (index == 0) {
|
||||
if (aIndex == 0)
|
||||
return DoCommand();
|
||||
}
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* We are a pushbutton
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsAccessNode
|
||||
|
||||
nsresult
|
||||
nsXULButtonAccessible::Init()
|
||||
{
|
||||
nsresult rv = nsAccessibleWrap::Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (ContainsMenu())
|
||||
nsCoreUtils::GeneratePopupTree(mDOMNode);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsAccessible
|
||||
|
||||
nsresult
|
||||
nsXULButtonAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
{
|
||||
@ -112,12 +127,11 @@ nsXULButtonAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible states: focused, focusable, unavailable(disabled)
|
||||
*/
|
||||
nsresult
|
||||
nsXULButtonAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
// Possible states: focused, focusable, unavailable(disabled).
|
||||
|
||||
// get focus and disable status from base class
|
||||
nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
@ -152,63 +166,118 @@ nsXULButtonAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
if (element) {
|
||||
PRBool isDefault = PR_FALSE;
|
||||
element->HasAttribute(NS_LITERAL_STRING("default"), &isDefault) ;
|
||||
if (isDefault)
|
||||
*aState |= nsIAccessibleStates::STATE_DEFAULT;
|
||||
if (ContainsMenu())
|
||||
*aState |= nsIAccessibleStates::STATE_HASPOPUP;
|
||||
|
||||
nsAutoString type;
|
||||
element->GetAttribute(NS_LITERAL_STRING("type"), type);
|
||||
if (type.EqualsLiteral("menu") || type.EqualsLiteral("menu-button")) {
|
||||
*aState |= nsIAccessibleStates::STATE_HASPOPUP;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::_default))
|
||||
*aState |= nsIAccessibleStates::STATE_DEFAULT;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsXULButtonAccessible::CacheChildren()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsAccessible protected
|
||||
|
||||
void
|
||||
nsXULButtonAccessible::CacheChildren()
|
||||
{
|
||||
// An XUL button accessible may have 1 child dropmarker accessible
|
||||
// In general XUL button has not accessible children. Nevertheless menu
|
||||
// buttons can have button (@type="menu-button") and popup accessibles
|
||||
// (@type="menu-button" or @type="menu").
|
||||
|
||||
if (!mWeakShell) {
|
||||
mAccChildCount = eChildCountUninitialized;
|
||||
return; // This outer doc node has been shut down
|
||||
}
|
||||
if (mAccChildCount == eChildCountUninitialized) {
|
||||
mAccChildCount = 0; // Avoid reentry
|
||||
|
||||
SetFirstChild(nsnull);
|
||||
PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
|
||||
|
||||
// XXX: no children until the button is menu button. Probably it's not
|
||||
// totally correct but in general AT wants to have leaf buttons.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
|
||||
PRBool isMenu = content->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::type,
|
||||
nsAccessibilityAtoms::menu,
|
||||
eCaseMatters);
|
||||
|
||||
PRBool isMenuButton = isMenu ?
|
||||
PR_FALSE :
|
||||
content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
||||
nsAccessibilityAtoms::menuButton, eCaseMatters);
|
||||
|
||||
if (!isMenu && !isMenuButton)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIAccessible> buttonAccessible;
|
||||
nsCOMPtr<nsIAccessible> menupopupAccessible;
|
||||
|
||||
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
|
||||
walker.GetFirstChild();
|
||||
nsCOMPtr<nsIAccessible> dropMarkerAccessible;
|
||||
|
||||
while (walker.mState.accessible) {
|
||||
dropMarkerAccessible = walker.mState.accessible;
|
||||
PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
|
||||
|
||||
if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
|
||||
// Get an accessbile for menupopup or panel elements.
|
||||
menupopupAccessible = walker.mState.accessible;
|
||||
|
||||
} else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
|
||||
// Button type="menu-button" contains a real button. Get an accessible
|
||||
// for it. Ignore dropmarker button what is placed as a last child.
|
||||
buttonAccessible = walker.mState.accessible;
|
||||
break;
|
||||
}
|
||||
|
||||
walker.GetNextSibling();
|
||||
}
|
||||
|
||||
// If the anonymous tree walker can find accessible children,
|
||||
// and the last one is a push button, then use it as the only accessible
|
||||
// child -- because this is the scenario where we have a dropmarker child
|
||||
if (!menupopupAccessible)
|
||||
return;
|
||||
|
||||
if (dropMarkerAccessible) {
|
||||
if (nsAccUtils::RoleInternal(dropMarkerAccessible) ==
|
||||
nsIAccessibleRole::ROLE_PUSHBUTTON) {
|
||||
SetFirstChild(dropMarkerAccessible);
|
||||
nsRefPtr<nsAccessible> childAcc =
|
||||
nsAccUtils::QueryAccessible(dropMarkerAccessible);
|
||||
childAcc->SetNextSibling(nsnull);
|
||||
childAcc->SetParent(this);
|
||||
mAccChildCount = 1;
|
||||
}
|
||||
SetFirstChild(menupopupAccessible);
|
||||
|
||||
nsRefPtr<nsAccessible> menupopupAcc =
|
||||
nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
|
||||
menupopupAcc->SetParent(this);
|
||||
|
||||
mAccChildCount++;
|
||||
|
||||
if (buttonAccessible) {
|
||||
if (menupopupAcc)
|
||||
menupopupAcc->SetNextSibling(buttonAccessible);
|
||||
else
|
||||
SetFirstChild(buttonAccessible);
|
||||
|
||||
nsRefPtr<nsAccessible> buttonAcc =
|
||||
nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
|
||||
buttonAcc->SetParent(this);
|
||||
|
||||
mAccChildCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XUL Dropmarker: can contain arbitrary HTML content
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible protected
|
||||
|
||||
PRBool
|
||||
nsXULButtonAccessible::ContainsMenu()
|
||||
{
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
{&nsAccessibilityAtoms::menu, &nsAccessibilityAtoms::menuButton, nsnull};
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return content->FindAttrValueIn(kNameSpaceID_None, nsAccessibilityAtoms::type,
|
||||
strings, eCaseMatters) >= 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULDropmarkerAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
|
@ -46,26 +46,46 @@
|
||||
#include "nsXULMenuAccessible.h"
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
|
||||
/**
|
||||
* Used for XUL button.
|
||||
*
|
||||
* @note Don't inherit from nsFormControlAccessible - it doesn't allow children
|
||||
* and a button can have a dropmarker child.
|
||||
*/
|
||||
class nsXULButtonAccessible : public nsAccessibleWrap
|
||||
// Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
|
||||
{
|
||||
public:
|
||||
enum { eAction_Click = 0 };
|
||||
nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
void CacheChildren();
|
||||
|
||||
// nsXULButtonAccessible
|
||||
PRBool ContainsMenu();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used for XUL checkbox.
|
||||
*/
|
||||
class nsXULCheckboxAccessible : public nsFormControlAccessible
|
||||
{
|
||||
public:
|
||||
|
@ -273,7 +273,7 @@ nsresult
|
||||
nsXULMenuitemAccessible::Init()
|
||||
{
|
||||
nsresult rv = nsAccessibleWrap::Init();
|
||||
nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
|
||||
nsCoreUtils::GeneratePopupTree(mDOMNode);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -642,46 +642,6 @@ nsXULMenupopupAccessible::GetStateInternal(PRUint32 *aState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsXULMenupopupAccessible::FindInNodeList(nsIDOMNodeList *aNodeList,
|
||||
nsIAtom *aAtom, PRUint32 aNameSpaceID)
|
||||
{
|
||||
PRUint32 numChildren;
|
||||
if (!aNodeList || NS_FAILED(aNodeList->GetLength(&numChildren))) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
for (PRUint32 childIndex = 0; childIndex < numChildren; childIndex++) {
|
||||
aNodeList->Item(childIndex, getter_AddRefs(childNode));
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(childNode);
|
||||
if (content && content->NodeInfo()->Equals(aAtom, kNameSpaceID_XUL)) {
|
||||
nsIDOMNode *matchNode = childNode;
|
||||
NS_ADDREF(matchNode);
|
||||
return matchNode;
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void nsXULMenupopupAccessible::GenerateMenu(nsIDOMNode *aNode)
|
||||
{
|
||||
// Set menugenerated="true" on the menupopup node to generate the
|
||||
// sub-menu items if they have not been generated
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
aNode->GetChildNodes(getter_AddRefs(nodeList));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> menuPopup = FindInNodeList(nodeList, nsAccessibilityAtoms::menupopup,
|
||||
kNameSpaceID_XUL);
|
||||
nsCOMPtr<nsIDOMElement> popupElement(do_QueryInterface(menuPopup));
|
||||
if (popupElement) {
|
||||
nsAutoString attr;
|
||||
popupElement->GetAttribute(NS_LITERAL_STRING("menugenerated"), attr);
|
||||
if (!attr.EqualsLiteral("true")) {
|
||||
popupElement->SetAttribute(NS_LITERAL_STRING("menugenerated"), NS_LITERAL_STRING("true"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULMenupopupAccessible::GetNameInternal(nsAString& aName)
|
||||
{
|
||||
@ -704,15 +664,23 @@ nsXULMenupopupAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
nsCOMPtr<nsIAccessible> parent;
|
||||
GetParent(getter_AddRefs(parent));
|
||||
if (parent) {
|
||||
// Some widgets like the search bar have several popups, owned by buttons
|
||||
PRUint32 role = nsAccUtils::Role(parent);
|
||||
if (role == nsIAccessibleRole::ROLE_COMBOBOX ||
|
||||
role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
|
||||
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
|
||||
return NS_OK;
|
||||
|
||||
} else if (role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
|
||||
// Some widgets like the search bar have several popups, owned by buttons.
|
||||
nsCOMPtr<nsIAccessible> grandParent;
|
||||
parent->GetParent(getter_AddRefs(grandParent));
|
||||
if (role == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
|
||||
*aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aRole = nsIAccessibleRole::ROLE_MENUPOPUP;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -113,6 +113,10 @@ public:
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used for XUL menupopup and panel.
|
||||
*/
|
||||
class nsXULMenupopupAccessible : public nsXULSelectableAccessible
|
||||
{
|
||||
public:
|
||||
@ -122,11 +126,6 @@ public:
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsXULMenupopupAccessible
|
||||
static already_AddRefed<nsIDOMNode> FindInNodeList(nsIDOMNodeList *aNodeList,
|
||||
nsIAtom *aAtom, PRUint32 aNameSpaceID);
|
||||
static void GenerateMenu(nsIDOMNode *aNode);
|
||||
};
|
||||
|
||||
class nsXULMenubarAccessible : public nsAccessibleWrap
|
||||
|
@ -42,6 +42,8 @@ srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = accessible
|
||||
|
||||
DIRS = tree
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@ -88,13 +90,9 @@ _TEST_FILES =\
|
||||
$(warning test_childAtPoint.xul temporarily disabled) \
|
||||
test_cssattrs.html \
|
||||
test_descr.html \
|
||||
test_elm_filectrl.html \
|
||||
test_elm_listbox.xul \
|
||||
$(warning test_elm_media.html temporarily disabled) \
|
||||
test_elm_plugin.html \
|
||||
test_elm_select.html \
|
||||
test_elm_tree.xul \
|
||||
test_elm_txtcntnr.html \
|
||||
test_events_caretmove.html \
|
||||
test_events_coalescence.html \
|
||||
test_events_doc.html \
|
||||
@ -102,6 +100,7 @@ _TEST_FILES =\
|
||||
test_events_flush.html \
|
||||
test_events_focus.html \
|
||||
test_events_focus.xul \
|
||||
test_events_focusdoc.html \
|
||||
test_events_mutation.html \
|
||||
test_events_scroll.xul \
|
||||
test_events_tree.xul \
|
||||
|
@ -4,6 +4,8 @@
|
||||
const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
|
||||
const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
|
||||
const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
|
||||
const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
|
||||
const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
|
||||
const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
|
||||
const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
|
||||
const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
|
||||
@ -27,11 +29,14 @@ const ROLE_LINK = nsIAccessibleRole.ROLE_LINK;
|
||||
const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
|
||||
const ROLE_LISTBOX = nsIAccessibleRole.ROLE_LISTBOX;
|
||||
const ROLE_LISTITEM = nsIAccessibleRole.ROLE_LISTITEM;
|
||||
const ROLE_MENUITEM = nsIAccessibleRole.ROLE_MENUITEM;
|
||||
const ROLE_MENUPOPUP = nsIAccessibleRole.ROLE_MENUPOPUP;
|
||||
const ROLE_NOTHING = nsIAccessibleRole.ROLE_NOTHING;
|
||||
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
|
||||
const ROLE_OUTLINE = nsIAccessibleRole.ROLE_OUTLINE;
|
||||
const ROLE_OUTLINEITEM = nsIAccessibleRole.ROLE_OUTLINEITEM;
|
||||
const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
|
||||
const ROLE_PARENT_MENUITEM = nsIAccessibleRole.ROLE_PARENT_MENUITEM;
|
||||
const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
|
||||
const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
|
||||
const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
|
||||
|
@ -35,6 +35,9 @@
|
||||
// attribute.
|
||||
testDescr("img3", "description");
|
||||
|
||||
// Description from content of h2.
|
||||
testDescr("p", "heading");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -61,5 +64,7 @@
|
||||
<img id="img2" title="title" />
|
||||
<img id="img3" alt="name" title="description" />
|
||||
|
||||
<h2 id="heading">heading</h2>
|
||||
<p id="p" aria-describedby="heading" role="button">click me</p>
|
||||
</body>
|
||||
</html>
|
||||
|
102
accessible/tests/mochitest/test_events_focusdoc.html
Normal file
102
accessible/tests/mochitest/test_events_focusdoc.html
Normal file
@ -0,0 +1,102 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible document focus event 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"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Focus invoker.
|
||||
*/
|
||||
function takeFocus(aAcc)
|
||||
{
|
||||
this.DOMNode = aAcc; // xxx rename this expected property in events.js
|
||||
|
||||
this.invoke = function takeFocus_invoke()
|
||||
{
|
||||
this.DOMNode.takeFocus();
|
||||
};
|
||||
|
||||
this.check = function takeFocus_check()
|
||||
{
|
||||
testStates(this.DOMNode, STATE_FOCUSABLE | STATE_FOCUSED);
|
||||
};
|
||||
|
||||
this.getID = function takeFocus_getID() { return aAcc.name + " focus"; };
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
//var gA11yEventDumpID = "eventdump";
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// setup
|
||||
var frameDoc = document.getElementById("iframe").contentDocument;
|
||||
frameDoc.designMode = "on";
|
||||
var frameDocAcc = getAccessible(frameDoc, [nsIAccessibleDocument]);
|
||||
var buttonAcc = getAccessible("b1");
|
||||
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_FOCUS);
|
||||
|
||||
// try to give focus to contentEditable frame twice to cover bug 512059
|
||||
gQueue.push(new takeFocus(buttonAcc));
|
||||
gQueue.push(new takeFocus(frameDocAcc));
|
||||
gQueue.push(new takeFocus(buttonAcc));
|
||||
gQueue.push(new takeFocus(frameDocAcc));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512058"
|
||||
title="Can't set focus to designMode document via accessibility APIs">
|
||||
Mozilla Bug 512058
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512059"
|
||||
title="Accessibility focus event never fired for designMode document after the first focus">
|
||||
Mozilla Bug 512059
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="testContainer">
|
||||
<button id="b1">a button</button>
|
||||
<iframe id="iframe" src="about:blank"></iframe>
|
||||
<button id="b2">a button</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
61
accessible/tests/mochitest/tree/Makefile.in
Normal file
61
accessible/tests/mochitest/tree/Makefile.in
Normal file
@ -0,0 +1,61 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = accessible/tree
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES =\
|
||||
test_button.xul \
|
||||
test_colorpicker.xul \
|
||||
test_combobox.xul \
|
||||
test_filectrl.html \
|
||||
test_media.html \
|
||||
test_menu.xul \
|
||||
test_select.html \
|
||||
test_tree.xul \
|
||||
test_txtctrl.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
|
198
accessible/tests/mochitest/tree/test_button.xul
Normal file
198
accessible/tests/mochitest/tree/test_button.xul
Normal file
@ -0,0 +1,198 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL button hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button1
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [ ]
|
||||
};
|
||||
testAccessibleTree("button1", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button2
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button2", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button3
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button3", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button4
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [ ]
|
||||
};
|
||||
testAccessibleTree("button4", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button5
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button5", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button6
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button6", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<button id="button1" label="hello"/>
|
||||
<button id="button2" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
<button id="button3" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
|
||||
<toolbarbutton id="button4" label="hello"/>
|
||||
<toolbarbutton id="button5" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="button6" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
75
accessible/tests/mochitest/tree/test_colorpicker.xul
Normal file
75
accessible/tests/mochitest/tree/test_colorpicker.xul
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL button hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button1
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_BUTTONDROPDOWNGRID,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ALERT,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var colorButtons = accTree.children[0].children;
|
||||
for (var idx = 0; idx < 70; idx++) {
|
||||
var obj = { role: ROLE_PUSHBUTTON };
|
||||
colorButtons.push(obj);
|
||||
}
|
||||
|
||||
testAccessibleTree("colorpicker", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<colorpicker id="colorpicker" type="button"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
138
accessible/tests/mochitest/tree/test_combobox.xul
Normal file
138
accessible/tests/mochitest/tree/test_combobox.xul
Normal file
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL menulist and textbox @autocomplete hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// menulist
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_COMBOBOX,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("menulist", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textbox@type=autocomplete #1 (history)
|
||||
|
||||
accTree = {
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // context menu popup
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("autocomplete", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textbox@type=autocomplete #2 (child menupoup)
|
||||
|
||||
accTree = {
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // autocomplete menu popup
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_ENTRY,
|
||||
children: [ ]
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // context menu popup
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("autocomplete2", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menulist id="menulist">
|
||||
<menupopup>
|
||||
<menuitem label="item"/>
|
||||
<menuitem label="item"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
|
||||
<textbox id="autocomplete" type="autocomplete"
|
||||
autocompletesearch="history"
|
||||
value="http://localhost:8888/redirect-a11y.html"/>
|
||||
|
||||
<textbox id="autocomplete2" type="autocomplete">
|
||||
<menupopup>
|
||||
<menuitem label="item1"/>
|
||||
</menupopup>
|
||||
</textbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
73
accessible/tests/mochitest/tree/test_media.html
Normal file
73
accessible/tests/mochitest/tree/test_media.html
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
||||
-->
|
||||
<head>
|
||||
<title>HTML5 audio/video 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/role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test the accessible tree
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{ // start/stop button
|
||||
role: ROLE_PUSHBUTTON
|
||||
},
|
||||
{ // buffer bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
},
|
||||
{ // progress bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
},
|
||||
{ // slider of progress bar
|
||||
role: ROLE_SLIDER
|
||||
},
|
||||
{ // mute button
|
||||
role: ROLE_PUSHBUTTON
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("audio", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="Expose HTML5 video and audio elements' embedded controls through accessibility APIs"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=483573">Mozilla Bug 483573</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<audio id="audio" src="chrome://mochikit/content/a11y/accessible/bug461281.ogg"
|
||||
controls="true"></audio>
|
||||
|
||||
<div id="eventDump"></div>
|
||||
</body>
|
||||
</html>
|
86
accessible/tests/mochitest/tree/test_menu.xul
Normal file
86
accessible/tests/mochitest/tree/test_menu.xul
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL menu hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
if (LINUX) {
|
||||
// XXX: bug 527646
|
||||
|
||||
todo(false, "Failure on linux.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
name: "menu",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("menu", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menu id="menu" label="menu">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
@ -1288,7 +1288,7 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
}
|
||||
|
||||
let NP = {};
|
||||
Cu.import("resource://gre/modules/NetworkPrioritizer.jsm", NP);
|
||||
Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
|
||||
NP.trackBrowserWindow(window);
|
||||
|
||||
// initialize the session-restore service (in case it's not already running)
|
||||
|
@ -138,6 +138,10 @@ window.addEventListener("unload", function () {
|
||||
}
|
||||
}, false);
|
||||
|
||||
window.addEventListener("deactivate", function () {
|
||||
window.close();
|
||||
}, false);
|
||||
|
||||
window.addEventListener("keypress", function (event) {
|
||||
if (event.keyCode == event.DOM_VK_ESCAPE) {
|
||||
window.close();
|
||||
|
@ -49,7 +49,7 @@ try {
|
||||
// not critical, remain silent
|
||||
}
|
||||
|
||||
Components.utils.import("resource://gre/modules/openLocationLastURL.jsm");
|
||||
Components.utils.import("resource:///modules/openLocationLastURL.jsm");
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
|
@ -283,6 +283,11 @@ function onLoadPageInfo()
|
||||
window.arguments.length >= 1 &&
|
||||
window.arguments[0];
|
||||
|
||||
if (!args || !args.doc) {
|
||||
gWindow = window.opener.content;
|
||||
gDocument = gWindow.document;
|
||||
}
|
||||
|
||||
// init media view
|
||||
var imageTree = document.getElementById("imagetree");
|
||||
imageTree.view = gImageView;
|
||||
@ -339,6 +344,7 @@ function resetPageInfo(args)
|
||||
/* Call registered overlay reset functions */
|
||||
onResetRegistry.forEach(function(func) { func(); });
|
||||
|
||||
/* Rebuild the data */
|
||||
loadTab(args);
|
||||
}
|
||||
|
||||
@ -383,18 +389,7 @@ function loadTab(args)
|
||||
gDocument = args.doc;
|
||||
gWindow = gDocument.defaultView;
|
||||
}
|
||||
else {
|
||||
if ("gBrowser" in window.opener)
|
||||
gWindow = window.opener.gBrowser.contentWindow;
|
||||
else
|
||||
gWindow = window.opener.frames[0];
|
||||
gDocument = gWindow.document;
|
||||
}
|
||||
|
||||
if (args && args.imageElement)
|
||||
gImageElement = args.imageElement;
|
||||
|
||||
/* Rebuild the data */
|
||||
gImageElement = args && args.imageElement;
|
||||
|
||||
/* Load the page info */
|
||||
@ -597,6 +592,8 @@ function addImage(url, type, alt, elem, isBg)
|
||||
else {
|
||||
var i = gImageHash[url][type][alt];
|
||||
gImageView.data[i][COL_IMAGE_COUNT]++;
|
||||
if (elem == gImageElement)
|
||||
gImageView.data[i][COL_IMAGE_NODE] = elem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1184,6 +1181,8 @@ function selectImage() {
|
||||
for (var i = 0; i < tree.view.rowCount; i++) {
|
||||
if (gImageElement == gImageView.data[i][COL_IMAGE_NODE]) {
|
||||
tree.view.selection.select(i);
|
||||
tree.treeBoxObject.ensureRowIsVisible(i);
|
||||
tree.focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ function disableAddons() {
|
||||
var em = Components.classes["@mozilla.org/extensions/manager;1"]
|
||||
.getService(Components.interfaces.nsIExtensionManager);
|
||||
var type = nsIUpdateItem.TYPE_EXTENSION + nsIUpdateItem.TYPE_LOCALE;
|
||||
var items = em.getItemList(type, { });
|
||||
var items = em.getItemList(type);
|
||||
for (var i = 0; i < items.length; ++i)
|
||||
em.disableItem(items[i].id);
|
||||
|
||||
@ -96,7 +96,7 @@ function disableAddons() {
|
||||
// Disable plugins
|
||||
var phs = Components.classes["@mozilla.org/plugin/host;1"]
|
||||
.getService(Components.interfaces.nsIPluginHost);
|
||||
var plugins = phs.getPluginTags({ });
|
||||
var plugins = phs.getPluginTags();
|
||||
for (i = 0; i < plugins.length; ++i)
|
||||
plugins[i].disabled = true;
|
||||
}
|
||||
|
@ -356,19 +356,19 @@ Sanitizer.prototype = {
|
||||
{
|
||||
// Clear site-specific permissions like "Allow this site to open popups"
|
||||
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
pm.removeAll();
|
||||
|
||||
// Clear site-specific settings like page-zoom level
|
||||
var cps = Components.classes["@mozilla.org/content-pref/service;1"]
|
||||
.getService(Components.interfaces.nsIContentPrefService);
|
||||
.getService(Components.interfaces.nsIContentPrefService);
|
||||
cps.removeGroupedPrefs();
|
||||
|
||||
// Clear "Never remember passwords for this site", which is not handled by
|
||||
// the permission manager
|
||||
var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
|
||||
.getService(Components.interfaces.nsILoginManager);
|
||||
var hosts = pwmgr.getAllDisabledHosts({})
|
||||
.getService(Components.interfaces.nsILoginManager);
|
||||
var hosts = pwmgr.getAllDisabledHosts();
|
||||
for each (var host in hosts) {
|
||||
pwmgr.setLoginSavingEnabled(host, true);
|
||||
}
|
||||
|
@ -1514,9 +1514,9 @@
|
||||
var l = this.mTabs.length - this._removingTabs.length;
|
||||
var newTab = false;
|
||||
if (l == 1) {
|
||||
closeWindow = aCloseWindowWithLastTab != null ?
|
||||
aCloseWindowWithLastTab :
|
||||
this.mPrefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
|
||||
closeWindow = aCloseWindowWithLastTab != null ? aCloseWindowWithLastTab :
|
||||
!window.toolbar.visible ||
|
||||
this.mPrefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
|
||||
|
||||
// Closing the tab and replacing it with a blank one is notably slower
|
||||
// than closing the window right away. If the caller opts in, take
|
||||
|
@ -97,6 +97,7 @@ _BROWSER_FILES = \
|
||||
browser_bug455852.js \
|
||||
browser_bug462673.js \
|
||||
browser_bug481560.js \
|
||||
browser_bug484315.js \
|
||||
browser_bug477014.js \
|
||||
browser_bug495058.js \
|
||||
browser_bug517902.js \
|
||||
|
@ -104,31 +104,31 @@ function test() {
|
||||
window_B.addEventListener("load", function(aEvent) {
|
||||
window_B.removeEventListener("load", arguments.callee, false);
|
||||
window_B.gBrowser.addEventListener("load", function(aEvent) {
|
||||
// waitForFocus can attach to the wrong "window" with about:blank loading first
|
||||
// So just ensure that we're getting the load event for the right URI
|
||||
if (window_B.gBrowser.currentURI.spec == "about:blank")
|
||||
return;
|
||||
window_B.gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
// On Linux, waitForFocus doesn't work if the window is already focused,
|
||||
// so focus window_A first.
|
||||
waitForFocus(function() {
|
||||
isWindowState(window_A, [10, 0]);
|
||||
isWindowState(window_B, [-10]);
|
||||
|
||||
waitForFocus(function() {
|
||||
isWindowState(window_A, [10, 0]);
|
||||
isWindowState(window_B, [-10]);
|
||||
isWindowState(window_A, [0, -10]);
|
||||
isWindowState(window_B, [0]);
|
||||
|
||||
waitForFocus(function() {
|
||||
isWindowState(window_A, [0, -10]);
|
||||
isWindowState(window_B, [0]);
|
||||
isWindowState(window_A, [10, 0]);
|
||||
isWindowState(window_B, [-10]);
|
||||
|
||||
waitForFocus(function() {
|
||||
isWindowState(window_A, [10, 0]);
|
||||
isWindowState(window_B, [-10]);
|
||||
|
||||
// And we're done. Cleanup & run the next test
|
||||
window_B.close();
|
||||
window_A.gBrowser.removeTab(tab_A3);
|
||||
executeSoon(runNextTest);
|
||||
}, window_B);
|
||||
}, window_A);
|
||||
}, window_B);
|
||||
}, window_A);
|
||||
// And we're done. Cleanup & run the next test
|
||||
window_B.close();
|
||||
window_A.gBrowser.removeTab(tab_A3);
|
||||
executeSoon(runNextTest);
|
||||
}, window_B);
|
||||
}, window_A);
|
||||
}, window_B);
|
||||
|
||||
}, true);
|
||||
}, false);
|
||||
|
@ -1,15 +1,6 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// focus the url field so that it will can ensure the focus is there when
|
||||
// the window is refocused after the dialog closes
|
||||
gURLBar.focus();
|
||||
|
||||
window.addEventListener("focus", function () {
|
||||
window.removeEventListener("focus", arguments.callee, false);
|
||||
finish();
|
||||
}, false);
|
||||
|
||||
var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
|
||||
|
||||
win.addEventListener("load", function () {
|
||||
@ -18,13 +9,15 @@ function test() {
|
||||
win.content.addEventListener("focus", function () {
|
||||
win.content.removeEventListener("focus", arguments.callee, false);
|
||||
|
||||
win.gBrowser.selectedTab.addEventListener("TabClose", function () {
|
||||
ok(false, "shouldn't have gotten the TabClose event for the last tab");
|
||||
}, false);
|
||||
|
||||
EventUtils.synthesizeKey("w", { accelKey: true }, win);
|
||||
|
||||
ok(win.closed, "accel+w closed the window immediately");
|
||||
}, false);
|
||||
|
||||
win.gBrowser.selectedTab.addEventListener("TabClose", function () {
|
||||
ok(false, "shouldn't have gotten the TabClose event for the last tab");
|
||||
finish();
|
||||
}, false);
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
25
browser/base/content/test/browser_bug484315.js
Normal file
25
browser/base/content/test/browser_bug484315.js
Normal file
@ -0,0 +1,25 @@
|
||||
function test() {
|
||||
var contentWin = window.open("about:blank", "", "width=100,height=100");
|
||||
var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator)
|
||||
.getEnumerator("navigator:browser");
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
if (win.content == contentWin) {
|
||||
gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
|
||||
win.gBrowser.removeCurrentTab();
|
||||
ok(win.closed, "popup is closed");
|
||||
|
||||
// clean up
|
||||
if (!win.closed)
|
||||
win.close();
|
||||
if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
|
||||
gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw "couldn't find the content window";
|
||||
}
|
@ -33,5 +33,6 @@ function test() {
|
||||
"data:text/html," +
|
||||
"<img src='about:logo?a' height=200 width=250>" +
|
||||
"<img src='about:logo?b' height=200 width=250 alt=1>" +
|
||||
"<img src='about:logo?b' height=200 width=250 alt=2>" +
|
||||
"<img src='about:logo?b' height=100 width=150 alt=2 id='test-image'>";
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ var gNextTest = null;
|
||||
function get_test_plugin() {
|
||||
var ph = Components.classes["@mozilla.org/plugin/host;1"]
|
||||
.getService(Components.interfaces.nsIPluginHost);
|
||||
var tags = ph.getPluginTags({});
|
||||
var tags = ph.getPluginTags();
|
||||
|
||||
// Find the test plugin
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
|
@ -198,11 +198,15 @@ function openUILinkIn( url, where, allowThirdPartyFixup, postData, referrerUrl )
|
||||
createInstance(Ci.nsISupportsString);
|
||||
wuri.data = url;
|
||||
|
||||
var allowThirdPartyFixupSupports = Cc["@mozilla.org/supports-PRBool;1"].
|
||||
createInstance(Ci.nsISupportsPRBool);
|
||||
allowThirdPartyFixupSupports.data = allowThirdPartyFixup;
|
||||
|
||||
sa.AppendElement(wuri);
|
||||
sa.AppendElement(null);
|
||||
sa.AppendElement(referrerUrl);
|
||||
sa.AppendElement(postData);
|
||||
sa.AppendElement(allowThirdPartyFixup);
|
||||
sa.AppendElement(allowThirdPartyFixupSupports);
|
||||
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
|
@ -36,6 +36,7 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../places/src \
|
||||
-I$(srcdir)/../privatebrowsing/src \
|
||||
-I$(srcdir)/../about \
|
||||
-I$(srcdir)/../dirprovider \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
@ -47,6 +48,7 @@ SHARED_LIBRARY_LIBS = \
|
||||
../places/src/$(LIB_PREFIX)browserplaces_s.$(LIB_SUFFIX) \
|
||||
../privatebrowsing/src/$(LIB_PREFIX)privatebrowsing_s.$(LIB_SUFFIX) \
|
||||
../about/$(LIB_PREFIX)browserabout_s.$(LIB_SUFFIX) \
|
||||
../dirprovider/$(LIB_PREFIX)browserdir_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
|
||||
|
@ -106,3 +106,6 @@
|
||||
#define NS_BROWSER_ABOUT_REDIRECTOR_CID \
|
||||
{ 0x7e4bb6ad, 0x2fc4, 0x4dc6, { 0x89, 0xef, 0x23, 0xe8, 0xe5, 0xcc, 0xf9, 0x80 } }
|
||||
|
||||
// {6DEB193C-F87D-4078-BC78-5E64655B4D62}
|
||||
#define NS_BROWSERDIRECTORYPROVIDER_CID \
|
||||
{ 0x6deb193c, 0xf87d, 0x4078, { 0xbc, 0x78, 0x5e, 0x64, 0x65, 0x5b, 0x4d, 0x62 } }
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include "nsBrowserCompsCID.h"
|
||||
#include "DirectoryProvider.h"
|
||||
#include "nsPlacesImportExportService.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
@ -84,6 +85,7 @@ using namespace mozilla::browser;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(DirectoryProvider)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPlacesImportExportService)
|
||||
#if defined(XP_WIN)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
|
||||
@ -124,6 +126,14 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrivateBrowsingServiceWrapper, Init)
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "Browser Directory Provider",
|
||||
NS_BROWSERDIRECTORYPROVIDER_CID,
|
||||
NS_BROWSERDIRECTORYPROVIDER_CONTRACTID,
|
||||
DirectoryProviderConstructor,
|
||||
DirectoryProvider::Register,
|
||||
DirectoryProvider::Unregister
|
||||
},
|
||||
|
||||
#if defined(XP_WIN)
|
||||
{ "Browser Shell Service",
|
||||
NS_SHELLSERVICE_CID,
|
||||
|
@ -36,6 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "DirectoryProvider.h"
|
||||
|
||||
#include "nsIFile.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
@ -56,52 +57,15 @@
|
||||
#include "nsStringAPI.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
class nsBrowserDirectoryProvider :
|
||||
public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
namespace mozilla {
|
||||
namespace browser {
|
||||
|
||||
static NS_METHOD Register(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const char *aType,
|
||||
const nsModuleComponentInfo *aInfo);
|
||||
|
||||
static NS_METHOD Unregister(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const nsModuleComponentInfo *aInfo);
|
||||
|
||||
private:
|
||||
nsresult RestoreBookmarksFromBackup(const nsACString& aLeafName,
|
||||
nsIFile* aParentDir, nsIFile* aTarget);
|
||||
void EnsureProfileFile(const nsACString& aLeafName,
|
||||
nsIFile* aParentDir, nsIFile* aTarget);
|
||||
|
||||
class AppendingEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
AppendingEnumerator(nsISimpleEnumerator* aBase,
|
||||
char const *const *aAppendList);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISimpleEnumerator> mBase;
|
||||
char const *const *const mAppendList;
|
||||
nsCOMPtr<nsIFile> mNext;
|
||||
};
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsBrowserDirectoryProvider,
|
||||
NS_IMPL_ISUPPORTS2(DirectoryProvider,
|
||||
nsIDirectoryServiceProvider,
|
||||
nsIDirectoryServiceProvider2)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserDirectoryProvider::GetFile(const char *aKey, PRBool *aPersist,
|
||||
nsIFile* *aResult)
|
||||
DirectoryProvider::GetFile(const char *aKey, PRBool *aPersist, nsIFile* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -290,8 +254,7 @@ AppendDistroSearchDirs(nsIProperties* aDirSvc, nsCOMArray<nsIFile> &array)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserDirectoryProvider::GetFiles(const char *aKey,
|
||||
nsISimpleEnumerator* *aResult)
|
||||
DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -331,17 +294,10 @@ nsBrowserDirectoryProvider::GetFiles(const char *aKey,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static char const kContractID[] = "@mozilla.org/browser/directory-provider;1";
|
||||
|
||||
// {6DEB193C-F87D-4078-BC78-5E64655B4D62}
|
||||
#define NS_BROWSERDIRECTORYPROVIDER_CID \
|
||||
{ 0x6deb193c, 0xf87d, 0x4078, { 0xbc, 0x78, 0x5e, 0x64, 0x65, 0x5b, 0x4d, 0x62 } }
|
||||
|
||||
NS_METHOD
|
||||
nsBrowserDirectoryProvider::Register(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const char *aType,
|
||||
const nsModuleComponentInfo *aInfo)
|
||||
DirectoryProvider::Register(nsIComponentManager* aCompMgr, nsIFile* aPath,
|
||||
const char *aLoaderStr, const char *aType,
|
||||
const nsModuleComponentInfo *aInfo)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -352,15 +308,16 @@ nsBrowserDirectoryProvider::Register(nsIComponentManager* aCompMgr,
|
||||
|
||||
rv = catMan->AddCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
|
||||
"browser-directory-provider",
|
||||
kContractID, PR_TRUE, PR_TRUE, nsnull);
|
||||
NS_BROWSERDIRECTORYPROVIDER_CONTRACTID,
|
||||
PR_TRUE, PR_TRUE, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD
|
||||
nsBrowserDirectoryProvider::Unregister(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const nsModuleComponentInfo *aInfo)
|
||||
DirectoryProvider::Unregister(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const nsModuleComponentInfo *aInfo)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -374,32 +331,17 @@ nsBrowserDirectoryProvider::Unregister(nsIComponentManager* aCompMgr,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBrowserDirectoryProvider)
|
||||
|
||||
static const nsModuleComponentInfo components[] = {
|
||||
{
|
||||
"nsBrowserDirectoryProvider",
|
||||
NS_BROWSERDIRECTORYPROVIDER_CID,
|
||||
kContractID,
|
||||
nsBrowserDirectoryProviderConstructor,
|
||||
nsBrowserDirectoryProvider::Register,
|
||||
nsBrowserDirectoryProvider::Unregister
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(BrowserDirProvider, components)
|
||||
NS_IMPL_ISUPPORTS1(nsBrowserDirectoryProvider::AppendingEnumerator,
|
||||
nsISimpleEnumerator)
|
||||
NS_IMPL_ISUPPORTS1(DirectoryProvider::AppendingEnumerator, nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserDirectoryProvider::AppendingEnumerator::HasMoreElements(PRBool *aResult)
|
||||
DirectoryProvider::AppendingEnumerator::HasMoreElements(PRBool *aResult)
|
||||
{
|
||||
*aResult = mNext ? PR_TRUE : PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserDirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
|
||||
DirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
|
||||
{
|
||||
if (aResult)
|
||||
NS_ADDREF(*aResult = mNext);
|
||||
@ -440,7 +382,7 @@ nsBrowserDirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBrowserDirectoryProvider::AppendingEnumerator::AppendingEnumerator
|
||||
DirectoryProvider::AppendingEnumerator::AppendingEnumerator
|
||||
(nsISimpleEnumerator* aBase,
|
||||
char const *const *aAppendList) :
|
||||
mBase(aBase),
|
||||
@ -449,3 +391,6 @@ nsBrowserDirectoryProvider::AppendingEnumerator::AppendingEnumerator
|
||||
// Initialize mNext to begin.
|
||||
GetNext(nsnull);
|
||||
}
|
||||
|
||||
} // namespace browser
|
||||
} // namespace mozilla
|
89
browser/components/dirprovider/DirectoryProvider.h
Normal file
89
browser/components/dirprovider/DirectoryProvider.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* ***** 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 the Mozilla Firefox browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef DirectoryProvider_h__
|
||||
#define DirectoryProvider_h__
|
||||
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#define NS_BROWSERDIRECTORYPROVIDER_CONTRACTID \
|
||||
"@mozilla.org/browser/directory-provider;1"
|
||||
|
||||
namespace mozilla {
|
||||
namespace browser {
|
||||
|
||||
class DirectoryProvider : public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
|
||||
static NS_METHOD Register(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const char *aType,
|
||||
const nsModuleComponentInfo *aInfo);
|
||||
|
||||
static NS_METHOD Unregister(nsIComponentManager* aCompMgr,
|
||||
nsIFile* aPath, const char *aLoaderStr,
|
||||
const nsModuleComponentInfo *aInfo);
|
||||
|
||||
private:
|
||||
class AppendingEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
AppendingEnumerator(nsISimpleEnumerator* aBase,
|
||||
char const *const *aAppendList);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISimpleEnumerator> mBase;
|
||||
char const *const *const mAppendList;
|
||||
nsCOMPtr<nsIFile> mNext;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace browser
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // DirectoryProvider_h__
|
@ -42,12 +42,13 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = browsercomps
|
||||
LIBRARY_NAME = browserdirprovider
|
||||
SHORT_LIBNAME = brwsrdir
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = BrowserDirProvider
|
||||
FORCE_SHARED_LIB = 1
|
||||
MODULE = browserdir
|
||||
LIBRARY_NAME = browserdir_s
|
||||
|
||||
DIRS = tests
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
FORCE_USE_PIC = 1
|
||||
|
||||
# Because we are an application component, link against the CRT statically
|
||||
# (on Windows, but only if we're not building our own CRT for jemalloc)
|
||||
@ -55,7 +56,12 @@ ifndef MOZ_MEMORY
|
||||
USE_STATIC_LIBS = 1
|
||||
endif
|
||||
|
||||
CPPSRCS = nsBrowserDirectoryProvider.cpp
|
||||
EXPORTS_NAMESPACES = mozilla/browser
|
||||
EXPORTS_mozilla/browser = DirectoryProvider.h
|
||||
|
||||
CPPSRCS = DirectoryProvider.cpp
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/../build
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(XPCOM_GLUE_LDOPTS) \
|
||||
|
49
browser/components/dirprovider/tests/Makefile.in
Normal file
49
browser/components/dirprovider/tests/Makefile.in
Normal file
@ -0,0 +1,49 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ryan Flint <rflint@mozilla.com> (Original Author)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = browser/components/dirprovider/tests
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = test_browserdir
|
||||
|
||||
XPCSHELL_TESTS = unit
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
@ -0,0 +1,52 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ryan Flint <rflint@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 ***** */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var gProfD = do_get_profile();
|
||||
var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
|
||||
getService(Ci.nsIProperties);
|
||||
var gPrefSvc = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
function writeTestFile(aParent, aName) {
|
||||
let file = aParent.clone();
|
||||
file.append(aName);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
|
||||
return file;
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ryan Flint <rflint@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 ***** */
|
||||
|
||||
// We need to run this test separately since DirectoryProvider persists BMarks
|
||||
|
||||
function run_test() {
|
||||
let dir = gProfD.clone();
|
||||
let tfile = writeTestFile(dir, "bookmarkfile.test");
|
||||
gPrefSvc.setCharPref("browser.bookmarks.file", tfile.path);
|
||||
|
||||
let bmarks = gDirSvc.get("BMarks", Ci.nsIFile);
|
||||
do_check_true(tfile.equals(bmarks));
|
||||
}
|
91
browser/components/dirprovider/tests/unit/test_keys.js
Normal file
91
browser/components/dirprovider/tests/unit/test_keys.js
Normal file
@ -0,0 +1,91 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ryan Flint <rflint@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 ***** */
|
||||
|
||||
function test_usr_micsum() {
|
||||
let mdir = gProfD.clone();
|
||||
mdir.append("microsummary-generators");
|
||||
|
||||
let tmdir = gDirSvc.get("UsrMicsumGens", Ci.nsIFile);
|
||||
do_check_true(tmdir.equals(mdir));
|
||||
|
||||
if (!tmdir.exists())
|
||||
tmdir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
|
||||
|
||||
do_check_true(tmdir.isWritable());
|
||||
|
||||
let tfile = writeTestFile(tmdir, "usrmicsum");
|
||||
do_check_true(tfile.exists());
|
||||
|
||||
mdir.append(tfile.leafName);
|
||||
do_check_true(mdir.exists());
|
||||
}
|
||||
|
||||
function test_app_micsum() {
|
||||
let mdir = gDirSvc.get("XCurProcD", Ci.nsIFile);
|
||||
mdir.append("microsummary-generators");
|
||||
|
||||
let tmdir = gDirSvc.get("MicsumGens", Ci.nsIFile);
|
||||
do_check_true(tmdir.equals(mdir));
|
||||
}
|
||||
|
||||
function test_bookmarkhtml() {
|
||||
let bmarks = gProfD.clone();
|
||||
bmarks.append("bookmarks.html");
|
||||
|
||||
let tbmarks = gDirSvc.get("BMarks", Ci.nsIFile);
|
||||
do_check_true(bmarks.equals(tbmarks));
|
||||
}
|
||||
|
||||
function test_prefoverride() {
|
||||
let dir = gDirSvc.get("DefRt", Ci.nsIFile);
|
||||
dir.append("existing-profile-defaults.js");
|
||||
|
||||
let tdir = gDirSvc.get("ExistingPrefOverride", Ci.nsIFile);
|
||||
do_check_true(dir.equals(tdir));
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
[test_usr_micsum,
|
||||
test_app_micsum,
|
||||
test_bookmarkhtml,
|
||||
test_prefoverride
|
||||
].forEach(function(f) {
|
||||
do_test_pending();
|
||||
print("Running test: " + f.name);
|
||||
f();
|
||||
do_test_finished();
|
||||
});
|
||||
}
|
@ -134,7 +134,8 @@ interface nsIWebContentConverterService : nsIWebContentHandlerRegistrar
|
||||
* The content type to get handlers for
|
||||
* @returns An array of nsIWebContentHandlerInfo objects
|
||||
*/
|
||||
void getContentHandlers(in AString contentType, out unsigned long count,
|
||||
void getContentHandlers(in AString contentType,
|
||||
[optional] out unsigned long count,
|
||||
[retval,array,size_is(count)] out nsIWebContentHandlerInfo handlers);
|
||||
|
||||
/**
|
||||
|
@ -1041,7 +1041,7 @@ FeedWriter.prototype = {
|
||||
// List of web handlers
|
||||
var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||
getService(Ci.nsIWebContentConverterService);
|
||||
var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType), {});
|
||||
var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType));
|
||||
if (handlers.length != 0) {
|
||||
for (var i = 0; i < handlers.length; ++i) {
|
||||
menuItem = this._document.createElementNS(XUL_NS, "menuitem");
|
||||
|
@ -335,23 +335,24 @@ PlacesTreeView.prototype = {
|
||||
},
|
||||
|
||||
_convertPRTimeToString: function PTV__convertPRTimeToString(aTime) {
|
||||
var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds
|
||||
const MS_PER_MINUTE = 60000;
|
||||
const MS_PER_DAY = 86400000;
|
||||
let timeMs = aTime / 1000; // PRTime is in microseconds
|
||||
|
||||
// Date is calculated starting from midnight, so the modulo with a day are
|
||||
// milliseconds from today's midnight.
|
||||
// getTimezoneOffset corrects that based on local time.
|
||||
// 86400000 = 24 * 60 * 60 * 1000 = 1 day
|
||||
// 60000 = 60 * 1000 = 1 minute
|
||||
var dateObj = new Date();
|
||||
var timeZoneOffsetInMs = dateObj.getTimezoneOffset() * 60000;
|
||||
var now = dateObj.getTime() - timeZoneOffsetInMs;
|
||||
var midnight = now - (now % (86400000));
|
||||
// getTimezoneOffset corrects that based on local time, notice midnight
|
||||
// can have a different offset during DST-change days.
|
||||
let dateObj = new Date();
|
||||
let now = dateObj.getTime() - dateObj.getTimezoneOffset() * MS_PER_MINUTE;
|
||||
let midnight = now - (now % MS_PER_DAY);
|
||||
midnight += new Date(midnight).getTimezoneOffset() * MS_PER_MINUTE;
|
||||
|
||||
var dateFormat = timeInMilliseconds - timeZoneOffsetInMs >= midnight ?
|
||||
let dateFormat = timeMs >= midnight ?
|
||||
Ci.nsIScriptableDateFormat.dateFormatNone :
|
||||
Ci.nsIScriptableDateFormat.dateFormatShort;
|
||||
|
||||
var timeObj = new Date(timeInMilliseconds);
|
||||
let timeObj = new Date(timeMs);
|
||||
return (this._dateService.FormatDateTime("", dateFormat,
|
||||
Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
|
||||
timeObj.getFullYear(), timeObj.getMonth() + 1,
|
||||
|
@ -1138,64 +1138,146 @@ var PlacesUIUtils = {
|
||||
|
||||
// Get the folder id for the organizer left-pane folder.
|
||||
get leftPaneFolderId() {
|
||||
var leftPaneRoot = -1;
|
||||
var allBookmarksId;
|
||||
let leftPaneRoot = -1;
|
||||
let allBookmarksId;
|
||||
|
||||
// Shortcuts to services.
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
var as = PlacesUtils.annotations;
|
||||
let bs = PlacesUtils.bookmarks;
|
||||
let as = PlacesUtils.annotations;
|
||||
|
||||
// Get all items marked as being the left pane folder. We should only have
|
||||
// one of them.
|
||||
var items = as.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO);
|
||||
// This is the list of the left pane queries.
|
||||
let queries = {
|
||||
"PlacesRoot": { title: "" },
|
||||
"History": { title: this.getString("OrganizerQueryHistory") },
|
||||
"Tags": { title: this.getString("OrganizerQueryTags") },
|
||||
"AllBookmarks": { title: this.getString("OrganizerQueryAllBookmarks") },
|
||||
"BookmarksToolbar":
|
||||
{ title: null,
|
||||
concreteTitle: PlacesUtils.getString("BookmarksToolbarFolderTitle"),
|
||||
concreteId: PlacesUtils.toolbarFolderId },
|
||||
"BookmarksMenu":
|
||||
{ title: null,
|
||||
concreteTitle: PlacesUtils.getString("BookmarksMenuFolderTitle"),
|
||||
concreteId: PlacesUtils.bookmarksMenuFolderId },
|
||||
"UnfiledBookmarks":
|
||||
{ title: null,
|
||||
concreteTitle: PlacesUtils.getString("UnsortedBookmarksFolderTitle"),
|
||||
concreteId: PlacesUtils.unfiledBookmarksFolderId },
|
||||
};
|
||||
// All queries but PlacesRoot.
|
||||
const EXPECTED_QUERY_COUNT = 6;
|
||||
|
||||
// Removes an item and associated annotations, ignoring eventual errors.
|
||||
function safeRemoveItem(aItemId) {
|
||||
try {
|
||||
if (as.itemHasAnnotation(aItemId, ORGANIZER_QUERY_ANNO) &&
|
||||
!(as.getItemAnnotation(aItemId, ORGANIZER_QUERY_ANNO) in queries)) {
|
||||
// Some extension annotated their roots with our query annotation,
|
||||
// so we should not delete them.
|
||||
return;
|
||||
}
|
||||
// removeItemAnnotation does not check if item exists, nor the anno,
|
||||
// so this is safe to do.
|
||||
as.removeItemAnnotation(aItemId, ORGANIZER_FOLDER_ANNO);
|
||||
as.removeItemAnnotation(aItemId, ORGANIZER_QUERY_ANNO);
|
||||
// This will throw if the annotation is an orphan.
|
||||
bs.removeItem(aItemId);
|
||||
}
|
||||
catch(e) { /* orphan anno */ }
|
||||
}
|
||||
|
||||
// Returns true if item really exists, false otherwise.
|
||||
function itemExists(aItemId) {
|
||||
try {
|
||||
bs.getItemIndex(aItemId);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all items marked as being the left pane folder.
|
||||
let items = as.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {});
|
||||
if (items.length > 1) {
|
||||
// Something went wrong, we cannot have more than one left pane folder,
|
||||
// remove all left pane folders and continue. We will create a new one.
|
||||
items.forEach(bs.removeItem);
|
||||
items.forEach(safeRemoveItem);
|
||||
}
|
||||
else if (items.length == 1 && items[0] != -1) {
|
||||
leftPaneRoot = items[0];
|
||||
// Check organizer left pane version.
|
||||
var version = as.getItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO);
|
||||
if (version != ORGANIZER_LEFTPANE_VERSION) {
|
||||
// If version is not valid we must rebuild the left pane.
|
||||
bs.removeItem(leftPaneRoot);
|
||||
|
||||
// Check that organizer left pane root is valid.
|
||||
let version = as.getItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO);
|
||||
if (version != ORGANIZER_LEFTPANE_VERSION || !itemExists(leftPaneRoot)) {
|
||||
// Invalid root, we must rebuild the left pane.
|
||||
safeRemoveItem(leftPaneRoot);
|
||||
leftPaneRoot = -1;
|
||||
}
|
||||
}
|
||||
|
||||
var queriesTitles = {
|
||||
"PlacesRoot": "",
|
||||
"History": this.getString("OrganizerQueryHistory"),
|
||||
// TODO: Bug 489681, Tags needs its own string in places.properties
|
||||
"Tags": bs.getItemTitle(PlacesUtils.tagsFolderId),
|
||||
"AllBookmarks": this.getString("OrganizerQueryAllBookmarks"),
|
||||
"Downloads": this.getString("OrganizerQueryDownloads"),
|
||||
"BookmarksToolbar": null,
|
||||
"BookmarksMenu": null,
|
||||
"UnfiledBookmarks": null
|
||||
};
|
||||
|
||||
if (leftPaneRoot != -1) {
|
||||
// A valid left pane folder has been found.
|
||||
// Build the leftPaneQueries Map. This is used to quickly access them
|
||||
// Build the leftPaneQueries Map. This is used to quickly access them,
|
||||
// associating a mnemonic name to the real item ids.
|
||||
delete this.leftPaneQueries;
|
||||
this.leftPaneQueries = {};
|
||||
var items = as.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO);
|
||||
// While looping through queries we will also check for titles validity.
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var queryName = as.getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
|
||||
this.leftPaneQueries[queryName] = items[i];
|
||||
|
||||
let items = as.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, {});
|
||||
// While looping through queries we will also check for their validity.
|
||||
let queriesCount = 0;
|
||||
for(let i = 0; i < items.length; i++) {
|
||||
let queryName = as.getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
|
||||
// Some extension did use our annotation to decorate their items
|
||||
// with icons, so we should check only our elements, to avoid dataloss.
|
||||
if (!(queryName in queries))
|
||||
continue;
|
||||
|
||||
let query = queries[queryName];
|
||||
query.itemId = items[i];
|
||||
|
||||
if (!itemExists(query.itemId)) {
|
||||
// Orphan annotation, bail out and create a new left pane root.
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that all queries have valid parents.
|
||||
let parentId = bs.getFolderIdForItem(query.itemId);
|
||||
if (items.indexOf(parentId) == -1 && parentId != leftPaneRoot) {
|
||||
// The parent is not part of the left pane, bail out and create a new
|
||||
// left pane root.
|
||||
break;
|
||||
}
|
||||
|
||||
// Titles could have been corrupted or the user could have changed his
|
||||
// locale. Check title is correctly set and eventually fix it.
|
||||
if (bs.getItemTitle(items[i]) != queriesTitles[queryName])
|
||||
bs.setItemTitle(items[i], queriesTitles[queryName]);
|
||||
// locale. Check title and eventually fix it.
|
||||
if (bs.getItemTitle(query.itemId) != query.title)
|
||||
bs.setItemTitle(query.itemId, query.title);
|
||||
if ("concreteId" in query) {
|
||||
if (bs.getItemTitle(query.concreteId) != query.concreteTitle)
|
||||
bs.setItemTitle(query.concreteId, query.concreteTitle);
|
||||
}
|
||||
|
||||
// Add the query to our cache.
|
||||
this.leftPaneQueries[queryName] = query.itemId;
|
||||
queriesCount++;
|
||||
}
|
||||
|
||||
if (queriesCount != EXPECTED_QUERY_COUNT) {
|
||||
// Queries number is wrong, so the left pane must be corrupt.
|
||||
// Note: we can't just remove the leftPaneRoot, because some query could
|
||||
// have a bad parent, so we have to remove all items one by one.
|
||||
items.forEach(safeRemoveItem);
|
||||
safeRemoveItem(leftPaneRoot);
|
||||
}
|
||||
else {
|
||||
// Everything is fine, return the current left pane folder.
|
||||
delete this.leftPaneFolderId;
|
||||
return this.leftPaneFolderId = leftPaneRoot;
|
||||
}
|
||||
delete this.leftPaneFolderId;
|
||||
return this.leftPaneFolderId = leftPaneRoot;
|
||||
}
|
||||
|
||||
// Create a new left pane folder.
|
||||
var self = this;
|
||||
var callback = {
|
||||
// Helper to create an organizer special query.
|
||||
@ -1203,7 +1285,7 @@ var PlacesUIUtils = {
|
||||
let itemId = bs.insertBookmark(aParentId,
|
||||
PlacesUtils._uri(aQueryUrl),
|
||||
bs.DEFAULT_INDEX,
|
||||
queriesTitles[aQueryName]);
|
||||
queries[aQueryName].title);
|
||||
// Mark as special organizer query.
|
||||
as.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, aQueryName,
|
||||
0, as.EXPIRE_NEVER);
|
||||
@ -1219,7 +1301,7 @@ var PlacesUIUtils = {
|
||||
create_folder: function CB_create_folder(aFolderName, aParentId, aIsRoot) {
|
||||
// Left Pane Root Folder.
|
||||
let folderId = bs.createFolder(aParentId,
|
||||
queriesTitles[aFolderName],
|
||||
queries[aFolderName].title,
|
||||
bs.DEFAULT_INDEX);
|
||||
// We should never backup this, since it changes between profiles.
|
||||
as.setItemAnnotation(folderId, EXCLUDE_FROM_BACKUP_ANNO, 1,
|
||||
|
@ -62,6 +62,10 @@ var windowObserver = {
|
||||
var query = leftPaneQueries[i];
|
||||
is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
|
||||
query.correctTitle, "Title is correct for query " + query.name);
|
||||
if ("concreteId" in query) {
|
||||
is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
|
||||
query.concreteTitle, "Concrete title is correct for query " + query.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Close Library window.
|
||||
@ -105,12 +109,28 @@ function test() {
|
||||
var queryName = PlacesUtils.annotations
|
||||
.getItemAnnotation(items[i],
|
||||
ORGANIZER_QUERY_ANNO);
|
||||
leftPaneQueries.push({ name: queryName,
|
||||
itemId: itemId,
|
||||
correctTitle: PlacesUtils.bookmarks
|
||||
.getItemTitle(itemId) });
|
||||
var query = { name: queryName,
|
||||
itemId: itemId,
|
||||
correctTitle: PlacesUtils.bookmarks.getItemTitle(itemId) }
|
||||
switch (queryName) {
|
||||
case "BookmarksToolbar":
|
||||
query.concreteId = PlacesUtils.toolbarFolderId;
|
||||
query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
|
||||
break;
|
||||
case "BookmarksMenu":
|
||||
query.concreteId = PlacesUtils.bookmarksMenuFolderId;
|
||||
query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
|
||||
break;
|
||||
case "UnfiledBookmarks":
|
||||
query.concreteId = PlacesUtils.unfiledBookmarksFolderId;
|
||||
query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
|
||||
break;
|
||||
}
|
||||
leftPaneQueries.push(query);
|
||||
// Rename to a bad title.
|
||||
PlacesUtils.bookmarks.setItemTitle(itemId, "badName");
|
||||
PlacesUtils.bookmarks.setItemTitle(query.itemId, "badName");
|
||||
if ("concreteId" in query)
|
||||
PlacesUtils.bookmarks.setItemTitle(query.concreteId, "badName");
|
||||
}
|
||||
|
||||
// Open Library, this will kick-off left pane code.
|
||||
|
@ -156,7 +156,11 @@
|
||||
var text = treeView.getCellText(r, c);
|
||||
switch (c.element.getAttribute("anonid")) {
|
||||
case "title":
|
||||
is(text, node.title, "Title is correct");
|
||||
// The title can differ, we did not set any title so we would
|
||||
// expect null, but in such a case the view will generate a title
|
||||
// through PlacesUIUtils.getBestTitle.
|
||||
if (node.title)
|
||||
is(text, node.title, "Title is correct");
|
||||
break;
|
||||
case "url":
|
||||
is(text, node.uri, "Uri is correct");
|
||||
|
@ -0,0 +1,224 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** 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 Places Unit Test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Tests that we build a working leftpane in various corruption situations.
|
||||
*/
|
||||
|
||||
// Used to store the original leftPaneFolderId getter.
|
||||
let gLeftPaneFolderIdGetter;
|
||||
let gAllBookmarksFolderIdGetter;
|
||||
// Used to store the original left Pane status as a JSON string.
|
||||
let gReferenceJSON;
|
||||
let gLeftPaneFolderId;
|
||||
// Third party annotated folder.
|
||||
let gFolderId;
|
||||
|
||||
// Corruption cases.
|
||||
let gTests = [
|
||||
|
||||
function test1() {
|
||||
print("1. Do nothing, checks test calibration.");
|
||||
},
|
||||
|
||||
function test2() {
|
||||
print("2. Delete the left pane folder.");
|
||||
PlacesUtils.bookmarks.removeItem(gLeftPaneFolderId);
|
||||
},
|
||||
|
||||
function test3() {
|
||||
print("3. Delete a child of the left pane folder.");
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(gLeftPaneFolderId, 0);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
},
|
||||
|
||||
function test4() {
|
||||
print("4. Delete AllBookmarks.");
|
||||
PlacesUtils.bookmarks.removeItem(PlacesUIUtils.allBookmarksFolderId);
|
||||
},
|
||||
|
||||
function test5() {
|
||||
print("5. Create a duplicated left pane folder.");
|
||||
let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
"PlacesRoot",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, ORGANIZER_FOLDER_ANNO,
|
||||
"PlacesRoot", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
},
|
||||
|
||||
function test6() {
|
||||
print("6. Create a duplicated left pane query.");
|
||||
let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
"AllBookmarks",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, ORGANIZER_QUERY_ANNO,
|
||||
"AllBookmarks", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
},
|
||||
|
||||
function test7() {
|
||||
print("7. Remove the left pane folder annotation.");
|
||||
PlacesUtils.annotations.removeItemAnnotation(gLeftPaneFolderId,
|
||||
ORGANIZER_FOLDER_ANNO);
|
||||
},
|
||||
|
||||
function test8() {
|
||||
print("8. Remove a left pane query annotation.");
|
||||
PlacesUtils.annotations.removeItemAnnotation(PlacesUIUtils.allBookmarksFolderId,
|
||||
ORGANIZER_QUERY_ANNO);
|
||||
},
|
||||
|
||||
function test9() {
|
||||
print("9. Remove a child of AllBookmarks.");
|
||||
let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUIUtils.allBookmarksFolderId, 0);
|
||||
PlacesUtils.bookmarks.removeItem(id);
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
function run_test() {
|
||||
// We want empty roots.
|
||||
remove_all_bookmarks();
|
||||
|
||||
// Import PlacesUIUtils.
|
||||
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader);
|
||||
scriptLoader.loadSubScript("chrome://browser/content/places/utils.js", this);
|
||||
do_check_true(!!PlacesUIUtils);
|
||||
|
||||
// Check getters.
|
||||
gLeftPaneFolderIdGetter = PlacesUIUtils.__lookupGetter__("leftPaneFolderId");
|
||||
do_check_eq(typeof(gLeftPaneFolderIdGetter), "function");
|
||||
gAllBookmarksFolderIdGetter = PlacesUIUtils.__lookupGetter__("allBookmarksFolderId");
|
||||
do_check_eq(typeof(gAllBookmarksFolderIdGetter), "function");
|
||||
|
||||
// Add a third party bogus annotated item. Should not be removed.
|
||||
gFolderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
"test",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.annotations.setItemAnnotation(gFolderId, ORGANIZER_QUERY_ANNO,
|
||||
"test", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
|
||||
// Create the left pane, and store its current status, it will be used
|
||||
// as reference value.
|
||||
gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
|
||||
gReferenceJSON = folderToJSON(gLeftPaneFolderId);
|
||||
|
||||
// Kick-off tests.
|
||||
do_test_pending();
|
||||
do_timeout(0, "run_next_test();");
|
||||
}
|
||||
|
||||
function run_next_test() {
|
||||
if (gTests.length) {
|
||||
// Create corruption.
|
||||
let test = gTests.shift();
|
||||
test();
|
||||
// Regenerate getters.
|
||||
PlacesUIUtils.__defineGetter__("leftPaneFolderId", gLeftPaneFolderIdGetter);
|
||||
gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
|
||||
PlacesUIUtils.__defineGetter__("allBookmarksFolderId", gAllBookmarksFolderIdGetter);
|
||||
// Check the new left pane folder.
|
||||
let leftPaneJSON = folderToJSON(gLeftPaneFolderId);
|
||||
do_check_true(compareJSON(gReferenceJSON, leftPaneJSON));
|
||||
do_check_eq(PlacesUtils.bookmarks.getItemTitle(gFolderId), "test");
|
||||
// Go to next test.
|
||||
do_timeout(0, "run_next_test();");
|
||||
}
|
||||
else {
|
||||
// All tests finished.
|
||||
remove_all_bookmarks();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a folder item id to a JSON representation of it and its contents.
|
||||
*/
|
||||
function folderToJSON(aItemId) {
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.setFolders([aItemId], 1);
|
||||
let options = PlacesUtils.history.getNewQueryOptions();
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
|
||||
let root = PlacesUtils.history.executeQuery(query, options).root;
|
||||
let writer = {
|
||||
value: "",
|
||||
write: function PU_wrapNode__write(aStr, aLen) {
|
||||
this.value += aStr;
|
||||
}
|
||||
};
|
||||
PlacesUtils.serializeNodeAsJSONToOutputStream(root, writer, false, false);
|
||||
do_check_true(writer.value.length > 0);
|
||||
return writer.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the JSON representation of 2 nodes, skipping everchanging properties
|
||||
* like dates.
|
||||
*/
|
||||
function compareJSON(aNodeJSON_1, aNodeJSON_2) {
|
||||
let JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
|
||||
node1 = JSON.decode(aNodeJSON_1);
|
||||
node2 = JSON.decode(aNodeJSON_2);
|
||||
|
||||
// List of properties we should not compare (expected to be different).
|
||||
const SKIP_PROPS = ["dateAdded", "lastModified", "id"];
|
||||
|
||||
function compareObjects(obj1, obj2) {
|
||||
do_check_eq(obj1.__count__, obj2.__count__);
|
||||
for (let prop in obj1) {
|
||||
// Skip everchanging values.
|
||||
if (SKIP_PROPS.indexOf(prop) != -1)
|
||||
continue;
|
||||
// Skip undefined objects, otherwise we hang on them.
|
||||
if (!obj1[prop])
|
||||
continue;
|
||||
if (typeof(obj1[prop]) == "object")
|
||||
return compareObjects(obj1[prop], obj2[prop]);
|
||||
if (obj1[prop] !== obj2[prop]) {
|
||||
print(prop + ": " + obj1[prop] + "!=" + obj2[prop]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return compareObjects(node1, node2);
|
||||
}
|
@ -661,7 +661,7 @@ FeedHandlerInfo.prototype = {
|
||||
}
|
||||
|
||||
// Add the registered web handlers. There can be any number of these.
|
||||
var webHandlers = this._converterSvc.getContentHandlers(this.type, {});
|
||||
var webHandlers = this._converterSvc.getContentHandlers(this.type);
|
||||
for each (let webHandler in webHandlers)
|
||||
this._possibleApplicationHandlers.appendElement(webHandler, false);
|
||||
|
||||
|
@ -365,6 +365,10 @@ PrivateBrowsingService.prototype = {
|
||||
getService(Ci.nsIHttpAuthManager);
|
||||
authMgr.clearAll();
|
||||
|
||||
try {
|
||||
this._prefs.deleteBranch("geo.wifi.access_token.");
|
||||
} catch (ex) {}
|
||||
|
||||
if (!this._inPrivateBrowsing) {
|
||||
// Clear the error console
|
||||
let consoleService = Cc["@mozilla.org/consoleservice;1"].
|
||||
@ -557,7 +561,7 @@ PrivateBrowsingService.prototype = {
|
||||
getService(Ci.nsILoginManager)) {
|
||||
// Clear all passwords for domain
|
||||
try {
|
||||
let logins = lm.getAllLogins({});
|
||||
let logins = lm.getAllLogins();
|
||||
for (let i = 0; i < logins.length; i++)
|
||||
if (logins[i].hostname.hasRootDomain(aDomain))
|
||||
lm.removeLogin(logins[i]);
|
||||
@ -567,7 +571,7 @@ PrivateBrowsingService.prototype = {
|
||||
catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
|
||||
|
||||
// Clear any "do not save for this site" for this domain
|
||||
let disabledHosts = lm.getAllDisabledHosts({});
|
||||
let disabledHosts = lm.getAllDisabledHosts();
|
||||
for (let i = 0; i < disabledHosts.length; i++)
|
||||
if (disabledHosts[i].hasRootDomain(aDomain))
|
||||
lm.setLoginSavingEnabled(disabledHosts, true);
|
||||
|
@ -37,19 +37,23 @@
|
||||
|
||||
// This provides the tests with a download URL which never finishes.
|
||||
|
||||
var timer;
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.processAsync();
|
||||
|
||||
const nsITimer = Components.interfaces.nsITimer;
|
||||
|
||||
function stall() {
|
||||
timer = null;
|
||||
// This write will throw if the connection has been closed by the browser.
|
||||
response.write("stalling...\n");
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(nsITimer);
|
||||
timer.initWithCallback(stall, 500, nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
stall();
|
||||
|
||||
const nsITimer = Components.interfaces.nsITimer;
|
||||
var timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(nsITimer);
|
||||
timer.initWithCallback(stall, 500, nsITimer.TYPE_REPEATING_SLACK);
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
/* ***** 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 Private Browsing Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Nochum Sossonko.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Nochum Sossonko <nsossonko@hotmail.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Test to ensure the geolocation token is cleared when changing the private
|
||||
// browsing mode
|
||||
|
||||
const accessToken = '{"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"}'
|
||||
function run_test_on_service() {
|
||||
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch2);
|
||||
var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
prefBranch.setCharPref("geo.wifi.access_token.test", accessToken);
|
||||
var token = prefBranch.getCharPref("geo.wifi.access_token.test");
|
||||
do_check_eq(token, accessToken);
|
||||
pb.privateBrowsingEnabled = true;
|
||||
token = "";
|
||||
try {
|
||||
token = prefBranch.getCharPref("geo.wifi.access_token.test");
|
||||
}
|
||||
catch(e){}
|
||||
finally {
|
||||
do_check_eq(token, "");
|
||||
}
|
||||
token = "";
|
||||
prefBranch.setCharPref("geo.wifi.access_token.test", accessToken);
|
||||
pb.privateBrowsingEnabled = false;
|
||||
try {
|
||||
token = prefBranch.getCharPref("geo.wifi.access_token.test");
|
||||
}
|
||||
catch(e){}
|
||||
finally {
|
||||
do_check_eq(token, "");
|
||||
}
|
||||
}
|
||||
|
||||
// Support running tests on both the service itself and its wrapper
|
||||
function run_test() {
|
||||
run_test_on_all_services();
|
||||
}
|
@ -41,7 +41,7 @@ function run_test_on_service()
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/openLocationLastURL.jsm");
|
||||
Cu.import("resource:///modules/openLocationLastURL.jsm");
|
||||
|
||||
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
@ -300,13 +300,13 @@ EngineChangeOp.prototype = {
|
||||
function EngineStore() {
|
||||
var searchService = Cc["@mozilla.org/browser/search-service;1"].
|
||||
getService(Ci.nsIBrowserSearchService);
|
||||
this._engines = searchService.getVisibleEngines({}).map(this._cloneEngine);
|
||||
this._defaultEngines = searchService.getDefaultEngines({}).map(this._cloneEngine);
|
||||
this._engines = searchService.getVisibleEngines().map(this._cloneEngine);
|
||||
this._defaultEngines = searchService.getDefaultEngines().map(this._cloneEngine);
|
||||
|
||||
this._ops = [];
|
||||
|
||||
// check if we need to disable the restore defaults button
|
||||
var someHidden = this._defaultEngines.some(function (e) {return e.hidden;});
|
||||
var someHidden = this._defaultEngines.some(function (e) e.hidden);
|
||||
gEngineManagerDialog.showRestoreDefaults(someHidden);
|
||||
}
|
||||
EngineStore.prototype = {
|
||||
|
@ -149,7 +149,7 @@
|
||||
<property name="engines" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (!this._engines)
|
||||
this._engines = this.searchService.getVisibleEngines({ });
|
||||
this._engines = this.searchService.getVisibleEngines();
|
||||
return this._engines;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
@ -69,6 +69,8 @@ components/aboutRights.js
|
||||
components/aboutRobots.js
|
||||
components/aboutSessionRestore.js
|
||||
components/compreg.dat
|
||||
components/@DLL_PREFIX@browserdirprovider@DLL_SUFFIX@
|
||||
components/@DLL_PREFIX@brwsrdir@DLL_SUFFIX@
|
||||
components/@DLL_PREFIX@myspell@DLL_SUFFIX@
|
||||
components/@DLL_PREFIX@spellchecker@DLL_SUFFIX@
|
||||
components/@DLL_PREFIX@spellchk@DLL_SUFFIX@
|
||||
|
@ -6,8 +6,6 @@ deleteDomainNoSelection=Delete domain
|
||||
load-js-data-url-error=For security reasons, javascript or data urls cannot be loaded from the history window or sidebar.
|
||||
noTitle=(no title)
|
||||
|
||||
bookmarksMenuName=Bookmarks Menu
|
||||
bookmarksToolbarName=Bookmarks Toolbar
|
||||
bookmarksMenuEmptyFolder=(Empty)
|
||||
|
||||
# LOCALIZATION NOTE (bookmarksBackupFilename) :
|
||||
@ -94,6 +92,7 @@ recentTagsTitle=Recent Tags
|
||||
OrganizerQueryHistory=History
|
||||
OrganizerQueryDownloads=Downloads
|
||||
OrganizerQueryAllBookmarks=All Bookmarks
|
||||
OrganizerQueryTags=Tags
|
||||
|
||||
# LOCALIZATION NOTE (tagResultLabel) :
|
||||
# This is what we use to form the label (for screen readers)
|
||||
|
@ -103,7 +103,7 @@ toolbarbutton.bookmark-item-microsummarized {
|
||||
max-width: 20em;
|
||||
}
|
||||
|
||||
toolbarbutton.bookmark-item:hover:active,
|
||||
toolbarbutton.bookmark-item:hover:active:not([disabled="true"]),
|
||||
toolbarbutton.bookmark-item[open="true"] {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 1px;
|
||||
|
@ -150,15 +150,18 @@ shellMkdir (wchar_t **pArgv)
|
||||
|
||||
/* check if directory already exists */
|
||||
_wgetcwd ( path, _MAX_PATH );
|
||||
if ( _wchdir ( tmpPath ) != -1 ) {
|
||||
_wchdir ( path );
|
||||
if ( _wchdir ( tmpPath ) == -1 &&
|
||||
_wmkdir ( tmpPath ) == -1 && // might have hit EEXIST
|
||||
_wchdir ( tmpPath ) == -1) { // so try again
|
||||
char buf[2048];
|
||||
_snprintf(buf, 2048, "Could not create the directory: %S",
|
||||
tmpPath);
|
||||
perror ( buf );
|
||||
retVal = 3;
|
||||
break;
|
||||
} else {
|
||||
if ( _wmkdir ( tmpPath ) == -1 ) {
|
||||
printf ( "%ls: ", tmpPath );
|
||||
perror ( "Could not create the directory" );
|
||||
retVal = 3;
|
||||
break;
|
||||
}
|
||||
// get back to the cwd
|
||||
_wchdir ( path );
|
||||
}
|
||||
if ( *pArg == '\0' ) /* complete path? */
|
||||
break;
|
||||
|
@ -7762,14 +7762,10 @@ dnl
|
||||
dnl Build jsctypes on the platforms we can.
|
||||
dnl
|
||||
AC_SUBST(BUILD_CTYPES)
|
||||
case "$OS_TEST" in
|
||||
arm*)
|
||||
;;
|
||||
*)
|
||||
if test "$OS_TARGET" != "WINCE" -o `echo $OS_TEST | grep -ic arm` != 1; then
|
||||
BUILD_CTYPES=1
|
||||
AC_DEFINE(BUILD_CTYPES)
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl NECKO_ configuration options are not global
|
||||
_NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_"
|
||||
|
@ -93,7 +93,7 @@ XPIDLSRCS = \
|
||||
nsIContentPolicy.idl \
|
||||
nsIDocumentEncoder.idl \
|
||||
nsIDOMFile.idl \
|
||||
nsIDOMFileRequest.idl \
|
||||
nsIDOMFileReader.idl \
|
||||
nsIDOMFileInternal.idl \
|
||||
nsIDOMFileList.idl \
|
||||
nsIDOMFileException.idl \
|
||||
|
@ -41,8 +41,8 @@ interface nsIDOMEventListener;
|
||||
interface nsIDOMFile;
|
||||
interface nsIDOMFileError;
|
||||
|
||||
[scriptable, uuid(074FEC26-7FAB-4E05-9E60-EC49E148F5EF)]
|
||||
interface nsIDOMFileRequest : nsISupports
|
||||
[scriptable, uuid(5db0ce80-de44-40c0-a346-e28aac4aa978)]
|
||||
interface nsIDOMFileReader : nsISupports
|
||||
{
|
||||
void readAsBinaryString(in nsIDOMFile filedata);
|
||||
void readAsText(in nsIDOMFile filedata, [optional] in DOMString encoding);
|
||||
@ -55,7 +55,7 @@ interface nsIDOMFileRequest : nsISupports
|
||||
const unsigned short DONE = 2;
|
||||
readonly attribute unsigned short readyState;
|
||||
|
||||
readonly attribute DOMString response;
|
||||
readonly attribute DOMString result;
|
||||
readonly attribute nsIDOMFileError error;
|
||||
|
||||
// event handler attributes
|
||||
@ -63,9 +63,9 @@ interface nsIDOMFileRequest : nsISupports
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_FILEREQUEST_CID \
|
||||
#define NS_FILEREADER_CID \
|
||||
{0x06aa7c21, 0xfe05, 0x4cf2, \
|
||||
{0xb1, 0xc4, 0x0c, 0x71, 0x26, 0xa4, 0xf7, 0x13}}
|
||||
#define NS_FILEREQUEST_CONTRACTID \
|
||||
"@mozilla.org/files/filerequest;1"
|
||||
#define NS_FILEREADER_CONTRACTID \
|
||||
"@mozilla.org/files/filereader;1"
|
||||
%}
|
@ -44,9 +44,10 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIScriptLoaderObserver.h"
|
||||
|
||||
// e68ddc48-4055-4ba9-978d-c49d9cf3189a
|
||||
#define NS_ISCRIPTELEMENT_IID \
|
||||
{ 0x4b916da5, 0x82c4, 0x45ab, \
|
||||
{ 0x99, 0x15, 0xcc, 0xcd, 0x9e, 0x2c, 0xb1, 0xe6 } }
|
||||
{ 0xe68ddc48, 0x4055, 0x4ba9, \
|
||||
{ 0x97, 0x8d, 0xc4, 0x9d, 0x9c, 0xf3, 0x18, 0x9a } }
|
||||
|
||||
/**
|
||||
* Internal interface implemented by script elements
|
||||
@ -87,6 +88,11 @@ public:
|
||||
*/
|
||||
virtual PRBool GetScriptDeferred() = 0;
|
||||
|
||||
/**
|
||||
* Is the script async. Currently only supported by HTML scripts.
|
||||
*/
|
||||
virtual PRBool GetScriptAsync() = 0;
|
||||
|
||||
void SetScriptLineNumber(PRUint32 aLineNumber)
|
||||
{
|
||||
mLineNumber = aLineNumber;
|
||||
|
@ -84,7 +84,7 @@ CPPSRCS = \
|
||||
nsDOMAttributeMap.cpp \
|
||||
nsDOMDocumentType.cpp \
|
||||
nsDOMFile.cpp \
|
||||
nsDOMFileRequest.cpp \
|
||||
nsDOMFileReader.cpp \
|
||||
nsDOMLists.cpp \
|
||||
nsDOMParser.cpp \
|
||||
nsDOMSerializer.cpp \
|
||||
|
@ -115,8 +115,18 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
// We always require a plaintext version
|
||||
|
||||
// note that we assign text/unicode as mime type, but in fact nsHTMLCopyEncoder
|
||||
// ignore it and use text/html or text/plain depending where the selection
|
||||
// is. if it is a selection into input/textarea element or in a html content
|
||||
// with pre-wrap style : text/plain. Otherwise text/html.
|
||||
// see nsHTMLCopyEncoder::SetSelection
|
||||
mimeType.AssignLiteral(kUnicodeMime);
|
||||
PRUint32 flags = nsIDocumentEncoder::OutputPreformatted;
|
||||
|
||||
// we want preformatted for the case where the selection is inside input/textarea
|
||||
// and we don't want pretty printing for others cases, to not have additionnal
|
||||
// line breaks which are then converted into spaces by the htmlConverter (see bug #524975)
|
||||
PRUint32 flags = nsIDocumentEncoder::OutputPreformatted | nsIDocumentEncoder::OutputRaw;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
||||
NS_ASSERTION(domDoc, "Need a document");
|
||||
|
@ -35,7 +35,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMFileRequest.h"
|
||||
#include "nsDOMFileReader.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -89,9 +89,9 @@
|
||||
|
||||
#define NS_PROGRESS_EVENT_INTERVAL 50
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
|
||||
nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadEndListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFile)
|
||||
@ -100,7 +100,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
|
||||
nsXHREventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadEndListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFile)
|
||||
@ -109,32 +109,32 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFileRequest)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(FileRequest)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(FileReader)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMFileRequest, nsXHREventTarget)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMFileRequest, nsXHREventTarget)
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMFileReader, nsXHREventTarget)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMFileReader, nsXHREventTarget)
|
||||
|
||||
static const PRUint32 FILE_AS_BINARY = 1;
|
||||
static const PRUint32 FILE_AS_TEXT = 2;
|
||||
static const PRUint32 FILE_AS_DATAURL = 3;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::GetOnloadend(nsIDOMEventListener** aOnloadend)
|
||||
nsDOMFileReader::GetOnloadend(nsIDOMEventListener** aOnloadend)
|
||||
{
|
||||
return GetInnerEventListener(mOnLoadEndListener, aOnloadend);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::SetOnloadend(nsIDOMEventListener* aOnloadend)
|
||||
nsDOMFileReader::SetOnloadend(nsIDOMEventListener* aOnloadend)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(LOADEND_STR),
|
||||
mOnLoadEndListener, aOnloadend);
|
||||
@ -143,18 +143,18 @@ nsDOMFileRequest::SetOnloadend(nsIDOMEventListener* aOnloadend)
|
||||
//nsICharsetDetectionObserver
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::Notify(const char *aCharset, nsDetectionConfident aConf)
|
||||
nsDOMFileReader::Notify(const char *aCharset, nsDetectionConfident aConf)
|
||||
{
|
||||
CopyASCIItoUTF16(aCharset, mCharset);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//nsDOMFileRequest constructors/initializers
|
||||
//nsDOMFileReader constructors/initializers
|
||||
|
||||
nsDOMFileRequest::nsDOMFileRequest()
|
||||
nsDOMFileReader::nsDOMFileReader()
|
||||
: mFileData(nsnull), mReadCount(0),
|
||||
mDataLen(0), mDataFormat(0),
|
||||
mReadyState(nsIDOMFileRequest::INITIAL),
|
||||
mReadyState(nsIDOMFileReader::INITIAL),
|
||||
mProgressEventWasDelayed(PR_FALSE),
|
||||
mTimerIsActive(PR_FALSE),
|
||||
mReadTotal(0), mReadTransferred(0),
|
||||
@ -163,7 +163,7 @@ nsDOMFileRequest::nsDOMFileRequest()
|
||||
nsLayoutStatics::AddRef();
|
||||
}
|
||||
|
||||
nsDOMFileRequest::~nsDOMFileRequest()
|
||||
nsDOMFileReader::~nsDOMFileReader()
|
||||
{
|
||||
if (mListenerManager)
|
||||
mListenerManager->Disconnect();
|
||||
@ -172,7 +172,7 @@ nsDOMFileRequest::~nsDOMFileRequest()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::Init()
|
||||
nsDOMFileReader::Init()
|
||||
{
|
||||
// Set the original mScriptContext and mPrincipal, if available.
|
||||
// Get JSContext from stack.
|
||||
@ -211,8 +211,8 @@ nsDOMFileRequest::Init()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
PRUint32 argc, jsval *argv)
|
||||
nsDOMFileReader::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
PRUint32 argc, jsval *argv)
|
||||
{
|
||||
mOwner = do_QueryInterface(aOwner);
|
||||
if (!mOwner) {
|
||||
@ -236,57 +236,57 @@ nsDOMFileRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
// nsIInterfaceRequestor
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::GetInterface(const nsIID & aIID, void **aResult)
|
||||
nsDOMFileReader::GetInterface(const nsIID & aIID, void **aResult)
|
||||
{
|
||||
return QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
// nsIDOMFileRequest
|
||||
// nsIDOMFileReader
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::GetReadyState(PRUint16 *aReadyState)
|
||||
nsDOMFileReader::GetReadyState(PRUint16 *aReadyState)
|
||||
{
|
||||
*aReadyState = mReadyState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::GetResponse(nsAString& aResponse)
|
||||
nsDOMFileReader::GetResult(nsAString& aResult)
|
||||
{
|
||||
aResponse = mResponse;
|
||||
aResult = mResult;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::GetError(nsIDOMFileError** aError)
|
||||
nsDOMFileReader::GetError(nsIDOMFileError** aError)
|
||||
{
|
||||
NS_IF_ADDREF(*aError = mError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::ReadAsBinaryString(nsIDOMFile* aFile)
|
||||
nsDOMFileReader::ReadAsBinaryString(nsIDOMFile* aFile)
|
||||
{
|
||||
return ReadFileContent(aFile, EmptyString(), FILE_AS_BINARY);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::ReadAsText(nsIDOMFile* aFile,
|
||||
const nsAString &aCharset)
|
||||
nsDOMFileReader::ReadAsText(nsIDOMFile* aFile,
|
||||
const nsAString &aCharset)
|
||||
{
|
||||
return ReadFileContent(aFile, aCharset, FILE_AS_TEXT);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::ReadAsDataURL(nsIDOMFile* aFile)
|
||||
nsDOMFileReader::ReadAsDataURL(nsIDOMFile* aFile)
|
||||
{
|
||||
return ReadFileContent(aFile, EmptyString(), FILE_AS_DATAURL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::Abort()
|
||||
nsDOMFileReader::Abort()
|
||||
{
|
||||
if (mReadyState != nsIDOMFileRequest::LOADING)
|
||||
if (mReadyState != nsIDOMFileReader::LOADING)
|
||||
return NS_OK;
|
||||
|
||||
//Clear progress and file data
|
||||
@ -298,9 +298,9 @@ nsDOMFileRequest::Abort()
|
||||
mReadCount = 0;
|
||||
mDataLen = 0;
|
||||
|
||||
//Revert status, response and readystate attributes
|
||||
SetDOMStringToNull(mResponse);
|
||||
mReadyState = nsIDOMFileRequest::DONE;
|
||||
//Revert status, result and readystate attributes
|
||||
SetDOMStringToNull(mResult);
|
||||
mReadyState = nsIDOMFileReader::DONE;
|
||||
mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
|
||||
|
||||
//Non-null channel indicates a read is currently active
|
||||
@ -319,14 +319,14 @@ nsDOMFileRequest::Abort()
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
|
||||
|
||||
mReadyState = nsIDOMFileRequest::INITIAL;
|
||||
mReadyState = nsIDOMFileReader::INITIAL;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsITimerCallback
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::Notify(nsITimer* aTimer)
|
||||
nsDOMFileReader::Notify(nsITimer* aTimer)
|
||||
{
|
||||
mTimerIsActive = PR_FALSE;
|
||||
if (mProgressEventWasDelayed) {
|
||||
@ -338,7 +338,7 @@ nsDOMFileRequest::Notify(nsITimer* aTimer)
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMFileRequest::StartProgressEventTimer()
|
||||
nsDOMFileReader::StartProgressEventTimer()
|
||||
{
|
||||
if (!mProgressNotifier) {
|
||||
mProgressNotifier = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
@ -355,17 +355,17 @@ nsDOMFileRequest::StartProgressEventTimer()
|
||||
// nsIStreamListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
nsDOMFileReader::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
nsDOMFileReader::OnDataAvailable(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aInputStream,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
{
|
||||
//Update memory buffer to reflect the contents of the file
|
||||
mFileData = (char *)PR_Realloc(mFileData, aOffset + aCount);
|
||||
@ -377,11 +377,11 @@ nsDOMFileRequest::OnDataAvailable(nsIRequest *aRequest,
|
||||
|
||||
//Continuously update our binary string as data comes in
|
||||
if (mDataFormat == FILE_AS_BINARY) {
|
||||
PRUint32 oldLen = mResponse.Length();
|
||||
PRUint32 oldLen = mResult.Length();
|
||||
PRUint32 newLen = oldLen + aCount;
|
||||
PRUnichar *buf;
|
||||
|
||||
if (mResponse.GetMutableData(&buf, newLen) != newLen) {
|
||||
if (mResult.GetMutableData(&buf, newLen) != newLen) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -409,9 +409,9 @@ nsDOMFileRequest::OnDataAvailable(nsIRequest *aRequest,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileRequest::OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus)
|
||||
nsDOMFileReader::OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
//If we're here as a result of a call from Abort(),
|
||||
//simply ignore the request.
|
||||
@ -425,8 +425,8 @@ nsDOMFileRequest::OnStopRequest(nsIRequest *aRequest,
|
||||
mProgressNotifier->Cancel();
|
||||
}
|
||||
|
||||
//FileRequest must be in DONE stage after a load
|
||||
mReadyState = nsIDOMFileRequest::DONE;
|
||||
//FileReader must be in DONE stage after a load
|
||||
mReadyState = nsIDOMFileReader::DONE;
|
||||
|
||||
//Set the status field as appropriate
|
||||
if (NS_FAILED(aStatus)) {
|
||||
@ -437,12 +437,12 @@ nsDOMFileRequest::OnStopRequest(nsIRequest *aRequest,
|
||||
nsresult rv;
|
||||
switch (mDataFormat) {
|
||||
case FILE_AS_BINARY:
|
||||
break; //Already accumulated mResponse
|
||||
break; //Already accumulated mResult
|
||||
case FILE_AS_TEXT:
|
||||
rv = GetAsText(mCharset, mFileData, mDataLen, mResponse);
|
||||
rv = GetAsText(mCharset, mFileData, mDataLen, mResult);
|
||||
break;
|
||||
case FILE_AS_DATAURL:
|
||||
rv = GetAsDataURL(mFile, mFileData, mDataLen, mResponse);
|
||||
rv = GetAsDataURL(mFile, mFileData, mDataLen, mResult);
|
||||
break;
|
||||
default:
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -458,9 +458,9 @@ nsDOMFileRequest::OnStopRequest(nsIRequest *aRequest,
|
||||
// Helper methods
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::ReadFileContent(nsIDOMFile* aFile,
|
||||
const nsAString &aCharset,
|
||||
PRUint32 aDataFormat)
|
||||
nsDOMFileReader::ReadFileContent(nsIDOMFile* aFile,
|
||||
const nsAString &aCharset,
|
||||
PRUint32 aDataFormat)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
|
||||
|
||||
@ -490,15 +490,15 @@ nsDOMFileRequest::ReadFileContent(nsIDOMFile* aFile,
|
||||
rv = mChannel->AsyncOpen(this, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//FileRequest should be in loading state here
|
||||
mReadyState = nsIDOMFileRequest::LOADING;
|
||||
//FileReader should be in loading state here
|
||||
mReadyState = nsIDOMFileReader::LOADING;
|
||||
DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMFileRequest::DispatchError(nsresult rv)
|
||||
nsDOMFileReader::DispatchError(nsresult rv)
|
||||
{
|
||||
//Set the status attribute, and dispatch the error event
|
||||
switch (rv) {
|
||||
@ -519,7 +519,7 @@ nsDOMFileRequest::DispatchError(nsresult rv)
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMFileRequest::DispatchProgressEvent(const nsAString& aType)
|
||||
nsDOMFileReader::DispatchProgressEvent(const nsAString& aType)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = nsEventDispatcher::CreateEvent(nsnull, nsnull,
|
||||
@ -547,10 +547,10 @@ nsDOMFileRequest::DispatchProgressEvent(const nsAString& aType)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::GetAsText(const nsAString &aCharset,
|
||||
const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsAString& aResult)
|
||||
nsDOMFileReader::GetAsText(const nsAString &aCharset,
|
||||
const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsAString& aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCAutoString charsetGuess;
|
||||
@ -574,10 +574,10 @@ nsDOMFileRequest::GetAsText(const nsAString &aCharset,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::GetAsDataURL(nsIFile *aFile,
|
||||
const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsAString& aResult)
|
||||
nsDOMFileReader::GetAsDataURL(nsIFile *aFile,
|
||||
const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsAString& aResult)
|
||||
{
|
||||
aResult.AssignLiteral("data:");
|
||||
|
||||
@ -621,10 +621,10 @@ nsDOMFileRequest::GetAsDataURL(nsIFile *aFile,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::ConvertStream(const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
const char *aCharset,
|
||||
nsAString &aResult)
|
||||
nsDOMFileReader::ConvertStream(const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
const char *aCharset,
|
||||
nsAString &aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICharsetConverterManager> charsetConverter =
|
||||
@ -650,9 +650,9 @@ nsDOMFileRequest::ConvertStream(const char *aFileData,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileRequest::GuessCharset(const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsACString &aCharset)
|
||||
nsDOMFileReader::GuessCharset(const char *aFileData,
|
||||
PRUint32 aDataLen,
|
||||
nsACString &aCharset)
|
||||
{
|
||||
// First try the universal charset detector
|
||||
nsCOMPtr<nsICharsetDetector> detector
|
@ -35,8 +35,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMFileRequest_h__
|
||||
#define nsDOMFileRequest_h__
|
||||
#ifndef nsDOMFileReader_h__
|
||||
#define nsDOMFileReader_h__
|
||||
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsString.h"
|
||||
@ -53,7 +53,7 @@
|
||||
#include "nsICharsetDetectionObserver.h"
|
||||
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileRequest.h"
|
||||
#include "nsIDOMFileReader.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIDOMFileError.h"
|
||||
#include "nsIInputStream.h"
|
||||
@ -63,23 +63,23 @@
|
||||
|
||||
#include "nsXMLHttpRequest.h"
|
||||
|
||||
class nsDOMFileRequest : public nsXHREventTarget,
|
||||
public nsIDOMFileRequest,
|
||||
public nsIStreamListener,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIJSNativeInitializer,
|
||||
public nsITimerCallback,
|
||||
public nsICharsetDetectionObserver
|
||||
class nsDOMFileReader : public nsXHREventTarget,
|
||||
public nsIDOMFileReader,
|
||||
public nsIStreamListener,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIJSNativeInitializer,
|
||||
public nsITimerCallback,
|
||||
public nsICharsetDetectionObserver
|
||||
{
|
||||
public:
|
||||
nsDOMFileRequest();
|
||||
virtual ~nsDOMFileRequest();
|
||||
nsDOMFileReader();
|
||||
virtual ~nsDOMFileReader();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMFILEREQUEST
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMFileRequest, nsXHREventTarget)
|
||||
NS_DECL_NSIDOMFILEREADER
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMFileReader, nsXHREventTarget)
|
||||
|
||||
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::);
|
||||
|
||||
@ -126,7 +126,7 @@ protected:
|
||||
PRUint32 mDataLen;
|
||||
PRUint32 mDataFormat;
|
||||
|
||||
nsString mResponse;
|
||||
nsString mResult;
|
||||
PRUint16 mReadyState;
|
||||
|
||||
PRBool mProgressEventWasDelayed;
|
@ -111,6 +111,7 @@ GK_ATOM(area, "area")
|
||||
GK_ATOM(ascending, "ascending")
|
||||
GK_ATOM(aspectRatio, "aspect-ratio")
|
||||
GK_ATOM(assign, "assign")
|
||||
GK_ATOM(async, "async")
|
||||
GK_ATOM(attribute, "attribute")
|
||||
GK_ATOM(attributeSet, "attribute-set")
|
||||
GK_ATOM(aural, "aural")
|
||||
|
@ -139,6 +139,10 @@ nsScriptLoader::~nsScriptLoader()
|
||||
mRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0; i < mAsyncRequests.Count(); i++) {
|
||||
mAsyncRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
// Unblock the kids, in case any of them moved to a different document
|
||||
// subtree in the meantime and therefore aren't actually going away.
|
||||
for (PRUint32 j = 0; j < mPendingChildLoaders.Length(); ++j) {
|
||||
@ -501,7 +505,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
request = mPreloads[i].mRequest;
|
||||
request->mElement = aElement;
|
||||
request->mJSVersion = version;
|
||||
request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
|
||||
request->mDefer = mDeferEnabled && aElement->GetScriptDeferred() &&
|
||||
!aElement->GetScriptAsync();
|
||||
mPreloads.RemoveElementAt(i);
|
||||
|
||||
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
|
||||
@ -510,21 +515,34 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!request->mLoading && !request->mDefer && !hadPendingRequests &&
|
||||
ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
|
||||
// Can we run the script now?
|
||||
// This is true if we're done loading, the script isn't deferred and
|
||||
// there are either no scripts or stylesheets to wait for, or the
|
||||
// script is async
|
||||
PRBool readyToRun =
|
||||
!request->mLoading && !request->mDefer &&
|
||||
((!hadPendingRequests && ReadyToExecuteScripts()) ||
|
||||
aElement->GetScriptAsync());
|
||||
|
||||
if (readyToRun && nsContentUtils::IsSafeToRunScript()) {
|
||||
return ProcessRequest(request);
|
||||
}
|
||||
|
||||
// Not done loading yet. Move into the real requests queue and wait.
|
||||
mRequests.AppendObject(request);
|
||||
if (aElement->GetScriptAsync()) {
|
||||
mAsyncRequests.AppendObject(request);
|
||||
}
|
||||
else {
|
||||
mRequests.AppendObject(request);
|
||||
}
|
||||
|
||||
if (!request->mLoading && !hadPendingRequests && ReadyToExecuteScripts() &&
|
||||
!request->mDefer) {
|
||||
if (readyToRun) {
|
||||
nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
|
||||
&nsScriptLoader::ProcessPendingRequests));
|
||||
}
|
||||
|
||||
return request->mDefer ? NS_OK : NS_ERROR_HTMLPARSER_BLOCK;
|
||||
return request->mDefer || aElement->GetScriptAsync() ?
|
||||
NS_OK : NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,10 +550,10 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
request = new nsScriptLoadRequest(aElement, version);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
|
||||
|
||||
// First check to see if this is an external script
|
||||
if (scriptURI) {
|
||||
request->mDefer = mDeferEnabled && aElement->GetScriptDeferred() &&
|
||||
!aElement->GetScriptAsync();
|
||||
request->mURI = scriptURI;
|
||||
request->mIsInline = PR_FALSE;
|
||||
request->mLoading = PR_TRUE;
|
||||
@ -545,6 +563,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
request->mDefer = PR_FALSE;
|
||||
request->mLoading = PR_FALSE;
|
||||
request->mIsInline = PR_TRUE;
|
||||
request->mURI = mDocument->GetDocumentURI();
|
||||
@ -553,17 +572,19 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
|
||||
// If we've got existing pending requests, add ourselves
|
||||
// to this list.
|
||||
if (!request->mDefer && !hadPendingRequests &&
|
||||
ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
|
||||
if (!hadPendingRequests && ReadyToExecuteScripts() &&
|
||||
nsContentUtils::IsSafeToRunScript()) {
|
||||
return ProcessRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the request to our requests list
|
||||
NS_ENSURE_TRUE(mRequests.AppendObject(request),
|
||||
NS_ENSURE_TRUE(aElement->GetScriptAsync() ?
|
||||
mAsyncRequests.AppendObject(request) :
|
||||
mRequests.AppendObject(request),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (request->mDefer) {
|
||||
if (request->mDefer || aElement->GetScriptAsync()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -736,11 +757,30 @@ nsScriptLoader::ProcessPendingRequestsAsync()
|
||||
void
|
||||
nsScriptLoader::ProcessPendingRequests()
|
||||
{
|
||||
nsRefPtr<nsScriptLoadRequest> request;
|
||||
while (ReadyToExecuteScripts() &&
|
||||
(request = GetFirstPendingRequest()) &&
|
||||
!request->mLoading) {
|
||||
mRequests.RemoveObject(request);
|
||||
while (1) {
|
||||
nsRefPtr<nsScriptLoadRequest> request;
|
||||
if (ReadyToExecuteScripts()) {
|
||||
request = GetFirstPendingRequest();
|
||||
if (request && !request->mLoading) {
|
||||
mRequests.RemoveObject(request);
|
||||
}
|
||||
else {
|
||||
request = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
for (PRInt32 i = 0;
|
||||
!request && mEnabled && i < mAsyncRequests.Count();
|
||||
++i) {
|
||||
if (!mAsyncRequests[i]->mLoading) {
|
||||
request = mAsyncRequests[i];
|
||||
mAsyncRequests.RemoveObjectAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!request)
|
||||
break;
|
||||
|
||||
ProcessRequest(request);
|
||||
}
|
||||
|
||||
@ -751,7 +791,7 @@ nsScriptLoader::ProcessPendingRequests()
|
||||
}
|
||||
|
||||
if (mUnblockOnloadWhenDoneProcessing && mDocument &&
|
||||
!GetFirstPendingRequest()) {
|
||||
!GetFirstPendingRequest() && !mAsyncRequests.Count()) {
|
||||
// No more pending scripts; time to unblock onload.
|
||||
// OK to unblock onload synchronously here, since callers must be
|
||||
// prepared for the world changing anyway.
|
||||
@ -920,10 +960,11 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
nsresult rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen,
|
||||
aString);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (!mRequests.RemoveObject(request)) {
|
||||
mPreloads.RemoveElement(request, PreloadRequestComparator());
|
||||
} else {
|
||||
if (mRequests.RemoveObject(request) ||
|
||||
mAsyncRequests.RemoveObject(request)) {
|
||||
FireScriptAvailable(rv, request);
|
||||
} else {
|
||||
mPreloads.RemoveElement(request, PreloadRequestComparator());
|
||||
}
|
||||
}
|
||||
|
||||
@ -993,6 +1034,7 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
||||
// so if you see this assertion it is likely something else that is
|
||||
// wrong, especially if you see it more than once.
|
||||
NS_ASSERTION(mRequests.IndexOf(aRequest) >= 0 ||
|
||||
mAsyncRequests.IndexOf(aRequest) >= 0 ||
|
||||
mPreloads.Contains(aRequest, PreloadRequestComparator()),
|
||||
"aRequest should be pending!");
|
||||
|
||||
|
@ -300,6 +300,7 @@ protected:
|
||||
nsIDocument* mDocument; // [WEAK]
|
||||
nsCOMArray<nsIScriptLoaderObserver> mObservers;
|
||||
nsCOMArray<nsScriptLoadRequest> mRequests;
|
||||
nsCOMArray<nsScriptLoadRequest> mAsyncRequests;
|
||||
|
||||
// In mRequests, the additional information here is stored by the element.
|
||||
struct PreloadInfo {
|
||||
|
@ -323,6 +323,11 @@ _TEST_FILES = test_bug5141.html \
|
||||
test_range_bounds.html \
|
||||
test_bug475156.html \
|
||||
bug475156.sjs \
|
||||
test_copypaste.html \
|
||||
test_bug503481.html \
|
||||
file_bug503481.sjs \
|
||||
test_bug503481b.html \
|
||||
file_bug503481b_inner.html \
|
||||
$(NULL)
|
||||
|
||||
# Disabled; see bug 492181
|
||||
|
43
content/base/test/file_bug503481.sjs
Normal file
43
content/base/test/file_bug503481.sjs
Normal file
@ -0,0 +1,43 @@
|
||||
// 'timer' is global to avoid getting GCed which would cancel the timer
|
||||
var timer;
|
||||
const nsITimer = Components.interfaces.nsITimer;
|
||||
|
||||
function attemptUnblock(s) {
|
||||
try {
|
||||
let blockedResponse = null;
|
||||
getObjectState("bug503481_" + s, function(x) {blockedResponse = x.wrappedJSObject.r});
|
||||
blockedResponse.finish();
|
||||
setObjectState("bug503481_" + s, null);
|
||||
} catch(e) {
|
||||
dump("unable to unblock " + s + "retrying in half a second\n");
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(nsITimer);
|
||||
timer.initWithCallback(function () { attemptUnblock(s) }, 500, nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
dump("processing:" + request.queryString + "\n");
|
||||
|
||||
if (query.unblock) {
|
||||
attemptUnblock(query.unblock);
|
||||
}
|
||||
|
||||
if (query.blockOn) {
|
||||
response.processAsync();
|
||||
x = { r: response, QueryInterface: function(iid) { return this } };
|
||||
x.wrappedJSObject = x;
|
||||
setObjectState("bug503481_" + query.blockOn, x);
|
||||
}
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write(query.body);
|
||||
}
|
85
content/base/test/file_bug503481b_inner.html
Normal file
85
content/base/test/file_bug503481b_inner.html
Normal file
@ -0,0 +1,85 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Async script that isn't preloaded -->
|
||||
<script async src="file_bug503481.sjs?blockOn=R&body=runFirst();"></script>
|
||||
<script>
|
||||
firstRan = false;
|
||||
secondRan = false;
|
||||
thirdRan = false;
|
||||
forthRan = false;
|
||||
fifthRan = false;
|
||||
sixthRan = false;
|
||||
function runFirst() {
|
||||
firstRan = true;
|
||||
}
|
||||
function runThird() {
|
||||
parent.is(forthRan, false, "forth should still be blocked");
|
||||
unblock("T");
|
||||
thirdRan = true;
|
||||
}
|
||||
function runForth() {
|
||||
forthRan = true;
|
||||
}
|
||||
function runFifth() {
|
||||
parent.is(sixthRan, false, "sixth should be not run before non-async fifth");
|
||||
fifthRan = true;
|
||||
}
|
||||
function runSixth() {
|
||||
parent.is(fifthRan, true, "fifth should run before async sixth");
|
||||
sixthRan = true;
|
||||
}
|
||||
|
||||
function done() {
|
||||
parent.is(firstRan, true, "first should have run by onload");
|
||||
parent.is(secondRan, true, "second should have run by onload");
|
||||
parent.is(thirdRan, true, "third should have run by onload");
|
||||
parent.is(forthRan, true, "forth should have run by onload");
|
||||
parent.is(fifthRan, true, "fifth should have run by onload");
|
||||
parent.is(sixthRan, true, "sixth should have run by onload");
|
||||
parent.SimpleTest.finish();
|
||||
}
|
||||
|
||||
var reqs = [];
|
||||
function unblock(s) {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "file_bug503481.sjs?unblock=" + s);
|
||||
xhr.send();
|
||||
reqs.push(xhr);
|
||||
}
|
||||
|
||||
|
||||
parent.is(firstRan, false, "First async script shouldn't have run");
|
||||
unblock("R");
|
||||
</script>
|
||||
|
||||
<!-- test that inline async isn't actually async -->
|
||||
<script async>
|
||||
secondRan = true;
|
||||
</script>
|
||||
<script async>
|
||||
parent.is(secondRan, true, "Second script shouldn't be async");
|
||||
</script>
|
||||
|
||||
<!-- test that setting both defer and async treats the script as async -->
|
||||
<script defer async src="file_bug503481.sjs?blockOn=S&body=runThird();"></script>
|
||||
<script>
|
||||
parent.is(thirdRan, false, "third should not have run yet");
|
||||
unblock("S");
|
||||
</script>
|
||||
<script src="file_bug503481.sjs?blockOn=T&body=runForth();"></script>
|
||||
|
||||
<!-- test that preloading an async script works -->
|
||||
<script>
|
||||
setTimeout(function () { unblock("U"); }, 1000);
|
||||
</script>
|
||||
<script src="file_bug503481.sjs?blockOn=U&body=runFifth();"></script>
|
||||
<script async src="file_bug503481.sjs?blockOn=V&body=runSixth();"></script>
|
||||
<script>
|
||||
parent.is(fifthRan, true, "fifth should have run by now");
|
||||
parent.is(sixthRan, false, "sixth should not have run yet");
|
||||
unblock("V");
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="done()">
|
70
content/base/test/test_bug503481.html
Normal file
70
content/base/test/test_bug503481.html
Normal file
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=503481
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 503481</title>
|
||||
<script src="/MochiKit/packed.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="done();">
|
||||
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481"
|
||||
target="_blank" >Mozilla Bug 503481</a>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function done() {
|
||||
is(firstRan, true, "first has run");
|
||||
is(secondRan, true, "second has run");
|
||||
is(thirdRan, true, "third has run");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
var reqs = [];
|
||||
function unblock(s) {
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "file_bug503481.sjs?unblock=" + s);
|
||||
xhr.send();
|
||||
reqs.push(xhr);
|
||||
}
|
||||
var firstRan = false, secondRan = false, thirdRan = false;
|
||||
function runFirst() { firstRan = true; }
|
||||
function runSecond() {
|
||||
is(thirdRan, true, "should have run third already");
|
||||
secondRan = true;
|
||||
}
|
||||
function runThird() {
|
||||
is(secondRan, false, "shouldn't have unblocked second yet");
|
||||
thirdRan = true;
|
||||
unblock("B");
|
||||
}
|
||||
</script>
|
||||
<script id=firstScript async src="file_bug503481.sjs?blockOn=A&body=runFirst();"></script>
|
||||
<script id=firstScriptHelper>
|
||||
is(document.getElementById("firstScript").async, true,
|
||||
"async set");
|
||||
is(document.getElementById("firstScriptHelper").async, false,
|
||||
"async not set");
|
||||
document.getElementById("firstScript").async = false;
|
||||
is(document.getElementById("firstScript").async, false,
|
||||
"async no longer set");
|
||||
is(document.getElementById("firstScript").hasAttribute("async"), false,
|
||||
"async attribute no longer set");
|
||||
is(firstRan, false, "First async script shouldn't have run");
|
||||
unblock("A");
|
||||
</script>
|
||||
|
||||
<script async src="file_bug503481.sjs?blockOn=B&body=runSecond();"></script>
|
||||
<script async src="file_bug503481.sjs?blockOn=C&body=runThird();"></script>
|
||||
<script>
|
||||
is(secondRan, false, "Second async script shouldn't have run");
|
||||
is(thirdRan, false, "Third async script shouldn't have run");
|
||||
unblock("C");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
23
content/base/test/test_bug503481b.html
Normal file
23
content/base/test/test_bug503481b.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=503481
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 503481</title>
|
||||
<script src="/MochiKit/packed.js"></script>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481"
|
||||
target="_blank" >Mozilla Bug 503481</a>
|
||||
|
||||
<iframe src="file_bug503481b_inner.html"></iframe>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
// script in the iframe will call SimpleTest.finish()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
94
content/base/test/test_copypaste.html
Normal file
94
content/base/test/test_copypaste.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
-->
|
||||
<head>
|
||||
<title>Test for copy/paste</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=524975">Mozilla Bug </a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function testCopyPaste () {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
// selection of the node
|
||||
var node = document.getElementById('draggable');
|
||||
window.getSelection().selectAllChildren(node);
|
||||
|
||||
// let's copy the selection
|
||||
var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
|
||||
var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
|
||||
var documentViewer = docShell.contentViewer
|
||||
.QueryInterface(Components.interfaces.nsIContentViewerEdit);
|
||||
documentViewer.copySelection();
|
||||
|
||||
//--------- now check the content of the clipboard
|
||||
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
|
||||
.getService(Components.interfaces.nsIClipboard);
|
||||
|
||||
// is the clipboard contain a text/unicode data ?
|
||||
var transferable = Components.classes['@mozilla.org/widget/transferable;1']
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
transferable.addDataFlavor("text/unicode");
|
||||
clipboard.getData(transferable, 1);
|
||||
var data = {}
|
||||
transferable.getTransferData ("text/unicode", data, {} ) ;
|
||||
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
|
||||
"This is a draggable bit of text.");
|
||||
|
||||
// is the clipboard contain a text/html data ?
|
||||
transferable = Components.classes['@mozilla.org/widget/transferable;1']
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
transferable.addDataFlavor("text/html");
|
||||
clipboard.getData(transferable, 1);
|
||||
transferable.getTransferData ("text/html", data, {} ) ;
|
||||
is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
|
||||
"<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em>\n bit of text.</div>");
|
||||
|
||||
//------ let's paste now in the textarea and verify its content
|
||||
var textarea = document.getElementById('input');
|
||||
textarea.focus();
|
||||
textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
|
||||
.editor.paste(1);
|
||||
is(textarea.value, "This is a draggable bit of text.");
|
||||
|
||||
|
||||
// test copy/paste from/to textarea
|
||||
var val = "1\n 2\n 3"
|
||||
textarea.value=val;
|
||||
textarea.select();
|
||||
textarea.editor.copy();
|
||||
|
||||
textarea.value="";
|
||||
textarea.editor.paste(1);
|
||||
is(textarea.value, val);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(testCopyPaste);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div>
|
||||
|
||||
<div id="draggable" title="title to have a long HTML line">This is a <em>draggable</em> bit of text.</div>
|
||||
<textarea id="input"></textarea>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -61,48 +61,48 @@ var domFileBinary = file.getAsBinary();
|
||||
var domFileBinary2 = utf16File.getAsBinary();
|
||||
var domFileBinary3 = utf32File.getAsBinary();
|
||||
|
||||
var request1 = new FileRequest();
|
||||
var request1 = new FileReader();
|
||||
request1.onload = handleTextISO1;
|
||||
request1.readAsText(file, "iso-8859-1");
|
||||
|
||||
var request2 = new FileRequest();
|
||||
var request2 = new FileReader();
|
||||
request2.onload = handleTextUTF8;
|
||||
request2.readAsText(file);
|
||||
|
||||
var request3 = new FileRequest();
|
||||
var request3 = new FileReader();
|
||||
request3.onload = handleTextUTF8;
|
||||
request3.readAsText(file, "");
|
||||
|
||||
var request4 = new FileRequest();
|
||||
var request4 = new FileReader();
|
||||
request4.onload = handleTextUTF8;
|
||||
request4.readAsText(file, "UTF-8");
|
||||
|
||||
//Test a variety of encodings, and make sure they work properly
|
||||
//Also, test a variety of the same calls with different numbers of arguments
|
||||
var request5 = new FileRequest();
|
||||
var request5 = new FileReader();
|
||||
request5.onload = handleTextUTF16;
|
||||
request5.readAsText(utf16File, "UTF-16");
|
||||
|
||||
var request6 = new FileRequest();
|
||||
var request6 = new FileReader();
|
||||
request6.onload = handleTextUTF32;
|
||||
request6.readAsText(utf32File, "UTF-32");
|
||||
|
||||
//Test binary data accessor
|
||||
var request7 = new FileRequest();
|
||||
var request7 = new FileReader();
|
||||
request7.onload = handleDataBinary;
|
||||
request7.readAsBinaryString(file);
|
||||
|
||||
var request71 = new FileRequest();
|
||||
var request71 = new FileReader();
|
||||
request71.onload = handleDataBinary16;
|
||||
request71.readAsBinaryString(utf16File);
|
||||
|
||||
var request72 = new FileRequest();
|
||||
var request72 = new FileReader();
|
||||
request72.onload = handleDataBinary32;
|
||||
request72.readAsBinaryString(utf32File);
|
||||
|
||||
//Test data URI encoding on differing file sizes
|
||||
//Testing data URI when length % 3 == 0
|
||||
var request8 = new FileRequest();
|
||||
var request8 = new FileReader();
|
||||
request8.onload = handleDataURI;
|
||||
request8.readAsDataURL(file);
|
||||
|
||||
@ -110,7 +110,7 @@ request8.readAsDataURL(file);
|
||||
var file2 = createFileWithData(testData2, "02");
|
||||
var domFileData1 = file2.getAsDataURL();
|
||||
|
||||
var request9 = new FileRequest();
|
||||
var request9 = new FileReader();
|
||||
request9.onload = handleDataURI1;
|
||||
request9.readAsDataURL(file2);
|
||||
|
||||
@ -118,13 +118,13 @@ request9.readAsDataURL(file2);
|
||||
var file3 = createFileWithData(testData3, "03");
|
||||
var domFileData2 = file3.getAsDataURL();
|
||||
|
||||
var request10 = new FileRequest();
|
||||
var request10 = new FileReader();
|
||||
request10.onload = handleDataURI2;
|
||||
request10.readAsDataURL(file3);
|
||||
|
||||
//Test asynchronous property of file access
|
||||
var globalVar = 0;
|
||||
var request105 = new FileRequest();
|
||||
var request105 = new FileReader();
|
||||
request105.onload = incGlobalVar;
|
||||
request105.readAsText(file, "");
|
||||
is(globalVar, 0, "testing to make sure getAsText doesn't block subsequent execution");
|
||||
@ -142,19 +142,19 @@ var fileList = document.getElementById('fileList');
|
||||
fileList.value = testFile4.path;
|
||||
var file4 = fileList.files[0];
|
||||
|
||||
var request11 = new FileRequest();
|
||||
var request11 = new FileReader();
|
||||
request11.onabort = handleCancel;
|
||||
request11.readAsText(file4);
|
||||
request11.abort();
|
||||
|
||||
//Test error handling - Note: currently throws exceptions
|
||||
/*testFile4.permissions = 0;
|
||||
var request12 = new FileRequest();
|
||||
var request12 = new FileReader();
|
||||
request12.onerror = handleSecurityError;
|
||||
request12.readAsText(file4, "");
|
||||
|
||||
testFile4.remove(false);
|
||||
var request13 = new FileRequest();
|
||||
var request13 = new FileReader();
|
||||
request13.onerror = handleNotFoundError;
|
||||
request13.readAsText(file4, "");*/
|
||||
|
||||
@ -164,7 +164,7 @@ function incGlobalVar(fileAsText) {
|
||||
}
|
||||
|
||||
function handleCancel(event) {
|
||||
var fileAsText = event.target.response;
|
||||
var fileAsText = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error.code, FileError.ABORT_ERR, "error code set to CANCELED for canceled reads");
|
||||
is(fileAsText, null, "file data should be null on canceled reads");
|
||||
@ -172,7 +172,7 @@ function handleCancel(event) {
|
||||
}
|
||||
|
||||
function handleTextISO1(event) {
|
||||
var fileAsText = event.target.response;
|
||||
var fileAsText = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error, null, "error code set to null for successful data accesses");
|
||||
is(testData.length, fileAsText.length, "iso-1 async length should match testdata");
|
||||
@ -181,7 +181,7 @@ function handleTextISO1(event) {
|
||||
}
|
||||
|
||||
function handleTextUTF8(event) {
|
||||
var fileAsUTF8 = event.target.response;
|
||||
var fileAsUTF8 = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error, null, "error code set to null for successful data accesses");
|
||||
is(testData.length, fileAsUTF8.length, "UTF-8 async length should match testdata");
|
||||
@ -190,7 +190,7 @@ function handleTextUTF8(event) {
|
||||
}
|
||||
|
||||
function handleTextUTF16(event) {
|
||||
var fileAsUTF16 = event.target.response;
|
||||
var fileAsUTF16 = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error, null, "error code set to SUCCESS for successful data accesses");
|
||||
is(testData.length, fileAsUTF16.length, "UTF-16 async length should match testdata");
|
||||
@ -199,7 +199,7 @@ function handleTextUTF16(event) {
|
||||
}
|
||||
|
||||
function handleTextUTF32(event) {
|
||||
var fileAsUTF32 = event.target.response;
|
||||
var fileAsUTF32 = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error, null, "error code set to SUCCESS for successful data accesses");
|
||||
is(testData.length, fileAsUTF32.length, "UTF-32 async length should match testdata");
|
||||
@ -209,7 +209,7 @@ function handleTextUTF32(event) {
|
||||
|
||||
//Tests dataURI.length % 3 == 0
|
||||
function handleDataURI(event) {
|
||||
var fileAsDataURI = event.target.response;
|
||||
var fileAsDataURI = event.target.result;
|
||||
is(domFileData.length, fileAsDataURI.length, "data URI async length should match dom file data");
|
||||
is(domFileData, fileAsDataURI, "data URI async string result should match dom file data");
|
||||
testHasRun();
|
||||
@ -217,7 +217,7 @@ function handleDataURI(event) {
|
||||
|
||||
//Tests dataURI.length % 3 == 1
|
||||
function handleDataURI1(event) {
|
||||
var fileAsDataURI = event.target.response;
|
||||
var fileAsDataURI = event.target.result;
|
||||
is(domFileData1.length, fileAsDataURI.length, "data URI async length should match dom file data1");
|
||||
is(domFileData1, fileAsDataURI, "data URI async string result should match dom file data1");
|
||||
testHasRun();
|
||||
@ -225,35 +225,35 @@ function handleDataURI1(event) {
|
||||
|
||||
//Tests dataURI.length % 3 == 2
|
||||
function handleDataURI2(event) {
|
||||
var fileAsDataURI = event.target.response;
|
||||
var fileAsDataURI = event.target.result;
|
||||
is(domFileData2.length, fileAsDataURI.length, "data URI async length should match dom file data2");
|
||||
is(domFileData2, fileAsDataURI, "data URI async string result should match dom file data2");
|
||||
testHasRun();
|
||||
}
|
||||
|
||||
function handleDataBinary(event) {
|
||||
var fileAsBinary = event.target.response;
|
||||
var fileAsBinary = event.target.result;
|
||||
is(domFileBinary.length, fileAsBinary.length, "binary data async length should match dom file binary");
|
||||
is(domFileBinary, fileAsBinary, "binary data async string result should match dom file binary");
|
||||
testHasRun();
|
||||
}
|
||||
|
||||
function handleDataBinary16(event) {
|
||||
var fileAsBinary = event.target.response;
|
||||
var fileAsBinary = event.target.result;
|
||||
is(domFileBinary2.length, fileAsBinary.length, "binary data async length should match dom file binary16");
|
||||
is(domFileBinary2, fileAsBinary, "binary data async string result should match dom file binary16");
|
||||
testHasRun();
|
||||
}
|
||||
|
||||
function handleDataBinary32(event) {
|
||||
var fileAsBinary = event.target.response;
|
||||
var fileAsBinary = event.target.result;
|
||||
is(domFileBinary3.length, fileAsBinary.length, "binary data async length should match dom file binary32");
|
||||
is(domFileBinary3, fileAsBinary, "binary data async string result should match dom file binary32");
|
||||
testHasRun();
|
||||
}
|
||||
|
||||
function handleSecurityError(event) {
|
||||
var fileAsText = event.target.response;
|
||||
var fileAsText = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error.code, FileError.SECURITY_ERR, "code for file security error should have value 18");
|
||||
is(fileAsText, null, "file content should be null when error is encountered");
|
||||
@ -261,7 +261,7 @@ function handleSecurityError(event) {
|
||||
}
|
||||
|
||||
function handleNotFoundError(event) {
|
||||
var fileAsText = event.target.response;
|
||||
var fileAsText = event.target.result;
|
||||
var error = event.target.error;
|
||||
is(error.code, FileError.NOT_FOUND_ERR, "code for file not found error should have value 8");
|
||||
is(fileAsText, null, "file content should be null when error is encountered");
|
||||
|
@ -1983,9 +1983,13 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
// change during the drag.
|
||||
dataTransfer->SetReadOnly();
|
||||
|
||||
if (status != nsEventStatus_eConsumeNoDefault)
|
||||
DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, isSelection);
|
||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
PRBool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, isSelection);
|
||||
if (dragStarted) {
|
||||
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that frame event handling doesn't care about NS_DRAGDROP_GESTURE,
|
||||
// which is just as well since we don't really know which frame to
|
||||
@ -2106,7 +2110,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PRBool
|
||||
nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
@ -2116,18 +2120,19 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
// Default handling for the draggesture/dragstart event.
|
||||
//
|
||||
// First, check if a drag session already exists. This means that the drag
|
||||
// service was called directly within a draggesture handler. In this case,
|
||||
// don't do anything more, as it is assumed that the handler is managing
|
||||
// drag and drop manually.
|
||||
// drag and drop manually. Make sure to return true to indicate that a drag
|
||||
// began.
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (dragSession)
|
||||
return; // already a drag in progress
|
||||
return PR_TRUE;
|
||||
|
||||
// No drag session is currently active, so check if a handler added
|
||||
// any items to be dragged. If not, there isn't anything to drag.
|
||||
@ -2135,7 +2140,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
if (aDataTransfer)
|
||||
aDataTransfer->GetMozItemCount(&count);
|
||||
if (!count)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
// Get the target being dragged, which may not be the same as the
|
||||
// target of the mouse event. If one wasn't set in the
|
||||
@ -2148,7 +2153,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
if (!dragTarget) {
|
||||
dragTarget = do_QueryInterface(aDragTarget);
|
||||
if (!dragTarget)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// check which drag effect should initially be used. If the effect was not
|
||||
@ -2183,7 +2188,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsISupportsArray> transArray;
|
||||
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
|
||||
if (!transArray)
|
||||
return;
|
||||
return PR_FALSE;
|
||||
|
||||
// XXXndeakin don't really want to create a new drag DOM event
|
||||
// here, but we need something to pass to the InvokeDragSession
|
||||
@ -2231,6 +2236,8 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
imageX, imageY, domDragEvent,
|
||||
aDataTransfer);
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -3598,7 +3605,7 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
|
||||
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
||||
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
|
||||
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
|
||||
event.nativeMsg = ((nsMouseEvent*)aEvent)->nativeMsg;
|
||||
event.pluginEvent = ((nsMouseEvent*)aEvent)->pluginEvent;
|
||||
event.relatedTarget = aRelatedContent;
|
||||
|
||||
mCurrentTargetContent = aTargetContent;
|
||||
|
@ -322,18 +322,19 @@ protected:
|
||||
|
||||
/*
|
||||
* Perform the default handling for the dragstart/draggesture event and set up a
|
||||
* drag for aDataTransfer if it contains any data.
|
||||
* drag for aDataTransfer if it contains any data. Returns true if a drag has
|
||||
* started.
|
||||
*
|
||||
* aDragEvent - the dragstart/draggesture event
|
||||
* aDataTransfer - the data transfer that holds the data to be dragged
|
||||
* aDragTarget - the target of the drag
|
||||
* aIsSelection - true if a selection is being dragged
|
||||
*/
|
||||
void DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection);
|
||||
PRBool DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection);
|
||||
|
||||
PRBool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ INPUT(popupText1): blur \n\
|
||||
setPrefAndDoTest(eventLogForNewWindow,'Body',2); // 2 = open new window as window
|
||||
}
|
||||
|
||||
if (navigator.platform.indexOf("Lin") == -1) {
|
||||
if (navigator.platform.indexOf("Lin") == -1 && navigator.platform.indexOf("SunOS") == -1) {
|
||||
SimpleTest.waitForExplicitFinish(); // the finish() call is in bug299673.js
|
||||
addLoadEvent(doTest);
|
||||
} else {
|
||||
|
@ -268,15 +268,9 @@ nsHTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
||||
|
||||
nsRefPtr<nsPLDOMEvent> event = new nsPLDOMEvent(this, aEventName, PR_TRUE);
|
||||
if (event) {
|
||||
// If we have script blockers on the stack then we want to run as soon as
|
||||
// they are removed. Otherwise punt the runable to the event loop as we
|
||||
// don't know when it will be safe to run script. In particular, we might
|
||||
// be in the middle of a pagehide right now, and firing this event at that
|
||||
// point is not such a great idea.
|
||||
if (nsContentUtils::IsSafeToRunScript())
|
||||
event->PostDOMEvent();
|
||||
else
|
||||
event->RunDOMEventWhenSafe();
|
||||
// Always run async in order to avoid running script when the content
|
||||
// sink isn't expecting it.
|
||||
event->PostDOMEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsIDOMHTMLScriptElement.h"
|
||||
#include "nsIDOMNSHTMLScriptElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -304,6 +305,7 @@ nsHTMLScriptEventHandler::Invoke(nsISupports *aTargetObject,
|
||||
|
||||
class nsHTMLScriptElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLScriptElement,
|
||||
public nsIDOMNSHTMLScriptElement,
|
||||
public nsScriptElement
|
||||
{
|
||||
public:
|
||||
@ -322,8 +324,8 @@ public:
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLScriptElement
|
||||
NS_DECL_NSIDOMHTMLSCRIPTELEMENT
|
||||
NS_DECL_NSIDOMNSHTMLSCRIPTELEMENT
|
||||
|
||||
// nsIScriptElement
|
||||
virtual void GetScriptType(nsAString& type);
|
||||
@ -331,6 +333,7 @@ public:
|
||||
virtual void GetScriptText(nsAString& text);
|
||||
virtual void GetScriptCharset(nsAString& charset);
|
||||
virtual PRBool GetScriptDeferred();
|
||||
virtual PRBool GetScriptAsync();
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
@ -378,10 +381,11 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLScriptElement, nsGenericElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLScriptElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLScriptElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE4(nsHTMLScriptElement,
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLScriptElement,
|
||||
nsIDOMHTMLScriptElement,
|
||||
nsIScriptLoaderObserver,
|
||||
nsIScriptElement,
|
||||
nsIDOMNSHTMLScriptElement,
|
||||
nsIMutationObserver)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLScriptElement,
|
||||
nsGenericHTMLElement)
|
||||
@ -450,6 +454,7 @@ nsHTMLScriptElement::SetText(const nsAString& aValue)
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Charset, charset)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLScriptElement, Defer, defer)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLScriptElement, Async, async)
|
||||
NS_IMPL_URI_ATTR(nsHTMLScriptElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Type, type)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLScriptElement, HtmlFor, _for)
|
||||
@ -519,11 +524,22 @@ nsHTMLScriptElement::GetScriptCharset(nsAString& charset)
|
||||
PRBool
|
||||
nsHTMLScriptElement::GetScriptDeferred()
|
||||
{
|
||||
PRBool defer;
|
||||
PRBool defer, async;
|
||||
GetAsync(&async);
|
||||
GetDefer(&defer);
|
||||
nsCOMPtr<nsIURI> uri = GetScriptURI();
|
||||
|
||||
return defer && uri;
|
||||
return !async && defer && uri;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLScriptElement::GetScriptAsync()
|
||||
{
|
||||
PRBool async;
|
||||
GetAsync(&async);
|
||||
nsCOMPtr<nsIURI> uri = GetScriptURI();
|
||||
|
||||
return async && uri;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -155,7 +155,7 @@ _TEST_FILES += \
|
||||
small-shot.ogg \
|
||||
sound.ogg \
|
||||
$(NULL)
|
||||
|
||||
|
||||
# Wave sample files
|
||||
_TEST_FILES += \
|
||||
big.wav \
|
||||
@ -178,7 +178,6 @@ _TEST_FILES += \
|
||||
ifdef MOZ_OGG
|
||||
_TEST_FILES += \
|
||||
dynamic_redirect.sjs \
|
||||
test_access_control.html \
|
||||
file_access_controls.html \
|
||||
test_bug448534.html \
|
||||
test_bug468190.html \
|
||||
@ -225,9 +224,10 @@ _TEST_FILES += \
|
||||
# test_autobuffer2.html
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
# These tests are disabled on windows until we
|
||||
# figure out the random failures. See bug 475369.
|
||||
# figure out the random failures. See bug 475369 and bug 526323
|
||||
_TEST_FILES += \
|
||||
test_timeupdate3.html \
|
||||
test_access_control.html \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
@ -4084,7 +4084,7 @@ ConvolvePixel(const PRUint8 *aSourceData,
|
||||
}
|
||||
for (PRInt32 i = 0; i < channels; i++) {
|
||||
aTargetData[aY * aStride + 4 * aX + offsets[i]] =
|
||||
BoundInterval(static_cast<PRInt32>(sum[i] / aDivisor + aBias * 255), 256);
|
||||
BoundInterval(static_cast<PRInt32>(sum[i] / aDivisor + aBias), 256);
|
||||
}
|
||||
if (aPreserveAlpha) {
|
||||
aTargetData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A] =
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
virtual void GetScriptText(nsAString& text);
|
||||
virtual void GetScriptCharset(nsAString& charset);
|
||||
virtual PRBool GetScriptDeferred();
|
||||
virtual PRBool GetScriptAsync();
|
||||
|
||||
// nsScriptElement
|
||||
virtual PRBool HasScriptContent();
|
||||
@ -232,6 +233,12 @@ nsSVGScriptElement::GetScriptDeferred()
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGScriptElement::GetScriptAsync()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsScriptElement methods
|
||||
|
||||
|
@ -2892,7 +2892,8 @@ nsXULDocument::ResumeWalk()
|
||||
// <html:script src="..." />) can be properly re-loaded if the
|
||||
// cached copy of the document becomes stale.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> overlayURI = mCurrentPrototype->GetURI();
|
||||
nsCOMPtr<nsIURI> overlayURI =
|
||||
mCurrentPrototype ? mCurrentPrototype->GetURI() : nsnull;
|
||||
|
||||
while (1) {
|
||||
// Begin (or resume) walking the current prototype.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user